Fused location API runtime permissions error

2.4k views Asked by At

I am trying to get the permission for accessing the location and using the Fusedlocation provider API for android, however, my app crashes on opening. I reviewed the Google developer documentation and made the changes appropriately to the respective method.

When I get a location, I am passing the coordinates and store them using SharedPreferences. Can you please let me know what did I not handle in the program or handle incorrectly?

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, LocationListener {

private final String TAG = "LocationActivity";

private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;

String lat, lon;
Location mLastLocation;
GridView androidGridView;
String[] gridViewString = {


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //checkAppPermission();
    Log.d(TAG, "Test location ..............");
    //setup GoogleApiclient
    buildGoogleApiClient();
    Log.d(TAG, "After build api client");
}
public void checkAppPermission(){
    if (checkPermission()) {
        Toast.makeText(this, "Permission already granted.", Toast.LENGTH_LONG).show();
    } else {
        requestPermission();
        Toast.makeText(this, "Please request permission.", Toast.LENGTH_LONG).show();
    }
}
private boolean checkPermission() {
    int result = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION);
    Log.d(TAG, "Test location 2..............");
    return result == PackageManager.PERMISSION_GRANTED;

}
private void requestPermission() {

    ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, 1);
    Log.d(TAG, "requestPermissions..............");
}
//This method will be called when the user will tap on allow or deny
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    //Checking the request code of our request
    Log.d(TAG, "onRequestPermissionsResult..............");

    if (requestCode == 1) {

        //If permission is granted
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            //Displaying a toast
            Toast.makeText(this, "Permission granted now you can read the storage", Toast.LENGTH_LONG).show();
        } else {
            //Displaying another toast if permission is not granted
            Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (shouldShowRequestPermissionRationale(android.Manifest.permission.ACCESS_FINE_LOCATION)) {
                    showMessageOKCancel("You need to allow access to both the permissions",
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                        requestPermissions(new String[]{ACCESS_FINE_LOCATION,},
                                                1);
                                    }
                                }
                            });
                    return;
                }
            }
        }
    }
}


private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
    new AlertDialog.Builder(MainActivity.this)
            .setMessage(message)
            .setPositiveButton("OK", okListener)
            .setNegativeButton("Cancel", null)
            .create()
            .show();
}

protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();
    Log.d(TAG, "GoogleAPIclient init ..............");

}

@Override
protected void onStart() {
    super.onStart();
    // Connect the client.
    Log.d(TAG, "onStart fired ..............");
    mGoogleApiClient.connect();

}

@Override
protected void onStop() {
    // Disconnecting the client invalidates it.
    mGoogleApiClient.disconnect();
    Log.d(TAG, "onStop fired ..............");
    super.onStop();
}

@Override
public void onConnected(Bundle bundle) {
    checkAppPermission();
    Log.d(TAG, "inside onconnected");
    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(1000); // Update location every 10 seconds
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
    if (mLastLocation != null) {
        lat = String.valueOf(mLastLocation.getLatitude());
        lon = String.valueOf(mLastLocation.getLongitude());
    }
    Log.d(TAG,"" +lat);
    Log.d(TAG,""+ lon);
    Log.d(TAG, "calling storeprefs inside onconnected");
    storeprefs(lat,lon);
}

@Override
public void onConnectionSuspended(int i) {
    Log.i(TAG, "GoogleApiClient connection has been suspend");
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Log.i(TAG, "GoogleApiClient connection has failed");
}
@Override
protected void onPause() {
    super.onPause();
}

@Override
public void onLocationChanged(Location location) {
    // New location has now been determined
    String lat = Double.toString(location.getLatitude());
    String lon = Double.toString(location.getLongitude());
    Log.i(TAG, lat);
    Log.i(TAG, lon);
    storeprefs(lat,lon);
    // You can now create a LatLng Object for use with maps
    //LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());

}

Error:

 FATAL EXCEPTION: main
                                               Process: com.example.android.wesport, PID: 11572
                                               java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.wesport/com.example.android.wesport.MainActivity}: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
                                                   at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
                                                   at android.os.Handler.dispatchMessage(Handler.java:102)
                                                   at android.os.Looper.loop(Looper.java:154)
                                                   at android.app.ActivityThread.main(ActivityThread.java:6077)
                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
                                                Caused by: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
                                                   at com.google.android.gms.internal.zzof.zzd(Unknown Source)
                                                   at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
                                                   at com.example.android.wesport.MainActivity.onCreate(MainActivity.java:82)
                                                   at android.app.Activity.performCreate(Activity.java:6662)
                                                   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
                                                   at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
                                                   at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                   at android.os.Looper.loop(Looper.java:154) 
                                                   at android.app.ActivityThread.main(ActivityThread.java:6077) 
                                                   at java.lang.reflect.Method.invoke(Native Method) 
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 

Stack trace 2

FATAL EXCEPTION: main
              Process: com.example.android.wesport, PID: 5763
              java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations.
                  at android.os.Parcel.readException(Parcel.java:1683)
                  at android.os.Parcel.readException(Parcel.java:1636)
                  at com.google.android.gms.location.internal.zzi$zza$zza.zza(Unknown Source)
                  at com.google.android.gms.location.internal.zzk.zza(Unknown Source)
                  at com.google.android.gms.location.internal.zzl.zza(Unknown Source)
                  at com.google.android.gms.location.internal.zzd$1.zza(Unknown Source)
                  at com.google.android.gms.location.internal.zzd$1.zza(Unknown Source)
                  at com.google.android.gms.internal.zznt$zza.zzb(Unknown Source)
                  at com.google.android.gms.internal.zzoc.zzf(Unknown Source)
                  at com.google.android.gms.internal.zzoc.zzd(Unknown Source)
                  at com.google.android.gms.internal.zzoh.zzd(Unknown Source)
                  at com.google.android.gms.internal.zzof.zzd(Unknown Source)
                  at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
                  at com.example.android.wesport.MainActivity.onConnected(MainActivity.java:171)
                  at com.google.android.gms.common.internal.zzl.zzm(Unknown Source)
                  at com.google.android.gms.internal.zzof.zzk(Unknown Source)
                  at com.google.android.gms.internal.zzod.zzsb(Unknown Source)
                  at com.google.android.gms.internal.zzod.onConnected(Unknown Source)
                  at com.google.android.gms.internal.zzoh.onConnected(Unknown Source)
                  at com.google.android.gms.internal.zznw.onConnected(Unknown Source)
                  at com.google.android.gms.common.internal.zzk$1.onConnected(Unknown Source)
                  at com.google.android.gms.common.internal.zzd$zzj.zztp(Unknown Source)
                  at com.google.android.gms.common.internal.zzd$zza.zzc(Unknown Source)
                  at com.google.android.gms.common.internal.zzd$zza.zzw(Unknown Source)
                  at com.google.android.gms.common.internal.zzd$zze.zztr(Unknown Source)
                  at com.google.android.gms.common.internal.zzd$zzd.handleMessage(Unknown Source)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6077)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
1

There are 1 answers

3
CommonsWare On BEST ANSWER
Caused by: java.lang.IllegalStateException: GoogleApiClient is not connected yet.

You cannot call requestLocationUpdates() until onConnected() is called. However, you are calling requestLocationUpdates() already in onCreate(), if you have determined that you hold the runtime permission.