Вход в Google не работает на устройстве, но в эмуляторе работает нормально?

Я работаю над приложением исключительно для внутреннего использования, а не для Play Store или чего-то в этом роде. Его необходимо установить на наш сканер Zebra под управлением Android 10.

Цель приложения — просматривать Google Диск, а затем мы выбираем электронные таблицы и сканируем материалы.

В настоящее время при использовании эмулятора (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."
            }
        }
    }

Я пробовал обновить ключи SHA-1 на консоли Firebase любыми другими, которые, по моему мнению, могут быть.

Я попробовал использовать другую учетную запись, которая работает на эмуляторе, но результат тот же.

Честно говоря, я не могу придумать, что еще можно попробовать, поскольку на самом деле я не получаю какого-либо конкретного кода ошибки.

Любая помощь или совет будут очень признательны, поскольку я понимаю, что это может быть узкоспециализированный вопрос.

РЕДАКТИРОВАТЬ

Кроме того, только что попробовал это на новом эмуляторе, и теперь я получаю сообщение об ошибке:

java.lang.IllegalArgumentException: имя не должно быть пустым: null

2-е РЕДАКТИРОВАНИЕ

Итак, я кое-что придумал. Мне удалось найти старый телефон Android (Oppo A5), установить на него свое приложение, и оно работает как положено. Я могу войти в систему и делать все, как в эмуляторе. Итак, устройство, на котором он мне нужен (Zebra TC52), просто не входит в систему с помощью Google в приложении. На самом устройстве включена учетная запись Google, и службы Play обновлены, но я не уверен, что я могу с этим поделать сейчас.

Это очень странная проблема. Есть ли другой способ получить доступ к Google Диску и Таблицам через приложение, которое не использует GoogleSignIn, поскольку, возможно, это сработает в моем случае?

Привет Каюл. Я немного не понимаю, что именно вы хотите сделать. Я вижу, что вы используете API авторизации, API входа в Google и API CredentialManager. Ваша цель — просто войти в систему с помощью токена Google ID?

Ali Naddaf 26.06.2024 20:29

@AliNaddaf Привет, Али. Извините, если что-то неясно, я не смог найти лучшего способа объяснить это. По сути, все, что я хочу сделать, это войти в систему с учетной записью Google и иметь полный доступ к Google Диску и Google Таблицам этой учетной записи.

Kayul 26.06.2024 22:49

@AliNaddaf Похоже, я нашел виновника во втором редактировании, мне удалось заставить его работать на запасном телефоне Android, который у меня был, но не на сканере, работающем под управлением Android. Есть ли у вас какие-либо рекомендации по другому способу использования Диска/Таблиц через API в моем приложении, которое не использует GoogleSignIn? (конечно, лучше всего было бы каким-то образом заставить его работать на моем сканере, но я не знаю, с чего начать) Большое спасибо

Kayul 27.06.2024 01:36
1
3
129
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

«Проблема у меня возникает, когда я пытаюсь установить приложение на физическое устройство. Я получаю нижний лист «Вход в систему» ​​(ожидается), а затем получаю экран «Google не подтвердил это приложение»»

Пробовали ли вы отключить защиту воспроизведения на физическом устройстве?

https://support.google.com/googleplay/answer/2812853?hl=en

Спасибо за предложение. Только что попробовал и, к сожалению, без изменений.

Kayul 27.06.2024 00:22
Ответ принят как подходящий

Что ж, похоже, обновление Android с 10 до 13 решило эту проблему.

Мне удалось найти файл обновления для моего устройства, поскольку это устройство Zebra, но у нас нет контракта на обслуживание, и теперь оно правильно входит в систему.

Все еще использую устаревшие методы, но смогу пересечь этот мост позже.

Другие вопросы по теме