Search code examples
androidgoogle-maps-api-2

Exception in Android Google Map Api V2


I tried this piece of code from an example,but get exceptions in onResume().I can't understand what's the problem?Anyone can give suggestion for this?

My code

public class MainActivity extends Activity 
        implements LocationSource, LocationListener{

final int RQS_GooglePlayServices = 1;
private GoogleMap myMap;
TextView tvLocInfo;

LocationManager myLocationManager = null;
OnLocationChangedListener myLocationListener = null;
Criteria myCriteria;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tvLocInfo = (TextView)findViewById(R.id.locinfo);

    FragmentManager myFragmentManager = getFragmentManager();
    MapFragment myMapFragment 
        = (MapFragment)myFragmentManager.findFragmentById(R.id.map);
    myMap = myMapFragment.getMap();

    myMap.setMyLocationEnabled(true);

    myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

    myCriteria = new Criteria();
    myCriteria.setAccuracy(Criteria.ACCURACY_FINE);
    myLocationManager = (LocationManager)getSystemService(LOCATION_SERVICE);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_legalnotices:
        String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
                getApplicationContext());
        AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
        LicenseDialog.setTitle("Legal Notices");
        LicenseDialog.setMessage(LicenseInfo);
        LicenseDialog.show();
        return true;    
    }
    return super.onOptionsItemSelected(item);   
}

@Override
protected void onResume() {
    super.onResume();

    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());

    if (resultCode == ConnectionResult.SUCCESS){
        Toast.makeText(getApplicationContext(), 
                "isGooglePlayServicesAvailable SUCCESS", 
                Toast.LENGTH_LONG).show();

        //Register for location updates using a Criteria, and a callback on the specified looper thread.
        myLocationManager.requestLocationUpdates(
                0L,             //minTime
                0.0f,           //minDistance
                myCriteria,     //criteria
                this,           //listener
                null);          //looper

        //Replaces the location source of the my-location layer.
        myMap.setLocationSource(this);

    }else{
        GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);    
    }

}

@Override
protected void onPause() {
    myMap.setLocationSource(null);
    myLocationManager.removeUpdates(this);

    super.onPause();
}

@Override
public void activate(OnLocationChangedListener listener) {
    myLocationListener = listener;
}

@Override
public void deactivate() {
    myLocationListener = null;
}

@Override
public void onLocationChanged(Location location) {
    if (myLocationListener != null) {
        myLocationListener.onLocationChanged(location);

        double lat = location.getLatitude();
        double lon = location.getLongitude();

        tvLocInfo.setText(
                "lat: " + lat + "\n" +
                "lon: " + lon);
    }
}

@Override
public void onProviderDisabled(String arg0) {
    // TODO Auto-generated method stub

}

@Override
public void onProviderEnabled(String arg0) {
    // TODO Auto-generated method stub

}

@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
    // TODO Auto-generated method stub

}

}

Logcat view

02-12 10:56:34.907: W/dalvikvm(1986): threadid=1: thread exiting with uncaught exception (group=0x40e55258)
02-12 10:56:34.922: E/AndroidRuntime(1986): FATAL EXCEPTION: main
02-12 10:56:34.922: E/AndroidRuntime(1986): java.lang.RuntimeException: Unable to resume activity {com.example.androidmapsv2/com.example.androidmapsv2.MainActivity}: java.lang.IllegalArgumentException: no provider_s found for criteria
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2491)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2519)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2033)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.app.ActivityThread.access$600(ActivityThread.java:127)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1179)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.os.Looper.loop(Looper.java:137)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.app.ActivityThread.main(ActivityThread.java:4508)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at java.lang.reflect.Method.invokeNative(Native Method)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at java.lang.reflect.Method.invoke(Method.java:511)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at dalvik.system.NativeStart.main(Native Method)
02-12 10:56:34.922: E/AndroidRuntime(1986): Caused by: java.lang.IllegalArgumentException: no provider_s found for criteria
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.os.Parcel.readException(Parcel.java:1331)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.os.Parcel.readException(Parcel.java:1281)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.location.ILocationManager$Stub$Proxy.requestLocationUpdates(ILocationManager.java:671)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.location.LocationManager._requestLocationUpdates(LocationManager.java:582)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.location.LocationManager.requestLocationUpdates(LocationManager.java:563)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at com.example.androidmapsv2.MainActivity.onResume(MainActivity.java:88)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1159)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.app.Activity.performResume(Activity.java:4553)
02-12 10:56:34.922: E/AndroidRuntime(1986):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2481)
02-12 10:56:34.922: E/AndroidRuntime(1986):     ... 12 more

Solution

  • You should look at the Android-Developers page where you can find the declaration of the requestLocationUpdates method.

    public void requestLocationUpdates (long minTime, float minDistance, Criteria criteria, LocationListener listener, Looper looper)
    

    There you can see what Exceptions the method throws

    Throws
        IllegalArgumentException    if criteria is null
        IllegalArgumentException    if listener is null
        SecurityException   if no suitable permission is present
    

    If you now look at your code

        myLocationManager.requestLocationUpdates(
                0L,             //minTime
                0.0f,           //minDistance
                myCriteria,     //criteria
                this,           //listener
                null);          //looper
    

    and your Exception

    E/AndroidRuntime: java.lang.RuntimeException: Unable to resume activity {...}: 
            java.lang.IllegalArgumentException: no provider_s found for criteria
                       ^^^^^^^ this                              and this  ^^^^
    

    aswell as

    at com.example.androidmapsv2.MainActivity.onResume(MainActivity.java:88)
    

    you can see that the IllegalArgumentException is thrown in line 88. The reason for this is that criteria is null when requestLocationUpdates is called.

    The initialization of your criteria in OnCreate is not enough. When your OnResume is called you need to do a null check to confirm that the criteria is instantiated.