GooglePlayServicesUtil与GoogleApiAvailability的区别

109

我正在尝试在我的Android应用程序中使用Google Play服务。正如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时,我收到了错误消息:

enter image description here


我在哪里可以找到GoogleApiAvailability?我找不到它。 - mcmillab
@mcmillab +1。我从8.1.0升级到8.4.0,GooglePlayServicesUtil消失了(这似乎是一个“次要”的更新的不良做法),但我没有看到可以用作替代的GoogleApiAvailability - spaaarky21
在更新到 Firebase 时,请查看以下内容: http://www.etivy.com/googleapiavailability-missed-with-firebase-messaging-9-4-0/ - Gelldur
6个回答

213

我已经找到解决方案。在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" 是一个常量,用于在 Android 应用程序中请求 Google Play 服务的解决方案。它通常被用来处理设备上缺少或需要更新的 Google Play 服务版本。 - Saman Sattari
12
私有静态变量 PLAY_SERVICES_RESOLUTION_REQUEST 的值为 9000。 - Ferrmolina
7
这是一个任意的整数,你可以随便设定它的值。 - Timmmm
4
有些人更喜欢将值设为9000以上的某个数。 - matthias_b_nz
14
整个 Google Play Services 库的设计一团糟。它有很多缺陷,难以理解,并且缺乏文档。 - mr5
显示剩余6条评论

65

现在不应再使用类GooglePlayServicesUtil

以下是如何改用GoogleApiAvailability类的方法 - 例如,当需要GCM(或任何其他谷歌服务)时:

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类”的来源吗?Google Play服务API太令人困惑了。 - Lachezar
8
GooglePlayServicesUtil 中的所有方法都被标记为过时,而且在 javadoc 的顶部推荐使用 GoogleApiAvailability 类中的 GOOGLE_PLAY_SERVICES_PACKAGE 常量。这是 Google 告诉你不要再使用 GooglePlayServicesUtil 类的方式。 - Alexander Farber
3
如果设备安装的 Google Play 服务版本较老,其中不存在 GoogleApiAvailability 类,会怎样呢?如果我们静态引用该类,即使在条件表达式中,是否会导致应用崩溃? - Kevin Krumwiede
6
@Kevin Krumwiede,“GoogleApiAvailability”是客户端库的一部分。因此,它的代码已编译到应用程序中=>不要担心这个。 - WindRider
9
不应该调用onActivityResult()方法。该方法是用于在另一个活动返回结果时从外部调用的。 - Yar
显示剩余4条评论

11

您将需要使用GoogleApiAvailability代替:

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

this代表着上下文


9
检查设备是否已安装 Google Play Services APK。如果没有,请显示一个对话框,允许用户从 Google Play 商店下载 APK 或在设备的系统设置中启用它。
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;
}

1

在这两个方法之间加入.getInstance()就可以了。


1
这是对问题最简明扼要的回答。 - Leo Bastin

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)

        }
    )

或者您可以根据自己的需求进行定制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接