API Google Диска – имя не должно быть пустым: null (Но я передал действительное имя учетной записи в GoogleAccountCredential)

Недавно у меня есть код Android, который обращается к Google Диску. Я использую клиентскую библиотеку API Google API для Java вместо клиентской библиотеки сервисов Google Play

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

Код работает 100% штрафа в течение нескольких лет, если я использую targetSdkVersion 21 .

В последнее время я targetSdkVersion 23 свое приложение в targetSdkVersion 23 , с 0 сменой кода на Google Диске.

Тем не менее, код FileList fileList = request.execute(); тайну в FileList fileList = request.execute(); , Со следующим исключением.

Журнал ошибок при использовании 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) 

Если я google, я получаю Google Drive на ошибке android: java.lang.IllegalArgumentException: имя не должно быть пустым: null , в котором указано, что имя учетной записи не передается объекту учетных данных.

Тем не менее, я почти уверен, что мой учетный объект передан с действительным именем учетной записи (в формате xxx@gmail.com)

 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 вводит разрешения во время выполнения. Мне было интересно, может ли это исключение относиться к этому?

Я также попробую с последней версией библиотеки 1.21.0. Тем не менее, я все еще получаю аналогичный журнал ошибок

Журнал ошибок при использовании 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) 

Обновление моего дальнейшего тестирования

Вышеуказанные 2 журнала ошибок генерируются во время тестирования с использованием Nexus 5, версии 6.0.1 для Android

Однако, если я проведу те же тесты с использованием Nexus 4, версии Android 5.1.1, ошибок не будет! Оба 1.18.0-rc и 1.21.0 работают нормально

Следовательно, похоже, что авария сильно связана с версией Android.

Похоже, что клиентская библиотека Drive API для Java вызывает GoogleAuthUtil.getToken() , для которой требуется разрешение GET_ACCOUNTS . Вы должны иметь это разрешение в своем манифесте и запросить его во время выполнения, если это необходимо.

Это связано с тем, что из Android 6.0 (API level 23) вам нужно получить разрешение «Контакты», прежде чем вы будете ссылаться на конечные точки google.

Вы можете увидеть здесь полную информацию – https://developer.android.com/training/permissions/requesting.html

Это справедливо только для опасных групп разрешений и разрешений (в зависимости от того, насколько они связаны с конфиденциальностью пользователей). Подробнее – https://developer.android.com/guide/topics/security/permissions.html#perm-groups

У меня была такая же проблема, все разрешения были предоставлены, и все же я получил эту ошибку.

Моя простая проблема заключалась в том, что googleSignInAccount.getSignInAccount().getAccount() null . В этом случае, если вы НЕ запрашиваете разрешения электронной почты ( GoogleSignInOptions.Builder.requestEmail ). Похоже, что эта учетная запись не может быть создана без электронной почты пользователя.

Поэтому обязательно добавьте это разрешение в GoogleSignInOptions