|
public void onErrorRemoteException() {
Log.e(TAG, "isBillingSupportedAsync onError, 无法连接ONE store服务");
}
@Override
public void onErrorSecurityException() {
Log.e(TAG, "isBillingSupportedAsync onError, 应用状态异常下请求支付");
}
@Override
public void onErrorNeedUpdateException() {
Log.e(TAG, "isBillingSupportedAsync onError, 需要更新ONE store客户端");
}
};
// ONE store应用内支付API版本
int IAP_API_VERSION = 5;
mPurchaseClient.isBillingSupportedAsync(IAP_API_VERSION, mBillingSupportedListener);
4-4、查询商品信息
开发者在 ArrayList输入采用queryProductAsync方法的参数中放入想要获取信息的应用内商品ID并调用,返回结果至已注册的监听器。
商品ID指开发者在开发者中心注册商品时自定义的商品ID。商品信息会以 ProductDetail形式返回至 onSuccess监听器。
/
PurchaseClient的 queryProductsAsync API (商品信息查询)回调监听器
*/
PurchaseClient.QueryProductsListener mQueryProductsListener = new PurchaseClient.QueryProductsListener() {
@Override
public void onSuccess(List<ProductDetail> productDetails) {
Log.d(TAG, "queryProductsAsync onSuccess, " + productDetails.toString());
}
@Override
public void onErrorRemoteException() {
Log.e(TAG, "queryProductsAsync onError, 无法连接ONE store服务 ");
}
@Override
public void onErrorSecurityException() {
Log.e(TAG, "queryProductsAsync onError, 应用状态异常下请求支付 ");
}
@Override
public void onErrorNeedUpdateException() {
Log.e(TAG, "queryProductsAsync onError, 需要更新ONE store客户端");
}
@Override
public void onError(IapResult result) {
Log.e(TAG, "queryProductsAsync onError, " + result.toString());
}
};
int IAP_API_VERSION = 5;
String productType = IapEnum.ProductType.IN_APP.getType(); // "inapp"
ArrayList<String> productCodes = new ArrayList<>();
productCodes.add("p5000");
productCodes.add("p10000");
mPurchaseClient.queryProductsAsync(IAP_API_VERSION, productCodes, productType, mQueryProductsListener);
4-5、发起购买请求
调用launchPurchaseFlowAsync方法执行购买。调用方法时,输入想要购买的应用内商品ID、商品名称、商品类别和开发者任意决定的launchPurchaseFlowAsync(不超过100byte),该值用于支付成功后确认数据的正确性和附加数据,并以参数传递的requestCode用于确认返回至onActivityResult的数据。
购买成功时结果返回至onSuccess监听器,以SDK的 PurchaseData规格返回。开发者基于收到的结果,再通过 developerPayload确认数据的正确性和附加数据,以签名信息来验证。
管理型商品,通过设置商品消耗处理为用户提供商品。
ONE store面向用户开展发送优惠券、 购物返现(cashback)等各种优惠推广活动。开发者发起购买请求时,可通过gameUserId、promotionApplicable参数,允许或控制用户参加推广活动。开发者选择应用的唯一标识符及是否参与活动并传递给ONE store,ONE store基于该值处理用户的活动优惠。
注意:gameUserId,protectionApplicable参数必须事先应用于ONE store经理的促销工作。一般说来,该值不应发送。
此外,gameUserId参数应当送到散列单一值,以便在事先发送价值信息时,没有隐私信息保护问题。
/
PurchaseClient的 launchPurchaseFlowAsync API (购买)回调监听器
*/
PurchaseClient.PurchaseFlowListener mPurchaseFlowListener = new PurchaseClient.PurchaseFlowListener() {
@Override
public void onSuccess(PurchaseData purchaseData) {
Log.d(TAG, "launchPurchaseFlowAsync onSuccess, " + purchaseData.toString());
// 购买成功后检查开发者payload。
if (!isValidPayload(purchaseData.getDeveloperPayload())) {
Log.d(TAG, "launchPurchaseFlowAsync onSuccess, Payload is not valid.");
return;
}
// 购买成功后检查签名。
boolean validPurchase = AppSecurity.isValidPurchase(purchaseData.getPurchaseData(), purchaseData.getSignature());
if (validPurchase) {
if (product5000.equals(purchaseData.getProductId())) {{
// 管理型商品(inapp)购买成功后消耗。
consumeItem(purchaseData);
}
} else {
Log.d(TAG, "launchPurchaseFlowAsync onSuccess, Signature is not valid.");
return;
}
}
@Override
public void onError(IapResult result) {
Log.e(TAG, "launchPurchaseFlowAsync onError, " + result.toString());
}
@Override
public void onErrorRemoteException() {
Log.e(TAG, "launchPurchaseFlowAsync onError, 无法连接ONE store服务 ");
}
@Override
public void onErrorSecurityException() {
Log.e(TAG, "launchPurchaseFlowAsync onError, 应用状态异常下请求支付 ");
}
@Override
public void onErrorNeedUpdateException() {
Log.e(TAG, "launchPurchaseFlowAsync onError, 需要更新ONE store客户端 ");
}
};
int IAP_API_VERSION = 5;
int PURCHASE_REQUEST_CODE
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整资料开源分享
= 1000; // 返回至onActivityResult的request code
String product5000 = "p5000"; // 请求购买的商品ID
String productName = ""; // ""时显示开发者中心注册的商品名称
String productType = IapEnum.ProductType.IN_APP.getType(); // "inapp"
String devPayload = AppSecurity.generatePayload();
String gameUserId = ""; // 默认 ""
boolean promotionApplicable = false;
mPurchaseClient.launchPurchaseFlowAsync(IAP_API_VERSION, "调用Activity".this, PURCHASE_REQUEST_CODE, product5000, productName, productType, devPayload, gameUserId, promotionApplicable, mPurchaseFlowListener);
支付成功时返回至监听器的Purchase信息参考“应用内支付参考 - getPurchaseIntent() 发起购买请求”。
支付结果会返回至调用launchPurchaseFlowAsync的Activity的onActivityResult,在这里须添加handlePurchaseData方法,以SDK处理购买结果。启动handlePurchaseData方法时,如果作为请求购买的参数输入的 PurchaseFlowListener为null的话,会返回false(失败)。成功或错误的处理结果会通过 PurchaseFlowListener来返回。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.e(TAG, "onActivityResult resultCode " + resultCode);
switch (requestCode) {
case PURCHASE_REQUEST_CODE:
/
调用 launchPurchaseFlowAsync API 时收到的intent数据通过handlePurchaseData解析返回值。
* 解析后返回结果通过调用 launchPurchaseFlowAsync 时的 PurchaseFlowListener 返回。
/
if (resultCode == Activity.RESULT_OK) {
if (mPurchaseClient.handlePurchaseData(data) == false) {
Log.e(TAG, "onActivityResult handlePurchaseData false ");
// listener is null
}
} else {
Log.e(TAG, "onActivityResult user canceled");
// user canceled , do nothing..
}
break;
default:
}
}
4-6、商品消耗
如为管理型商品(inapp),未消耗已购商品时无法再次购买。用户购买商品后,其购买信息托管给ONE store,商品被消耗,ONE store立刻收回用户购买商品的权限。也就是说,如过购买了管理型商品而未消耗,可作为永久性商品,如购买后立刻消耗商品,可作为消耗型商品,如超过一定期限消耗已购商品,可作为限期型商品。要发起商品消耗请求时,将返回至launchPurchaseFlowAsync或queryPurchasesAsync的购买信息,作为 consumeAsync 方法的参数传递并调用。
/
* PurchaseClient的 consumeAsync API (商品消耗)回调监听器
/
PurchaseClient.ConsumeListener mConsumeListener = new PurchaseClient.ConsumeListener() {
@Override
public void onSuccess(PurchaseData purchaseData) {
Log.d(TAG, "consumeAsync onSuccess, " + purchaseData.toString());
// 商品消耗成功后,按各开发者编写的购买成功方案进行。
}
@Override
public void onErrorRemoteException() {
Log.e(TAG, "consumeAsync onError, 无法连接ONE store服务");
}
@Override
public void onErrorSecurityException() {
Log.e(TAG, "consumeAsync onError, 应用状态异常下请求支付");
}
@Override
public void onErrorNeedUpdateException() {
Log.e(TAG, "consumeAsync onError, 需要更新ONE store客户端 ");
}
@Override
public void onError(IapResult result) {
Log.e(TAG, "consumeAsync onError, " + result.toString());
}
};
int IAP_API_VERSION = 5;
PurchaseData purchaseData; // 查询购买记录及请求购买后接到的PurchaseData
mPurchaseClient.consumeAsync(IAP_API_VERSION, purchaseData, mConsumeListener);
4-7、查询购买记录
调用queryPurchasesAsync方法来获取用户已购但未消耗的管理型商品(inapp)和用户订阅的包月自动支付商品(auto)。SDK会验证签名以确认购买信息数据伪造与否,如签名验证失败,会将“IapResult”内定义的 IapResult.IAP_ERROR_SIGNATURE_VERIFICATION值返回至onError监听器。出现错误表示购买信息数据有伪造的可能,有必要确认是否有abusing袭击。
开发者查询购买记录获得管理型商品(inapp),可通过设置商品消耗向用户提供商品。
/
* PurchaseClient的queryPurchasesAsync API (查询购买记录)回调监听器
*/
PurchaseClient.QueryPurchaseListener mQueryPurchaseListener = new PurchaseClient.QueryPurchaseListener() {
@Override
public void onSuccess(List<PurchaseData> purchaseDataList, String productType) {
Log.d(TAG, "queryPurchasesAsync onSuccess, " + purchaseDataList.toString());
if (IapEnum.ProductType.IN_APP.getType().equalsIgnoreCase(productType)) {
// 如为查询购买记录后获取的管理型商品( inapp),先验证签名,成功后消耗商品。
} else if (IapEnum.ProductType.AUTO.getType().equalsIgnoreCase(productType)) {
// 如为查询购买记录后获取的包月自动支付商品( auto),先验证签名,成功后根据开发者应用处理需求编写方案。
}
}
@Override
public void onErrorRemoteException() {
Log.e(TAG, "queryPurchasesAsync onError, 无法连接ONE store服务");
}
@Override
public void onErrorSecurityException() {
Log.e(TAG, "queryPurchasesAsync onError, 应用状态异常下请求支付");
}
@Override
public void onErrorNeedUpdateException() {
Log.e(TAG, "queryPurchasesAsync onError, 需要更新ONE store客户端 ");
}
@Override
public void onError(IapResult result) {
Log.e(TAG, "queryPurchasesAsync onError, " + result.toString());
}
};
int IAP_API_VERSION = 5;
String productType = IapEnum.ProductType.IN_APP.getType(); // "inapp"
mPurchaseClient.queryPurchasesAsync(IAP_API_VERSION, productType, mQueryPurchaseListener);
4-8、移动端消耗失败,导致掉单
架构师筑基包括哪些内容
我花了将近半个月时间将:深入 Java 泛型.、注解深入浅出、并发编程.、数据传输与序列化、Java 虚拟机原理、反射与类加载、高效 IO、Kotlin项目实战等等Android架构师筑基必备技能整合成了一套系统知识笔记PDF,相信看完这份文档,你将会对这些Android架构师筑基必备技能有着更深入、更系统的理解。
由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容
注:资料与上面思维导图一起看会更容易学习哦!每个点每个细节分支,都有对应的目录内容与知识点!
这份资料就包含了所有Android初级架构师所需的所有知识!
本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录
</div>
<div id="asideoffset"></div>
|
免责声明:
1. 本站所有资源来自网络搜集或用户上传,仅作为参考不担保其准确性!
2. 本站内容仅供学习和交流使用,版权归原作者所有!© 查看更多
3. 如有内容侵害到您,请联系我们尽快删除,邮箱:kf@codeae.com
|