接下来给大家介绍下亚马逊登录、储值SDK的接入流程!!
登录api文档:https://developer.amazon.com/zh/docs/login-with-amazon/use-sdk-android.html
储值api文档:https://developer.amazon.com/zh/docs/in-app-purchasing/iap-implement-iap.html
一、登录流程
1.配置
AndroidManifest.xml
<!-- 登录 -->
<activity
android:name="com.amazon.identity.auth.device.workflow.WorkflowActivity"
android:allowTaskReparenting="true"
android:launchMode="singleTask"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- android:host must use the full package name found in Manifest General Attributes -->
<data
android:host="${applicationId}"
android:scheme="amzn" />
</intent-filter>
</activity>
2.创建 RequestContext
private RequestContext requestContext;
public void onCreate(Activity activity) {
......
requestContext = RequestContext.create(activity);
}
3.创建 AuthorizeListener
requestContext.registerListener(new AuthorizeListener() {
/*授权已成功完成。*/
@Override
public void onSuccess(AuthorizeResult result) {
/*您的应用现已获得请求范围授权*/
/**
* UserInfo:username,userId,email
*/
Map<String, String> map = result.getUser().getUserInfo();
}
/*尝试授权
应用时出错。*/
@Override
public void onError(AuthError ae) {
/*提示用户发生错误*/
}
/*授权未完成便已取消。*/
@Override
public void onCancel(AuthCancellation cancellation) {
/*将UI重新设置为随时登录状态*/
}
});
4.登录
public void login() {
AuthorizationManager.authorize(new AuthorizeRequest
.Builder(requestContext)
.addScopes(ProfileScope.profile(), ProfileScope.postalCode())
.build());
}
5.登出
public void logout(Activity activity) {
AuthorizationManager.signOut(activity, new Listener<Void, AuthError>() {
@Override
public void onSuccess(Void response) {
// 设置退出状态UI
Log.e("测试", "logout:onSuccess = ");
}
@Override
public void onError(AuthError authError) {
// 记录错误
Log.e("测试", "logout:onError = " + authError.toString());
}
});
}
6.获取用户信息
建议在生命周期 onStart 中调用
public void getUserInfo(Activity activity) {
Scope[] scopes = {
ProfileScope.profile(),
ProfileScope.postalCode()
};
AuthorizationManager.getToken(activity, scopes, new Listener<AuthorizeResult, AuthError>() {
@Override
public void onSuccess(AuthorizeResult result) {
if (result.getAccessToken() != null) {
/*用户已登录*/
getUser(activity);
Log.e("测试", "getUserInfo:onSuccess = " + result.getAccessToken());
} else {
/*用户未登录*/
Log.e("测试", "getUserInfo:onSuccess+ = " + result.getAccessToken());
}
}
@Override
public void onError(AuthError ae) {
/*用户未登录*/
Log.e("测试", "getUserInfo:onError = " + ae.toString());
}
});
}
private void getUser(Activity activity) {
User.fetch(activity, new Listener<User, AuthError>() {
@Override
public void onSuccess(User user) {
String name = user.getUserName();
String email = user.getUserEmail();
String account = user.getUserId();
String zipCode = user.getUserPostalCode();
Log.e("测试", "getUser:onSuccess: name = " + name);
Log.e("测试", "getUser:onSuccess: email = " + email);
Log.e("测试", "getUser:onSuccess: account = " + account);
Log.e("测试", "getUser:onSuccess: zipCode = " + zipCode);
}
@Override
public void onError(AuthError authError) {
}
});
}
7.生命周期
public void onResume() {
if (requestContext != null) {
requestContext.onResume();
}
}
public void onStart(Activity activity) {
getUserInfo(activity);
}
8.Api key配置
9.登录示例图
二、储值流程
1.配置
AndroidManifest.xml
<!-- amazon储值 -->
<receiver
android:name="com.amazon.device.iap.ResponseReceiver"
android:permission="com.amazon.inapp.purchasing.Permission.NOTIFY">
<intent-filter>
<action android:name="com.amazon.inapp.purchasing.NOTIFY" />
</intent-filter>
</receiver>
2.创建 PurchasingListener
private static final PurchasingListener purchasingListener = new PurchasingListener() {
@Override
public void onUserDataResponse(UserDataResponse userDataResponse) {
Log.i(TAG, "onUserDataResponse: called!");
UserDataResponse.RequestStatus status = userDataResponse.getRequestStatus();
switch (status) {
case SUCCESSFUL:
currentUserId = userDataResponse.getUserData().getUserId();
currentMarketplace = userDataResponse.getUserData().getMarketplace();
break;
case FAILED:
case NOT_SUPPORTED:
// 失败。
break;
}
}
@Override
public void onProductDataResponse(ProductDataResponse productDataResponse) {
Log.i(TAG, "onUserDataResponse: called!");
ProductDataResponse.RequestStatus status = productDataResponse.getRequestStatus();
switch (status) {
case SUCCESSFUL:
break;
case FAILED:
break;
}
}
@Override
public void onPurchaseResponse(PurchaseResponse purchaseResponse) {
Log.i(TAG, "onPurchaseResponse: called!");
PurchaseResponse.RequestStatus status = purchaseResponse.getRequestStatus();
switch (status) {
case SUCCESSFUL:
Receipt receipt = purchaseResponse.getReceipt();
handleReceipt(receipt, purchaseResponse.getUserData());
break;
case FAILED:
case INVALID_SKU:
case NOT_SUPPORTED:
//ALREADY_PURCHASED 这不适用于消耗品。只有申请授权和订阅查看相关样本以获取更多细节
case ALREADY_PURCHASED:
break;
}
}
@Override
public void onPurchaseUpdatesResponse(PurchaseUpdatesResponse purchaseUpdatesResponse) {
Log.i(TAG, "onPurchaseUpdatesResponse: called!");
// 处理收据
PurchaseUpdatesResponse.RequestStatus status = purchaseUpdatesResponse.getRequestStatus();
switch (status) {
case SUCCESSFUL:
break;
case FAILED:
break;
}
}
};
3.初始化
public static void init(Activity activity) {
Log.i(TAG, "init: called!");
PurchasingService.registerListener(activity, purchasingListener);
}
4.获取用户信息
/**
* 获取用户信息
* 在onResume()调用
* 回调在onUserDataResponse()
*/
public static void getUserInfo() {
Log.i(TAG, "getUserInfo: called!");
PurchasingService.getUserData();
}
5.获取订单记录(掉单补单检测)
/**
* 掉单补单检测
* <p>
* false - 返回自上次调用getPurchaseUpdates()之后的购买记录的分页响应。
* 检索用户的待定消费品、权利和订阅购买的收据。亚马逊建议在大部分情况下使用此方法。
* <p>
* true - 检索用户的完整购买记录。您需要将数据存储在某个位置(例如服务器端数据缓存),
* 或将所有数据保存在内存中。
* <p>
* 在onResume()调用
* 回调在onPurchaseUpdatesResponse()
*
*/
public static void getPurchaseUpdates() {
Log.i(TAG, "getPurchaseUpdates: called!");
PurchasingService.getPurchaseUpdates(false);
}
6.获取商品信息
/**
* 获取商品信息,验证SKU
* 仅在onResume中验证产品SKU
* 回调在onProductDataResponse()
* <p>
* consumable:消费品
* entitlement:权利
* subscription:订阅商品
*/
public static void getProductData() {
Log.i(TAG, "getProductData: called!");
Set<String> productSkus = new HashSet<String>();
for (AmazonSku amazonSku : AmazonSku.values()) {
productSkus.add(amazonSku.getSku());
}
PurchasingService.getProductData(productSkus);
}
7.拉起储值
/**
* 拉起储值
* 回调在onPurchaseResponse()
*/
public static void Purchase(String sku) {
Log.i(TAG, "Purchase: called!");
RequestId requestId = PurchasingService.purchase(sku);
}
8.处理购买
/**
* 处理收据
*
* @param receipt
* @param userData
*/
private static void handleReceipt(Receipt receipt, UserData userData) {
Log.i(TAG, "handleReceipt: called! = " + receipt.getProductType());
switch (receipt.getProductType()) {
case CONSUMABLE:
// try to do your application logic to fulfill the customer purchase
handleConsumablePurchase(receipt, userData);
break;
case ENTITLED:
// check entitled sample app to know how to handle entitled
// purchases
break;
case SUBSCRIPTION:
// check subscription sample app to know how to handle subscription
// purchases
break;
}
}
/**
* 处理购买收据,消耗
*
* @param receipt
* @param userData
*/
private static void handleConsumablePurchase(Receipt receipt, UserData userData) {
try {
Log.i(TAG, "handleConsumablePurchase: called! isCanceled = " + receipt.isCanceled());
if (receipt.isCanceled()) {
// consumable purchase.
} else {
grantConsumablePurchase(receipt, userData);
}
return;
} catch (Exception e) {
Log.e(TAG, "Purchase cannot be completed, please retry");
}
}
/**
* 向用户授予商品(发币)
*
* @param receipt
* @param userData
*/
private static void grantConsumablePurchase(Receipt receipt, UserData userData) {
Log.i(TAG, "grantConsumablePurchase: called!");
try {
//创单
// createPurchase(receipt.getReceiptId(), userData.getUserId());
// 验证SKU是否仍然适用。
AmazonSku amazonSku = AmazonSku.fromSku(receipt.getSku(), userData.getMarketplace());
if (amazonSku == null) {
/**
* 如果SKU不再适用,请使用
* 状态“UNAVAILABLE”调用PurchasingService.notifyFulfillment
*/
PurchasingService.notifyFulfillment(receipt.getReceiptId(), FulfillmentResult.UNAVAILABLE);
Log.e(TAG, "收据中的SKU [" + receipt.getSku() + "]不再有效");
return;
}
PurchasingService.notifyFulfillment(receipt.getReceiptId(), FulfillmentResult.FULFILLED);
} catch (Exception e) {
// 不管出于任何原因,如果该应用无法履行购买,
// 请在此处添加您自己的错误处理代码。
// 在您下次调用PurchasingService.getPurchaseUpdates API时,
// 亚马逊会尝试再次发送消费品购买收据
Log.e(TAG, "未能授予消费品购买,错误为" + e.getMessage());
}
}
9.调用点位
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AmazonApi.init(this);
AmazonApi.Purchase(AmazonSku.ORANGE.getSku());
}
@Override
protected void onResume() {
super.onResume();
AmazonApi.getUserInfo();
AmazonApi.getPurchaseUpdates();
AmazonApi.getProductData();
}
10.注意
1.储值的json文件需要copy到手机本地,路径为:/mnt/sdcard/amazon.sdktester.json。
2.可以结合需求加入创单发奖的逻辑进行封装使用。
11.储值示例图
12.沙盒测试
参考官方文档:https://developer.amazon.com/zh/docs/in-app-purchasing/iap-testing-overview.html
Demo下载地址:https://download.csdn.net/download/weixin_43699349/88692020
至此,亚马逊的登录储值SDK就接入完成了!!