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
相关产品推荐
相关产品推荐

