Verify Purchase on Start of Activity

719 views Asked by At

I want to verify the in-app purchase when app is running for the first time & grant access of ad-free version to user. User has already purchased the app (non-consumable). I am using Google Play Billing library, the below code is working when user clicks on Remove Ads button. I am storing a flag IS_PURCHASED in pref to check purchase status. Reinstalling the app shows ads as it cannot set the flag but when I click on Remove Ads it says 'Already purchased' as expected.

MainActivity onCreate() method

        //Method storing the flag IS_PURCHASED
         setupBillingClient();
        //Setup Google billing client for app's first run
        if(settings.isFirstRun()) {
            removeAds(); 
            drawer.openDrawer(Gravity.LEFT);
        }
        Boolean isPurchased = settings.getBoolean(MainActivity.this, "IS_PURCHASED");
        RelativeLayout bottomAd = findViewById(R.id.rowAdView);
        if(isPurchased) {
            bottomAd.setVisibility(View.GONE);
        }else{
            //Load banner ad
            mBannerAd = (AdView) findViewById(R.id.banner_AdView);
            AdRequest adRequest = new AdRequest.Builder().build();
            mBannerAd.loadAd(adRequest);
        }

Menu Remove Ads setting a flag

@Override
    public boolean onNavigationItemSelected(MenuItem item) {
        Intent intent;
        // Handle navigation view item clicks here.
        int id = item.getItemId();
        Intent intentExpr;
        String expr;
        switch (id) { 
    //Remove Ads and store flag IS_PURCHASED in pref 
            case R.id.nav_remove_ads:
                removeAds();
                break;
           //other cases
      
        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

Method implementation

 public void setupBillingClient(){
        //To create a BillingClient, use newBuilder(). To receive updates on purchases, we must also call setListener(),
        // passing a reference to a PurchasesUpdatedListener. This listener receives updates for all purchases of this app.
        billingClient = BillingClient.newBuilder(MainActivity.this).enablePendingPurchases().setListener(new PurchasesUpdatedListener() {
            @Override
            //This method starts when user buys a product
            public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> list) {
                if(list != null && billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK)
                {
                    for(Purchase purchase : list)
                    {
                        handlePurchase(purchase);
                    }
                }
                else
                {
                    if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED)
                    {
                        Toast.makeText(MainActivity.this, "Please try purchasing again", Toast.LENGTH_SHORT).show();
                    }
                    else
                    {
                        if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED)
                        {
                            settings.saveBoolean(MainActivity.this, "IS_PURCHASED", true);
                            if(!settings.isFirstRun()) { //show msg for remove ad button click & not when reinstall
                                recreate(); //restart Activity to hide ads
                                Toast.makeText(MainActivity.this, "Already purchased", Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
                }
            }
        }).build();

        //After you have created a BillingClient, we need to establish a connection to Google Play.
        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK)
                {
                    Log.d("MainActivity", "Successfully connected to Billing client");
                }
                else
                {
                    Log.d("MainActivity", "Failed to connect Billing client");
                }
            }
            @Override
            public void onBillingServiceDisconnected() {
                Log.d("MainActivity", "Disconnected from the Client");
            }
        });

    }

    private void handlePurchase(Purchase purchase) {
        try {
            //On purchase set IS_PURCHASED true
            /*if(purchase.getSku().equals(productId)){
                settings.saveBoolean(MainActivity.this, "IS_PURCHASED", true);
            }*/
            //Get purchase acknowledgement
            if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
                settings.saveBoolean(MainActivity.this, "IS_PURCHASED", true); //In case purchase was acknowledge before
                if (!purchase.isAcknowledged()) {
                    AcknowledgePurchaseParams acknowledgePurchaseParams =
                            AcknowledgePurchaseParams.newBuilder()
                                    .setPurchaseToken(purchase.getPurchaseToken())
                                    .build();
                    AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = new AcknowledgePurchaseResponseListener() {
                        @Override
                        public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
                            settings.saveBoolean(MainActivity.this, "IS_PURCHASED", true);
                            recreate(); //restart activity on acknowledgement of purchase
                            Toast.makeText(MainActivity.this, "Purchase successful! Enjoy the Ad-Free version", Toast.LENGTH_SHORT).show();
                        }
                    };
                    billingClient.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
                }else{
                    recreate(); //restart activity if already acknowledged
                }
            }
        }
        catch (Exception e)
        {
            Log.d(TAG, e.getMessage());
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    public void removeAds(){
        skulist.add(productId);
        final SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
        params.setSkusList(skulist).setType(BillingClient.SkuType.INAPP);
        billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
            @Override
            public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> list) {
                if(list != null && billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK)
                {
                    for(final SkuDetails skuDetails : list)
                    {
                        String sku = skuDetails.getSku(); // your Product id
                        String price = skuDetails.getPrice(); // your product price
                        String description = skuDetails.getDescription(); // product description
                        //method opens Popup for billing purchase
                        BillingFlowParams flowParams = BillingFlowParams.newBuilder()
                                .setSkuDetails(skuDetails)
                                .build();
                        BillingResult responsecode = billingClient.launchBillingFlow(MainActivity.this,flowParams);
                    }
                }
            }
        });
    }

Also suggest if there is any other way better than this.

Thanks in advance!

1

There are 1 answers

0
deepak kulkarni On

Well I found the solution. You can check app already purchase using queryPurchases method. I was also setting the flag in wrong place. If someone is facing the same issue, call the following method in onBillingSetupFinished

    //Check already purchases using queryPurchases
    private boolean isAlreadyPurchased() {
        if (billingClient.isReady()) {
            Purchase.PurchasesResult purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
            List<Purchase> purchases = purchasesResult.getPurchasesList();
            for (Purchase pur : purchases) {
                String thisSku = pur.getSku();
                if (thisSku.equals(sku)) {
                    return true;
                }
            }
        }
        return false;
    }