使用当前活动的 Google 云端硬盘集成

2022-09-04 21:07:56

是否可以在不创建自己的活动的情况下与Google云端硬盘集成,而仅使用应用程序的当前活动而不会用Google云端硬盘相关代码污染它?

我有一个后台“服务”(不是Android服务 - 只是一个与UI无关的类),负责从Google云端硬盘加载一些数据。作为一项服务,它没有真正的业务是一项活动。但是,云端硬盘集成的示例具有 覆盖,用于处理需要身份验证的情况。我不确定如果我的服务未作为活动实现,我将如何获得此信息。onActivityResult

假设我可以从我的“服务”中获得对当前数据的引用,那么有没有办法以完全独立的方式实现Google云端硬盘集成?Activity


答案 1

我从具有活动和同步服务的应用中执行了类似的操作。您实际上可以在此处的演示中看到很多功能。此演示不使用服务,但想法保持不变。

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

  • 回调将控制权传递给 GooPlaySvcs 进行身份验证/授权,其结果返回 。再次连接,清洗,冲洗,重复...onConnFail()onActivityResult()
  • 回调会告诉您的活动一切准备就绪。onConnOK()

正如我所指出的,如果您处理多个GooDrive帐户,则必须再次调用,以便为新帐户创建新帐户。只需沿着这里的“REQ_ACCPICK”小径您还必须管理您的帐户,如此处的客户经理“AM”类所示。这种舞蹈的大部分都可以在MainActivity中看到。
为了完整起见,我还应该提到,您可以通过省略 in 和 用于重置帐户选取,将帐户管理留给 GooPlaySvcs。但是你的应用不会知道当前用户是谁。然而,另一个帐户管理可以通过PlusApi来处理(或者无论它叫什么,从未使用过它)。但是我说点题外话。init()GoogleApiClientsetAccountName(email)GoogleApiClient.Builder()clearDefaultAccountAndReconnect()

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

在这里提到的演示中,所有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
    }
  }
});

风格取决于应用的需求(包含已消耗返回值的意大利面条代码与异步处理)。

值得一提的是,此演示使用 API 的 GDAA 版本。还有一个 REST Api 可以以相同的方式处理(仅限同步风格)。此处提供了使用完全相同的逻辑和方法的替代演示。您甚至可以将两者组合成一个单例类,同时具有两者
并呈现。com.google.api.services.drive.Drivecom.google.android.gms.common.api.GoogleApiClient

但是,混合GDAA和REST Api是危险的,因为您肯定会遇到由GDAA按照自己的计划同步而引起的计时问题,而REST则在您的控制之下。


答案 2

仅当存在需要用户干预的身份验证失败时,才使用 onActivityResult 代码路径。因此,根据定义,它不能简单地由您的服务“在后台”处理。

对于后台服务,我认为处理身份验证失败的一种适当方法是显示一条通知,大意为“您需要进行身份验证才能继续”。您可以将 Intent 附加到通知,以便在用户点击通知时启动您自己的“ResolveAuthActivity”。此 ResolveAuthActivity 只是尝试连接到 API,处理 onConnectionFailed 中的故障,然后启动解析 Intent。解决故障后,ResolveAuthActivity 可能会戳您的服务以尝试再次连接到 API。


推荐