anjlab / android-inapp-billing-v3

A lightweight implementation of Android In-app Billing Version 3
Other
2.2k stars 536 forks source link

Retrieves listOwnedProducts only when in background #550

Open jansvanda opened 2 months ago

jansvanda commented 2 months ago

Hi there,

Recently I upgraded my app from SDK 29 to 34 and something weird happens:

I came along a weird bug. (@serggl I feel like you could be interested).

I had problems for two days to retrieve owned Products from this library. Sometimes it worked, but in 95% cases it did not work and my app told me whole time that I have nothing purchased yet.

You say here, that this gets called when everything is loaded from the history: ` @Override public void onPurchaseHistoryRestored() { /*

This is my code at the start of the app inside my SplashActivity.java:

bp = BillingProcessor.newBillingProcessor(this, LICENSE_KEY, MERCHANT_ID, new BillingProcessor.IBillingHandler() {
            @Override
            public void onProductPurchased(@NonNull String productId, @Nullable PurchaseInfo purchaseInfo) {
            }
            @Override
            public void onBillingError(int errorCode, @Nullable Throwable error) {
                showToast("onBillingError: " + errorCode);
                Log.d("FUCK", "onBillingError: " + errorCode);
            }
            @Override
            public void onBillingInitialized() {
                Log.d("FUCK", "Billing init");

            }
            @Override
            public void onPurchaseHistoryRestored() {

                Log.d("FUCK", "called onPurchaseHistoryRestored");
                for(String sku : bp.listOwnedProducts()){
                    Log.d("FUCK", "Owned Managed Product: " + sku);

                    if (sku.equals(PRODUCT_ID)){
                        Log.i("FUCK", "Activating SKU: " + sku);
                        prefs.edit().putBoolean("purchased", true).apply();
                        prefs.edit().putString("key_paid", "paid").apply();
                        binding.imageProSplash.setVisibility(View.VISIBLE);
                    } else {
                        Log.e("billing", "setting unpaid");
                        prefs.edit().putBoolean("purchased", false).apply();
                        prefs.edit().putString("key_paid", "unpaid").apply();
                        binding.imageProSplash.setVisibility(View.VISIBLE);
                    }
                }
            }
        });
    bp.initialize();

Now with normally screen on and app deployed the Logs are following:

image

BUT with screen off during installation of the app to the device, i got following Logs:

image

Can you anyone tell me if this is correct? I don't have the feeling this is right. Also I don't wanna push this into release... It doesn't retrieve the purchased products!

Using version: 2.2.0

minSdkVersion 26
targetSdkVersion 34
compileSdk 34
buildToolsVersion '34.0.0'
 implementation 'com.android.billingclient:billing:7.0.0'
    implementation 'com.android.billingclient:billing-ktx:7.0.0'
jansvanda commented 2 months ago

Oh I missed to tell the part how I came to try this solution.. I searched for onPurchaseHistoryRestored in the code and found this line https://github.com/anjlab/android-inapp-billing-v3/blob/a13bb215b1176eac9d1d78322262de2bd237303e/library/src/main/java/com/anjlab/android/iab/v3/BillingProcessor.java#L130 Which I don't even know why somhow rang my bell and I tried to "background" the app while the process. And voila - it helped...

Does this not happen in production? I mean i got a version of older anjlab billing plugin on google play and there it works great.

jansvanda commented 2 months ago

Guys, i am not lying - this is some weird stuff here. My purchased products get retrieved only when i close the app or turn the phone's screen off. I am testing on a OnePlus 6 running Android 11, with signed debug apk, same versioncode and name as the one uploaded on Gplay. Any help would be much appreciated.

jansvanda commented 2 months ago

Okay seems like i used it wrong all the time. This is what works now each time: `private void initBillingClient() { bp = BillingProcessor.newBillingProcessor(this, LICENSE_KEY, MERCHANT_ID, new BillingProcessor.IBillingHandler() { @Override public void onProductPurchased(@NonNull String productId, @Nullable PurchaseInfo purchaseInfo) { //showToast("onProductPurchased: " + productId); Log.d("HansBilling","Purchased "+productId); } @Override public void onBillingError(int errorCode, @Nullable Throwable error) { showToast("onBillingError: " + errorCode); Log.d("HansBilling", "onBillingError: " + errorCode); } @Override public void onBillingInitialized() { //showToast("onBillingInitialized"); Log.d("HansBilling", "Billing init"); }

        @Override
        public void onPurchaseHistoryRestored() {
            Log.d("HansBilling", "called onPurchaseHistoryRestored");

            bp.loadOwnedPurchasesFromGoogleAsync(new IPurchasesResponseListener() {
                @Override
                public void onPurchasesSuccess() {
                    if (bp.isPurchased(PRODUCT_ID)) {
                        showToast("Máte zakoupenou verzi PRO, aktivuji ...");
                        prefs.edit().putBoolean("purchased", true).apply();
                        prefs.edit().putString("key_paid", "paid").apply();
                        binding.imageProSplash.setVisibility(View.VISIBLE);
                    }
                }

                @Override
                public void onPurchasesError() {
                    Log.d("HansBilling", "purchase error" );

                }
            });

            for(String sku : bp.listOwnedProducts()){
                Log.d("HansBilling", "Owned Managed Product: " + sku);

                if (sku.equals(PRODUCT_ID)){
                    showToast("Máte zakoupenou verzi PRO, aktivuji ...");
                    Log.i("HansBilling", "Activating SKU: " + sku);
                    prefs.edit().putBoolean("purchased", true).apply();
                    prefs.edit().putString("key_paid", "paid").apply();
                    binding.imageProSplash.setVisibility(View.VISIBLE);
                } else {
                    Log.e("billing", "setting unpaid");
                    prefs.edit().putBoolean("purchased", false).apply();
                    prefs.edit().putString("key_paid", "unpaid").apply();
                    binding.imageProSplash.setVisibility(View.VISIBLE);
                }
            }
        }
    });

    bp.initialize();

}`