警告:此文档已弃用。 有关使用 OAuth 2.0 授权 Android 应用的信息,请参阅 Android Play 服务授权文档。
本文介绍了如何在 Android 上结合使用 Tasks API 和 OAuth 2.0。其中介绍了获取用户 Google Tasks 访问权限的授权机制,以及如何在 Android 应用中提供可直接使用的 Tasks API 服务对象。
为了让您的 Android 应用能够使用 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 访问数据所需的授权令牌。
要使用 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 调用的必要条件。为此,请按以下步骤操作:
- 创建项目或使用现有项目
- 将 Tasks API 开关切换为开启,从而在项目中启用 Tasks 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 ListtaskLists = 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 中显示默认任务列表的任务。
请按照这些说明运行示例,您也可以随时将反馈或问题发布到 Google Tasks API 论坛。