如何确定应用程序是否已与 Google Drive 断开连接?

abh*_*ank 5 android scopes google-drive-api google-drive-android-api

我正在构建一个应用程序,我将应用程序数据存储在 Google Drive 上的应用程序特定文件夹中。我已经能够设置与文件存储和检索相关的所有内容。我面临的问题是关于权限。用户可以选择从 Google Drive 设置面板断开应用程序。

我使用DriveScopes.DRIVE_APPDATA含义https://www.googleapis.com/auth/drive.appdata范围来保存数据。

在此处输入图片说明

我试图弄清楚如何找出这是否发生在应用程序端。如果我尝试继续使用与驱动器相关的 api,应用程序被断开连接,那么它会崩溃并显示UserRecoverableAuthException.

com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException
    at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:297)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:868)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:476)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:409)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:526)
    at abhiank.maplocs.ui.drivesync.DriveSyncService.onHandleIntent(DriveSyncService.kt:68)
    at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:78)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:214)
    at android.os.HandlerThread.run(HandlerThread.java:67)
 Caused by: com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission
    at com.google.android.gms.auth.zze.zzb(Unknown Source:13)
    at com.google.android.gms.auth.zzd.zza(Unknown Source:77)
    at com.google.android.gms.auth.zzd.zzb(Unknown Source:20)
    at com.google.android.gms.auth.zzd.getToken(Unknown Source:7)
    at com.google.android.gms.auth.zzd.getToken(Unknown Source:5)
    at com.google.android.gms.auth.zzd.getToken(Unknown Source:2)
    at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source:55)
    at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:267)
    at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:292)
Run Code Online (Sandbox Code Playgroud)

我尝试了以下方法来确定应用程序是否没有权限或范围。

  1. 查看GoogleSignInAccountGoogleSignIn.getLastSignedInAccount(this). account.grantedScopes()在应用程序断开连接后,它具有以下可用范围。drive.appdata即使应用程序已断开连接也会显示。
[https://www.googleapis.com/auth/drive.appdata, https://www.googleapis.com/auth/userinfo.profile, https://www.googleapis.com/auth/userinfo.email, openid, profile, email]
Run Code Online (Sandbox Code Playgroud)
  1. 最后一点我想是hasPermissions在可用的方法GoogleSignIn。我检查了此调用是否可以使用 APP_DATA 范围,它返回 true。所以也没有帮助。
GoogleSignIn.hasPermissions(account, Scope(DriveScopes.DRIVE_APPDATA))
Run Code Online (Sandbox Code Playgroud)

我现在真的被困住了。任何帮助将不胜感激。谢谢。

abh*_*ank 0

我最终在驱动器相关代码周围使用了 try-catch 并捕获了UserRecoverableAuthIOException. 根据文档,这在以下情况下被调用:

UserRecoverableAuthExceptions 表示可通过用户操作(例如用户登录)恢复的 Google 身份验证错误。

这对我来说效果很好。考虑到这个问题已经两年没有收到任何其他答案,似乎没有任何方法可以通过 API 或 SDK 调用获取有关应用程序是否断开连接的信息。

这是我使用的代码

fun getGoogleDriveService(context: Context): Drive {
    val credential = GoogleAccountCredential.usingOAuth2(context, setOf(DriveScopes.DRIVE_APPDATA))
    credential.selectedAccount = GoogleSignIn.getLastSignedInAccount(context)!!.account
    return Drive.Builder(NetHttpTransport(), GsonFactory(), credential)
            .setApplicationName(DriveSyncService.APP_NAME)
            .build()
}

try {
    val driveService = getGoogleDriveService(this)
    var fileList = driveService.files().list().execute()
    //...
    //more code
} catch (e: UserRecoverableAuthIOException) {
    /*
    Doing a sign-out on the googleSignInClient so that there is no mismatch 
    in sign-in state and so that when I start sign-in process again, it 
    starts afresh
    */
    googleSignInClient.signOut()
    /*
    Then I show a pop up telling user that app was disconnected and 
    to sign in again. And then on click I start the sign-in flow again. 
    */
} catch (e: GoogleJsonResponseException) {
    //https://googleapis.dev/java/google-api-client/latest/index.html?com/google/api/client/googleapis/json/GoogleJsonResponseException.html
    //404 is file being updated/deleted was not found
    if (e.message != null && e.message!!.contains("storageQuotaExceeded")) {
        //todo handle storage exceeded error. Inform user
    }
} catch (e: IOException) {
    //todo handle network error
}

Run Code Online (Sandbox Code Playgroud)