【问题标题】:Android: How to check if user have active subscription or notAndroid:如何检查用户是否有活动订阅
【发布时间】:2019-11-26 14:24:12
【问题描述】:

我正在使用Google Billing 并尝试通过两种解决方案了解订阅是否已过期:

  1. billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.SUBS) { billingResult, purchasesList -> }

  2. val purchasesList = billingClient.queryPurchases(BillingClient.SkuType.SUBS).purchasesList

他们会返回类似的东西:

{
  "productId": "weekly_with_trial",
  "purchaseToken": "someToken",
  "purchaseTime": 1563305764597,
  "developerPayload": null
}
{
  "orderId": "GPA.3380-7704-5235-01361",
  "packageName": "com.myapp",
  "productId": "weekly_trial_trial",
  "purchaseTime": 1563305764597,
  "purchaseState": 0,
  "purchaseToken": "someToken",
  "autoRenewing": false,
  "acknowledged": false
}

他们俩都向我返回了购买清单,但没有任何关于它是否过期的信息。如何检查?

【问题讨论】:

    标签: android kotlin android-billing


    【解决方案1】:

    Google play billing 的文档清楚地表明,有两个函数可以获取购买列表

    val purchasesResult: PurchasesResult =
            billingClient.queryPurchases(SkuType.INAPP)
    

    当您进行查询购买时,只有有效订阅会出现在此列表中。只要应用内商品在此列表中,用户就应该有权访问它

    这意味着如果购买已过期,那么您将不会在 queryPurchase 的响应中获得该购买项目。 但是您必须记住,它返回的是 google play store 的本地缓存结果。

    因此,为了从网络调用中获取购买请求,您需要使用异步方法,即 queryPurchaseHistoryAsync()

    billingClient.queryPurchaseHistoryAsync(SkuType.INAPP, { billingResult, purchasesList ->
       if (billingResult.responseCode == BillingResponse.OK && purchasesList != null) {
           for (purchase in purchasesList) {
               // Process the result.
           }
       }
    })
    

    但是,对象中存在一个问题,该对象包含有关用户为每个产品 ID 进行的最近购买的信息,即使该购买已过期、取消或消耗。

    因此您可以使用 queryPurchase() 来获取所有活跃的购买。

    【讨论】:

    • 取消订阅后,订阅从列表中删除需要多长时间?我已经购买了每周订阅并在之后将其删除,等待 1.5 小时,它仍然在响应
    • 尝试清除您的 Play 商店缓存并再次检查。
    • Buuuut,如何在生产中使用它?
    • 您面临的问题实际上是现在在 google 的末尾打开,您可以阅读此线程以获取更多详细信息 link,并且此线程中提供的最新解决方案是 link
    • 您好 Rajat,感谢您的回答!只是一个快速的问题。如果用户在 2018 年订阅了我的应用,在 2019 年取消了它,然后在 2020 年再次订阅,那么当用户点击恢复时,我是否可以获取有关 2018 年订阅的详细信息?
    【解决方案2】:

    这是我用来检查有效订阅的代码:

    private void isUserHasSubscription(Context context) {
            billingClient = BillingClient.newBuilder(context).enablePendingPurchases().setListener(this).build();
            billingClient.startConnection(new BillingClientStateListener() {
                @Override
                public void onBillingSetupFinished(BillingResult billingResult) {
                    Purchase.PurchasesResult purchasesResult=billingClient.queryPurchases(BillingClient.SkuType.SUBS);
    
                    billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.SUBS,(billingResult1, list) -> {
                        
                        Log.d("billingprocess","purchasesResult.getPurchasesList():"+purchasesResult.getPurchasesList());
                        
                        if (billingResult1.getResponseCode() == BillingClient.BillingResponseCode.OK &&
                                !Objects.requireNonNull(purchasesResult.getPurchasesList()).isEmpty()) {
    
                                //here you can pass the user to use the app because he has an active subscription  
                                Intent myIntent=new Intent(context,MainActivity.class);
                                startActivity(myIntent);
                        }
                    });
                }
                @Override
                public void onBillingServiceDisconnected() {
                    // Try to restart the connection on the next request to
                    // Google Play by calling the startConnection() method.
                    Log.d("billingprocess","onBillingServiceDisconnected");
                }
            });
        }
    

    【讨论】:

    • 谢谢。这是唯一可靠的工作示例。没有其他文档说明如何在其他任何地方使用它……这太荒谬了。
    猜你喜欢
    • 1970-01-01
    • 2017-07-13
    • 2016-08-04
    • 2016-09-30
    • 2012-09-03
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    相关资源
    最近更新 更多