Как настроить учетные данные Google Диска в приложении Android?

Приложение было зарегистрировано в «Google API-консоли» как «установленное приложение» – кажется, что это подходящая настройка для Android-приложения, нет?

Таким образом, у меня есть идентификатор клиента и секретный идентификатор. Чтобы было ясно: это не веб-приложение, а приложение Google Диск – это приложение для Android, доступ к другим данным пользователей в облаке Google Диска.

В приложении я получаю учетную запись (работает), и я запрашиваю токен (работает). Теперь я хочу подключиться к Google Диску с этим токеном и идентификатором клиента. Результатом является «401, неверные учетные данные». Что случилось с этим кодом?

public class ActivityMain extends Activity implements DialogInterface.OnClickListener { // https://developers.google.com/drive/scopes private static final String AUTH_TOKEN_TYPE = "oauth2:https://www.googleapis.com/auth/drive"; // https://code.google.com/apis/console/ private static final String CLIENT_ID = "999999999999999.apps.googleusercontent.com"; private AccountManager accountManager; private Account[] accounts; private String authName; private String authToken; @Override public void onClick(final DialogInterface dialogInterface, final int item) { processAccountSelected(accounts[item]); } @Override public void onCreate(final Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.activitymain); accountManager = AccountManager.get(this); accounts = accountManager.getAccountsByType("com.google"); if (accounts == null || accounts.length == 0) { // TODO } else if (accounts.length == 1) { processAccountSelected(accounts[0]); } else if (accounts.length > 1) { showDialog(MyConstants.DIALOG_ACCOUNTCHOSER); } } @Override protected Dialog onCreateDialog(final int id) { switch (id) { case MyConstants.DIALOG_ACCOUNTCHOSER: AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); String[] names = new String[accounts.length]; for (int i = 0; i < accounts.length; i++) { names[i] = accounts[i].name; } alertDialogBuilder.setItems(names, this); alertDialogBuilder.setTitle("Select a Google account"); return alertDialogBuilder.create(); } return null; } private void processAccountSelected(final Account account) { if (account != null) { authName = account.name.toString(); if (!Tools.isEmpty(authName)) { Toast.makeText(this, authName, Toast.LENGTH_LONG).show(); accountManager.getAuthToken(account, AUTH_TOKEN_TYPE, null, this, new AccountManagerCallback<Bundle>() { public void run(final AccountManagerFuture<Bundle> future) { try { authToken = future.getResult().getString( AccountManager.KEY_AUTHTOKEN); processTokenReceived(); } catch (OperationCanceledException exception) { // TODO } catch (Exception exception) { Log.d(this.getClass().getName(), exception.getMessage()); } } }, null); } } } private void processListFiles(final Drive drive) { List<File> result = new ArrayList<File>(); Files.List request = null; try { request = drive.files().list(); } catch (IOException exception) { } do { try { FileList files = request.execute(); result.addAll(files.getItems()); request.setPageToken(files.getNextPageToken()); } catch (IOException exception) { // --> 401 invalid credentials } } while (request.getPageToken() != null && request.getPageToken().length() > 0); } private void processTokenReceived() { if (!Tools.isEmpty(authToken)) { final HttpTransport transport = AndroidHttp.newCompatibleTransport(); final JsonFactory jsonFactory = new GsonFactory(); GoogleCredential credential = new GoogleCredential(); credential.setAccessToken(authToken); Drive drive = new Drive.Builder(transport, jsonFactory, credential) .setApplicationName(getString(R.string.txt_appname)) .setJsonHttpRequestInitializer(new GoogleKeyInitializer(CLIENT_ID)) .build(); if (drive != null) { processListFiles(drive); } } } } 

Я должен сказать, что это полная беспорядок. В Интернете так много страниц, показывающих только части, и существует так много страниц, использующих устаревшие, отсутствующие или разные методы, чтобы сделать то же самое. Есть, на мой взгляд, не две страницы, показывающие тот же способ получить данные с Google Диска из приложения Android.

Любая помощь высоко ценится.

EDIT: Я мог бы решить это сам. Это была комбинация различных изменений:

  • Придется установить андроид: minSdkVersion = "11" в качестве требования
  • Приходилось использовать текущие библиотеки: google-api-client-1.11.0-beta.jar, google-api-client-android-1.11.0-beta.jar, google-api-services-drive-v2-rev9-1.8 .0-beta.jar, google-http-client-1.11.0-beta.jar, google-http-client-android-1.11.0-beta.jar, google-http-client-gson-1.11.0-beta .jar, google-http-client-jackson2-1.11.0-beta.jar, google-oauth-client-1.11.0-beta.jar, gson-2.1.jar, guava-11.0.1.jar, jackson-core -2.0.5.jar, jsr305-1.3.9.jar

Это текущая часть, чтобы получить объект Drive:

  GoogleCredential credential = new GoogleCredential(); credential.setAccessToken(authToken); HttpTransport transport = AndroidHttp.newCompatibleTransport(); JsonFactory jsonFactory = new AndroidJsonFactory(); drive = new Drive.Builder(transport, jsonFactory, credential) .setApplicationName(getString(R.string.txt_appname)) .setJsonHttpRequestInitializer( new GoogleKeyInitializer(APIKEY_SIMPLE)) .build(); if (drive != null) { } 

Solutions Collecting From Web of "Как настроить учетные данные Google Диска в приложении Android?"

Да, документация довольно трудно поймать.

Просто измените

 new GoogleKeyInitializer(CLIENT_ID) 

в

 new GoogleKeyInitializer(SIMPLE_API_ACCESS_KEY) 

И он должен работать.

Вы можете найти свой SIMPLE_API_ACCESS_KEY в консоли API Google в разделе « Простой доступ к API» на странице « Доступ к API key ). Если этот раздел недоступен, вам необходимо сначала активировать доступ к API-интерфейсу на странице « Службы» .

Есть два вопроса с включенным фрагментом.

  1. Вы должны аннулировать старый authToken, прежде чем authToken новый authToken из AccountManager.

     AccountManager.get(activity).invalidateAuthToken("com.google", authToken); accountManager.getAuthToken(...); 
  2. Вызов setJsonHttpRequestInitializer должен использовать простой API-ключ, объявленный в консоли API для вашего проекта.

    • Его можно получить, посетив консоль API .
    • Нажмите « Доступ к API» в меню слева.
    • Найдите простой доступ к API и скопируйте ключ API .
    • Установите ключ API при создании объекта Drive.

      .setJsonHttpRequestInitializer (новый GoogleKeyInitializer (KEY))

Существует небольшой образец, демонстрирующий недействительность маркера: http://chiarg.com/?p=429

Я попробовал все это и, наконец, нашел этот код для работы с Google Calendar api. Я использовал 401 каждый раз, когда использовал GoogleCredentials и передавал его в сборку.

 HttpTransport transport = AndroidHttp.newCompatibleTransport();; JsonFactory jsonFactory = new GsonFactory(); HttpRequestInitializer httpRequestInitializer; Log.i("Reached calendar builder", "Reached calendar builder"+accessToken); //GoogleCredential credential = new GoogleCredential(); httpRequestInitializer = new HttpRequestInitializer(){ public void initialize(HttpRequest request) throws IOException { request.getHeaders().setAuthorization(GoogleHeaders.getGoogleLoginValue(accessToken)); } }; Calendar service = new Calendar.Builder(transport, jsonFactory, httpRequestInitializer) .setApplicationName("Meetrbus/1.0") .setJsonHttpRequestInitializer(new GoogleKeyInitializer("API_KEY")) .build(); } 

Я подробно рассказал об использовании Google Диска на Android:

Android Открыть и сохранить файлы в / из Google Диска SDK

Используя методы, которые я излагаю в этом ответе, я могу подтвердить, что вы можете сделать следующее:

  • Установка и доступ к метаданным
  • Загрузить файлы
  • Загрузить файлы
  • Перемещение файлов между каталогами Google Диска
  • Полностью удалить файлы с диска