Search code examples
androidcrashlocationmanager

Location Method Calls Crashes On Some Devices


I've got an app that uses MapView and I print out the user's latitude, longitude and horizontal accuracy to some labels. This all works fine on my HTC Wildfire, but on my SE Xperia the app crashes whenever I try to touch Location.getLatitude(), Location.getLongitude() or Location.getAccuracy().

I've got a hunch that it could be the GPS on the Xperia being so slow the location manager hasn't obtained its coordinates when I'm polling for lat, long and accuracy - but how can i safeguard against this?

Here's the snippet:

        mapView.setBuiltInZoomControls(false);
        mc = mapView.getController();
        int maxLat = (int) (34.07687 * 1E6);
        int maxLon = (int) (-118.438239 * 1E6);
        int minLat = (int) (34.06489 * 1E6);
        int minLon = (int) (-118.452358 * 1E6);
        List <Overlay> overlays = mapView.getOverlays();

        MyLocationOverlay myLocationOverlay = new MyLocationOverlay(this, mapView);
        myLocationOverlay.enableMyLocation();
        overlays.add(myLocationOverlay);

        mc.zoomToSpan(Math.abs(maxLat - minLat), Math.abs(maxLon - minLon));

        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);    
        Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 



        GeoPoint gp = new GeoPoint((int)(location.getLatitude() * 1E6), (int)(location.getLongitude() * 1E6));

LOGCAT OUTPUT:

01-09 13:32:04.086: W/dalvikvm(1794): threadid=1: thread exiting with uncaught exception (group=0x2aac8560)
01-09 13:32:04.086: E/AndroidRuntime(1794): FATAL EXCEPTION: main
01-09 13:32:04.086: E/AndroidRuntime(1794): java.lang.NullPointerException
01-09 13:32:04.086: E/AndroidRuntime(1794):     at no.tibeapp.sno.UlovligeGarnActivity$1.run(UlovligeGarnActivity.java:180)
01-09 13:32:04.086: E/AndroidRuntime(1794):     at android.os.Handler.handleCallback(Handler.java:587)
01-09 13:32:04.086: E/AndroidRuntime(1794):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-09 13:32:04.086: E/AndroidRuntime(1794):     at android.os.Looper.loop(Looper.java:123)
01-09 13:32:04.086: E/AndroidRuntime(1794):     at android.app.ActivityThread.main(ActivityThread.java:3701)
01-09 13:32:04.086: E/AndroidRuntime(1794):     at java.lang.reflect.Method.invokeNative(Native Method)
01-09 13:32:04.086: E/AndroidRuntime(1794):     at java.lang.reflect.Method.invoke(Method.java:507)
01-09 13:32:04.086: E/AndroidRuntime(1794):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)
01-09 13:32:04.086: E/AndroidRuntime(1794):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
01-09 13:32:04.086: E/AndroidRuntime(1794):     at dalvik.system.NativeStart.main(Native Method)

Solution

  • That's because LocationManager.getLastKnownLocation() can return null.

    In your code, you requested GPS provider to update your deivce's location. But when device's GPS is off, that method return null.

    And if any requests hasn't been processed through LocationManager, LocationManager.getLastKnownLocation() return null value as well. Because LocationManager doesn't have a "Last Known Locations" value.

    (You can check LocationManager's state with following adb command)

    $adb shell dumpsys location
    

    Therefore, if you want to get success with your code snippet, your device's GPS is ON and LocationManager has a "Last Known Locations"

    Well, I use LocationManager.getLastKnownLocation() method as well, but slightly different .

    I just check if there is any "Last Known Locations" value with LocationManager.getLastKnownLocation() method. Because that is fastest way to resolve current location value. However, If it return null, then request location update through requestLocationUpdates.

    Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
    if (location == null) {
        // request location update!!
        lm.requestLocationUpdates (LocationManager.GPS_PROVIDER, 0, 0, listener);
    }
    

    There is also some technic resolve device's location, I think that's gonna be huge answer. Instead, I will link this video which is great explanation about location. (and other more tips!!)