本文介绍了Google Drive API - 名称不能为空:null(但我已将有效帐户名称传递给 GoogleAccountCredential)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

最近,我有访问 Google Drive 的 Android 代码.我正在使用 Google APIs 客户端库 for Java 而不是 Google Play 服务客户端库

Recently, I have Android code which accesses to Google Drive. I'm using Google APIs Client Library for Java instead of Google Play services client library

private static GoogleCloudFile searchFromGoogleDrive(Drive drive, String qString, HandleUserRecoverableAuthIOExceptionable h, PublishProgressable p) {
    try {
        Files.List request = drive.files().list().setQ(qString);

        do {
            if (p.isCancelled()) {
                return null;
            }

            FileList fileList = request.execute();

如果我使用 targetSdkVersion 21,代码可以 100% 正常运行几年.

The code works 100% fine for several years, if I use targetSdkVersion 21.

最近,我将我的应用迁移到 targetSdkVersion 23,Google Drive 相关代码更改为 0.

Recently, I migrate my app to targetSdkVersion 23, with 0 change on Google Drive related code.

但是,代码在 FileList fileList = request.execute(); 处崩溃,但有以下异常.

However, the code crashes mystery at FileList fileList = request.execute();, with the following exception.

Process: org.yccheok.jstock.gui, PID: 30317
java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:309)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)
 Caused by: java.lang.IllegalArgumentException: the name must not be empty: null
    at android.accounts.Account.<init>(Account.java:48)
    at com.google.android.gms.auth.zzd.getToken(Unknown Source)
    at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
    at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:255)
    at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:279)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
    at org.yccheok.jstock.gui.Utils.searchFromGoogleDrive(Utils.java:208)
    at org.yccheok.jstock.gui.Utils._loadFromGoogleDrive(Utils.java:277)
    at org.yccheok.jstock.gui.Utils.loadFromGoogleDrive(Utils.java:344)
    at org.yccheok.jstock.gui.LoadFromCloudTask.doInBackground(LoadFromCloudTask.java:23)
    at org.yccheok.jstock.gui.LoadFromCloudTask.doInBackground(LoadFromCloudTask.java:9)
    at android.os.AsyncTask$2.call(AsyncTask.java:295)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
    at java.lang.Thread.run(Thread.java:818) 

如果我 google,我会得到 GoogleDrive on android 错误:java.lang.IllegalArgumentException: name must not be empty: null ,这表明帐户名称未传递给凭据对象.

If I google, I get Google Drive on android error: java.lang.IllegalArgumentException: the name must not be empty: null , which states that account name is not passed to credential object.

但是,我很确定我的凭据对象是通过有效的帐户名(格式为 [email protected])传递的

However, I'm pretty much sure that my credential object is passed with valid account name (in format [email protected])

protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
    switch (requestCode) {
    case RequestCode.REQUEST_ACCOUNT_PICKER_LOAD_FROM_CLOUD:
        if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
            String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
            Log.i("CHEOK", "accountName = " + accountName);
            if (accountName != null) {
                JStockApplication.instance().getJStockOptions().setUsername(accountName);
                Utils.getGoogleAccountCredential().setSelectedAccountName(accountName);

Utils.java

public static GoogleAccountCredential getGoogleAccountCredential() {
    return googleAccountCredential;
}

private static final GoogleAccountCredential googleAccountCredential = GoogleAccountCredential.usingOAuth2(JStockApplication.instance(),
    Arrays.asList(
        DriveScopes.DRIVE_APPDATA,
        // Legacy. Shall be removed after a while...
        DriveScopes.DRIVE
    )
);

private Drive getDriveService() {
    return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), Utils.getGoogleAccountCredential()).build();
}

另外,我很确定我的 OAuth 2.0 通过 Google Developers Console 正确(对于调试密钥库和生产密钥库)最近,Android 6 引入了运行时权限.我想知道,这个异常是否与此有关?

Also, I'm pretty sure that my OAuth 2.0 correctly through Google Developers Console (For both debug keystore & production keystore)Recently, Android 6 introduces run-time permissions. I was wondering, can this exception related to that?

我进一步尝试使用最新的库版本 1.21.0.但是,我仍然收到类似的错误日志

I further try with latest library version 1.21.0. However, I still get similar error log

java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:309)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IllegalArgumentException: the name must not be empty: null
    at android.accounts.Account.<init>(Account.java:48)
    at com.google.android.gms.auth.zzd.getToken(Unknown Source)
    at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
    at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:255)
    at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:279)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
    at org.yccheok.jstock.gui.Utils.searchFromGoogleDrive(Utils.java:208)
    at org.yccheok.jstock.gui.Utils._loadFromGoogleDrive(Utils.java:277)
    at org.yccheok.jstock.gui.Utils.loadFromGoogleDrive(Utils.java:344)
    at org.yccheok.jstock.gui.LoadFromCloudTask.doInBackground(LoadFromCloudTask.java:23)
    at org.yccheok.jstock.gui.LoadFromCloudTask.doInBackground(LoadFromCloudTask.java:9)
    at android.os.AsyncTask$2.call(AsyncTask.java:295)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
    at java.lang.Thread.run(Thread.java:818) 

更新我的进一步测试

以上 2 个错误日志是在我使用 Nexus 5,Android 版本 6.0.1 进行测试时生成的

Update on my further testing

The above 2 error logs are generated while I'm testing using Nexus 5, Android version 6.0.1

但是,如果我使用 Nexus 4,Android 版本 5.1.1 进行相同的测试,则不会出现错误!1.18.0-rc 和 1.21.0 都可以正常工作

因此,崩溃似乎与 Android 版本密切相关.

Hence, it seems the crash is strongly related to Android version.

推荐答案

看起来像 Drive API Client Library for Java 调用 GoogleAuthUtil.getToken(),需要 GET_ACCOUNTS 权限.您需要在清单中拥有该权限,并在运行时酌情请求.

It looks like the Drive API Client Library for Java calls into GoogleAuthUtil.getToken(), which requires the GET_ACCOUNTS permission. You need to have that permission in your manifest and request it at runtime, as appropriate.

更新:使用 Google Drive REST v3 API,不需要 GET_ACCOUNTS 权限.相反,需要电子邮件权限.您可以通过调用 GoogleSignInOptions.Builder.requestEmail 来请求它.

UPDATE:With Google Drive REST v3 API, GET_ACCOUNTS permission is not required. Instead, Email permission is required. You can ask for it by calling GoogleSignInOptions.Builder.requestEmail.

这篇关于Google Drive API - 名称不能为空:null(但我已将有效帐户名称传递给 GoogleAccountCredential)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 16:23