在 Android 上使用 Tasks API

警告:此文档已弃用。 有关使用 OAuth 2.0 授权 Android 应用的信息,请参阅 Android Play 服务授权文档

本文介绍了如何在 Android 上结合使用 Tasks API 和 OAuth 2.0。其中介绍了获取用户 Google Tasks 访问权限的授权机制,以及如何在 Android 应用中提供可直接使用的 Tasks API 服务对象。

为了让您的 Android 应用能够使用 Tasks API,您需要完成以下几个步骤:

  1. 选择用户的 Google 账号
  2. 从 Task API 的 AccountManager 获取 OAuth 2.0 访问令牌
  3. 确定您的项目并设置 Tasks 服务对象
  4. 调用 Tasks API

导入 Google 的客户端库

本文档中的示例使用适用于 Java 的 Google API 客户端库。您需要将以下 JAR 文件添加到 Android 应用中,为此,请将下面列出的 JAR 文件放置在 Android 应用根目录下的 /assets 文件夹中。此外,随着本文档的创建,查看是否有新版本。

导入 Google API 客户端库 jar 及其 Android 扩展(全部为 google-api-java-client-1.4.1-beta.zip):

  • google-api-client-1.4.1-beta.jar
  • google-api-client-extensions-android2-1.4.1-beta.jar
  • google-api-client-googleapis-1.4.1-beta.jar
  • google-api-client-googleapis-extensions-android2-1.4.1-beta.jar

导入特定于 Tasks 的 jar:

导入依赖项(全部为 google-api-java-client-1.4.1-beta.zip):

  • 通用编解码器-1.3.jar
  • Gson-1.6.jar
  • guava-r09.jar
  • httpclient-4.0.3.jar
  • httpcore-4.0.1.jar
  • jackson-core-asl-1.6.7.jar
  • jsr305-1.3.9.jar

Android 设备上的 Google 账号

从 Android 2.0 开始,AccountManager 会管理您在环境中注册的账号,即列在设置 >账号和同步。具体而言,它负责处理授权流程,并可以生成使用 API 访问数据所需的授权令牌。

在您的 Android 环境中注册的账号
在您的 Android 环境中注册的账号

要使用 AccountManager 获取账号和请求授权令牌,您需要在 Android 应用清单中添加以下权限:

<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />

您可以使用 AccountManager 获取要访问其 Tasks 的 Google 账号。AccountManager 不仅管理 Google 账号,还管理来自其他供应商的账号。因此,您需要使用以下代码来专门请求 Google 账号:

AccountManager accountManager = AccountManager.get(activity);
Account[] accounts = accountManager.getAccountsByType("com.google");

此外,适用于 Java 的 Google API 客户端库附带了 GoogleAccountManager,它仅处理 Google 账号:

GoogleAccountManager googleAccountManager = new GoogleAccountManager(activity);
Account[] accounts = googleAccountManager.getAccounts();

如果 Android 设备上有多个 Google 账号可用,您应该通过一个对话框提示用户他想要使用的账号,其内容可能如下所示:

选择账号对话框
选择账号对话框

您可以在 activity 的 onCreateDialog 方法中使用以下 switch/case 代码来构建此类对话框:

@Override
protected Dialog onCreateDialog(int id) {
  switch (id) {
    case DIALOG_ACCOUNTS:
      AlertDialog.Builder builder = new AlertDialog.Builder(this);
      builder.setTitle("Select a Google account");
      final Account[] accounts = accountManager.getAccountsByType("com.google");
      final int size = accounts.length;
      String[] names = new String[[]size];
      for (int i = 0; i < size; i++) {
        names[[]i] = accounts[[]i].name;
      }
      builder.setItems(names, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
          // Stuff to do when the account is selected by the user
          gotAccount(accounts[[]which]);
        }
      });
      return builder.create();
  }
  return null;
}

调用 showDialog(DIALOG_ACCOUNTS) 将显示账号选择器对话框。

Android 上的 Google API 授权流程

现在,用户已经选择了账号,接下来,我们可以要求 AccountManager 为 Task API 颁发 OAuth 2.0 访问令牌。这是通过调用 AccountManager.getAuthToken() 方法完成的。在 AccountManager.getAuthToken() 调用期间,AccountManager 将负责联系 Google API 授权端点。AccountManager 检索到授权令牌后,将运行您在方法调用中定义的 AccountManagerCallback

manager.getAuthToken(account, AUTH_TOKEN_TYPE, null, activity, new AccountManagerCallback<Bundle>() {
    public void run(AccountManagerFuture<Bundle> future) {
      try {
        // If the user has authorized your application to use the tasks API
        // a token is available.
        String token = future.getResult().getString(AccountManager.KEY_AUTHTOKEN);
        // Now you can use the Tasks API...
        useTasksAPI(token);
      } catch (OperationCanceledException e) {
        // TODO: The user has denied you access to the API, you should handle that
      } catch (Exception e) {
        handleException(e);
      }
    }
  }, null);

您可能已经知道,Android AccountManager 针对 OAuth 2.0 提供了实验性支持。在设置 AUTH_TOKEN_TYPE 时,您只需在要访问的 API 范围前添加 oauth2: 前缀。因此,对于 Tasks API,您可以使用:

String AUTH_TOKEN_TYPE = "oauth2:https://www.googleapis.com/auth/tasks";

将上述值用作 AUTH_TOKEN_TYPE 时的问题是,字符串 oauth2:https://www.googleapis.com/auth/tasks 将在授权对话框中显示为您要访问的 Google 产品的名称。为了解决此问题,Tasks API 提供了特殊的(人类可读)AUTH_TOKEN_TYPE 别名。这相当于使用 OAuth 2.0 范围。例如,您可以使用:

String AUTH_TOKEN_TYPE = "Manage your tasks";

您还可以使用 AUTH_TOKEN_TYPE 别名 查看您的任务,相当于 Tasks API 只读 范围:oauth2:https://www.googleapis.com/auth/tasks.readonly

AccountManager.getAuthToken() 调用期间,AccountManager 将检查您的应用是否已获授权访问 Tasks API。如果您的应用尚未获得授权,则 AccountManager 会启动 Activity,并向用户显示授权对话框,以便他们可以允许拒绝您的应用在其账号中使用 Tasks API。

授权对话框
授权对话框

如果用户拒绝您的应用访问 Tasks API,则在 future.getResult() 调用期间会抛出 OperationCanceledException。这种情况下,您应该妥善处理此问题,例如,要求再次选择账号,或显示一条消息,带有一个用于重新授予访问权限的按钮。

识别您的应用并设置 Tasks API 服务对象

现在您的应用已获得对 Tasks API 的访问授权,并且已获得访问令牌,您还需从 Google API 控制台的项目中获取一个 API 密钥,因为这是进行 Tasks API 调用的必要条件。为此,请按以下步骤操作:

  1. 创建项目或使用现有项目
  2. 将 Tasks API 开关切换为开启,从而在项目中启用 Tasks API
  3. 您可以在以下位置找到 API 密钥API 访问权限 >简单的 API 访问 >API 密钥

从 API 控制台获取 API 密钥
从 API 控制台获取 API 密钥

API 密钥是必填项,因为它用于标识您的应用,进而允许 API 扣除配额并使用为项目定义的配额规则。您需要在 Tasks 服务对象中指定 API 密钥

useTasksAPI(String accessToken) {
  // Setting up the Tasks API Service
  HttpTransport transport = AndroidHttp.newCompatibleTransport();
  AccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(accessToken);
  Tasks service = new Tasks(transport, accessProtectedResource, new JacksonFactory());
  service.accessKey = INSERT_YOUR_API_KEY;
  service.setApplicationName("Google-TasksSample/1.0");

  // TODO: now use the service to query the Tasks API
}

accessToken仅在一定时间内有效,因此在过期后,您必须获取新的访问令牌。有 2 种处理方式:

  • 每次通过 API 发出请求时,都向 AccountManager 请求 accessToken。由于 AccountManager 会缓存令牌,因此该解决方案可以接受。
  • 请继续使用 accessToken,直至收到 403 错误,此时您请求向 AccountManager 提供新令牌。

通过 API 处理任务

至此,您应该已经拥有了一个已设置完毕的 Tasks API 服务对象,您可以按照 Tasks API 开发者指南中所述,使用该对象查询该 API,例如:

// Getting all the Task lists
List taskLists = service.tasklists.list().execute().items;

// Getting the list of tasks in the default task list
List tasks = service.tasks.list("@default").execute().items;

// Add a task to the default task list
Task task = new Task();
task.title = "New Task";
task.notes = "Please complete me";
task.due = "2010-10-15T12:00:00.000Z";
Task result = service.tasks.insert("@default", task).execute();

切勿忘记向您的 Android 应用清单添加访问互联网的权限,否则对 Tasks API 端点的上述请求将失败:

<uses-permission android:name="android.permission.INTERNET" />

示例应用

我们最近向适用于 Java 的 Google API 客户端库示例代码库添加了一个新示例,以帮助您开始在 Android 上使用 Tasks API 和 OAuth 2.0。此示例是一个简单但功能完善的 Android 应用,它请求授权以使用 Tasks API,并在 ListView 中显示默认任务列表的任务。

在 ListView 中显示默认任务列表中的任务
在 ListView 中显示默认任务列表中的任务

请按照这些说明运行示例,您也可以随时将反馈或问题发布到 Google Tasks API 论坛