Daniele
Daniele

Reputation: 4343

Android In-App Billing: Ads are not removing when In-App is made

I have implemented In-App Billing in my Activity

this is my onIabPurchaseFinished() method:

@Override
public void onIabPurchaseFinished(IabResult result, Purchase info) {

    if (!verifyDeveloperPayload(info)) {
        Toast.makeText(this, R.string.error_purchasing, Toast.LENGTH_LONG).show();
    }

    Toast.makeText(this, R.string.premium_bought, Toast.LENGTH_LONG).show();

    if (info.getSku().equals("chords_premium")) {

        /** salva isPremium tra SharedPreferences */
        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.putString("status", "purchased");
        editor.apply();
    }
}

As you can see I save the String "status" to SharedPreferences so that I can access it from anywhere, and keep it stored even after the app is closed.

Then in my other Activities where ads are implemented I wrote like this:

final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    final String status = prefs.getString("status", "free");


    /** gestisce le pubblicita */
    if (status.equals("free")) {
        MobileAds.initialize(getApplicationContext(), "ca-app-pub-6723047396589178/2654753246");

        AdView listBanner = (AdView) findViewById(R.id.chords_list_banner);
        AdRequest adRequest = new AdRequest.Builder().build();
        listBanner.loadAd(adRequest);

        /** carica Ad a tutto schermo */
        chordsListAd = new InterstitialAd(this);
        chordsListAd.setAdUnitId("ca-app-pub-6723047396589178/7447672046");
        requestNewInterstitial();


        chordsListAd.setAdListener(new AdListener() {
            @Override
            public void onAdClosed() {
                requestNewInterstitial();
            }
        });
    }

As you can see here the Ads are surrounded by an if statement that checks if the "status"String is set to free.

The problem is that when I buy Premium, the Ads are still shown. How can I fix it?

Upvotes: 0

Views: 413

Answers (2)

kgandroid
kgandroid

Reputation: 5595

Check if the inapp purchase is made:

//*************************************checking in app purchase has been made********************************// 
    void testInApp()
    {
        if (!blnBind) return;
        if (mService == null) return;

        int result;
        try {
            result = mService.isBillingSupported(3, getPackageName(), "inapp");

            //Toast.makeText(context, "isBillingSupported() - success : return " + String.valueOf(result), Toast.LENGTH_SHORT).show();
            Log.i(tag, "isBillingSupported() - success : return " + String.valueOf(result));
        } catch (RemoteException e) {
            e.printStackTrace();

            //Toast.makeText(context, "isBillingSupported() - fail!", Toast.LENGTH_SHORT).show();
            Log.w(tag, "isBillingSupported() - fail!");
            return;
        } 
    }

    void checkInApp()
    {

        if (!blnBind) return;
        if (mService == null) return;

        Bundle ownedItems;
        try {
            ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);

            //Toast.makeText(context, "getPurchases() - success return Bundle", Toast.LENGTH_SHORT).show();
            Log.i(tag, "getPurchases() - success return Bundle");
        } catch (RemoteException e) {
            e.printStackTrace();

            //Toast.makeText(context, "getPurchases - fail!", Toast.LENGTH_SHORT).show();
            Log.w(tag, "getPurchases() - fail!");
            return;
        }

        int response = ownedItems.getInt("RESPONSE_CODE");
        //Toast.makeText(context, "getPurchases() - \"RESPONSE_CODE\" return " + String.valueOf(response), Toast.LENGTH_SHORT).show();
        Log.i(tag, "getPurchases() - \"RESPONSE_CODE\" return " + String.valueOf(response));

        if (response != 0) return;

        ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
        ArrayList<String> purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
        ArrayList<String> signatureList = ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE");
        String continuationToken = ownedItems.getString("INAPP_CONTINUATION_TOKEN");

        Log.i(tag, "getPurchases() - \"INAPP_PURCHASE_ITEM_LIST\" return " + ownedSkus.toString());
        Log.i(tag, "getPurchases() - \"INAPP_PURCHASE_DATA_LIST\" return " + purchaseDataList.toString());
        Log.i(tag, "getPurchases() - \"INAPP_DATA_SIGNATURE\" return " + (signatureList != null ? signatureList.toString() : "null"));
        Log.i(tag, "getPurchases() - \"INAPP_CONTINUATION_TOKEN\" return " + (continuationToken != null ? continuationToken : "null"));

        // TODO: management owned purchase  


        try {


            if(purchaseDataList.size()>0){
                jinapp=new JSONArray(purchaseDataList.toString());
                JSONObject c =  jinapp.getJSONObject(0);

                String productid=c.getString("productId");

                if(productid!=null){
                    SharedPreferences.Editor editor = prefpurchase.edit();
                    editor.putBoolean(Constants.APP_IS_PURCHASED,true);
                    editor.commit();
                }
            }   
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // TODO: management owned purchase  

    }

Write the code in your SplashScreen

Now in the activity/fragment in which you are showing your ad,write the following code:

//*******************to check purchase has been made.If yes disable ads and no then show ads******************//
        prefpurchase = this.getSharedPreferences(Constants.GET_IN_APP_STATE, Context.MODE_PRIVATE);

        //Toast.makeText(context, "bindService - return " + String.valueOf(blnBind), Toast.LENGTH_SHORT).show();

        //In App Purchase

        ispurchased=prefpurchase.getBoolean(Constants.APP_IS_PURCHASED,false);
        System.out.println("ispurchased-->"+ispurchased);
        if(ispurchased)
        {
            setContentView(R.layout.activity_home_noads);

        }else{
            System.out.println("Getting ad");
            setContentView(R.layout.activity_home);
            //Locate the Banner Ad in activity_main.xml
            AdView adView = (AdView) this.findViewById(R.id.adView);
            AdRequest adRequest = new AdRequest.Builder()
            // Add a test device to show Test Ads
            //.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
            //.addTestDevice("B2D63***************************")
            .build();


            // Load ads into Banner Ads
            adView.loadAd(adRequest);
        }
    //*******************************************************************************************************//

The logic is simple,you are creating two versions of your layout,one with ad and the other without ad.

Load the correct layout depending on the value of sharedpreference.

mService:

Write this code globally in splashscreen before onCreate():

private IInAppBillingService mService;
    private ServiceConnection mServiceConn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mService = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = IInAppBillingService.Stub.asInterface(service);
        }
    };

blnBind

Declare blnBind globally:

boolean blnBind;

In onCreate() of SplashActivity write:

// Bind Service
        blnBind = bindService(new Intent(
                "com.android.vending.billing.InAppBillingService.BIND"),
                mServiceConn, Context.BIND_AUTO_CREATE);

        //Toast.makeText(context, "bindService - return " + String.valueOf(blnBind), Toast.LENGTH_SHORT).show();
        Log.i(tag, "bindService - return " + String.valueOf(blnBind)); 
        //In App Purchase

GET_IN_APP_STATE or APP_IS_PURCHASED are created for shared Preferences,that acts as a key for preference values.

//Preferences to check in app purchase
    final static public String GET_IN_APP_STATE = "prefinapp";
    public static final String APP_IS_PURCHASED ="AppIsPurchased";

Whenever a purchase is made,don't forget to set the shared preference value to true.

Upvotes: 1

aman shivhare
aman shivhare

Reputation: 334

It's because you are saving your data in Base Context and trying to find it in the current Activity context using (this).

final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);

to

final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());

Also, a more recommeded way to query In-App purchased items is to query In- App inventory instead of storing in sharedprefs.

As mention in Google Docs

Query Purchased Items

Upon a successful purchase, the user’s purchase data is cached locally by Google Play’s In-app Billing service. It is good practice to frequently query the In-app Billing service for the user’s purchases, for example whenever the app starts up or resumes, so that the user’s current in-app product ownership information is always reflected in your app.

To retrieve the user’s purchases from your app, call queryInventoryAsync(QueryInventoryFinishedListener) on your IabHelper instance. The QueryInventoryFinishedListener argument specifies a listener that is notified when the query operation has completed and handles the query response. It is safe to make this call fom your main thread.

mHelper.queryInventoryAsync(mGotInventoryListener); //mHelper is IabHelper instance

If the query is successful, the query results are stored in an Inventory object that is passed back to the listener. The In-app Billing service returns only the purchases made by the user account that is currently logged in to the device.

IabHelper.QueryInventoryFinishedListener mGotInventoryListener
   = new IabHelper.QueryInventoryFinishedListener() {
   public void onQueryInventoryFinished(IabResult result,
      Inventory inventory) {

      if (result.isFailure()) {
        // handle error here
      }
      else {
        // does the user have the premium upgrade?
        mIsPremium = inventory.hasPurchase(SKU_PREMIUM);
        // update UI accordingly
      }
   }
};

Upvotes: 1

Related Questions