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

Zebra TC52扫描器Android10设备Google Sign In失效,模拟器正常求助

Google Sign-In 在Zebra TC52设备上异常,寻求无GoogleSignIn的Drive/Sheets访问方案

我正在开发一款仅内部使用、无需上架Play Store的应用,目标设备是运行Android 10的Zebra TC52扫描器,核心功能是浏览Google Drive、选择电子表格并扫描库存。

目前在Android 10模拟器上一切正常:Google Sign-In(使用已弃用方法,暂未掌握新方法)可以正常工作,其余功能也符合预期。但在Zebra物理设备上安装后出现异常流程:

  • 先显示预期的「正在登录」底部弹窗
  • 随后出现「Google未验证此应用」界面(模拟器无此问题)
  • 点击「继续」后显示「出现错误」,再点击下一步跳转到Google的「400. That's an error」页面

奇怪的是,日志中明确显示Credentials retrieved successfully(凭证获取成功),且模拟器和物理设备使用的是同一个Google账号。

我已经尝试过:

  • 在Firebase控制台更新SHA-1密钥
  • 更换模拟器上可用的其他账号
    但问题依旧,且未获取到具体错误码,暂时无排查思路。

代码片段

onCreate 代码

authorizationLauncher = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
            if (result.resultCode == Activity.RESULT_OK) {
                val authorizationResult = Identity.getAuthorizationClient(this)
                    .getAuthorizationResultFromIntent(result.data)
                initializeDriveService(authorizationResult, initialFolderId = "1R0p0N30zZLltpRBJqIN3PGR5dMnLnx1M")
                authorizationStatus.value = "Authorization successful"
            } else {
                authorizationStatus.value = "Authorization failed"
            }
        }

        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestIdToken(getString(WEB_CLIENT_ID))
            .requestScopes(Scope(DriveScopes.DRIVE), Scope(SheetsScopes.SPREADSHEETS))
            .build()

        googleSignInClient = GoogleSignIn.getClient(this, gso)

        signInWithGoogle()

        setContent {
            ZebraStockScannerTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    if (::driveService.isInitialized && fileListState.value.isNotEmpty()) {
                        GoogleFileExplorer(
                            driveService = driveService,
                            initialFolderId = "",
                            fileListState = fileListState,
                            onExtractedDataChanged = { newData ->
                                extractedData = newData
                            }
                        )
                    } else {
                        Text(text = "Connecting to Google Drive, please wait...")
                    }
                }
            }
        }

登录相关函数

private fun signInWithGoogle() {
        val credentialManager = CredentialManager.create(this)
        val nonce = generateNonce()

        val googleIdOption = GetGoogleIdOption.Builder()
            .setFilterByAuthorizedAccounts(true)
            .setServerClientId(getString(WEB_CLIENT_ID))
            .setAutoSelectEnabled(true)
            .setNonce(nonce)
            .build()

        val request = GetCredentialRequest.Builder()
            .addCredentialOption(googleIdOption)
            .build()

        lifecycleScope.launch {
            try {
                val result = credentialManager.getCredential(
                    request = request,
                    context = this@GoogleSignInActivity
                )
                Log.d(TAG, "Credentials retrieved successfully")
                handleSignIn(result)
            } catch (e: NoCredentialException) {
                signInWithGoogleFallback()
            } catch (e: GetCredentialException) {
                handleSignInFailure(e, this@GoogleSignInActivity)
            } catch (e: Exception) {
            }
        }
    }

    private fun signInWithGoogleFallback() {
        val signInIntent = googleSignInClient.signInIntent
        startActivityForResult(signInIntent, RC_SIGN_IN)
    }

    private fun handleSignIn(result: GetCredentialResponse) {
        when (val credential = result.credential) {
            is GoogleIdTokenCredential -> {
                try {
                    val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)
                    Log.d(TAG, "Google ID Token: ${googleIdTokenCredential.id}")
                    userEmail = googleIdTokenCredential.id
                    requestDriveAuthorization(initialFolderId = "")
                } catch (e: GoogleIdTokenParsingException) {
                    authorizationStatus.value = "Invalid Google ID token response"
                } catch (e: Exception) {
                    Log.e(TAG, "Unexpected error during Google ID token parsing: ${e.message}", e)
                }
            }

            else -> {
                Log.e(TAG, "Unexpected type of credential")
                authorizationStatus.value = "Unexpected type of credential"
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_AUTHORIZE && resultCode == Activity.RESULT_OK) {
            val authorizationResult =
                Identity.getAuthorizationClient(this).getAuthorizationResultFromIntent(data)
            initializeDriveService(authorizationResult, initialFolderId = "1R0p0N30zZLltpRBJqIN3PGR5dMnLnx1M")
        } else if (requestCode == RC_SIGN_IN) {
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            try {
                handleSignInResult(task)
            } catch (e: Exception) {
                Log.e(TAG, "Error handling sign-in result: ${e.localizedMessage}")
                authorizationStatus.value = "Sign-in error: ${e.localizedMessage}"
            }
        }
    }

    private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) {
        try {
            val account = completedTask.getResult(ApiException::class.java)
            userEmail = account.email
            requestDriveAuthorization(initialFolderId = "1w9iWcvUtfwK-i5EC-azALMlMfuyDnHmb")
        } catch (e: ApiException) {
            authorizationStatus.value = "Google sign-in failed: ${e.statusCode}"
        } catch (e: Exception) {
            Log.e(TAG, "Unexpected error during sign-in: ${e.localizedMessage}")
        }
    }

    private fun requestDriveAuthorization(initialFolderId: String) {
        val requestedScopes = listOf(Scope(DriveScopes.DRIVE), Scope(SheetsScopes.SPREADSHEETS))
        val authorizationRequest = AuthorizationRequest.Builder()
            .setRequestedScopes(requestedScopes)
            .build()

        Identity.getAuthorizationClient(this)
            .authorize(authorizationRequest)
            .addOnSuccessListener { authorizationResult ->
                if (authorizationResult.hasResolution()) {
                    val pendingIntent = authorizationResult.pendingIntent
                    try {
                        val intentSenderRequest = pendingIntent?.let { IntentSenderRequest.Builder(it).build() }
                        authorizationLauncher.launch(intentSenderRequest)
                    } catch (e: Exception) {
                    }
                } else {
                    initializeDriveService(authorizationResult, initialFolderId)
                    authorizationStatus.value = "Authorization successful"
                }
            }
            .addOnFailureListener { e ->
                Log.e(TAG, "Failed to authorize", e)
                if (e is UserRecoverableAuthIOException) {
                    startActivityForResult(e.intent, REQUEST_AUTHORIZE)
                } else {
                    authorizationStatus.value = "Authorization failed"
                }
            }
    }

    private fun initializeDriveService(authorizationResult: AuthorizationResult, initialFolderId: String) {
        lifecycleScope.launch {
            try {
                val credential = GoogleAccountCredential.usingOAuth2(
                    this@GoogleSignInActivity, listOf(DriveScopes.DRIVE, SheetsScopes.SPREADSHEETS)
                )
                credential.selectedAccountName = userEmail

                driveService = Drive.Builder(
                    GoogleNetHttpTransport.newTrustedTransport(),
                    JacksonFactory.getDefaultInstance(),
                    credential
                ).setApplicationName(getString(R.string.app_name)).build()

                // Initialize folder name and ID caches
                val folderNameCache = mutableMapOf<String, String>()
                val folderIdCache = mutableMapOf<String, String>()

                // Fetch the initial file list from the specified folder ID
                val files = fetchFiles(driveService, initialFolderId, folderNameCache, folderIdCache)
                // Update UI or state with fetched files
                fileListState.value = files
            } catch (e: Exception) {
                Log.e("GoogleSignInActivity", "Error initializing Drive service", e)
                showDialogState.value = true
                errorMessageState.value = "Failed to initialize Drive service."
            }
        }
    }

后续编辑补充

第一次编辑

在新模拟器上测试时,出现错误:java.lang.IllegalArgumentException: the name must not be empty: null

第二次编辑

发现将应用安装在旧安卓手机(Oppo A5)上可正常运行,能登录并完成所有操作,与模拟器一致。但目标设备Zebra TC52无法通过应用完成Google登录,该设备已登录Google账号且Play Services为最新版本。

现在想请教:是否有无需使用GoogleSignIn即可访问Google Drive和Sheets的方法?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:03:11