I wanted to integrate Google drive into my app for storing user's app data in it.
What I have tried
I have implemented Google Sign-In from Google dev doc and requested drive scope from additional scopes section. Also I tried to request scope directly from .requestScope()
method on GoogleSignInOptions.Builder
.
I have also added SHA-1 key in GCP.
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 information.
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"
}
}
I had to add myself as a testing user in GCP console > API and Services > Credentials.
You would require to publish the app if you want to make it publicly available.