Estoy escribiendo una aplicación basada en la ubicación. Mi ubicación funciona bien para API <23, pero siempre que estoy ejecutando en el dispositivo para API 23 aparece un error como "GoogleApiClient aún no está conectado".

Verifiqué con los registros que GoogleApiClient está conectado. Pero no entiendo cuál es el problema. A continuación se muestra el registro hasta que la aplicación se bloquea.

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

Mi registro de errores:

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) 

Y aquí está mi código que estoy intentando ejecutar.

    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();
}

Probé todas las soluciones posibles que se me ocurrieron. Por favor déjeme saber lo que me estoy perdiendo.

1
Raj krishna 13 ene. 2017 a las 03:11

1 respuesta

La mejor respuesta

El problema está en el método onRequestPermissionsResult.

Después de otorgar el permiso requerido, se llama al método startLocationUpdates() antes de que GoogleApiClient pueda conectarse correctamente. Debe poner startLocationUpdates() en el método de devolución de llamada onConnect() para asegurarse de que GoogleApiClient esté correctamente inicializado y conectado.

La razón por la que esto sucede solo a partir de la API 23 es porque terminará de llamar a este método solo a partir de esta API que había cambiado la forma en que se solicitan algunos permisos al usuario.

2
MatPag 13 ene. 2017 a las 03:16
startLocationUpdates() ya está en el método onConnected(). ¿Quiso decir que después de obtener el permiso tengo que empezar desde cero conectando GoogleApiClient y luego después de onConnected() debería ir a startLocationUpdates()?
 – 
Raj krishna
13 ene. 2017 a las 04:31
Gracias por tu comentario. Me ayudó a comprender que después de obtener el permiso, GoogleApiClient no estaba conectado. El motivo principal del bloqueo fue el método onPause(). Lo eliminé y usé el mismo código en onStop(). Está funcionando ahora. Gracias por su pronta respuesta. Lo aprecio.
 – 
Raj krishna
13 ene. 2017 a las 05:16
1
Según el logcat que publicó, el error estaba en la línea que mencioné. El onPause() fue la causa del bloqueo porque desconectó al cliente y cuando regresó a su actividad con el permiso correcto, GoogleApiClient no estaba conectado. Por cierto, puedes aceptar la respuesta si te ayudó a encontrar el problema;)
 – 
MatPag
13 ene. 2017 a las 11:48