请求 Google Drive Scope 权限时会给出无限加载对话框

问题描述

我想将 Google Drive 集成到我的应用中,以便在其中存储用户的应用数据。

我的尝试

我已从 Google dev doc 实施 Google 登录,并从 additional scopes 部分请求驱动范围。我还尝试直接从 .requestScope() 上的 GoogleSignInoptions.Builder 方法请求范围。

我还在 GCP 中添加了 SHA-1 密钥。

MainActivity.kt

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInoptions
import com.google.android.gms.common.SignInButton
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.common.api.Scope
import com.google.android.gms.tasks.Task
import com.google.android.material.textview.MaterialTextView


class MainActivity : AppCompatActivity(),View.OnClickListener {

    private val gso = GoogleSignInoptions.Builder(GoogleSignInoptions.DEFAULT_SIGN_IN)
        .requestemail()
        .build()

    private lateinit var mGoogleSignInClient: GoogleSignInClient
    lateinit var text: MaterialTextView
    lateinit var signInBtn: SignInButton


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mGoogleSignInClient = GoogleSignIn.getClient(this,gso)

        text = findViewById(R.id.text)
        signInBtn = findViewById(R.id.signInButton)

        signInBtn.setonClickListener(this)
    }

    override fun onStart() {
        super.onStart()
        val account = GoogleSignIn.getLastSignedInAccount(this)
        updateUI(account)
    }

    // Update the UI with user name
    private fun updateUI(account: GoogleSignInAccount?) {
        if (account != null)
            text.text = account.displayName
    }

    override fun onClick(v: View?) {
        if (v!!.id == R.id.signInButton) {
            signIn()
        }
    }

    private fun signIn() {
        val signInIntent = mGoogleSignInClient.signInIntent
        startActivityForResult(signInIntent,RC_SIGN_IN)
    }

    override fun onActivityResult(requestCode: Int,resultCode: Int,data: Intent?) {
        super.onActivityResult(requestCode,resultCode,data)
        if (requestCode == RC_SIGN_IN) {
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            handleSignInResult(task)
        } else if (RC_DRIVE == requestCode) {
            Log.d(TAG,"onActivityResult: Permission granted")
        }
    }

    private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) {
        try {
            val account = completedTask.getResult(ApiException::class.java)

            // Signed in successfully,show authenticated UI.
            updateUI(account)
            // If permission is not granted then it will request it
            if (!GoogleSignIn.hasPermissions(
                    GoogleSignIn.getLastSignedInAccount(this),Scope("https://www.googleapis.com/auth/drive.appdata")
                )
            ) {
                // This gives the infinitely loading screen
                GoogleSignIn.requestPermissions(
                    this,RC_DRIVE,GoogleSignIn.getLastSignedInAccount(this),Scope("https://www.googleapis.com/auth/drive.appdata")
                )
            }
        } catch (e: ApiException) {
            // The ApiException status code indicates the detailed failure reason.
            // Please refer to the GoogleSignInStatusCodes class reference for more @R_975_4045@ion.
            Log.w(TAG,"signInResult:Failed code=" + e.statusCode)
            updateUI(null)
        }
    }

    companion object {
        const val RC_SIGN_IN = 100
        const val RC_DRIVE = 101
        const val TAG = "MainActivity"
    }
}

解决方法

我必须在 GCP 控制台 > API 和服务 > 凭据中将自己添加为测试用户。

GCP console > API and Services > Credentials.

如果您想公开发布该应用,则需要发布该应用。