Use the Login with Amazon SDK for Android APIs (v2.0.2 and below)
Note that the instructions below apply only to older versions of the Login with Amazon SDK for Android (versions 2.0.2 and below).
Older SDKs are no longer available for download, but we have preserved the instructions here for the convenience of our developers who are still using them.
- Installing the Android Developer Tools
- Handle the Login Button and get Profile Data
- Check for User Login at Startup
- Clear Authorization State and Log Out a User
- Call AmazonAuthorizationManager Methods Synchronously
Installing the Android Developer Tools
The Login with Amazon SDK for Android will help you add Login with Amazon to your Android, Fire TV, and Fire tablet applications. We recommend you use the Login with Amazon SDK for Android with Android Studio, however, you can also use Eclipse with the ADT plugin. For steps on how to install Android Studio and on getting the Android SDK set up, see Get the Android SDK on developer.android.com
When the Android SDK is installed, find the SDK Manager application in your android installation. To develop for Login with Amazon, you must use the SDK Manager to install the SDK Platform for Android 2.2 or higher (API version 9). See Adding SDK Packages on developer.android.com for more information on using SDK Manager.
After installing the SDK, set up an Android Virtual Device (AVD) for running your apps. See Managing Virtual Devices on developer.android.com for instructions on setting up a virtual device.
Handle the Login Button and get Profile Data
This section explains how to call the authorize and getProfile APIs to login a user and retrieve their profile data. This includes creating an onClick listener for your Login with Amazon button in the onCreate method of your app.
Import the Login with Amazon API to your source file.
-
Import the Login with Amazon API to your source file.
To import the Login with Amazon API, add the following
importstatements to your source file: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; -
Initialize the
AmazonAuthorizationManager. You will need to declare aAmazonAuthorizationManagervariable and create a new instance of the class. Creating a new instance only requires your current application context and an empty bundle. The best place to initialize theAmazonAuthorizationManageris in theonCreatemethod of yourActivity. For example:private AmazonAuthorizationManager mAuthManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAuthManager = new AmazonAuthorizationManager(this, Bundle.EMPTY); } -
Create an
AuthorizeListener.AuthorizeListenerimplements theAuthorizationListenerinterface, and will process the result of theauthorizecall. It contains three methods,onSuccess,onError, andonCancel. Each method receives either aBundleor anAuthErrorobject.private class AuthorizeListener implements AuthorizationListener{ /* Authorization was completed successfully. */ @Override public void onSuccess(Bundle response) { } /* There was an error during the attempt to authorize the application. */ @Override public void onError(AuthError ae) { } /* Authorization was cancelled before it could be completed. */ @Override public void onCancel(Bundle cause) { } } -
Call
AmazonAuthorizationManager.authorize.In the
onClickhandler for your Login with Amazon button, callauthorizeto prompt the user to login and authorize your application.This method is responsible for authorizing the customer in one of the following ways:
-
Switches to the system browser and lets the customer sign in and consent to the requested information.
-
Switches to web view in a secure context, to let the customer sign in and consent to the requested information.
This secure context for #2 is currently made available as the Amazon Shopping app on Android devices. Amazon-created devices running Fire OS (for example Fire Tablets, and Fire TVs) always use this option even if there is no Amazon Shopping app on the device. Because of this, if the customer is already signed in to the Amazon Shopping app, this API will skip the sign-in page, leading to a Single Sign On experience for the customer.
When your application is authorized, it is authorized for one or more data sets known as scopes. The first parameter is an array of scopes that encompass the user data that you are requesting from Login with Amazon. The first time a user logs in to your app, they will be presented with a list of the data you are requesting and asked for approval. Login with Amazon currently supports three scopes:
profile, which contains the user's name, email address, and Amazon account id;profile:user_id, which contains only the Amazon account id; andpostal_code, which contains the user's zip/postal code.The best way to call
authorizeis asynchronously, so you do not have to block the UI thread or create a worker thread of your own. To callauthorizeasynchronously, pass an object that supports theAuthorizationListenerinterface as the last parameter:private AmazonAuthorizationManager mAuthManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAuthManager = new AmazonAuthorizationManager(this, Bundle.EMPTY); // Find the button with the login_with_amazon ID // and set up a click handler 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()); } }); } -
-
Create a
ProfileListener.ProfileListeneris our name for a class that implements theAPIListenerinterface, and will process the result of thegetProfilecall.APIListenercontains two methods,onSuccessandonError(it does not support onCancel because there is no way to cancel a getProfile call).onSuccessreceives aBundleobject with profile data, whileonErrorreceives anAuthErrorobject with information on the error.private class ProfileListener implements APIListener{ /* getProfile completed successfully. */ @Override public void onSuccess(Bundle response) { } /* There was an error during the attempt to get the profile. */ @Override public void onError(AuthError ae) { } } -
Implement
onSuccessfor yourAuthorizeListener. InonSuccess, callAmazonAuthorizationManager.getProfileto retrieve the customer profile .getProfile, likeauthorize, uses an asynchronous listener interface. ForgetProfile, that interface isAPIListener, notAuthorizationListener./* Authorization was completed successfully. */ @Override public void onSuccess(Bundle response) { mAuthManager.getProfile(new ProfileListener()); } -
Implement
onSuccessfor yourProfileListener.onSuccesshas two main tasks; retrieve the profile data from the responseBundle, and pass the data to the UI.updateProfileDatais a hypothetical function your app could implement to display profile details.setLoggedInState, another hypothetical function, would indicate that a user is logged in and give them a means of logging out. To retrieve the profile data from theBundle, we use names stored by theAuthzConstantsclass. TheonSuccessbundle contains the profile data in aBUNDLE_KEY.PROFILEbundle. Within the profile bundle, the scope data is indexed underPROFILE_KEY.NAME,PROFILE_KEY.EMAIL,PROFILE_KEY.USER_ID, andPROFILE_KEY.POSTAL_CODE.PROFILE_KEY.POSTAL_CODEis only included if you request thepostal_codescope.@Override public void onSuccess(Bundle response) { // Retrieve the data we need from the 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); } }); } -
Implement
onErrorfor yourProfileListener.onErrorincludes anAuthErrorobject containing details about the error./* There was an error during the attempt to get the profile. */ @Override public void onError(AuthError ae) { /* Retry or inform the user of the error */ } -
Implement
onErrorfor yourAuthorizeListener./* There was an error during the attempt to authorize the application. */ @Override public void onError(AuthError ae) { /* Inform the user of the error */ } -
Implement
onCancelfor yourAuthorizeListener. Because the authorization process presents a login screen (and possibly a consent screen ) to the user in a web browser (or a webview), the user will have an opportunity to cancel the login or navigate away from the web page. If they explicitly cancel the login process,onCancelis called. IfonCancelis called, you will want to reset your UI./* Authorization was cancelled before it could be completed. */ @Override public void onCancel(Bundle cause) { /* reset the UI to a ready-to-login state */ }Note: If the user navigates away from the login screen in the browser or webview and switches back to your app, the SDK will not detect that the login was not completed. If you detect user activity in your app before login is completed, you can assume they have navigated away from the browser and react accordingly.
Check for User Login at Startup
If a user logs into your app, closes the app, and restarts the app later, the app is still authorized to retrieve data. The user is not logged out automatically. At startup, you can show the user as logged in if your app is still authorized. This section explains how to use getToken to see if the app is still authorized.
-
Create a
TokenListener.TokenListenerimplements theAPIListenerinterface, and will process the result of thegetTokencall.APIListenercontains two methods,onSuccessandonError(it does not support onCancel because there is no way to cancel agetTokencall).onSuccessreceives aBundleobject with token data, whileonErrorreceives anAuthErrorobject with information on the error.private class TokenListener implements APIListener{ /* getToken completed successfully. */ @Override public void onSuccess(Bundle response) { } /* There was an error during the attempt to get the token. */ @Override public void onError(AuthError ae) { } } -
In the
onStartmethod of yourActivity, callgetTokento see if the application is still authorized.getTokenretrieves the raw access token that theAmazonAuthorizationManageruses to access a customer profile. If the token value is notnull, then the app is still authorized and a call togetProfileshould succeed.getTokenrequires the same scopes you requested in your call toauthorize.getTokensupports asychronous calls in the same manner asgetProfile, so you do not have to block the UI thread or create a worker thread of your own. To callgetTokenasynchronously, pass an object that supports theAPIListenerinterface as the final parameter.@Override protected void onStart(){ super.onStart(); mAuthManager.getToken(new String []{"profile","postal_code"}, new TokenListener()); } -
Implement
onSuccessfor yourTokenListener.onSuccesshas two tasks: to retrieve the token from theBundle, and if the token is valid, to callgetProfile. To retrieve the token data from theBundle, we use names stored by theAuthzConstantsclass. TheonSuccessbundle contains the token data in aBUNDLE_KEY.TOKENvalue. If that value is not null, this example callsgetProfileusing the same listener you declared in the previous section (see steps 7 and 8)./* getToken completed successfully. */ @Override public void onSuccess(Bundle response) { final String authzToken = response.getString(AuthzConstants.BUNDLE_KEY.TOKEN.val); if (!TextUtils.isEmpty(authzToken)) { // Retrieve the profile data mAuthManager.getProfile(new ProfileListener()); } }
Clear Authorization State and Log Out a User
The clearAuthorizationState method will clear the user's authorization data from the AmazonAuthorizationManager local data store. A user will have to log in again in order for the app to retrieve profile data. Use this method to log out a user, or to troubleshoot login problems in the app.
- Implement a logout mechanism. After a user has successfully logged in, you should provide a logout mechanism so they can clear their profile data and previously authorized scopes. Your mechanism might be a hyperlink, or a menu item. For this example we will create an
onClickmethod for a button. - In your logout handler, call
clearAuthorizationState.clearAuthorizationStatewill remove a user's authorization data (access tokens, profile) from the local store.clearAuthorizationStatetakes no parameters except for anAPIListenerto return success or failure. - Declare an anonymous
APIListener. Anonymous classes are a useful alternative to declaring a new class to implementAPIListener. - Implement
onSuccessinside theAPIListener. WhenclearAuthorizationStatesucceeds you should update your UI to remove references to the user, and provide a login mechanism users can use to log in again. - Implement
onErrorinside theAPIListener. IfclearAuthorizationStatereturns an error, you can let the user try to logout again.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Previous onCreate declarations omitted */
// Find the button with the logout ID and set up a click handler
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) {
// Set logged out state in UI
}
@Override
public void onError(AuthError authError) {
// Log the error
}
});
}
});
}
Call AmazonAuthorizationManager Methods Synchronously
Some AmazonAuthorizationManager methods return a Future object. This allows you to call the method synchronously instead of passing a listener as a parameter. If you do use a Future, you should not use it on a UI thread. If you block a UI thread for more than five seconds you will get an ANR (Application Not Responding) prompt. In the Handling the Login Button and Getting Profile Data example above, the onSuccess method for AuthorizeListener is called with a worker thread created by AmazonAuthorizationManager. This means it is safe to use that thread to call getProfile synchronously. To make a synchronous call, assign the return value from getProfile to a Future object, and call the get method on that object to wait until the method completes.
Future.get returns a Bundle object that contains a FUTURE_TYPE value of SUCCESS, ERROR, or CANCEL. If the method was a success, the same bundle will contain PROFILE_KEY values for the profile data. For example:
/* Authorization was completed successfully. */
@Override
public void onSuccess(Bundle response) {
Future<Bundle> future = mAuthManager.getProfile(null);
Bundle result = future.get();
// Find out if the call succeeded, and retrieve the profile
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)
{
// Get error object
AuthError authError = AuthError.extractError(result);
/* Use authError to diagnose error */
}
else if (future_type == AuthzConstants.FUTURE_TYPE.CANCEL)
{
/* User cancelled during authorization */
}
}
Last updated: Dec 01, 2022

