我正在开发一个纯粹供内部使用的应用程序,而不是用于 Play 商店或类似的东西。它将安装在运行 Android 10 的 Zebra 扫描仪上。
该应用程序的目的是浏览 Google Drive,然后我们选择电子表格并扫描库存。
目前,当使用模拟器(Android 10)时,一切都按预期工作,Google登录正常工作(所有这些都使用已弃用的方法,因为我不知道如何使用新方法),并且我的应用程序的其余部分按预期工作.
我遇到的问题是当我尝试在物理设备上安装应用程序时。我看到“正在让您登录”底页(预期),然后看到“Google 尚未验证此应用程序”屏幕(意外)。在模拟器上运行时我没有收到此消息,因为它按预期登录。
当我单击“继续”时,我会看到“出现问题”屏幕。当我在此屏幕上单击“下一步”时,我会看到一个 Google 屏幕,上面显示“400”。这是一个错误'
奇怪的是,我在日志中收到“凭据已成功检索”消息。
我在模拟器和物理设备上使用相同的 Google 帐户。
这是我的 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...")
}
}
}
}
我的其余登录功能,抱歉造成混乱。对于 Android 编码来说还很陌生。
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."
}
}
}
我已尝试使用我认为可能的任何其他密钥更新 Firebase 控制台上的 SHA-1 密钥。
我尝试使用在模拟器上运行的不同帐户,但结果仍然相同。
老实说,我想不出还有什么可以尝试的,因为我没有真正收到任何特定的错误代码。
非常感谢任何帮助或建议,因为我知道这可能是一个小众问题。
编辑
另外,刚刚在新的模拟器上尝试了这个,现在我收到错误:
java.lang.IllegalArgumentException:名称不能为空:null
“我遇到的问题是,当我尝试在物理设备上安装该应用程序时。我收到“请登录”底页(预期),然后收到“Google 尚未验证此应用程序”屏幕”
您是否尝试过关闭物理设备上的播放保护?
https://support.google.com/googleplay/answer/2812853?hl=zh-CN