You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

集成Google Play游戏服务遇ApiException 8错误及功能无响应求助

解决Google Play游戏服务登录错误ApiException:8的问题

首先明确一下,你遇到的ApiException:8对应的是SIGN_IN_FAILED,也就是静默登录失败,而且你的代码里没处理登录失败后的显式登录流程,这就是为啥没有登录提示、点击按钮毫无反应的核心原因。下面一步步帮你排查解决:


第一步:先把基础配置核对一遍

很多时候这类登录问题都是配置漏项导致的:

  • 核对包名与SHA-1签名:
    登录Play Console,进入你的游戏服务页面,检查「应用关联」里的包名,以及SHA-1签名是否和你当前调试/打包的APK完全一致。注意调试版和发布版的SHA-1是不同的,如果用调试模式测试,一定要把调试签名的SHA-1也添加进去。
  • 检查games-ids.xml配置:
    确保文件放在res/values/目录下,app_id和Play Console里的游戏ID完全匹配,排行榜ID也和你创建的一致,格式参考:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="app_id">你的游戏ID</string>
        <string name="leaderboard_id">你的排行榜ID</string>
    </resources>
    
  • 补充AndroidManifest.xml的必要配置:
    必须添加网络权限和游戏服务元数据:
    <uses-permission android:name="android.permission.INTERNET" />
    
    <application ...>
        <!-- 游戏服务ID配置 -->
        <meta-data
            android:name="com.google.android.gms.games.APP_ID"
            android:value="@string/app_id" />
        <!-- Google Play服务版本 -->
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
    </application>
    

第二步:修正代码逻辑,处理登录失败的情况

你的代码只调用了silentSignIn()(静默登录),但如果用户从未登录过、登录状态过期,静默登录就会失败,这时候必须触发显式登录弹窗。修改你的代码:

1. 更新初始化登录的方法

private val RC_SIGN_IN = 1001 // 自定义请求码,随便设个整数就行

fun initGoogleClientAndSignin() {
    val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
        .build()
    googleSignInClient = GoogleSignIn.getClient(this, gso)

    googleSignInClient?.silentSignIn()?.addOnCompleteListener{ task ->
        if (task.isSuccessful) {
            // 静默登录成功,初始化客户端
            val account = task.result!!
            achievementClient = Games.getAchievementsClient(this, account)
            leaderboardsClient = Games.getLeaderboardsClient(this, account)
            Toast.makeText(this, "Google游戏服务登录成功", Toast.LENGTH_SHORT).show()
        } else {
            // 静默登录失败,弹出登录窗口
            Log.e("Error", "signInError", task.exception)
            val signInIntent = googleSignInClient?.signInIntent
            startActivityForResult(signInIntent, RC_SIGN_IN)
        }
    }
}

2. 重写onActivityResult处理登录结果

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == RC_SIGN_IN) {
        val task = GoogleSignIn.getSignedInAccountFromIntent(data)
        try {
            val account = task.getResult(ApiException::class.java)
            // 显式登录成功,初始化客户端
            achievementClient = Games.getAchievementsClient(this, account)
            leaderboardsClient = Games.getLeaderboardsClient(this, account)
            Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show()
        } catch (e: ApiException) {
            Log.e("Error", "登录失败,错误码:${e.statusCode}", e)
        }
    }
}

3. 修复分数提交的时机问题

你在onCreate里直接调用leaderboardsClient?.submitScore,但此时leaderboardsClient可能还没初始化完成(因为登录是异步操作),所以要把提交逻辑放到登录成功后,或者按钮点击时先判断客户端是否可用:

button1.setOnClickListener {
    counter += 1
    tvDisplay.text = counter.toString()
    // 确保客户端初始化后再提交分数
    leaderboardsClient?.submitScore(getString(R.string.leaderboard_id), counter.toLong())
        ?.addOnCompleteListener { submitTask ->
            if (submitTask.isSuccessful) {
                Toast.makeText(this, "分数提交成功", Toast.LENGTH_SHORT).show()
            } else {
                Log.e("Error", "分数提交失败", submitTask.exception)
            }
        }
}

第三步:其他注意事项

  • 测试设备要安装最新版的Google Play服务,并且登录的Google账号必须在Play Console的「测试人员」列表里(未发布的游戏只能让测试人员登录)。
  • 如果用混淆打包,要在混淆规则里添加Google游戏服务的保护规则:
    -keep class com.google.android.gms.games.** { *; }
    -keep class com.google.android.gms.auth.api.signin.** { *; }
    

内容的提问来源于stack exchange,提问作者life4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 17:37:30