GooglePlayServicesUtil vs GoogleApiAvailability

102

Estoy intentando utilizar Google Play Service en mi aplicación de Android. Como dice el documento de Google, debemos verificar si la API de Google está disponible antes de usarla. He buscado alguna forma de comprobarlo. Esto es lo que obtuve:

private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
    if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
        GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                PLAY_SERVICES_RESOLUTION_REQUEST).show();
    } else {
        Log.i(TAG, "This device is not supported.");
        finish();
    }
    return false;
}
return true;
}

Pero cuando voy a la página de Google Api GooglePlayServicesUtil, https://developers.google.com/android/reference/com/google/android/gms/common/GooglePlayServicesUtil

Encuentro que todas las funciones están en desuso . Por ejemplo, el método

GooglePlayServicesUtil.isGooglePlayServicesAvailable (obsoleto)

Y Google recomienda usar:

GoogleApiAvailability.isGooglePlayServicesAvailable .

Sin embargo, cuando intento utilizar GoogleApiAvailability.isGooglePlayServicesAvailable, aparece el mensaje de error:

ingrese la descripción de la imagen aquí

James
fuente
¿Dónde encuentro GoogleApiAvailability? No lo encuentro.
mcmillab
@mcmillab +1. Actualicé de 8.1.0 a 8.4.0 y GooglePlayServicesUtilya no (lo que parece una mala práctica para una actualización "menor") pero no veo GoogleApiAvailabilityque lo use como reemplazo.
spaaarky21
Cuando actualice a Firebase, consulte
Dawid Drozd

Respuestas:

203

He encontrado la solución. En el GoogleApiAvailability, todos los métodos son métodos públicos, mientras que en GooglePlayServicesUtiltodos los métodos son funciones públicas estáticas.

Entonces, para usar GoogleApiAvailability, la forma correcta es:

private boolean checkPlayServices() {
    GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
    int result = googleAPI.isGooglePlayServicesAvailable(this);
    if(result != ConnectionResult.SUCCESS) {
        if(googleAPI.isUserResolvableError(result)) {
            googleAPI.getErrorDialog(this, result,
                    PLAY_SERVICES_RESOLUTION_REQUEST).show();
        }

        return false;
    }

    return true;
}
James
fuente
9
qué es: PLAY_SERVICES_RESOLUTION_REQUEST
Saman Sattari
12
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
Ferrrmolina
7
Es un número entero arbitrario. Puede recuperar el valor.
Timmmm
4
Algunos prefieren establecer el valor en algo más de 9000.
matthias_b_nz
12
Todo el diseño de la biblioteca de Google Play Services es un desastre. Todo tiene fallas y es difícil de seguir, además de la falta de documentación.
mr5
64

¡La clase GooglePlayServicesUtil ya no debería usarse!

Así es como se puede usar la clase GoogleApiAvailability en su lugar, cuando, por ejemplo, se necesita GCM (o cualquier otro servicio de Google):

public static final int REQUEST_GOOGLE_PLAY_SERVICES = 1972;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState == null) {
        startRegistrationService();
    }
}

private void startRegistrationService() {
    GoogleApiAvailability api = GoogleApiAvailability.getInstance();
    int code = api.isGooglePlayServicesAvailable(this);
    if (code == ConnectionResult.SUCCESS) {
        onActivityResult(REQUEST_GOOGLE_PLAY_SERVICES, Activity.RESULT_OK, null);
    } else if (api.isUserResolvableError(code) &&
        api.showErrorDialogFragment(this, code, REQUEST_GOOGLE_PLAY_SERVICES)) {
        // wait for onActivityResult call (see below)
    } else {
        Toast.makeText(this, api.getErrorString(code), Toast.LENGTH_LONG).show();
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(requestCode) {
        case REQUEST_GOOGLE_PLAY_SERVICES:
            if (resultCode == Activity.RESULT_OK) {
                Intent i = new Intent(this, RegistrationService.class); 
                startService(i); // OK, init GCM
            }
            break;

        default:
            super.onActivityResult(requestCode, resultCode, data);
    }
}

ACTUALIZAR:

REQUEST_GOOGLE_PLAY_SERVICESes una constante entera con nombre y valor arbitrarios, a la que se puede hacer referencia en el onActivityResult()método.

Además, llamar this.onActivityResult()con el código anterior está bien (también llama super.onActivityResult()en el otro lugar).

Alexander Farber
fuente
2
¿Puede señalar la fuente que afirma que "¡La clase GooglePlayServicesUtil ya no debería usarse!". La API de Google Play Services es muy confusa.
Lachezar
8
Todos los métodos en GooglePlayServicesUtil marcados como obsoletos más la recomendación en la parte superior del javadoc para tomar la GOOGLE_PLAY_SERVICES_PACKAGEconstante de la clase GoogleApiAvailability es la forma de Google de decirle: no use más la GooglePlayServicesUtilclase.
Alexander Farber
3
¿Qué pasa si el dispositivo tiene una versión anterior de los servicios de Google Play en la que la GoogleApiAvailabilityclase no existe? Si hacemos referencia a la clase de forma estática, incluso dentro de una expresión condicional, ¿no bloqueará la aplicación?
Kevin Krumwiede
6
@Kevin Krumwiede, GoogleApiAvailabilityes parte de la biblioteca cliente. Entonces su código está compilado en la aplicación => No se preocupe por eso.
WindRider
9
No debe llamar a onActivityResult (). Está destinado a ser llamado desde el exterior, cuando otra actividad devuelve un resultado.
Yar
10

Tendrá que utilizar GoogleApiAvailability en su lugar:

GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance(); 
int errorCode = googleApiAvailability.isGooglePlayServicesAvailable(this);

thisrepresenta el context.

Gaurav
fuente
9

Verifique el dispositivo para asegurarse de que tenga el APK de Google Play Services. Si no es así, muestra un cuadro de diálogo que permite a los usuarios descargar el APK de Google Play Store o habilitarlo en la configuración del sistema del dispositivo.

public static boolean checkPlayServices(Activity activity) {
    final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
    GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
    int resultCode = apiAvailability.isGooglePlayServicesAvailable(activity);
    if (resultCode != ConnectionResult.SUCCESS) {
        if (apiAvailability.isUserResolvableError(resultCode)) {
            apiAvailability.getErrorDialog(activity, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
                    .show();
        } else {
            Logger.logE(TAG, "This device is not supported.");
        }
        return false;
    }
    return true;
}
Anoop M
fuente
0

He agregado esto como divertido en la clase BaseActivity para usar en todos los lugares

    fun checkGooglePlayServices(okAction : ()-> Unit , errorAction: (msg:String, isResolved:Boolean)-> Unit){
    val apiAvailability = GoogleApiAvailability.getInstance()
    val resultCode = apiAvailability.isGooglePlayServicesAvailable(this)
    if (resultCode != ConnectionResult.SUCCESS) {
        if (apiAvailability.isUserResolvableError(resultCode)) {
            apiAvailability.getErrorDialog(
                this,
                resultCode,
                PLAY_SERVICES_RESOLUTION_REQUEST
            ).show()
             // dialoe when click on ok should let user go to install/update play serices


            errorAction("dialog is shown" , true)

        } else {
          "checkGooglePlayServices  This device is not supported.".log(mTag)
            errorAction("This device is not supported",false)
        }
    }else{
        okAction()
    }
}

companion object {
    const val PLAY_SERVICES_RESOLUTION_REQUEST = 1425
}

úsalo así

    (activity as? BaseActivity)?.checkGooglePlayServices({
        // ok so start map
        initializeMap()
    },
        { msg, isResolved ->
            if (!isResolved)
                context?.show(msg)

        }
    )

O puedes personalizarlo como quieras.

Mahmoud Mabrok
fuente