如何在Jetpack Compose安卓应用中检查内购状态并处理退款降级
核心思路
无需依赖后端,直接通过Google Billing Library主动查询用户的有效购买记录,用官方返回的状态覆盖本地偏好值,确保权限状态与Google Play后台完全同步。
具体实现步骤
1. 新增已购商品校验方法
在MainActivity2中添加专门的查询逻辑,校验用户当前是否拥有有效的Premium购买:
private fun queryValidPurchases() { // 先判断Billing Client是否就绪,未就绪则先建立连接 if (!billingClient.isReady) { startBillingConnection(object : BillingClientStateListener { override fun onBillingSetupFinished(billingResult: BillingResult) { if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) { performPurchaseQuery() } } override fun onBillingServiceDisconnected() { // 可添加重试逻辑,或提示用户检查网络 } }) return } performPurchaseQuery() } private fun performPurchaseQuery() { val queryParams = QueryPurchasesParams.newBuilder() .setProductType(BillingClient.ProductType.INAPP) .build() billingClient.queryPurchasesAsync(queryParams) { billingResult, purchases -> if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) { // 筛选有效购买:包含目标商品ID、已完成购买、已确认 val hasValidPremium = purchases.any { purchase -> purchase.products.contains(productId) && purchase.purchaseState == Purchase.PurchaseState.PURCHASED && purchase.isAcknowledged } // 更新本地偏好状态 lifecycleScope.launch { userPreferencesRepository.changePremiumStatus(hasValidPremium) } } else { // 查询失败时默认降级,或保留本地状态(根据需求调整) lifecycleScope.launch { userPreferencesRepository.changePremiumStatus(false) } } } }
2. 在关键节点触发校验
将校验逻辑放在应用启动、后台切前台的时机,确保每次用户使用应用时都同步状态:
- 修改
startBillingConnection的回调,启动时自动校验:
override fun onBillingSetupFinished(billingResult: BillingResult) { if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) { queryValidPurchases() // 启动时同步购买状态 } }
- 重写
onResume方法,后台恢复时再次校验:
override fun onResume() { super.onResume() if (billingClient.isReady) { queryValidPurchases() } else { startBillingConnection() } }
3. 完善一次性内购的确认逻辑
一次性内购必须调用acknowledgePurchase完成确认,否则Google Play会在3天后自动退款。补充handlePurchase方法:
private fun handlePurchase(purchase: Purchase) { if (!purchase.isAcknowledged) { val acknowledgeParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.purchaseToken) .build() billingClient.acknowledgePurchase(acknowledgeParams) { billingResult -> if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) { Toast.makeText(this, "Welcome to Groovy Premium!", Toast.LENGTH_SHORT).show() lifecycleScope.launch { userPreferencesRepository.changePremiumStatus(true) } } else { Toast.makeText(this, "Purchase confirmation failed", Toast.LENGTH_SHORT).show() } } } else { Toast.makeText(this, "Welcome to Groovy Premium!", Toast.LENGTH_SHORT).show() lifecycleScope.launch { userPreferencesRepository.changePremiumStatus(true) } } }
4. 退款后的自动降级逻辑
当用户退款后,Google Play会将该购买标记为无效,queryValidPurchases查询时会返回空的有效购买列表,此时本地偏好会自动被设为false,实现权限降级。
额外优化建议
- 添加"恢复购买"按钮:在应用设置页提供按钮,点击时触发
queryValidPurchases,让用户主动同步状态; - 限制查询频率:可添加时间戳判断,比如1小时内仅查询一次,减少不必要的网络请求;
- 权限前置校验:用户访问Premium功能前,先触发一次
queryValidPurchases,避免本地状态延迟。
内容的提问来源于stack exchange,提问作者Mehedi Hasan
相关产品推荐
相关产品推荐

