I am writing location based app. My location is working fine for API < 23 but whenever I am running on device for API 23 its giving error as "GoogleApiClient is not connected yet".
I checked with logs that GoogleApiClient is connected. But I dont understand what's the issue. Following is the log till application crashes.
01-13 05:20:26.200 2028-2028/com.example.raj.wallpaper1 D/numbering: startGoogleApiClient
01-13 05:20:26.206 2028-2028/com.example.raj.wallpaper1 D/numbering: onCreate
01-13 05:20:26.233 2028-2028/com.example.raj.wallpaper1 D/numbering: onStart
01-13 05:20:26.233 2028-2028/com.example.raj.wallpaper1 D/numbering: onResume
01-13 05:20:26.452 2028-2028/com.example.raj.wallpaper1 D/numbering: Location services connected.
01-13 05:20:26.453 2028-2028/com.example.raj.wallpaper1 D/numbering: googleApiClient: com.google.android.gms.internal.zzaal@d66379f
01-13 05:20:26.453 2028-2028/com.example.raj.wallpaper1 D/numbering: startLocationUpdates()
01-13 05:20:26.453 2028-2028/com.example.raj.wallpaper1 D/numbering: checkPermission()
01-13 05:20:26.453 2028-2028/com.example.raj.wallpaper1 D/numbering: googleApiClient: com.google.android.gms.internal.zzaal@d66379f
01-13 05:20:26.453 2028-2028/com.example.raj.wallpaper1 D/numbering: askPermission()
01-13 05:20:26.553 2028-2028/com.example.raj.wallpaper1 D/numbering: onResume
01-13 05:20:47.053 2028-2028/com.example.raj.wallpaper1 D/numbering: onRequestPermissionsResult()
01-13 05:20:47.058 2028-2028/com.example.raj.wallpaper1 D/numbering: startLocationUpdates()
01-13 05:20:47.058 2028-2028/com.example.raj.wallpaper1 D/numbering: checkPermission()
01-13 05:20:47.059 2028-2028/com.example.raj.wallpaper1 D/numbering: googleApiClient: com.google.android.gms.internal.zzaal@d66379f
01-13 05:20:47.059 2028-2028/com.example.raj.wallpaper1 D/numbering: startLocationServices
My error log:
Process: com.example.raj.wallpaper1, PID: 2028
java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=940, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.example.raj.wallpaper1/com.example.raj.wallpaper1.CuisinesList}: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at android.app.ActivityThread.deliverResults(ActivityThread.java:3720)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3763)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1403)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.internal.zzaak.zzb(Unknown Source)
at com.google.android.gms.internal.zzaan.zzb(Unknown Source)
at com.google.android.gms.internal.zzaal.zzb(Unknown Source)
at com.google.android.gms.internal.zzarl.requestLocationUpdates(Unknown Source)
at com.example.raj.wallpaper1.CuisinesList.startLocationUpdates(CuisinesList.java:384)
at com.example.raj.wallpaper1.CuisinesList.onRequestPermissionsResult(CuisinesList.java:419)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6567)
at android.app.Activity.dispatchActivityResult(Activity.java:6446)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3716)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3763)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1403)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
And here is my code which I am trying to run.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cuisines_list);
startGoogleApiClient();
latitude = (TextView) findViewById(R.id.latitude);
longitude = (TextView) findViewById((R.id.longitude));
}
@Override
protected void onStart() {
super.onStart();
Log.d("numbering", "onStart");
googleApiClient.connect();
}
@Override
protected void onResume() {
Log.d("numbering", "onResume");
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
if (googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
googleApiClient.disconnect();
};
}
public void startGoogleApiClient()
{
Log.d("numbering", "startGoogleApiClient");
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
public void startLocationServices()
{
Log.d("numbering", "startLocationServices");
locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) ; // 10 seconds, in milliseconds
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.d("numbering", "Location services connected.");
Log.d("numbering", "googleApiClient: " + googleApiClient.toString());
startLocationUpdates();
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
if (connectionResult.hasResolution() && this instanceof Activity) {
try {
Activity activity = (Activity) this;
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(activity, CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
/*
* If no resolution is available, display a dialog to the
* user with the error.
*/
Log.d("numbering", "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
@Override
public void onLocationChanged(Location location) {
Log.d("numbering", "onLocationChanged()");
if(googleApiClient.isConnected()) {
latitude.setText(String.valueOf(location.getLatitude()));
longitude.setText(String.valueOf(location.getLongitude()));
}
}
public void startLocationUpdates() {
Log.d("numbering", "startLocationUpdates()");
if ( checkPermission() ) {
Log.d("numbering", "googleApiClient: " + googleApiClient.toString());
startLocationServices();
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
else
{
Log.d("numbering", "googleApiClient: " + googleApiClient.toString());
askPermission();
}
}
private boolean checkPermission() {
Log.d("numbering", "checkPermission()");
// Ask for permission if it wasn't granted yet
return (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED );
}
private void askPermission() {
Log.d("numbering", "askPermission()");
ActivityCompat.requestPermissions(
this,
new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
REQ_PERMISSION
);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Log.d("numbering", "onRequestPermissionsResult()");
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch ( requestCode ) {
case REQ_PERMISSION: {
if ( grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED ){
// Permission granted
startLocationUpdates();
} else {
// Permission denied
permissionsDenied();
}
break;
}
}
}
private void permissionsDenied() {
Log.d("numbering", "permissionsDenied()");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
showMessageOKCancel("You need to allow locationForService permissions to run the application ",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQ_PERMISSION);
}
}
});
Log.w("numbering", "permissionsDenied()");
}
return;
}
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
I have tried every possible solution I can think of. Please let me know what I am missing.
The problem is in the onRequestPermissionsResult
method.
After granting the required permission, method startLocationUpdates()
it's called before the GoogleApiClient was able to connect correctly.
You should put startLocationUpdates()
in onConnect()
callback method to be sure that GoogleApiClient is correctly initialized and connected
The reason this is happening only starting from API 23 it's because you will end calling this method only starting from this API which had changed the way some permissions are requested to the user