El código solo devolverá 0.0, 0.0 coordenada GPS mientras lanza NullPointerException

Este es mi enésimo bash con la API de ubicación de Android, y parece que no puedo hacer que funcione correctamente. Este tutorial parece ser el más prometedor, pero solo puedo obtener este código para devolver una coordenada GPS de 0.0, 0.0 que no es muy útil …

Parece que hay una pista en cuanto a que getLocation () devuelve un error java.lang.NullPointerException, pero no estoy seguro de dónde debería incluso empezar a buscarlo.

Aquí está el error:

W/System.err: java.lang.NullPointerException W/System.err: at android.content.ContextWrapper.checkPermission(ContextWrapper.java:557) 

Intenté hacer un nuevo bloque de permisos, pegado en la parte inferior, pero me dio el mismo error.

¿Puede alguien señalarme en la dirección correcta aquí?

El código se divide en dos archivos de clase: MainActivity.java y GPSTracker.java.

GPSTracker.java

  package com.tutorial.android.location.api; // http://www.androidhive.xyz/2016/07/android-gps-location-manager-tutorial.html // with some modifications, especially for new permissions import android.Manifest; import android.app.Activity; import android.app.AlertDialog; import android.app.Service; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.IBinder; import android.provider.Settings; import android.support.annotation.Nullable; import android.support.v4.app.ActivityCompat; import android.util.Log; public class GPSTracker extends Service implements LocationListener { private String TAG = "¤¤"; private final Context mContext; public GPSTracker(Context mContext) { this.mContext = mContext; this.getLocation(); } boolean isGPSEnabled = false; boolean isNetworkEnabled = false; boolean canGetLocation = false; Location location; double latitude; double longitude; private static final long MIN_DISTANCE_CHANGE_FOR_UPDATE = 10; // 10 meters private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 30 sec protected LocationManager locationManager; public Location getLocation() { try { if(locationManager == null) { locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE); } if(isGPSEnabled != true) { isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); } if(isNetworkEnabled != true) { isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); } if (!isGPSEnabled && !isNetworkEnabled) { // no provider enabled :p Log.e(TAG, "getLocation() no provider :("); } else { this.canGetLocation = true; // get network location if (isNetworkEnabled) { // permission block: if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. // return TODO; } else { Log.e(TAG, "getLocation() permission DENIED"); } locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATE, this); if(locationManager != null) { location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if(location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } // get GPS location if(isGPSEnabled) { if(location == null) { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATE, this); Log.d(TAG, "getLocation() GPS Enabled"); if(locationManager != null){ location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if(location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } } } } catch (Exception e) { Log.e(TAG, "getLocation() ERROR...: " + e); e.printStackTrace(); } return location; } public double getLatitude() { if(location != null) { latitude = location.getLatitude(); } return latitude; } public double getLongitude() { if(location != null) { longitude = location.getLongitude(); } return longitude; } @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onLocationChanged(Location location) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { // GPS is ON Log.d(TAG, "GPS is ON"); } @Override public void onProviderDisabled(String provider) { // GPS is OFF Log.d(TAG, "GPS is OFF"); } // GPS dialog public boolean canGetLocation() { return this.canGetLocation; } // don't really need this when testing public void showSettingsAlert() { AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext); alertDialog.setTitle(R.string.gps_settings_title); alertDialog.setMessage(R.string.gps_settings_msg); alertDialog.setPositiveButton(R.string.gps_settings_word, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); mContext.startActivities(new Intent[]{intent}); // hm... } }); alertDialog.show(); } public void stopUsingGPS() { if(locationManager != null) { locationManager.removeUpdates(GPSTracker.this); } } } 

El bloque de permisos reescrito pero aún no funciona en GPSTracker.java:

 int permissionCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION); if(!(permissionCheck == PackageManager.PERMISSION_GRANTED)) { if(ActivityCompat.shouldShowRequestPermissionRationale((Activity) mContext, Manifest.permission.ACCESS_FINE_LOCATION)) { // explanation :p Log.i(TAG, "NOpe..."); } else { // request permission Log.d(TAG, "Requestion new permission"); ActivityCompat.requestPermissions((Activity) mContext, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, 1); } } 

MainActivity.java

 package com.tutorial.android.location.api; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; public class MainActivity extends AppCompatActivity { String TAG = "¤"; GPSTracker gps; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gps = new GPSTracker(this); if(gps.canGetLocation()) { Log.i(TAG, "onCreate() GPS is ON"); Log.i(TAG, "onCreate() " + gps.getLatitude()+ ", " + gps.getLongitude()); } else { Log.d(TAG, "onCreate() GPS is OFF"); } } } 

Este tutorial parece ser el más prometedor

Es un código realmente horrible.

Solo puedo obtener este código para devolver una coordenada GPS de 0.0, 0.0 que no es muy útil

Esto se debe a que solo tendrá una ubicación si getLastKnownLocation() devuelve uno. Es poco probable que lo haga.

El bloque de permisos reescrito pero aún no funciona en GPSTracker.java:

Hay dos problemas aquí:

  1. No puede solicitar permisos de un servicio.

  2. Este no es un servicio real. El autor de este código eligió crear una clase que amplíe el Service sin implementar o usar el servicio adecuadamente. Esto es lo que está causando su NullPointerException , ya que este no es un Context correctamente inicializado.

¿Puede alguien señalarme en la dirección correcta aquí?

Tira todo esto.

FWIW, aquí está mi aplicación de muestra para usar la API de LocationManager .

La receta es bastante simple:

Paso # 1: Obtenga un LocationManager llamando a getSystemService(Context.LOCATION_SERVICE) en algún Context . Yo hago eso en un fragmento:

  @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); template=getActivity().getString(R.string.url); mgr=(LocationManager)getActivity() .getSystemService(Context.LOCATION_SERVICE); } 

Paso # 2: Llamar requestUpdates() , pasando algo que implemente LocationListener . En mi caso, ese es el fragmento en sí mismo:

  @Override @SuppressWarnings({"MissingPermission"}) public void onStart() { super.onStart(); mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3600000, 1000, this); } 

Paso # 3: en onLocationChanged() de su LocationListener , haga algo con la Location que obtiene, que en mi caso es ejecutar una AsyncTask para obtener un pronóstico del tiempo:

  @Override public void onLocationChanged(Location location) { new FetchForecastTask().execute(location); } 

Paso # 4: Llame a removeUpdates() cuando haya terminado:

  @Override @SuppressWarnings({"MissingPermission"}) public void onStop() { mgr.removeUpdates(this); super.onStop(); } 

Y eso es todo (aparte de los permisos de tiempo de ejecución, que abstraigo en una AbstractPermissionsActivity ).

Si lo desea, use getLastKnownLocation() como una optimización , pero no confíe en ello.