Android Google Drive API-名称不能为空:null(但我已将有效帐户名传递给GoogleAccountCredential)

Android Google Drive API-名称不能为空:null(但我已将有效帐户名传递给GoogleAccountCredential),android,google-drive-api,Android,Google Drive Api,最近,我有Android代码,可以访问Google Drive。我正在使用Google API Java客户端库而不是Google Play services客户端库 private static GoogleCloudFile searchFromGoogleDrive(Drive drive, String qString, HandleUserRecoverableAuthIOExceptionable h, PublishProgressable p) { try {

最近,我有Android代码,可以访问Google Drive。我正在使用Google API Java客户端库而不是Google Play services客户端库

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
,与谷歌硬盘相关的代码更改为0

但是,代码在
FileList FileList=request.execute()处崩溃,但以下情况除外

使用1.18.0-rc时的错误日志 Utils.java 另外,我非常确定我的OAuth2.0通过Google开发者控制台(对于调试密钥库和生产密钥库)是正确的 最近,Android 6引入了运行时权限。我想知道,这个例外是否与此相关

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

使用1.21.0时的错误日志
java.lang.RuntimeException:执行doInBackground()时出错
在android.os.AsyncTask$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)
在android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
运行(Thread.java:818)
原因:java.lang.IllegalArgumentException:名称不能为空:null
在android.accounts.Account.(Account.java:48)
访问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.GoogleAppis.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)
位于com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
位于com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
位于org.yccheok.jstock.gui.Utils.searchFromGoogleDrive(Utils.java:208)
在org.yccheok.jstock.gui.Utils.\u loadFromGoogleDrive(Utils.java:277)
位于org.yccheok.jstock.gui.Utils.loadFromGoogleDrive(Utils.java:344)
位于org.yccheok.jstock.gui.LoadFromCloudTask.doInBackground(LoadFromCloudTask.java:23)
位于org.yccheok.jstock.gui.LoadFromCloudTask.doInBackground(LoadFromCloudTask.java:9)
在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)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
运行(Thread.java:818)
我进一步测试的最新情况 以上两个错误日志是在我使用Nexus5,Android版本6.0.1进行测试时生成的

但是,如果我使用Nexus 4、Android版本5.1.1进行相同的测试,则不会发生错误!1.18.0-rc和1.21.0运行良好


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

它看起来像是Java调用到
GoogleAuthUtil.getToken()
的驱动器API客户端库,它需要
获取帐户
权限。您需要在清单中拥有该权限,并根据需要在运行时请求该权限

更新:
使用Google Drive REST v3 API时,不需要获得
权限。相反,需要电子邮件许可。您可以通过调用
GoogleSignInOptions.Builder.requestEmail

来请求它,因为在
Android 6.0(API级别23)
中,您需要在调用google端点之前获得联系人权限

您可以在此处查看完整的详细信息-


这仅适用于危险权限和权限组(基于它们与用户隐私的关联程度)。更多详细信息-

我遇到了同样的问题,所有权限都被授予了,但我仍然遇到了这个错误

我的简单问题是,
googleSignInAccount.getSignInAccount().getAccount()
null
。如果您不请求电子邮件权限(
GoogleSignInOptions.Builder.requestEmail
),就会出现这种情况。似乎没有用户电子邮件就无法创建此帐户

因此,请确保将此权限添加到
GoogleSignionOptions
..

在我的情况下(Google Drive REST API v3),ProGuard是罪魁祸首,因为代码在调试模式下运行良好

只需将
-keep class com.google.*{*;}
添加到ProGuard规则中,就可以解决这个问题


PS:我必须调用
requestEmail()
,但我没有请求任何
GET\u帐户的权限。

我使用谷歌api客户端

// Dependency of Google Api client
implementation 'com.google.api-client:google-api-client:1.30.9'
implementation 'com.google.api-client:google-api-client-android:1.30.9'
implementation 'com.google.apis:google-api-services-drive:v3-rev20200413-1.30.9'
GoogleSignInOptions gso=新的GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT\u登录)
.requestScopes(新范围(Scopes.DRIVE\u APPFOLDER))
//要求发送电子邮件
.requestEmail()
.build();
GoogleSignInClient mGoogleSignInClient=GoogleSignIn.getClient(此为gso);
//in-onActivityResult方法
Task Task=GoogleSignIn.GetSignedAccou
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);
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();
}
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) 
// Dependency of Google Api client
implementation 'com.google.api-client:google-api-client:1.30.9'
implementation 'com.google.api-client:google-api-client-android:1.30.9'
implementation 'com.google.apis:google-api-services-drive:v3-rev20200413-1.30.9'