在 Android 上使用 Tasks API

警告:此文档已弃用。 如需了解如何使用 OAuth 2.0 向 Android 应用授权,请参阅 Android Play 服务授权文档

本文档介绍如何在 Android 上通过 OAuth 2.0 使用 Tasks API。还介绍了用于获取用户 Google Tasks 访问权限的授权机制,以及如何在 Android 应用中准备好可以使用 Tasks API 服务对象。

为了让您的 Android 应用使用 Tasks API,您需要执行几个步骤:

  1. 选择用户的 Google 账号
  2. AccountManager 获取适用于 Task API 的 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 的所有部分):

  • commons-codec-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 客户端库还带有一个仅处理 Google 帐号的 GoogleAccountManager

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 的授权,且已获得访问令牌,您还需要一个 API 密钥,您需要在 Google 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 仅在特定时间段内有效,因此您必须在过期后获取新的访问令牌。处理此问题的方法有两种:

  • 每次通过 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 的默认任务列表中显示任务

请按照这些instructions运行示例,如果您有任何疑问或问题,请随时到 Google Tasks API 论坛中发帖咨询。