Play Billing Library v1.0过期订阅逻辑处理咨询
处理订阅过期的逻辑方案(针对Play Billing Library v1.0)
你现在只在启动页通过queryPurchases检查当前有效的订阅,但订阅过期后这个方法就不会返回对应记录了,得从启动页状态校验和实时订阅状态监听两个维度完善逻辑,具体来说:
1. 启动页完善订阅状态校验
首先,Purchase对象自带getExpirationTime()方法,能拿到订阅的过期时间戳(毫秒级),我们可以用它判断订阅是否在有效期内。另外,订阅过期后queryPurchases不会返回该记录,这时候得通过queryPurchaseHistoryAsync查询历史订阅,确认用户是否曾订阅过但现已过期,从而调整权益状态。
修改后的代码示例:
if (billingResponse == BillingClient.BillingResponse.OK) { // 先查询当前有效的订阅 Purchase.PurchasesResult activeResult = mBillingClient.queryPurchases(BillingClient.SkuType.SUBS); if (activeResult.getPurchasesList().size() > 0) { Purchase activePurchase = activeResult.getPurchasesList().get(0); // 双重保险:避免缓存或异常导致的误判 long currentTime = System.currentTimeMillis(); if (activePurchase.getExpirationTime() > currentTime) { if (activePurchase.getSku().equals(constant.sku_subscription_weekly)) { premium = 2; } } else { // 订阅已过期,重置权益为普通用户状态 premium = 0; } } else { // 无有效订阅,查询历史记录确认是否曾订阅过 mBillingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.SUBS, new PurchaseHistoryResponseListener() { @Override public void onPurchaseHistoryResponse(int responseCode, List<Purchase> purchasesList) { if (responseCode == BillingClient.BillingResponse.OK && purchasesList.size() > 0) { Purchase historyPurchase = purchasesList.get(0); if (historyPurchase.getSku().equals(constant.sku_subscription_weekly)) { long currentTime = System.currentTimeMillis(); if (historyPurchase.getExpirationTime() <= currentTime) { // 用户曾订阅但已过期,重置权益 premium = 0; // 这里可以同步更新UI,比如隐藏付费功能入口 } } } else { // 用户从未订阅过,保持普通状态 premium = 0; } } }); } }
2. 监听实时订阅状态变化
用户的订阅可能在APP运行期间过期(比如自动续费失败、手动取消),光靠启动页检查不够,得注册PurchasesUpdatedListener监听状态变化,及时更新权益:
// 初始化BillingClient时绑定监听 mBillingClient = BillingClient.newBuilder(context).setListener(new PurchasesUpdatedListener() { @Override public void onPurchasesUpdated(int responseCode, List<Purchase> purchases) { if (responseCode == BillingClient.BillingResponse.OK && purchases != null) { // 处理购买/续费成功的情况 for (Purchase purchase : purchases) { if (purchase.getSku().equals(constant.sku_subscription_weekly)) { long currentTime = System.currentTimeMillis(); premium = purchase.getExpirationTime() > currentTime ? 2 : 0; // 同步更新UI或本地存储 } } } else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) { // 用户主动取消订阅,结合历史记录重置权益 // 这里可以调用queryPurchaseHistoryAsync再次确认状态 } // 其他错误情况根据业务需求处理 } }).build();
3. 注意宽限期的特殊处理
部分订阅在支付失败后会进入宽限期,这段时间用户仍能享受权益,直到宽限期结束才彻底过期。getExpirationTime()返回的就是宽限期结束时间,所以咱们的判断逻辑无需额外修改,直接用这个时间和当前时间对比即可。
4. 本地存储状态(可选但推荐)
建议把用户的订阅状态(比如premium值、过期时间)存在SharedPreferences或本地数据库里,APP启动时先读取本地状态,再通过BillingClient校验更新,既提升启动速度,也能避免网络问题导致的状态异常。
内容的提问来源于stack exchange,提问作者Khushi Patel
相关产品推荐
相关产品推荐

