2015-06-29 5 views
1

У меня возникли проблемы с API Google Диска в приложении для Android. На моем устройстве Nexus 4 с Android 5.1.1 работает нормально. На устройствах моего пользователя экран согласия, который я настроил, не отображается, вместо этого отображается только диалог выбора списка с электронной почтой пользователя, но он ничего не делает.Аутентификация API Google Drive

Я видел эту проблему на дереве других устройств с Android 5.0.1.

Я установил учетные данные OAuth 2.0 с помощью моего ключа SHA1 производства и экрана согласия. Как я уже сказал, он отлично работает на моем устройстве.

Я использую следующие параметры для компиляции моего приложения:

  • minSdkVersion = 15
  • targeSdKVerion = 22
  • compileSdkVersion = 22
  • Build Tools: 22.0.1
  • Platform Инструменты: 23rc3

И эти google libs:

  • com.android.support:support-v4:22.2.0
  • com.android.support:appcompat-v7:22.2.0
  • com.android.support:design:22.2.0
  • com.google.android.gms: стыковые услуги-объявления: 7.5.0
  • com.google.android.gms: стыковые услуги-привод: 7.5.0

Спасибо!

Вот как мой код выглядит сейчас:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (requestCode == REQUEST_CODE_RESOLUTION) { 
     if (resultCode == RESULT_OK) { 
      // Make sure the app is not already connected or attempting to connect. 
      if (!mBackupAsyncTask.getGoogleApiClient().isConnecting() && 
        !mBackupAsyncTask.getGoogleApiClient().isConnected()) { 
       // Connect and execute the task. 
       mBackupAsyncTask.getGoogleApiClient().connect(); 
      } 
     } 
    } 
} 

@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    Log.i(LOG_TAG, "GoogleApiClient connection failed: " + connectionResult.toString()); 

    if (!connectionResult.hasResolution()) { 
     Log.i(LOG_TAG, "Error with no resolution."); 
     // Show the localized error dialog. 
     GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(), this, 0).show(); 
    } else { 
     // The failure has a resolution. Resolve it. 
     // Called typically when the app is not yet authorized, and an authorization 
     // dialog is displayed to the user. 
     try { 
      connectionResult.startResolutionForResult(this, REQUEST_CODE_RESOLUTION); 
     } catch (IntentSender.SendIntentException e) { 
      Log.e(LOG_TAG, "Exception while starting resolution activity.", e); 
     } 
    } 
} 

public class DriveBackupAsyncTask extends ApiClientAsyncTask<Object, Void, Metadata> { 

    public DriveBackupAsyncTask(Context context) { 
     super(context); 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     mProgressBar.setIndeterminate(true); 
     mEfetuarBackupButton.setEnabled(false); 
     mRestaurarBackupButton.setEnabled(false); 
    } 

    @Override 
    protected Metadata doInBackgroundConnected(Object... params) { 
     if (params[0].equals(TASK_BACKUP)) { 
      DriveFile backupFile = DriveBackupHelper.createBackup(
        getGoogleApiClient(), 
        APP_FOLDER, 
        BACKUP_FILE, 
        getDbFile()); 

      if (backupFile != null) 
       return backupFile.getMetadata(getGoogleApiClient()).await().getMetadata(); 
     } 

     if (params[0].equals(TASK_RESTAURAR)) { 
      DriveFile backupFile = DriveBackupHelper.getBackupFile(
        getGoogleApiClient(), 
        APP_FOLDER, 
        BACKUP_FILE); 

      if (backupFile == null) 
       return null; 

      if (DriveBackupHelper.restoreBackup(getGoogleApiClient(), getDbFile(), backupFile)) 
       return backupFile.getMetadata(getGoogleApiClient()).await().getMetadata(); 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Metadata result) { 
     super.onPostExecute(result); 
     mProgressBar.setIndeterminate(false); 
     mEfetuarBackupButton.setEnabled(true); 
     mRestaurarBackupButton.setEnabled(true); 

     if (result == null) { 
      showError(getString(R.string.bkp_error)); 
     } else { 
      showMessage(getString(R.string.bkp_success)); 
     } 
    } 
} 
+0

Это диалоговое окно с просьбой выбрать учетную запись? Если на телефоне есть несколько учетных записей Google, и вы не создали свой GoogleApiClient с помощью 'useDefaultAccount()', отображается диалоговое окно с просьбой выбрать учетную запись. Вы говорите, что диалог «ничего не делает». Можете ли вы предоставить более подробную информацию? –

+0

Да, это диалоговое окно, предлагающее пользователю выбрать учетную запись. Когда пользователь выбирает учетную запись, ничего не происходит. Я не создавал свой клиент с опцией useDefaultAccount. –

+1

Фактически этот диалог появляется, даже если пользователь имеет только одну учетную запись. –

ответ

1

Это объяснение предполагает, что ваш код основан на Google API Guide для обработки ошибок соединения и структурировано аналогично примера, приведенного ниже (это копируется из Руководства):

@Override 
public void onConnectionFailed(ConnectionResult result) { 
    if (mResolvingError) { 
     // Already attempting to resolve an error. 
     return; 
    } else if (result.hasResolution()) { 
     try { 
      mResolvingError = true; 
      // This statement causing posting of the account picker dialog 
      // or other UI to resolve the connection problem. 
      result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR); 
     } catch (SendIntentException e) { 
      // There was an error with the resolution intent. Try again. 
      mGoogleApiClient.connect(); 
     } 
    } else { 
     // Show dialog using GooglePlayServicesUtil.getErrorDialog() 
     showErrorDialog(result.getErrorCode()); 
     mResolvingError = true; 
    } 
} 

Диалог, который вы видите, создается, когда пользователю нужно выбрать учетную запись. Оно порождается этим утверждением в onConnectionFailed():

result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR); 

Где REQUEST_RESOLVE_ERROR целая константа вы определяете. Когда пользователь выбирает учетную запись в диалоговом окне, ваша активность получает результат с кодом запроса, равным REQUEST_RESOLVE_ERROR. Ваша деятельность должна иметь метод для обработки результата, похожего на этот (также скопированный из Руководства):

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (requestCode == REQUEST_RESOLVE_ERROR) { 
     mResolvingError = false; 
     if (resultCode == RESULT_OK) { 
      // Make sure the app is not already connected or attempting to connect 
      if (!mGoogleApiClient.isConnecting() && 
        !mGoogleApiClient.isConnected()) { 
       mGoogleApiClient.connect(); 
      } 
     } 
    } 
} 

Когда вы говорите в своем сообщении, что диалог «ничего не делать», это говорит о том, что вы делаете не имеют метода onActivityResult() или, если вы это делаете, код не правильно обрабатывает результат из диалогового окна.

Если этот ответ вам не поможет, и у вас уже есть onActivityResult(), отправьте его вместе с onConnectionFailed().

+0

Хорошо, мое плохое. Сначала я использовал async-запросы для доступа к Google Drive, но затем я изменил запрос на синхронизацию с помощью этого демонстрационного приложения: https://github.com/googledrive/android-demos/blob/master/src/com/google/ android/gms/drive/sample/demo/SyncRequestsActivity.java Я сорвал onActivityResult из моего приложения, потому что не видел метод на демо, но я забыл проверить BaseDemoActivity. Теперь мое приложение работает нормально, я еще не знаю, почему он работал на моем устройстве. –

+0

Я все еще узнаю о соединениях GoogleApi. Мой опыт заключается в том, что при первом подключении приложения отображается [AccountPicker] (https://developers.google.com/android/reference/com/google/android/gms/common/AccountPicker), а затем диалог согласия. Если пользователь завершает оба из них и делает соединение, Менеджер учетных записей сохраняет выбранную учетную запись в качестве значений по умолчанию и любых токенов OAuth. При последующих запросах на соединение сохраненные значения используются для удобства пользователя (продолжение в следующем комментарии). –

+0

Для тестирования разработки было бы неплохо очистить сохраненные значения, чтобы реализовать весь код для разрешения отказа соединения. Я не нашел способ сделать это. Этот [связанный вопрос] (http://stackoverflow.com/questions/26457118/user-sign-out-clearing-the-default-google-account-does-not-cause-the-account-pi) обсуждает трудности других были с этим. –