
本教程详细阐述了如何在android应用中,使用google play billing library的`querypurchasesasync()`方法来检查用户的现有订阅状态,尤其是在应用启动时。文章将解释该方法与实时购买事件监听器(`purchasesupdatedlistener`)的区别,并提供完整的代码示例和最佳实践,确保用户订阅状态的准确性与安全性。
在Android应用中,管理用户订阅状态是实现内购功能的核心环节。当用户购买了订阅服务后,应用需要能够随时查询并验证该订阅的有效性,而不仅仅是在购买流程完成的当下。例如,当用户重新打开应用时,应用需要知道用户是否仍然拥有有效的订阅。
Google Play Billing Library 提供了两种主要机制来处理购买信息:
PurchasesUpdatedListener: 用于监听实时发生的购买事件,例如用户完成新的购买流程或取消支付。queryPurchasesAsync(): 用于查询用户当前已拥有的所有有效购买(包括订阅)。这是在应用启动或需要验证用户现有订阅状态时应使用的主要方法。
核心方法:查询现有订阅 queryPurchasesAsync()
queryPurchasesAsync() 方法是专门设计用来检索与用户Google账户关联的所有有效购买(包括订阅和非消耗性商品)的。它是一个异步操作,通过回调 PurchasesResponseListener 返回查询结果。
实现步骤与代码示例
在使用 queryPurchasesAsync() 之前,请确保您的 BillingClient 实例已正确初始化并连接到 Google Play 服务。
立即学习“Java免费学习笔记(深入)”;
Cowriter
AI 作家,帮助加速和激发你的创意写作
107 查看详情
import android.util.Log;import com.android.billingclient.api.AcknowledgePurchaseParams;import com.android.billingclient.api.BillingClient;import com.android.billingclient.api.BillingResult;import com.android.billingclient.api.Purchase;import com.android.billingclient.api.QueryPurchasesParams;import java.util.List;public class SubscriptionManager { private BillingClient billingClient; private static final String TAG = "SubscriptionManager"; // 构造函数或初始化方法中传入 BillingClient 实例 public SubscriptionManager(BillingClient client) { this.billingClient = client; } /** * 检查用户当前的订阅状态。 * 此方法应在 BillingClient 连接成功后调用。 */ public void checkSubscriptionStatus() { if (billingClient != null && billingClient.isReady()) { // 查询订阅类型商品 billingClient.queryPurchasesAsync( QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS).build(), (billingResult, purchases) -> { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { boolean hasActiveSubscription = false; if (purchases != null && !purchases.isEmpty()) { for (Purchase purchase : purchases) { // 验证购买状态和商品ID // 请替换 "your_subscription_product_id" 为您实际的订阅商品ID if (purchase.getProducts().contains("your_subscription_product_id") && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) { // 如果购买未被确认,则需要确认 if (!purchase.isAcknowledged()) { acknowledgePurchase(purchase); } // 购买已确认且状态为已购买,则视为有效订阅 if (purchase.isAcknowledged()) { hasActiveSubscription = true; Log.d(TAG, "用户拥有有效订阅: OrderId = " + purchase.getOrderId()); // TODO: 根据您的应用逻辑更新UI或应用状态 // 例如: Constant.subscription = true; break; // 找到一个有效订阅即可 } } } } if (!hasActiveSubscription) { Log.d(TAG, "用户没有有效的订阅。"); // TODO: 根据您的应用逻辑更新UI或应用状态 // 例如: Constant.subscription = false; } } else { Log.e(TAG, "查询订阅失败: " + billingResult.getDebugMessage()); } } ); } else { Log.e(TAG, "BillingClient 未准备好或为空,无法查询订阅。"); } } /** * 辅助方法:确认购买。 * Google Play 要求所有购买(包括订阅)必须在3天内确认。 * 未确认的购买会在3天后自动退款。 */ private void acknowledgePurchase(Purchase purchase) { AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); billingClient.acknowledgePurchase(acknowledgePurchaseParams, billingResult -> { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { Log.d(TAG, "购买已成功确认: OrderId = " + purchase.getOrderId()); // 确认成功后,可以再次触发订阅状态检查或直接更新UI // checkSubscriptionStatus(); // 重新检查以更新状态 } else { Log.e(TAG, "购买确认失败: " + billingResult.getDebugMessage()); } }); } // 您可能还需要一个方法来处理可消耗商品的消耗逻辑,如果您的应用有此类商品。 // 订阅商品不需要消耗。 /* void handleConsumablePurchase(Purchase purchase) { ConsumeParams consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); billingClient.consumeAsync(consumeParams, (billingResult, purchaseToken) -> { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { Log.d(TAG, "可消耗商品已成功消耗。"); // TODO: 授予用户商品 } else { Log.e(TAG, "可消耗商品消耗失败: " + billingResult.getDebugMessage()); } }); } */}
代码解释:
QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS).build(): 指定我们只查询订阅类型的商品。PurchasesResponseListener: 这是 queryPurchasesAsync 的回调接口,它接收 BillingResult 和一个 Purchase 列表。billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK: 检查查询操作本身是否成功。purchase.getProducts().contains(“your_subscription_product_id”): 这一步至关重要,它确保我们检查的是我们关心的特定订阅商品。务必将 “your_subscription_product_id” 替换为您的实际商品ID。purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED: 验证购买的状态是否为“已购买”。purchase.isAcknowledged(): 对于所有购买(包括订阅),Google Play 都要求进行确认。如果 isAcknowledged() 返回 false,则需要调用 acknowledgePurchase() 方法进行确认。未确认的购买将在3天后自动退款。acknowledgePurchase(purchase): 这是一个辅助方法,用于执行购买确认操作。
何时调用 checkSubscriptionStatus()?
为了确保用户订阅状态的及时性和准确性,您应该在以下关键时刻调用 checkSubscriptionStatus() 方法:
应用启动时: 在主 Activity 的 onResume() 方法中或应用初始化流程中调用,确保用户进入应用时,其订阅状态是最新的。从后台返回前台时: 同样可以在 onResume() 中处理,以防用户在应用处于后台期间订阅状态发生变化(例如,订阅到期或在其他设备上取消)。用户尝试访问受限内容时: 在用户尝试访问仅限订阅用户可用的高级功能之前进行检查。网络恢复时: 如果应用在离线状态下启动,当网络连接恢复后,应重新检查订阅状态。BillingClient 连接成功后: 确保 BillingClient 已准备就绪且连接成功。
PurchasesUpdatedListener 的角色
虽然 queryPurchasesAsync() 用于查询现有订阅,但 PurchasesUpdatedListener 仍然是处理 新发生购买事件 的关键。当用户完成购买流程(无论是成功、取消还是其他错误)时,此监听器会被触发。
import android.util.Log;import com.android.billingclient.api.BillingClient;import com.android.billingclient.api.BillingResult;import com.android.billingclient.api.Purchase;import com.android.billingclient.api.PurchasesUpdatedListener;import java.util.List;public class MyBillingClientLifecycleManager implements PurchasesUpdatedListener { private SubscriptionManager subscriptionManager; // 假设您有SubscriptionManager实例 public MyBillingClientLifecycleManager(SubscriptionManager manager) { this.subscriptionManager = manager; } @Override public void onPurchasesUpdated(BillingResult billingResult, List purchases) { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchases != null) { for (Purchase purchase : purchases) { // 对于新购买的订阅,需要进行确认 if (purchase.getProducts().contains("your_subscription_product_id")) { // 确认操作应在 SubscriptionManager 中处理 if (!purchase.isAcknowledged()) { subscriptionManager.acknowledgePurchase(purchase); } Log.d("BillingFlow", "新订阅购买成功并处理: OrderId = " + purchase.getOrderId()); // TODO: 更新应用状态,例如 Constant.subscription = true; } // 如果是可消耗商品,则需要消耗 // else if (purchase.getProducts().contains("your_consumable_product_id")) { // subscriptionManager.handleConsumablePurchase(purchase); // } } // 无论新购买成功与否,都建议重新查询一次以同步最新状态 subscriptionManager.checkSubscriptionStatus(); } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED){ Log.d("BillingFlow", "用户取消了购买流程。"); // TODO: 更新应用状态,例如 Constant.subscription = false; } else { Log.e("BillingFlow", "购买流程出现错误: " + billingResult.getDebugMessage()); } }}
注意: 订阅商品不需要像可消耗商品那样进行“消耗”。订阅只需在购买后进行一次“确认”即可。原始问题中 handlePurchase 方法中包含的 consumeAsync 逻辑,通常用于处理可消耗商品,不适用于订阅。
重要注意事项与最佳实践
购买确认 (Acknowledgement): 这是Google Play Billing中最关键的环节之一。所有购买(包括订阅和非消耗性商品)都必须在购买成功后的3天内通过 acknowledgePurchase() 方法进行确认。如果未在规定时间内确认,Google Play 将自动退款给用户,并且购买会被撤销。服务器端验证: 尽管客户端可以检查订阅状态,但为了防止作弊和提供更强大的安全性,强烈建议在您的后端服务器上
以上就是Android应用内购:在Java中实现用户订阅状态的准确检查的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1064246.html
微信扫一扫
支付宝扫一扫