Как программно получить местоположение (широта, долгота) в API 23 и выше в Android?

Я разрабатываю приложение, которое включает GPS и получает текущее местоположение. Мой код отлично работает во всех версиях Android, кроме API 23, то есть Marshmallows. Я тестирую Nexus 5 (API 23), Galaxy Note 3 (API 22).

Вот мой код

    public void program()
{
     locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MINIMUM_TIME_BETWEEN_UPDATES, MINIMUM_DISTANCE_CHANGE_FOR_UPDATES, new MyLocationListener());

    if (!locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {

        AlertDialog.Builder builder = new AlertDialog.Builder(NearBy.this);
        builder.setTitle("Location Service is Not Active");
        builder.setMessage("Please Enable your location services").setCancelable(false)
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {

                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivity(intent);

                    }
                });
        AlertDialog alert = builder.create();
        alert.show();
    } else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
        Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        Geocoder geocoder = new Geocoder(this, Locale.getDefault());
        List<Address> addresses = null;
        try {
            addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);

            final String cityName = addresses.get(0).getAddressLine(0) + " ";
            String stateName = addresses.get(0).getAddressLine(1) + " ";
            String countryName = addresses.get(0).getAddressLine(2) + " ";
            String country = addresses.get(0).getCountryName() + " ";
            String Area = addresses.get(0).getSubAdminArea() + " ";
            String Area1 = addresses.get(0).getAdminArea() + " ";
            String Area2 = addresses.get(0).getLocality() + " ";
            String Area3 = addresses.get(0).getSubLocality();
            Log.e("Locaton", cityName + stateName + countryName + country + Area + Area1 + Area2 + Area3);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }
}

Я получаю NullpointerException в

         addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);

только в Nexus 5 (API 23). Я также предоставил разрешение (ACCESS_FINE_LOCATION и ACCESS_COARSE_LOCATION) как в Mainfest, так и во время выполнения.

Пожалуйста, предоставьте решение для этого.

ОБНОВЛЕНО

Я изменил свой код. Я создал класс GPSTracker, и я получаю lat, Lng как 0

GPSTracker.java

  public class GPSTracker extends Activity implements LocationListener {
private final Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude

private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

protected LocationManager locationManager;

public GPSTracker(Context context) {
    this.mContext = context;
    getLocation();
}

public Location getLocation() {
    try {
        locationManager = (LocationManager) mContext
                .getSystemService(LOCATION_SERVICE);


        isGPSEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);

        isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (!isGPSEnabled && !isNetworkEnabled) {

        } else {
            this.canGetLocation = true;
            if (isNetworkEnabled) {
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                Log.d("Network", "Network");
                if (locationManager != null) {
                    location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                    }
                }
            }

            if (isGPSEnabled) {
                if (location == null) {
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("GPS Enabled", "GPS Enabled");
                    if (locationManager != null) {
                        location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return location;
}
@TargetApi(Build.VERSION_CODES.M)
public void stopUsingGPS() {
    if (locationManager != null) {
        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }
        locationManager.removeUpdates(GPSTracker.this);
    }
}


public double getLatitude() {
    if (location != null) {
        latitude = location.getLatitude();
    }

    return latitude;
}

public double getLongitude() {
    if (location != null) {
        longitude = location.getLongitude();
    }

    return longitude;
}


public boolean canGetLocation() {
    return this.canGetLocation;
}


public void showSettingsAlert() {
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

    alertDialog.setTitle("GPS is settings");

    alertDialog.setMessage("GPS is not enabled. Do you 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);
            mContext.startActivity(intent);
        }
    });

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

    alertDialog.show();
}

@Override
public void onLocationChanged(Location currentLocation) {

    this.location = currentLocation;
    getLatitude();
    getLongitude();

}

@Override
public void onProviderDisabled(String provider) {

}

@Override
public void onProviderEnabled(String provider) {


}

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

}
}

person Anish Kumar    schedule 22.03.2016    source источник
comment
Можете ли вы опубликовать вывод logcat?   -  person cafebabe1991    schedule 22.03.2016
comment
вы должны проверить разрешение времени выполнения, например, если ( Build.VERSION.SDK_INT ›= 23 && ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission( context, android.Manifest.permission. ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return ; }   -  person saeed    schedule 22.03.2016
comment
GPSTracker.java помог мне получить почтовый индекс - спасибо!   -  person Gene Bo    schedule 04.11.2016


Ответы (2)


Проблема

The location obtained may be null if the last know location could not be found due to various reasons. Read about it in the docs [here][2]

Причина/Как я это отладил

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

    Прочитайте здесь об этом методе

Устранение

Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

Убедитесь, что местоположение, полученное на предыдущем шаге, НЕ NULL, а затем продолжите работу с геокодером.

Фрагмент кода

...
else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
    Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    if(location == null) {
       log.d("TAG", "The location could not be found");
       return; 
    }
    //else, proceed with geocoding.
    Geocoder geocoder = new Geocoder(this, Locale.getDefault());

Получение местоположения — пример

Читать здесь

Полный код

Посмотреть здесь

person cafebabe1991    schedule 22.03.2016
comment
Если проблема в моем местоположении, то как я получу lat,lng с тем же кодом на других устройствах, которые работают в API 22 и ниже. На самом деле теперь я создал GPSTracker.java, и я получаю lat и lng как 0 - person Anish Kumar; 22.03.2016
comment
@AnishKumar: это возможно только на других устройствах, если в них было доступно lastKnownLocation. Попробуйте распечатать объект местоположения в этих устройствах, и вы убедитесь в этом сами. - person cafebabe1991; 22.03.2016
comment
Отлично @cafebabe1991. Я дам вам знать в ближайшее время. - person Anish Kumar; 22.03.2016
comment
Я попытался напечатать объект местоположения в нексусе 5, я получил Null. Но когда я запускаю другое устройство, я получаю местоположение. - person Anish Kumar; 22.03.2016
comment
Да. Спасибо дружище!!!. Есть ли способ отсортировать это? Я очень удивлен, потому что я только что запускаю свой старый проект в nexus 5, для которого targetSdkVersion и compileSdkVersion равны 22, и я получаю точное местоположение. - person Anish Kumar; 22.03.2016
comment
Видите ли, единственный способ сделать это — получить местоположение только тогда, когда соблюдены условия для его получения. Проверьте SettingsApi от Google, а затем следуйте этому руководству для получения дополнительной помощи. google.co.in/ Полный код для получения местоположения. .. github.com/googlesamples/android-play-location - person cafebabe1991; 22.03.2016
comment
Давайте продолжим обсуждение в чате. - person cafebabe1991; 22.03.2016

Сначала в зефир также добавьте все разрешения во время выполнения. В противном случае перезагрузите свой мобильный телефон и проверьте еще раз.

person AMIT YADAV    schedule 22.03.2016