简体   繁体   中英

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

I have an app with a subscription in 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,

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. 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. (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.

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. If I clear the app datam or reinstall the app then they return the purchase (once), then again null after restart.

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?

2 - is there a different API that your suppose to use to check the status of a subscription?

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?

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.

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. 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.

I also don't see how you're using 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 . And for the time being avoid trusting queryPurchases() :

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. 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.

By the way what's the value of isReady() right before queryPurchaseHistoryAsync , and what's the value of BillingResult::getDebugMessage and BillingResult::getResponseCode ?

Also, use isFeatureSupported , though it seems it's not like your problem is coming from here. 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)

Okay, figured it out, was my mistake.

I was calling queryPurchases() in my main activity onCreate(), but the BillingClient was not ready yet.

I moved it to onBillingSetupFinished() and it now returns the correct purchases. Everything is now working as expected. You get the active subscriptions when you call queryPurchases() after an app restart.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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