Получить текущее имя местоположения пользователя без использования gps или интернета, но с помощью поставщика сети в android

этот вопрос непосредственно связан с тем же преобладающим вопросом stackoverflow в "Android: получить текущее местоположение пользователя без использования gps или интернета " где принятый ответ фактически не отвечает на вопрос.

Я должен иметь возможность получить текущее имя местоположения (например:название города, название деревни) устройства через поставщика сети не с GPS или интернетом. Ниже приведен принятый ответ на этот вопрос. (Следующие части кода должны быть включено в onCreate() способ)

// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
    public void onLocationChanged(Location location) {
      // Called when a new location is found by the network location provider.
      makeUseOfNewLocation(location);
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {}

    public void onProviderEnabled(String provider) {}

    public void onProviderDisabled(String provider) {}
  };

// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

Я изменил приведенный выше код в связанном ответе следующим образом, но без успеха.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final TextView txtView = (TextView) findViewById(R.id.tv1);
    txtView.setText("ayyo samitha");
    ////

    // Acquire a reference to the system Location Manager
    LocationManager locationManager;
   locationManager= (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

    // Define a listener that responds to location updates
    LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
            // Called when a new location is found by the network location provider.
            makeUseOfNewLocation(location);

        }

        private void makeUseOfNewLocation(Location location) {
            txtView.setText("sam came in");
            txtView.append(location.toString());
        }

        public void onStatusChanged(String provider, int status, Bundle extras) {}

        public void onProviderEnabled(String provider) {
           // makeUseOfNewLocation(location);
        }

        public void onProviderDisabled(String provider) {}
    };

    // Register the listener with the Location Manager to receive location updates
    if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
    }

}

Как выполнить то, что я хочу, исправляя выше код или любой другой метод? Обратите внимание, что я хочу получить имя местоположения, но не долготы и широты. Кто-нибудь, пожалуйста, помогите мне.

6 ответов


то, что вы имеете в виду здесь (показывая имя местоположения на старых телефонах) делается с помощью "сотового вещания" (или "CB"). Это не имеет абсолютно ничего общего с API местоположения или любые вариации на эту.

сотовые вышки могут отправлять широковещательную информацию, которая может быть получена устройствами (что-то вроде "от одного до многих SMS"). Некоторые операторы использовали сотовую трансляцию для трансляции имени местоположения, где находится сотовая вышка. Некоторые операторы использовали передачу сотовой связи для передачи расположение (лат/Лонг) вышки сотовой связи. Некоторые операторы использовали сотовую трансляцию для отправки рекламных тикеров. Нет стандартов для информации, содержащейся в широковещательном сообщении CB, и каждый оператор мобильной связи может использовать это или нет.

поскольку большинство операторов не отправляют эти сообщения, вероятно, нет смысла тратить время на их получение и декодирование. Но если вы хотите попробовать, вы можете зарегистрировать BroadcastReceiver прослушивание этого Intent действие: android.provider.Telephony.SMS_CB_RECEIVED. Видеть документация для получения более подробной информации о том, какие данные содержатся в Intent.


проблема в том, что код, который вы пробовали, работает, вероятно, не так хорошо, как вы хотели. Например, точность, которую такой метод обеспечивает на Samsung Galaxy S3, составляет 2000 м, то есть фактическое положение находится в любом месте в радиусе 2 километров. Кроме того, вероятно, потребуется довольно большое изменение местоположения, прежде чем ваше приложение будет проинформировано об изменении местоположения, поскольку допустимая погрешность настолько велика.

GPS или LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY (Если используются сервисы Google Play) требуется, чтобы получить достаточно хорошее место. Это требует android.permission.ACCESS_FINE_LOCATION, однако, если вам не требуется только точность уровня км, в противном случае это разрешение является обязательным.

наконец, обратите внимание, что использование сервисов Google Play с LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY Я могу получить данные о местоположении с точностью до 10 м без включение GPS, поэтому это должно по-прежнему удовлетворять вашим требованиям.

Ниже приведен полный пример:

AndroidManifest.в XML

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

MainActivity.java

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

public class MainActivity extends Activity implements
        com.google.android.gms.location.LocationListener, ConnectionCallbacks,
        OnConnectionFailedListener {
    private final FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
    private GoogleApiClient mGoogleAPIClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mGoogleAPIClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API).addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).build();
    }

    @Override
    protected void onResume() {
        super.onResume();

        mGoogleAPIClient.connect();
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (mGoogleAPIClient != null) {
        mGoogleAPIClient.disconnect();
        }
    }

    @Override
    public void onConnected(Bundle arg0) {
        final LocationRequest locationRequest = LocationRequest.create();
        locationRequest
                .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);
        fusedLocationProviderApi.requestLocationUpdates(mGoogleAPIClient,
                locationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onConnectionFailed(ConnectionResult arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onLocationChanged(Location location) {
        // the location is no more than 10 min old, and with reasonable
        // accurarcy (50m), done
        if (System.currentTimeMillis() < location.getTime() + 10 * 60 * 1000
                && location.getAccuracy() < 50) {
            mGoogleAPIClient.disconnect();
            mGoogleAPIClient = null;
            ((TextView) findViewById(R.id.test)).setText(location.toString());
        }
    }
}

в соответствии с документами android с помощью LocationManager не является текущим рекомендуемым API (см. ссылка):

The Google Play services location APIs are preferred over the 
Android framework location APIs (android.location) as a way of
adding location awareness to your app.

чтобы узнать, как настроить клиентскую библиотеку служб Google, см. настройка в руководстве Google Play services.

после того, как вы связали клиентскую библиотеку Google Services с вашим приложением, вы можете достичь местоположения пользователя с помощью FusedLocationProviderApi:

    import android.location.Location;
    import android.os.Bundle;
    import android.support.v7.app.ActionBarActivity;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.Toast;

    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
    import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
    import com.google.android.gms.common.api.PendingResult;
    import com.google.android.gms.common.api.ResultCallback;
    import com.google.android.gms.common.api.Status;
    import com.google.android.gms.location.FusedLocationProviderApi;
    import com.google.android.gms.location.LocationListener;
    import com.google.android.gms.location.LocationRequest;
    import com.google.android.gms.location.LocationServices;

    public class MainActivity extends ActionBarActivity
            implements ConnectionCallbacks, OnConnectionFailedListener {

        // ..

        private GoogleApiClient mGoogleAPIClient;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            // create google api client object
            mGoogleAPIClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        }

        @Override
        protected void onStart() {
            super.onStart();

            mGoogleAPIClient.connect();
        }

        @Override
        protected void onStop() {
            super.onStop();

            mGoogleAPIClient.disconnect();
        }

        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {
            Toast.makeText(this,
                "Could not connect to Google Play Services",
                Toast.LENGTH_SHORT).show();

            finish();
        }

        @Override
        public void onConnected(Bundle bundle) {
            Log.i(TAG,
                "Successfuly connect to Google Play Services");

            // retrieve last location once connected
            Location lastLocation = LocationServices.FusedLocationApi
                .getLastLocation(mGoogleAPIClient);

            if (lastLocation == null) {
                // should request new one
                // location should be enabled
                Log.i(TAG,
                    "No location data previously acquired.. should request!");

                Toast.makeText(this,
                    "Requesting location data ..",
                    Toast.LENGTH_SHORT).show();

                LocationRequest locationRequest = LocationRequest.create();
                locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
                locationRequest.setInterval(5000);

                PendingResult<Status> result = LocationServices.FusedLocationApi
                    .requestLocationUpdates(mGoogleAPIClient,
                        locationRequest,
                        new LocationListener() {

                    @Override
                    public void onLocationChanged(Location location) {
                        makeUseOfNewLocation(location);
                    }
                });

                // TODO: use result to retrieve more info

            } else {
                makeUseOfNewLocation(lastLocation);
            }
        }

        @Override
        public void onConnectionSuspended(int i) {
        }

        private void makeUseOfNewLocation(Location location) {
             // do your stuff here
        }

Я проверил приведенный выше код и он работает без подключения к интернету, но это требуется, чтобы пользователь включил функцию определения местоположения на устройстве. Также требуется, чтобы пользователь уже включил функцию Истории местоположений в функцию местоположения.

надеюсь, что это помогает вам.


вы можете попробовать получить точность на уровне страны с помощью объекта Locale или с помощью службы телефонии. Нет интернета или GPS не требуется.

получение кода страны из локали:

String locale = context.getResources().getConfiguration().locale.getCountry();

получение кода страны из службы телефонии Android:

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
// Will work on all networks. Only provide the SIM card's country
String countryCode = tm.getSimCountryIso();

// Might not work well on CDMA networks. Will provide the country code
// for the country the device is currently in.
String currentCountryCode = tm.getNetworkCountryIso();

лучшие образцы кода и обсуждение здесь.


попробуйте этот код..

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;

public class AppLocationService extends Service implements LocationListener         {

protected LocationManager locationManager;
Location location;

private static final long MIN_DISTANCE_FOR_UPDATE = 10;
private static final long MIN_TIME_FOR_UPDATE = 1000 * 60 * 2;

public AppLocationService(Context context) {
    locationManager = (LocationManager) context
            .getSystemService(LOCATION_SERVICE);
}

public Location getLocation(String provider) {
    if (locationManager.isProviderEnabled(provider)) {
        locationManager.requestLocationUpdates(provider,
                MIN_TIME_FOR_UPDATE, MIN_DISTANCE_FOR_UPDATE, this);
        if (locationManager != null) {
            location = locationManager.getLastKnownLocation(provider);
            return location;
        }
    }
    return null;
}

@Override
public void onLocationChanged(Location location) {
}

@Override
public void onProviderDisabled(String provider) {
}

@Override
public void onProviderEnabled(String provider) {
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

}

и в следующий класс

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class AndroidLocationActivity extends Activity {

Button btnGPSShowLocation;
Button btnNWShowLocation;

AppLocationService appLocationService;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    appLocationService = new AppLocationService(
            AndroidLocationActivity.this);

    btnGPSShowLocation = (Button) findViewById(R.id.btnGPSShowLocation);
    btnGPSShowLocation.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {

            Location gpsLocation = appLocationService
                    .getLocation(LocationManager.GPS_PROVIDER);

            if (gpsLocation != null) {
                double latitude = gpsLocation.getLatitude();
                double longitude = gpsLocation.getLongitude();
                Toast.makeText(
                        getApplicationContext(),
                        "Mobile Location (GPS): \nLatitude: " + latitude
                                + "\nLongitude: " + longitude,
                        Toast.LENGTH_LONG).show();
            } else {
                showSettingsAlert("GPS");
            }

        }
    });

    btnNWShowLocation = (Button) findViewById(R.id.btnNWShowLocation);
    btnNWShowLocation.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {

            Location nwLocation = appLocationService
                    .getLocation(LocationManager.NETWORK_PROVIDER);

            if (nwLocation != null) {
                double latitude = nwLocation.getLatitude();
                double longitude = nwLocation.getLongitude();
                Toast.makeText(
                        getApplicationContext(),
                        "Mobile Location (NW): \nLatitude: " + latitude
                                + "\nLongitude: " + longitude,
                        Toast.LENGTH_LONG).show();
            } else {
                showSettingsAlert("NETWORK");
            }

        }
    });

}

public void showSettingsAlert(String provider) {
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(
            AndroidLocationActivity.this);

    alertDialog.setTitle(provider + " SETTINGS");

    alertDialog
            .setMessage(provider + " is not enabled! Want to go to settings menu?");

    alertDialog.setPositiveButton("Settings",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent(
                            Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    AndroidLocationActivity.this.startActivity(intent);
                }
            });

    alertDialog.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

    alertDialog.show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

} и это разрешение пользователя дано

<!-- to get location using GPS -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- to get location using NetworkProvider -->
<uses-permission android:name="android.permission.INTERNET" />

удачи с этим. Это называется геокодер. Или, более конкретно, обратное геокодирование, чтобы превратить координаты в читаемый человеком вывод. Я уверен, что google предоставляет платную услугу, но вы получаете кучу бесплатно. Поэтому планируйте кэширование результатов и использование кэшированных результатов, когда это возможно.

List<Address> list = geoCoder.getFromLocation(location
            .getLatitude(), location.getLongitude(), 1);
    if (list != null & list.size() > 0) {
        Address address = list.get(0);
        result = address.getLocality();
        return result;

https://developer.android.com/training/location/display-address.html

как получить название города от широты и долготы координаты в Google Maps?