GooglePlayServicesUtil против GoogleApiAvailability

103

Я пытаюсь использовать сервис Google Play в своем приложении для Android. Как говорится в документе Google, нам нужно проверить, доступен ли Google API, прежде чем использовать его. Я искал способ проверить это. Вот что у меня получилось:

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

Но когда я перехожу на страницу Google Api GooglePlayServicesUtil, https://developers.google.com/android/reference/com/google/android/gms/common/GooglePlayServicesUtil

Я считаю, что все функции устарели . Например, метод

GooglePlayServicesUtil.isGooglePlayServicesAvailable (не рекомендуется)

И Google рекомендует использовать:

GoogleApiAvailability.isGooglePlayServicesAvailable .

Однако, когда я пытаюсь использовать GoogleApiAvailability.isGooglePlayServicesAvailable, я получаю сообщение об ошибке:

введите описание изображения здесь

Джеймс
источник
где мне найти GoogleApiAvailability? Я не могу его найти.
mcmillab
@mcmillab +1. Я обновился с 8.1.0 до 8.4.0, и его GooglePlayServicesUtilбольше нет (что кажется плохой практикой для «незначительного» обновления), но я не собираюсь GoogleApiAvailabilityиспользовать его в качестве замены.
spaaarky21,
При обновлении до Firebase проверьте
Давид Дрозд

Ответы:

204

Я нашел решение. В GoogleApiAvailability, все методы являются открытым методом, в то время как GooglePlayServicesUtilвсе методы являются статическими общественными функциями.

Итак, чтобы использовать GoogleApiAvailability, правильный способ:

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
что такое: PLAY_SERVICES_RESOLUTION_REQUEST
Саман Саттари,
12
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
Fmolina
7
Это произвольное целое число. Вы можете придумать ценность.
Timmmm
4
Некоторые предпочитают устанавливать значение выше 9000.
matthias_b_nz 01
12
Дизайн всей библиотеки сервисов Google Play - это полный беспорядок. Все это несовершенно, плюс за этим сложно следить, да еще и отсутствие документации.
mr5
64

Класс GooglePlayServicesUtil больше использовать нельзя!

Вот как можно использовать вместо этого класс GoogleApiAvailability - например, когда требуется GCM (или любой другой сервис 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);
    }
}

ОБНОВИТЬ:

REQUEST_GOOGLE_PLAY_SERVICES- целочисленная константа с произвольным именем и значением, на которую можно ссылаться в onActivityResult()методе.

Кроме того, можно позвонить this.onActivityResult()по приведенному выше коду (вы также звоните super.onActivityResult()в другом месте).

Александр Фарбер
источник
2
Можете ли вы указать на источник, который утверждает, что «Класс GooglePlayServicesUtil больше не должен использоваться!». API сервисов Google Play очень сбивает с толку.
Lachezar
8
Все методы в GooglePlayServicesUtil, помеченные как устаревшие, плюс рекомендация в верхней части javadoc взять GOOGLE_PLAY_SERVICES_PACKAGEконстанту из класса GoogleApiAvailability - это способ Google сказать вам: больше не используйте этот GooglePlayServicesUtilкласс.
Александр Фарбер
3
Что делать, если на устройстве установлена ​​более старая версия сервисов Google Play, в которой GoogleApiAvailabilityкласс не существует? Если мы будем ссылаться на класс статически, даже внутри условного выражения, не приведет ли это к сбою приложения?
Кевин Крумвиде
6
@Kevin Krumwiede GoogleApiAvailability- часть клиентской библиотеки. Итак, его код скомпилирован в приложение => Не беспокойтесь об этом.
WindRider
9
Вы не должны вызывать onActivityResult (). Он предназначен для вызова извне, когда другое действие возвращает результат.
Яр
10

Вместо этого вам придется использовать GoogleApiAvailability :

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

thisпредставляет собой context.

Гаурав
источник
9

Убедитесь, что на устройстве есть APK-файл служб Google Play. В противном случае отобразите диалоговое окно, позволяющее пользователям загрузить APK из магазина Google Play или включить его в системных настройках устройства.

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

Я добавил это как развлечение в класс BaseActivity, чтобы использовать его во всех местах.

    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
}

используйте это так

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

        }
    )

Или вы можете настроить его как хотите.

Махмуд Маброк
источник