GPS Application crash

2019-09-19 04:01发布

问题:

I have to write an application which does several things, including recording the GPS location of the user when a correct username and password is entered. I only want the latitude and longitude at that exact moment, no recurring checks or anything of that nature. I think I found something similar to what I was looking for:

How to call to get a single gps fix when ever i want android?

However, eclipse didn't like the context since I hadn't initialized it yet. So here is that entire section of the code:

Context context = getBaseContext();
LocationManager locMan = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
Log.i(getClass().getSimpleName(),"Location Manager called");
Location loc = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Log.i(getClass().getSimpleName(),"Last known location received");
Double latitude = loc.getLatitude();
Log.i(getClass().getSimpleName(),"Latitude:"+latitude);
Double longitude = loc.getLongitude();
Log.i(getClass().getSimpleName(),"Longitude:"+longitude);
Toast.makeText(context, latitude+","+longitude, Toast.LENGTH_LONG).show();

And for permissions in the manifest:

<uses-permission android:name="com.foxcatch.code.insecure.LOCATION_FINDER" /> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

However this crashes when I try to access the latitude and longitude and assign them to doubles:

Double latitude = loc.getLatitude();
Double longitude = loc.getLongitude();

Here's the LogCat Error entry, its a little over my head:

04-28 18:00:39.346: E/AndroidRuntime(32548): FATAL EXCEPTION: main 04-28 18:00:39.346: E/AndroidRuntime(32548): Process: com.rps.personaldata, PID: 32548 04-28 18:00:39.346: E/AndroidRuntime(32548): java.lang.NullPointerException 04-28 18:00:39.346: E/AndroidRuntime(32548): at com.rps.personaldata.MainActivity$1.onClick(MainActivity.java:58) 04-28 18:00:39.346: E/AndroidRuntime(32548): at android.view.View.performClick(View.java:4445) 04-28 18:00:39.346: E/AndroidRuntime(32548): at android.view.View$PerformClick.run(View.java:18429) 04-28 18:00:39.346: E/AndroidRuntime(32548): at android.os.Handler.handleCallback(Handler.java:733) 04-28 18:00:39.346: E/AndroidRuntime(32548): at android.os.Handler.dispatchMessage(Handler.java:95) 04-28 18:00:39.346: E/AndroidRuntime(32548): at android.os.Looper.loop(Looper.java:136) 04-28 18:00:39.346: E/AndroidRuntime(32548): at android.app.ActivityThread.main(ActivityThread.java:5081) 04-28 18:00:39.346: E/AndroidRuntime(32548): at java.lang.reflect.Method.invokeNative(Native Method) 04-28 18:00:39.346: E/AndroidRuntime(32548): at java.lang.reflect.Method.invoke(Method.java:515) 04-28 18:00:39.346: E/AndroidRuntime(32548): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:781) 04-28 18:00:39.346: E/AndroidRuntime(32548): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 04-28 18:00:39.346: E/AndroidRuntime(32548): at dalvik.system.NativeStart.main(Native Method)

I'm new to android, and I'm just trying to figure all of this out. Thanks for any help.

回答1:

Why getting the BaseContext.. just simply call directly the getSystemService

change this:

LocationManager locMan = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);

to:

LocationManager locMan = (LocationManager)getSystemService(Context.LOCATION_SERVICE);



回答2:

locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER); is returning null, which is why you're getting the NullPointerException. Any Context should work in retrieving the LocationManager.

getLastKnownLocation(LocationManager.GPS_PROVIDER) may return null if GPS hasn't been used in the recent past (especially since last reboot).

If a slightly less accurate location (e.g., cell tower level) is acceptable for your application, a better approach is to loop through all LocationProviders and find a non-null location:

public static Location getLocation2(Context cxt) {
    LocationManager mgr = (LocationManager) cxt.getSystemService(Context.LOCATION_SERVICE);
    List<String> providers = mgr.getProviders(true);
    Location last = null;
    for (Iterator<String> i = providers.iterator(); i.hasNext(); ) {
        Location loc = mgr.getLastKnownLocation(i.next());
        // If this provider has a last location, and either:
        // 1. We don't have a last location,
        // 2. Our last location is older than this location.
        if (loc != null && (last == null || loc.getTime() > last.getTime())) {
            last = loc;
        }
    }
    return last;
}

This will use give you the last known GPS position if it is available, and if not, you'll likely get a NETWORK_PROVIDER position.

Note that in rare cases (on normal Android devices) all providers may return null. In this scenario, you'd need to register a LocationListener and wait for a new location to be provided. See https://stackoverflow.com/a/23224818/937715 for a full solution.

Related - for code that takes into consideration the accuracy of each position from each provider, see https://stackoverflow.com/a/21364664/937715.

One final note - you may want to consider using the new(er) fused location provider that is part of Google Play Services, which in my experience is better about always providing a last known location. For sample code that gets the last known location using the fused location provider, see the "Retrieving the Current Location" example.