Location Method Calls Crashes On Some Devices

2019-08-03 07:57发布

问题:

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)

回答1:

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!!)



回答2:

If it hasn't had a fix at all, then after the line

 Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 

location will be null. Therefore you need to cope with this by enclosing code that requires a location with

if (location != null){
    // your code
}


回答3:

or try this

private class JavaScriptInterface { // use in javascript 
    public double getLatitude() {
        try{
            return mostRecentLocation.getLatitude();
        }catch(Exception e){ //some devive without last location
            return 25.046254;//default set Taipei Train Station (City Land Mark)
        }   
    }
    public double getLongitude() {
        try{
            return mostRecentLocation.getLongitude();
        }catch(Exception e){ //some devive without last location
            return 121.51752;//default set Taipei Train Station (City Land Mark)
        }
    }
}