迁移到 Android 中的最新 Google 驱动器 API 时出错 - 超出了未经身份验证使用的每日限制。继续使用需要注册

Error while migrating to latest Google Drive API in Android - Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup

一个应用程序在 Play 商店上发布,它使用 'application data folder' 用于使用 Drive API. Everything works fine. However, this API is about to be turned down on 6th December, 2019 according to Google's announcement. Therefore, in order to support existing users, I have been migrating to latest API according to migration guidlines and an official sample app 的备份恢复目的。

我可以使用下面的代码 (from the official link) 成功进行身份验证。

GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                                         .requestEmail()
                                         .requestScopes(new Scope(DriveScopes.DRIVE_APPDATA))
                                         .build();
GoogleSignInClient client = GoogleSignIn.getClient(this, signInOptions);

// The result of the sign-in Intent is handled in onActivityResult.
startActivityForResult(client.getSignInIntent(), REQUEST_CODE_SIGN_IN);

我也在使用正确的范围 - DriveScopes.DRIVE_APPDATA 如官方文档所述。

我还在 onActivityResult()

中看到 'email' 和 'granted scopes' 的正确值
if (requestCode == REQUEST_CODE_SIGN_IN && resultCode == RESULT_OK) {

   GoogleSignIn.getSignedInAccountFromIntent(data).addOnSuccessListener(new OnSuccessListener<GoogleSignInAccount>() {
                @Override
                public void onSuccess(GoogleSignInAccount googleSignInAccount) {

                    Log.e("TAG", "Email - " + googleSignInAccount.getEmail()); // prints correct value
                    Log.e("TAG", "Granted scopes - " + googleSignInAccount.getGrantedScopes()); // prints correct value

                    GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(getActivity(), Collections.singleton(DriveScopes.DRIVE_APPDATA));
                    credential.setSelectedAccount(googleSignInAccount.getAccount());

                    Drive googleDriveService = new Drive.Builder(
                            AndroidHttp.newCompatibleTransport(),
                            new GsonFactory(),
                            credential)
                            .setApplicationName("App Name") // Changed it for now
                            .build();
                    mDriveServiceHelper = new DriveServiceHelper(googleDriveService);

                    queryFiles();
                }
            });
}

但是,每当我尝试使用下面的代码 (from the official link) 访问 queryFiles() 中的备份文件时,

FileList files = driveService.files().list()
    .setSpaces("appDataFolder")
    .setFields("nextPageToken, files(id, name)")
    .setPageSize(10)
    .execute();
for (File file : files.getFiles()) {
  System.out.printf("Found file: %s (%s)\n",
      file.getName(), file.getId());
}

它抛出以下错误

{
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "dailyLimitExceededUnreg",
    "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
    "extendedHelp": "https://code.google.com/apis/console"
   }
  ],
  "code": 403,
  "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
 }

请帮我修正错误。我相信,由于已发布的版本一切正常,因此在 Google API 控制台上的配置应该是正确的。

出于文档目的作为故障排除步骤:

转到

https://console.developers.google.com/project/<project-id>/apiui/api

或 Google 脚本:

https://script.google.com/home/usersettings

替换为您的应用程序 ID,并检查 Google 驱动器 API 是否已打开。

如果不是 - 如果是这种情况,请确保在打开它后获得一个新令牌。

我可能找不到所有有此问题的线程,但我可以尝试提供一些帮助。

主要答案

如果你和我一样使用 ProGuard。 ProGuard 可能会导致此错误在查询期间发生。我使用以下方法修复了它。

# Fix OAuth Drive API failure for release builds
-keep class * extends com.google.api.client.json.GenericJson { *; }
-keep class com.google.api.services.drive.** { *; }
-keepclassmembers class * { @com.google.api.client.util.Key <fields>; }

次要答案

请注意,您不要 需要使用 keys/tokens 将驱动器支架 API 与 Android 结合使用,就像您可能会从其他解决方案中找到的那样(它可能也不会伤害,但它可以)。它在这里与人们在其他地方谈论的内容不匹配(在这里他们不知道他们在谈论什么)。

在这里查看我的笔记以获取更多信息:Google Drive via OAuth release version receives dailyLimitExceededUnreg

如果您在调试构建中遇到问题,那么您没有正确完成所有操作。我的笔记应该能让你走上正轨。

如果您需要进一步的帮助,我可能会提供帮助,因为这太疯狂了。

使用新 API 从驱动器获取文件的示例

从下面看link

public Task<Pair<String, String>> readFile(String fileId)

https://github.com/gsuitedevs/android-samples/blob/master/drive/deprecation/app/src/main/java/com/google/android/gms/drive/sample/driveapimigration/DriveServiceHelper.java

id 来自查询结果,其中 id 是附加到从云端硬盘查询返回的查询信息的一部分。 id 是您要检索的文件的文件 ID。将其传递给 readFile,它会返回文件内容,您可以在本地保存到 java.io.File,例如 fileOutputStream.write(contents.getBytes());其中的内容是pair.second。然后你会希望(因为有时我们有更多的工作要做)相同 java.io.File.

如果您在 link 示例中也需要一个基本查询,您可以看到一个基本查询,但它缺少一些重要信息,因为根据您的操作,您可能需要检查是否已删除、获取文件大小、修改时间、md5、设置顺序等。您可能需要查看 https://developers.google.com/drive/api/v2/reference/files/list and https://developers.google.com/drive/api/v3/reference/files 等才能弄清楚。如果文件够多,也会有分页的要求。

我知道从代码中使用 Drive 有点疯狂(好吧,反正对我来说是这样哈哈)所以等一下 =)