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

问题描述

限时删除!!

最近,我有Android代码访问Google Drive。我正在使用适用于Java的Google API客户端库,而不是 Google Play服务客户端库
$ b

  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%



最近,我将我的应用迁移到 targetSdkVersion 23 Google Drive相关的代码。



然而,代码在 FileList fileList = request.execute(); 中崩溃了,有以下例外。



使用1.18.0-rc时的错误日志



 进程:org.yccheok.jstock.gui,PID:30317 
java.lang.RuntimeException:在android.os.AsyncTask中执行doInBackground()
时发生错误$ 3.done(AsyncTask。 java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
在java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:234)
在java.util.concurrent。 ThreadPoolEx $ java.util.concurrent.ThreadPoolExecutor
$ Worker.run(ThreadPoolExecutor.java:588)$ b $ java.util.run(Thread.java: 818)
导致:java.lang.IllegalArgumentException:名称不能为空:null在android.accounts.Account处为
。< init>(Account.java:48)
at com.google.android.gms.auth.zzd.getToken(未知来源)
,com.google.android.gms.auth.GoogleAuthUtil.getToken(未知来源)
,com.google.api。 client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:255)
,位于com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential $ RequestHandler.intercept (GoogleAccountCredential.java:279)
,位于com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
位于com.google.api.client.googleapis.services.AbstractGoogleClientRequest .executeUnparsed(AbstractGoogleClientRequest.java:4 10)
,位于com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
位于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)
在org.yccheok.jstock.gui.LoadFromCloudTask.doInBackground(LoadFromCloudTask.java:9)
at android.os.AsyncTask $ 2.call(AsyncTask.java:295)
在java.util。并发.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor .java:1113)
a t java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:588)$ b $在java.lang.Thread.run(Thread.java:818)

如果我google,我会得到,其中规定帐户名不会传递给凭证对象。



但是,我非常确定我的凭证对象是通过有效的帐户名称传递的(格​​式为[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。一段时间后将被删除...
DriveScopes.DRIVE

);

私人驱动器getDriveService(){
返回新的Drive.Builder(AndroidHttp.newCompatibleTransport(),新的GsonFactory(),Utils.getGoogleAccountCredential())。
}

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



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



使用1.21.0时的错误日志



  java.lang.RuntimeException:在android.os.AsyncTask执行doInBackground()
时发生错误$ 3.done(AsyncTask.java:309)$ java.util.concurrent.FutureTask中的
.finishCompletion(FutureTask.java:354)$ java.util.concurrent.FutureTask.setException处的
(FutureTask.java:223)$ 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)$ b $在java.lang.Thread.run(Thread.java:818)
导致:java.lang.IllegalArgumentException:名称不能为空:null在android.accounts.Account处的
。< init>(Account.java:48)
在com.google.android.gms.auth.zzd.getToken(Unkn自己的源)
在com.google.android.gms.auth.GoogleAuthUtil.getToken(未知源)
在com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential。 getToken(GoogleAccountCredential.java:255)
,位于com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential $ RequestHandler.intercept(GoogleAccountCredential.java:279)
com。 google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
,位于com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
,位于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._loadFromGo在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)
在java.util.concurrent.FutureTask.run(FutureTask.java:237)
在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:234)
在java.util.concurrent .ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)$ b $在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:588)$ b $在java.lang.Thread.run(Thread.java :818)



我的进一步测试更新





因此,它的崩溃似乎与Android版本紧密相关。 b $ b

解决方案

它看起来像用于Java的Drive API客户端库调用 GoogleAuthUtil.getToken() ,这需要 GET_ACCOUNTS 权限。您需要在清单中拥有该权限并在运行时请求它。


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();

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

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

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

Error log while using 1.18.0-rc

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) 

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.

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();
}

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?

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

Error log while using 1.21.0

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) 

Update on my further testing

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

However, if I conduct the same testing using Nexus 4, Android version 5.1.1, no error occurs! Both 1.18.0-rc and 1.21.0 are working fine

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

解决方案

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

1403页,肝出来的..

09-06 16:23