简体   繁体   English

如何检查用户是否在 Android、Google Play 中拥有有效订阅?

[英]How to check if the user has an active subscription in Android, Google Play?

I have an app with a subscription in Google Play.我在 Google Play 中有一个订阅的应用程序。 When the user starts the app, I need to know if the user has an active subscription.当用户启动应用程序时,我需要知道用户是否有活动订阅。 This would seem an obvious thing to do, but from searching and trying to implement it, it seems impossible?这似乎是一件显而易见的事情,但从搜索和尝试实现它,这似乎是不可能的?

I am using Google's newer billing 2/3, following Google's tutorials,我正在使用 Google 的新计费 2/3,遵循 Google 的教程,

class BillingManager implements PurchasesUpdatedListener
...
public void checkAsync() {
    Log.e(TAG, "checkAsync");
    billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.SUBS, new PurchaseHistoryResponseListener() {
        @Override
        public void onPurchaseHistoryResponse(BillingResult billingResult, List<PurchaseHistoryRecord> list) {
            Log.e(TAG, "checkCached result: " + list);
            if (list == null) {
                return;
            }

            for (PurchaseHistoryRecord ps : list) {
                //System.out.println("PAYMENT: " + ps.getSku() + " : " + ps.getPurchaseTime());
            }
        }
    });
}

public void checkCached() {
    Log.e(TAG, "checkCached");
    List<Purchase> result = billingClient.queryPurchases(BillingClient.SkuType.SUBS).getPurchasesList();
    Log.e(TAG, "checkCached result: " + result);
    if (result == null) {
        return;
    }
    for (Purchase purchase : result) {
        handlePurchase(purchase);
    }
}

This is how I think you're supposed to get a user's purchases.这就是我认为您应该获得用户购买的方式。 But it does not work at all, both calls return null always.但它根本不起作用,两个调用总是返回 null。 It only returns the correct purchases when you reinstall the app or clear the data.它仅在您重新安装应用程序或清除数据时返回正确的购买。

So how exactly is an app supposed to do this?那么一个应用程序究竟应该如何做到这一点呢?

Purchasing works for the app once I enter internal testing, and download it through the Google Play link.一旦我进入内部测试并通过 Google Play 链接下载它,就可以购买该应用程序。 (before that subscriptions do not work at all). (在此之前订阅根本不起作用)。

*** updated So to further clarify: ***更新所以进一步澄清:

I am using a valid test user, and subscriptions are working correctly.我正在使用有效的测试用户,并且订阅工作正常。 My question is on the what the API queryPurchases() or queryPurchaseHistoryAsync() are suppose to do.我的问题是 API queryPurchases() 或 queryPurchaseHistoryAsync() 应该做什么。

What I am seeing, is that these only return purchases that have not be processed by the app.我所看到的是,这些只是应用程序未处理的退货购买。 They seem to store that the purchase was processed in the apps data.他们似乎存储了购买是在应用程序数据中处理的。 After the purchase these return null, after the app restarts these return null.购买后这些返回 null,应用重新启动后这些返回 null。 If I clear the app datam or reinstall the app then they return the purchase (once), then again null after restart.如果我清除应用程序数据或重新安装应用程序然后他们返回购买(一次),然后在重新启动后再次返回 null。

From what I see, these are only useful to detect when a user reinstalls your app, or installs on a different phone.据我所知,这些仅对检测用户何时重新安装您的应用程序或安装在其他手机上有用。 They cannot be used to determine the status of a subscription.它们不能用于确定订阅的状态。

So my question is,所以我的问题是,

1 - is this something that just does not work in internal testing and will magically work differently when the app is release? 1 - 这是不是在内部测试中不起作用并且在应用程序发布时会神奇地以不同的方式工作?

2 - is there a different API that your suppose to use to check the status of a subscription? 2 - 是否有不同的 API 用于检查订阅状态?

3 - are you suppose to manage subscriptions yourself in your app by storing a user preference/cookie when you acknowledge the subscription the first time so you know when the subscription expires? 3 - 您是否想在您第一次确认订阅时通过存储用户偏好/cookie 在您的应用程序中自己管理订阅,以便您知道订阅何时到期?

You need "licenced testers".您需要“有执照的测试人员”。 They would allow you to "sideload" your app on devices, even for debug builds.它们将允许您在设备上“侧载”您的应用程序,即使是调试版本也是如此。 My interpretation of sideload in this case would cover installing from Android Studio build tools as well as adb install.... and other methods that don't involve the play store.在这种情况下,我对 sideload 的解释将涵盖从 Android Studio 构建工具以及adb install....和其他不涉及 Play 商店的方法进行安装。

https://developer.android.com/google/play/billing/test https://developer.android.com/google/play/billing/test

Ordinarily, the Google Play Billing API is blocked for apps that aren't signed and uploaded to Google Play.通常,Google Play 结算 API 对于未签名并上传到 Google Play 的应用程序会被阻止。 License testers can bypass this check, meaning you can sideload apps for testing, even for apps using debug builds with debug signatures without the need to upload to the new version of your app.许可证测试人员可以绕过此检查,这意味着您可以旁加载应用程序进行测试,即使是使用带有调试签名的调试版本的应用程序,也无需上传到应用程序的新版本。 Note that the package name must match that of the app that is configured for Google Play, and the Google account must be a license tester for the Google Play Console account.请注意,package 名称必须与为 Google Play 配置的应用程序的名称匹配,并且 Google 帐户必须是 Google Play 控制台帐户的许可证测试员。

I also don't see how you're using startConnection .我也看不到您如何使用startConnection Until that's completed successfully I wouldn't be sure you have the latest data.在成功完成之前,我不确定您是否拥有最新数据。 I wouldn't be surprised if that makes you get stale values.如果这使您获得陈旧的价值,我不会感到惊讶。 I would check that carefully to make sure there's no silent errors happening, by both looking at onBillingSetupFinished and onBillingServiceDisconnected .我会通过查看onBillingSetupFinishedonBillingServiceDisconnected仔细检查以确保没有发生静默错误。 And for the time being avoid trusting queryPurchases() :暂时避免信任queryPurchases()

https://medium.com/@NandagopalR/integrating-google-play-billing-into-an-android-application-b6eb6af176a7 https://medium.com/@NandagopalR/integrating-google-play-billing-into-an-android-application-b6eb6af176a7

The queryPurchases() method uses a cache of the Google Play Store app without initiating a network request. queryPurchases() 方法使用 Google Play 商店应用程序的缓存,而无需发起网络请求。 If you need to check the most recent purchase made by the user for each product ID, you can use queryPurchaseHistoryAsync(), passing the purchase type and a PurchaseHistoryResponseListener to handle the query result.如果您需要检查用户对每个产品 ID 的最近购买情况,可以使用 queryPurchaseHistoryAsync(),传递购买类型和 PurchaseHistoryResponseListener 来处理查询结果。

By the way what's the value of isReady() right before queryPurchaseHistoryAsync , and what's the value of BillingResult::getDebugMessage and BillingResult::getResponseCode ?顺便问一下,在queryPurchaseHistoryAsync之前isReady()的值是多少, BillingResult::getDebugMessageBillingResult::getResponseCode的值是多少?

Also, use isFeatureSupported , though it seems it's not like your problem is coming from here.另外,请使用isFeatureSupported ,尽管您的问题似乎不是来自这里。 But I'd advise not testing with subscriptions until you get all the moving parts working: https://developer.android.com/reference/com/android/billingclient/api/BillingClient#isFeatureSupported(java.lang.String)但我建议在所有活动部件正常工作之前不要使用订阅进行测试: https://developer.android.com/reference/com/android/billingclient/api/BillingClient#isFeatureSupported(java.lang.String)

Okay, figured it out, was my mistake.好吧,想通了,是我的错误。

I was calling queryPurchases() in my main activity onCreate(), but the BillingClient was not ready yet.我在我的主要活动 onCreate() 中调用了 queryPurchases(),但 BillingClient 还没有准备好。

I moved it to onBillingSetupFinished() and it now returns the correct purchases.我将它移到 onBillingSetupFinished() 并且它现在返回正确的购买。 Everything is now working as expected.现在一切都按预期工作。 You get the active subscriptions when you call queryPurchases() after an app restart.当您在应用重启后调用 queryPurchases() 时,您将获得活动订阅。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM