tyczj
tyczj

Reputation: 73936

LocationManager's getBestProvider returning null

I have a bunch of people reporting an error that I cannot reproduce. When trying to open a MapView it's reporting that the getBestProvider is returning null and I know that means that that no provider is found that fulfills my criteria which is ACCURACY_COARSE so if there is no GPS then it should fall back on either network or passive but it obviously doesn't on those user devices. What would that even mean then that GPS is off and there is no network connection?

I tried turning GPS off and putting the phone into airplane mode to try to reproduce the problem but still I was able to open the mapview without a force close so I don't know how to handle this problem.

locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
geocoder = new Geocoder(this);

Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
List<String> lProviders = locationManager.getProviders(false);
for(int i=0; i<lProviders.size(); i++){
    Log.d("LocationActivity", lProviders.get(i));
}
String provider = locationManager.getBestProvider(criteria, true); // null

long minTime = 60000;
float minDistance = 5;

locationManager.requestLocationUpdates(provider, minTime, minDistance, this);

error

java.lang.RuntimeException: Unable to start activity ComponentInfo{ecm2.android/ecm2.android.LocationActivity}: 
java.lang.IllegalArgumentException: provider==null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
at android.app.ActivityThread.access$2300(ActivityThread.java:125)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: provider==null
at android.location.LocationManager.requestLocationUpdates(LocationManager.java:625)
at ecm2.android.LocationActivity.onCreate(LocationActivity.java:142)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)

Upvotes: 24

Views: 30238

Answers (2)

Dekel Dahan
Dekel Dahan

Reputation: 201

androidManifest.xml

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

MapsActivity.java

 @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (permissions.length == 1 &&
            permissions[0] == android.Manifest.permission.ACCESS_FINE_LOCATION &&
            grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_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;
        }
        mMap.setMyLocationEnabled(true);
    } else {
        // Permission was denied. Display an error message.
    }
}

MapsActivity.java/onCreate()

if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {
        mMap.setMyLocationEnabled(true);
    } else {
        ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 1);
    }

this work for me;

Upvotes: 6

David Wasser
David Wasser

Reputation: 95628

In your call to getBestProvider() you've asked for enabled providers only (that's the second parameter in the method call which you have set to true). If the user has disabled all providers, you will get null.

In any case, you need to be able to deal with the situation where there are no available providers, so you'll need to check for null and tell the user that he has not enabled any location.

Upvotes: 24

Related Questions