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