Подтвердить что ты не робот

Интеграция с Google Диском с использованием текущей активности

Можно ли интегрироваться с Google Диском без создания собственной активности, вместо этого просто используя текущую активность для приложения, не загрязняя его кодом, связанным с Google Диском?

У меня есть фоновый "сервис" (а не служба Android - это только класс UI-agnostic), который отвечает за загрузку некоторых данных с Google Диска. Как услуга, у нее нет реального бизнеса, являющегося активностью. Тем не менее, образцы для интеграции с Drive имеют переопределение onActivityResult для обработки ситуации, когда требуется аутентификация. Я не уверен, как я получу эту информацию, если моя служба не будет реализована как активность.

Предполагая, что я могу получить ссылку на текущий Activity из моей "службы", можно ли каким-то образом реализовать интеграцию с Google Диском полностью автономным образом?

4b9b3361

Ответ 1

Я сделал что-то подобное из приложения, которое имеет Activity и SyncService. Вы действительно можете увидеть много функций в демо здесь. В этой демонстрации не используется служба, но идея остается прежней.

1/Создайте класс singleton (GDAA в этом случае) с помощью метода init(), который принимает ваш контекст активности. Этот init() будет создавать локальный статический GoogleApiClient, который остается живым, пока вам не нужно переключать учетные записи (объясняется позже).
init() вызывается с контекстом активности в начале или при необходимости переключиться на другую учетную запись пользователя (другой GooDrive для другого пользователя). Активность проходит в этом контексте и отправляет обратные вызовы onConnFail(), onConnOK().
Для полноты должно быть также условие для onConnectionSuspended(), если соединение прерывается (а не соединение WIFI/CELL, а также приостановление GooPlaySvcs).

  • Обратный вызов onConnFail() передает управление GooPlaySvcs для аутентификации/авторизации, результат которого возвращается в onActivityResult(). Подключите снова, промойте, промойте, повторите...
  • Обратный вызов onConnOK() сообщает вашей активности, что все готово.

Как я уже указывал, вам придется снова вызвать init(), если вы обрабатываете несколько учетных записей GooDrive, чтобы создать новую GoogleApiClient для новой учетной записи. Просто следуйте по маршруту "REQ_ACCPICK" здесь. Вам также придется управлять своими учетными записями, как вы можете видеть в классе "AM" менеджера аккаунта здесь. Большинство этих танцев можно увидеть в MainActivity.
Для полноты я должен также упомянуть, что вы можете оставить управление учетной записью в GooPlaySvcs, опуская setAccountName(email) в GoogleApiClient.Builder() и используя clearDefaultAccountAndReconnect() to reset сбор учетных записей. Но ваше приложение не будет знать, кем является текущий пользователь. Еще одно управление учетными записями можно обрабатывать с помощью PlusApi (или того, что он называется, никогда не использовал). Но я отвлекаюсь.

2/Когда инициализация завершена, а private static GoogleApiClient mGAC не имеет значения null и подключен, статические методы GDAA можно ссылаться из любого места вашего приложения, , включая службу. Методы, безусловно, потерпят неудачу, если GoogleApiClient не жив или не подключен.

В демо, упомянутом здесь, все вызовы GDAA имеют аромат "ожидание()" (синхронизация). Это не проблема, если они вызываются из потока, отличного от UI, как служба. Их можно легко превратить в асинхронные версии, как в этом примере:

DriveFile df = ...;
// sync version
DriveContentsResult rslt = df.open(mGAC, DriveFile.MODE_READ_ONLY, null).await();
if ((rslt != null) && rslt.getStatus().isSuccess()) {
  DriveContents cont = rslt.getDriveContents();
  InputStream is = cont.getInputStream();
  cont.discard(mGAC);    // or cont.commit();  they are equiv if READONLY
}
// async version
df.open(mGAC, DriveFile.MODE_READ_ONLY, null).setResultCallback(
  new ResultCallback<DriveContentsResult>() {
  @Override
  public void onResult(DriveContentsResult rslt) {
    if ((rslt != null) && rslt.getStatus().isSuccess()) {
      DriveContents cont = rslt.getDriveContents();
      InputStream is = cont.getInputStream();
      cont.discard(mGAC);    // or cont.commit();  they are equiv if READONLY
    }
  }
});

Аромат зависит от ваших потребностей приложения (код спагетти с потребляемыми возвращаемыми значениями против обработки асинхронных операций).

Следует отметить, что в этом демо используется версия GDAA Api. Существует REST Api, который можно обрабатывать одинаково (только для синхронизации). Альтернативная демоверсия, которая использует точно такую ​​же логику и методы, доступна здесь. Вы даже можете объединить два в один одноэлементный класс с обоими com.google.api.services.drive.Drive и com.google.android.gms.common.api.GoogleApiClient настоящее время.

Опасно смешивать GDAA и REST Api, так как вы наверняка столкнетесь с проблемами синхронизации, вызванными тем фактом, что GDAA синхронизируется по своему собственному расписанию, тогда как REST находится под вашим контролем.

Надеюсь, это помогло, Удачи.

Ответ 2

Код кода onActivityResult используется только в случае сбоя аутентификации, требующего вмешательства пользователя. Таким образом, по определению, он не может быть просто обработан "в фоновом режиме" вашей службой.

В случае фоновой службы, я думаю, что один из подходящих способов справиться с ошибкой аутентификации - показать уведомление, в котором говорится, что "вам нужно пройти аутентификацию для продолжения". Вы можете приложить намерение к уведомлению, чтобы он запускал вашу собственную "ResolveAuthActivity", когда пользователь нажимает на уведомление. Этот ResolveAuthActivity просто пытается подключиться к API, обрабатывает сбой в onConnectionFailed, а затем запускает решение Intent. После того, как отказ будет разрешен, ваша ResolveAuthActivity может выставить вашу службу, чтобы попытаться снова подключиться к API.

Ответ 3

Я думаю, что вы можете добиться эффекта, который хотите использовать с помощью google-диска. REST api вызывает https://developers.google.com/drive/v2/reference/

Здесь вы можете продолжить. Поскольку вы получаете контекст, вы можете совершать вызовы api для вождения. Для аутентификации, поскольку google следует за OAuth 2.0, вы можете использовать эти вызовы api для достижения аутентификации https://developers.google.com/identity/