Google 使用当前驱动集成 activity

Google Drive integration using current activity

是否可以在不创建自己的 activity 的情况下与 Google 驱动器集成,而只是将当前的 activity 用于应用程序而不用 Google 驱动器污染它相关代码?

我有一个后台 "service"(不是 Android 服务 - 只是一个 UI-不可知论者 class)负责从 [=29] 加载一些数据=] 开车。作为一项服务,它没有真正的业务是 activity。但是,samples for Drive integration 覆盖了 onActivityResult 来处理需要身份验证的情况。如果我的服务未作为 activity.

实现,我不确定如何获取此信息

假设我可以从我的 "service" 获得对当前 Activity 的引用,是否有某种方法可以以完全独立的方式实施 Google 驱动器集成?

我认为您可以使用 google 驱动器 REST api 调用 https://developers.google.com/drive/v2/reference/

来达到您想要的效果

以下是您可以继续的方法。 由于您获得了上下文,您可以执行 api 调用来驱动。对于身份验证,因为 google 遵循 OAuth 2.0,您可以使用这些 api 调用来实现身份验证 https://developers.google.com/identity/

onActivityResult 代码路径仅在身份验证失败需要用户干预时使用。因此,根据定义,它不能简单地由您的服务 "in the background" 处理。

在后台服务的情况下,我认为处理身份验证失败的一种适当方法是显示一条通知,说明 "You need to authenticate to continue" 的效果。您可以将 Intent 附加到通知,以便在用户点击通知时启动您自己的 "ResolveAuthActivity"。此 ResolveAuthActivity 只是尝试连接到 API,处理 onConnectionFailed 中的失败,然后启动解析 Intent。解决故障后,您的 ResolveAuthActivity 可以戳您的服务以尝试再次连接到 API。

我在一个具有 Activity 和 SyncService 的应用程序中做了类似的事情。您实际上可以在 demo here 中看到很多功能。 此演示不使用服务,但思路保持不变。

1/ 使用接受您的 activity 上下文的 init() 方法创建单例 class(在本例中为 GDAA) . init() 将实例化一个本地静态 GoogleApiClient,只要您不需要切换帐户(稍后解释),它就会保持活动状态。
init() 在开始时或需要切换到另一个用户帐户时使用 activity 上下文调用(不同用户使用不同的 GooDrive)。 Activity 传递上下文并提供 onConnFail(), onConnOK() 回调。
为了完整起见,还应提供 onConnectionSuspended() 以防连接中断(不是 WIFI/CELL 连接断开,而是 GooPlaySvcs 暂停)。

  • onConnFail() 回调将 authentication/authorization 的控制权传递给 GooPlaySvcs,其结果在 onActivityResult() 中返回。再次连接、洗涤、冲洗、重复...
  • onConnOK() 回调告诉您 activity 一切就绪。

正如我所指出的,如果您处理多个 GooDrive 帐户,则必须再次调用 init() 才能为新帐户创建新的 GoogleApiClient。只需跟随 'REQ_ACCPICK' 路径 here. You will also have to manage your accounts as you can see in the account manager 'AM' class here. Most of this dancing can be seen in the MainActivity.
为了完整起见,我还应该提到,您可以通过省略 GoogleApiClient.Builder() 中的 setAccountName(email) 并使用 clearDefaultAccountAndReconnect() 重置帐户选择,将帐户管理留给 GooPlaySvcs。但是您的应用不会知道当前用户是谁。还有一个帐户管理可以通过 PlusApi 来处理(或者不管它叫什么,从来没有用过)。但是我跑题了。

2/ 当初始化完成并且私有静态 GoogleApiClient mGAC 非空且已连接时,可以从应用中的任何位置引用 GDAA 静态方法,包括服务。如果 GoogleApiClient 不存在或未连接,这些方法肯定会失败。

在这里提到的演示中,所有 GDAA 调用都是 'await()'(同步)风格。如果从非 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
    }
  }
});

风格取决于您应用程序的需求(消耗 return 值的意大利面条代码与异步处理)。

值得一提的是,这个演示使用了GDAA version of the Api. There is a REST Api as well that can be handled the same way (sync flavor only). An alternate demo that uses exactly the same logic and methods is available here。您甚至可以将两者合并为一个单例 class 和 both
com.google.api.services.drive.Drivecom.google.android.gms.common.api.GoogleApiClient 现在。

虽然混合使用 GDAA 和 REST Api 是危险的,因为你肯定会 运行 由于 GDAA 按照自己的时间表同步而导致的时间问题,而 REST 在你的控制。