GooglePlayServicesUtil vs GoogleApiAvailability


102

Sto cercando di utilizzare Google Play Service nella mia app Android. Come dice il documento di Google, dobbiamo verificare se l'API di Google è disponibile prima di utilizzarla. Ho cercato in qualche modo per controllarlo. Ecco cosa ho ottenuto:

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

Ma quando vado alla pagina di Google Api GooglePlayServicesUtil, https://developers.google.com/android/reference/com/google/android/gms/common/GooglePlayServicesUtil

Trovo che tutte le funzioni siano deprecate . Ad esempio, il metodo

GooglePlayServicesUtil.isGooglePlayServicesAvailable (obsoleto)

E Google consiglia di utilizzare:

GoogleApiAvailability.isGooglePlayServicesAvailable .

Tuttavia, quando provo a utilizzare GoogleApiAvailability.isGooglePlayServicesAvailable, ricevo il messaggio di errore:

inserisci qui la descrizione dell'immagine


dove trovo GoogleApiAvailability? Non riesco a trovarlo.
mcmillab

@mcmillab +1. Ho aggiornato da 8.1.0 a 8.4.0 e non GooglePlayServicesUtilc'è più (che sembra una cattiva pratica per un aggiornamento "minore") ma non vedo GoogleApiAvailabilitydi usarlo come sostituto.
spaaarky21

Durante l'aggiornamento a Firebase, controlla questo: etivy.com/…
Dawid Drozd

Risposte:


203

Ho trovato la soluzione. In GoogleApiAvailability, tutti i metodi sono metodi pubblici, mentre in GooglePlayServicesUtiltutti i metodi sono funzioni pubbliche statiche.

Quindi, per utilizzare GoogleApiAvailability, il modo giusto è:

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

9
cos'è: PLAY_SERVICES_RESOLUTION_REQUEST
Saman Sattari

12
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
Ferrrmolina

7
È un numero intero arbitrario. Puoi recuperare il valore.
Timmmm,

4
Alcuni preferiscono impostare il valore su un valore superiore a 9000.
matthias_b_nz

12
L'intero design della libreria di Google Play Services è un vero casino. È tutto imperfetto ed è difficile da seguire, in aggiunta alla mancanza di documentazione.
mr5

64

La classe GooglePlayServicesUtil non dovrebbe più essere utilizzata!

Ecco come utilizzare invece la classe GoogleApiAvailability , quando ad esempio è necessario GCM (o qualsiasi altro servizio 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);
    }
}

AGGIORNARE:

REQUEST_GOOGLE_PLAY_SERVICESè una costante intera con nome e valore arbitrari, a cui è possibile fare riferimento nel onActivityResult()metodo.

Inoltre, chiamare this.onActivityResult()il codice sopra va bene (chiami anche super.onActivityResult()nell'altro posto).


2
Puoi indicare la fonte che afferma che "La classe GooglePlayServicesUtil non dovrebbe più essere utilizzata!". L'API di Google Play Services è così confusa.
Lachezar

8
Tutti i metodi in GooglePlayServicesUtil contrassegnati come deprecati più un consiglio nella parte superiore del javadoc per prendere la GOOGLE_PLAY_SERVICES_PACKAGEcostante dalla classe GoogleApiAvailability è il modo in cui Google ti dice: non usare più la GooglePlayServicesUtilclasse.
Alexander Farber

3
Cosa succede se il dispositivo ha una versione precedente di Google Play Services in cui la GoogleApiAvailabilityclasse non esiste? Se facciamo riferimento staticamente alla classe, anche all'interno di un'espressione condizionale, l'app non andrà in crash?
Kevin Krumwiede

6
@Kevin Krumwiede, GoogleApiAvailabilityfa parte della libreria client. Quindi il suo codice viene compilato nell'app => Non preoccuparti.
WindRider

9
Non dovresti chiamare onActivityResult (). È pensato per essere chiamato dall'esterno, quando un'altra attività restituisce un risultato.
Yar

10

Dovrai invece utilizzare GoogleApiAvailability :

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

thisrappresenta il context.


9

Controlla il dispositivo per assicurarti che abbia l'APK di Google Play Services. In caso contrario, visualizza una finestra di dialogo che consente agli utenti di scaricare l'APK da Google Play Store o di abilitarlo nelle impostazioni di 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;
}

0

L'ho aggiunto come divertente nella classe BaseActivity da utilizzare in tutti i posti

    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
}

usalo in questo modo

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

        }
    )

Oppure puoi personalizzarlo come desideri.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.