使用适用于Android API的Login with Amazon SDK(v2.0.2及更低版本)
请注意,以下说明仅适用于更低版本的Login with Amazon Android SDK(2.0.2及更低版本)。
较低版本的SDK虽然已不可下载,但本文将保留与之相关的说明,以便为正在使用这些SDK的开发者提供帮助。
安装Android开发者工具
适用于Android的Login with Amazon SDK将帮助您为Android、Fire TV和Fire平板电脑应用添加Login with Amazon。我们建议您结合Android Studio使用适用于Android的Login with Amazon SDK,不过,您也可以使用Eclipse与ADT插件。有关如何安装Android Studio和获取Android SDK安装程序的步骤,请前往developer.android.com页面参阅获取Android SDK
Android SDK安装完成后,在Android安装应用中找到SDK Manager(SDK管理器)。为开发Login with Amazon,必须使用SDK Manager安装SDK Platform for Android 2.2或更高版(API v9)。有关如何使用SDK Manager的信息,请前往developer.android.com页面参阅添加SDK程序包。
SDK安装完成后,安装Android虚拟设备(AVD)以运行应用。请前往developer.android.com页面参阅管理虚拟设备了解虚拟设备安装说明。
处理登录按钮并获取个人资料数据
本部分介绍了如何调用authorize
和getProfile
API来登录用户及检索其个人资料数据。这包括在应用的onCreate
方法中为您的Login with Amazon按钮创建onClick
侦听器。
将Login with Amazon API导入到源文件。
-
将Login with Amazon API导入到源文件。
要导入Login with Amazon API,需要为源文件添加以下
import
语句:import com.amazon.identity.auth.device.AuthError; import com.amazon.identity.auth.device.authorization.api.AmazonAuthorizationManager; import com.amazon.identity.auth.device.authorization.api.AuthorizationListener; import com.amazon.identity.auth.device.authorization.api.AuthzConstants;
-
初始化
AmazonAuthorizationManager
。您需要声明AmazonAuthorizationManager
变量并为此类创建新实例。创建新实例只对应用当前的环境有要求,且只需要一个空的应用。初始化AmazonAuthorizationManager
的最佳位置为Activity
中的onCreate
方法。例如:private AmazonAuthorizationManager mAuthManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAuthManager = new AmazonAuthorizationManager(this, Bundle.EMPTY); }
-
创建
AuthorizeListener
。AuthorizeListener
将实现AuthorizationListener
接口,处理authorize
调用的结果。一共包含三种方法:onSuccess
、onError
和onCancel
。每个方法都将接收到一个Bundle
或AuthError
对象。private class AuthorizeListener implements AuthorizationListener{ /*授权已成功完成。*/ @Override public void onSuccess(Bundle response) { } /*尝试授权应用时发生错误。*/ @Override public void onError(AuthError ae) { } /*授权未完成便已取消。*/ @Override public void onCancel(Bundle cause) { } }
-
调用
AmazonAuthorizationManager.authorize
。在Login with Amazon按钮的
onClick
处理程序中,调用authorize
来提示用户登录并授权应用。此方法通过以下其中一种方式授权客户:
-
切换到系统浏览器,以便客户登录并授权所需信息。
-
切换到安全环境下的网页视图,以便客户登录并授权所需信息。
目前,Android设备的亚马逊购物应用可实现#2的安全环境。运行Fire OS的亚马逊设备(例如Kindle Fire、Fire手机和Fire TV)始终使用此选项,即使设备中没有亚马逊购物应用,也不例外。因此,如果客户已登录到亚马逊购物应用,此API将跳过登录页面,为用户提供单点登录体验。
如果您的应用已获得授权,则将会得到一个或多个数据集的授权,即范围。第一个参数是一个范围数组,包含了向Login with Amazon请求的用户数据。用户首次登录您的应用时,将看到您请求的数据列表并会询问是否批准。Login with Amazon目前支持三个范围:
profile
包含用户的名称、电子邮件地址和亚马逊账户ID,profile:user_id
仅包含亚马逊账户ID,postal_code
包含用户的邮政编码。调用
authorize
的最佳方式为异步调用,因此您不必阻止UI线程或创建自己的工作线程。要异步调用authorize
,需要将支持AuthorizationListener
接口的对象作为最后一个参数进行传递:private AmazonAuthorizationManager mAuthManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAuthManager = new AmazonAuthorizationManager(this, Bundle.EMPTY); // 查找带有login_with_amazon ID的按钮 // 安装单击处理程序 mLoginButton = (Button) findViewById(R.id.login_with_amazon); mLoginButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mAuthManager.authorize( new String []{"profile","postal_code"}, Bundle.EMPTY, new AuthorizeListener()); } }); }
-
-
创建
ProfileListener
。ProfileListener
是实现APIListener
接口的类的名称,并处理getProfile
调用的结果。APIListener
包含两种方法,即onSuccess
和onError
(由于无法取消getProfile调用,该方法不支持onCance)。onSuccess
将收到包含个人资料数据的Bundle
对象,onError
将收到包含错误信息的AuthError
对象。private class ProfileListener implements APIListener{ /*getProfile成功完成。*/ @Override public void onSuccess(Bundle response) { } /*尝试获取个人资料时发生错误。*/ @Override public void onError(AuthError ae) { } }
-
为您的
AuthorizeListener
实现onSuccess
。在onSuccess
中,调用AmazonAuthorizationManager.getProfile
来检索客户个人资料客户个人资料。getProfile
与authorize
类似,使用异步侦听器接口。对于getProfile
,该接口为APIListener
,而不是AuthorizationListener
。/*授权已成功完成。*/ @Override public void onSuccess(Bundle response) { mAuthManager.getProfile(new ProfileListener()); }
-
为您的
ProfileListener
实现onSuccess
。onSuccess
具有两项主任务,即检索Bundle
响应中的个人资料数据,以及向UI传递数据。updateProfileData
是一项假想功能,您的应用可用以实现显示个人资料的详细信息。setLoggedInState
也是一项假想功能,用于显示用户已登录且拥有一种注销方式。要从Bundle
中检索个人资料数据,需要使用AuthzConstants
类中存储的名称。onSuccess
批的BUNDLE_KEY.PROFILE
批中包含个人资料数据。在个人资料批中,范围数据索引位于PROFILE_KEY.NAME
、PROFILE_KEY.EMAIL
、PROFILE_KEY.USER_ID
和PROFILE_KEY.POSTAL_CODE
。如果请求范围为postal_code
,则只显示PROFILE_KEY.POSTAL_CODE
。@Override public void onSuccess(Bundle response) { // 从Bundle中检索所需数据 Bundle profileBundle = response.getBundle( AuthzConstants.BUNDLE_KEY.PROFILE.val); String name = profileBundle.getString( AuthzConstants.PROFILE_KEY.NAME.val); String email = profileBundle.getString( AuthzConstants.PROFILE_KEY.EMAIL.val); String account = profileBundle.getString( AuthzConstants.PROFILE_KEY.USER_ID.val); String zipcode = profileBundle.getString( AuthzConstants.PROFILE_KEY.POSTAL_CODE.val); runOnUiThread(new Runnable() { @Override public void run() { updateProfileData(name, email, account, zipcode); } }); }
-
为您的
ProfileListener
实现onError
。onError
中的AuthError
对象包含错误的详细信息。/* 尝试获取个人资料时发生错误。*/ @Override public void onError(AuthError ae) { /*重试并提示用户发生错误*/ }
-
为您的
AuthorizeListener
实现onError
。/*尝试授权应用时发生错误。*/ @Override public void onError(AuthError ae) { /*提示用户发生错误*/ }
-
为您的
AuthorizeListener
实现onCancel
。由于授权流程会在网页浏览器(或网页视图)中向用户显示登录界面(可能也会显示同意界面同意界面),用户可以取消登录或导航离开该网页。如果用户明确取消登录流程,则调用onCancel
。如果已调用onCancel
,则需要重置您的UI。/*授权未完成便已取消。*/ @Override public void onCancel(Bundle cause) { /*将UI重新设置为随时登录状态*/ }
注意: 如果用户在浏览器或网页视图中导航离开登录界面,并切换返回到您的应用,SDK将检测不到登录未完成。如果您的应用在登录完成前检测到了用户活动,则可以假定用户已从浏览器导航离开并已做出相应反应。
检查首次登录的用户
如果用户登录并关闭您的应用,并在之后重新启动,应用仍然有权检索数据。用户不会自动注销。如果您的应用仍处于授权状态,可在启动时将用户显示为已登录。本部分介绍了如何使用getToken
确定应用是否仍处于授权状态。
-
创建
TokenListener
。TokenListener
实现APIListener
接口并处理getToken
调用的结果。APIListener
包含两种方法,即onSuccess
和onError
(由于无法取消getToken
调用,该方法不支持onCance)。onSuccess
将收到包含令牌数据的Bundle
对象,onError
将收到包含错误信息的AuthError
对象。private class TokenListener implements APIListener{ /*getToken成功完成。*/ @Override public void onSuccess(Bundle response) { } /*尝试获取令牌时发生错误。*/ @Override public void onError(AuthError ae) { } }
-
在
Activity
下的onStart
方法中,调用getToken
以查看应用是否仍处于授权状态。getToken
将检索AmazonAuthorizationManager
用于访问客户个人资料的原始访问令牌访问令牌。如果令牌值不为null
,则应用仍在处于授权状态,可成功调用getProfile
。getToken
的请求范围需要与authorize
的调用范围相同。getToken
支持与getProfile
相同的异步调用,因此无需阻止UI线程或创建您自己的工作线程。要异步调用getToken
异步,需要将支持APIListener
接口的对象作为最后一个参数进行传递。@Override protected void onStart(){ super.onStart(); mAuthManager.getToken(new String []{"profile","postal_code"}, new TokenListener()); }
-
为您的
TokenListener
实现onSuccess
。onSuccess
有两项任务:从Bundle
中检索令牌;如果令牌有效,则调用getProfile
。要从Bundle
中检索令牌数据,需要使用AuthzConstants
类中存储的名称。onSuccess
批的BUNDLE_KEY.TOKEN
值中包含令牌数据。如果该值不为空,此示例将使用上文声明的同一侦听器(见第7步与第8步)调用getProfile
。/* getToken成功完成。*/ @Override public void onSuccess(Bundle response) { final String authzToken = response.getString(AuthzConstants.BUNDLE_KEY.TOKEN.val); if (!TextUtils.isEmpty(authzToken)) { // 检索个人资料数据 mAuthManager.getProfile(new ProfileListener()); } }
清除授权状态并注销用户
clearAuthorizationState
方法将清除AmazonAuthorizationManager
本地数据存储中的用户授权数据。应用若要检索个人资料数据,必须令用户重新登录。使用此方法可注销用户,也可以对应用中的登录问题进行故障排除。
- 实现注销机制。您应在用户成功登录后提供注销机制,以便用户清除个人资料数据和以前的授权范围。这项机制可以是超链接,也可以是菜单项。本示例将为按钮创建
onClick
方法。 - 在注销处理程序中调用
clearAuthorizationState
。clearAuthorizationState
将在本地存储中删除用户的授权数据(访问令牌和个人资料)。clearAuthorizationState
只需要APIListener
返回成功或失败,除此之外,无需任何参数。 - 声明匿名的
APIListener
。匿名类是实现APIListener
时声明新类的有力方法。 - 在
APIListener
中实现onSuccess
。clearAuthorizationState
成功后,应更新UI来移除用户参考,并提供用户可用来再次登录的登录机制。 - 在
APIListener
内实现onError
。如果clearAuthorizationState
返回错误,可让用户尝试再次注销。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*省略之前的onCreate声明*/
// 查找带有注销ID的按钮并安装单击处理程序
mLogoutButton = (Button) findViewById(R.id.logout);
mLogoutButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mAuthManager.clearAuthorizationState(new APIListener() {
@Override
public void onSuccess(Bundle results) {
// 设置退出状态UI
}
@Override
public void onError(AuthError authError) {
// 记录错误
}
});
}
});
}
同步调用AmazonAuthorizationManager方法
有些 AmazonAuthorizationManager
方法会返回Future
对象。这可以用同步调用方法来代替侦听器的参数传递。Future
不应用于UI线程。如果某个UI线程的阻止时间超过五秒,则将收到ANR(应用程序未响应)提示。在上述处理登录按钮和获取个人资料数据的示例中,用于AuthorizeListener
的onSuccess
方法与AmazonAuthorizationManager
创建的工作线程一同进行调用。这意味着可以安全地使用该线程来同步调用getProfile
。要作出同步调用,需要将getProfile
的返回值分配给Future
对象,并在此对象上调用get
方法,直至方法完成。
Future.get
返回的Bundle
对象中会在SUCCESS
、ERROR
或CANCEL
中包含一项FUTURE_TYPE
值。如果此方法已成功,则此值将包含个人资料数据的PROFILE_KEY
值。例如:
/*授权已成功完成。*/
@Override
public void onSuccess(Bundle response) {
Future<Bundle> future = mAuthManager.getProfile(null);
Bundle result = future.get();
// 查找调用是否成功,并检索个人资料
Object future_type = result.get(AuthzConstants.BUNDLE_KEY.FUTURE.val);
if (future_type == AuthzConstants.FUTURE_TYPE.SUCCESS)
{
String name = result.getString(
AuthzConstants.PROFILE_KEY.NAME.val);
String email = result.getString(
AuthzConstants.PROFILE_KEY.EMAIL.val);
String account = result.getString(
AuthzConstants.PROFILE_KEY.USER_ID.val);
String zipcode = result.getString(
AuthzConstants.PROFILE_KEY.POSTAL_CODE.val);
runOnUiThread(new Runnable() {
@Override
public void run() {
updateProfileData(name, email, account, zipcode);
}
});
}
else if (future_type == AuthzConstants.FUTURE_TYPE.ERROR)
{
// 获取错误对象
AuthError authError = AuthError.extractError(result);
/*使用authError诊断错误*/
}
else if (future_type == AuthzConstants.FUTURE_TYPE.CANCEL)
{
/*用户在授权期间选择取消*/
}
}