Question

I Am trying to include in app purchase and i have successfully through in showing up SKUs available.Now I want to make a fake purchase.So I used appId = "android.test.purchased". For the first time it worked flawlessly, but from next it is throwing exception as below.

Attempt to invoke virtual method 'android.content.IntentSender android.app.PendingIntent.getIntentSender()' on a null object reference

Has anybody come across such situation?

package com.inappbilling.poc;

import java.util.ArrayList;

import org.json.JSONObject;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.android.vending.billing.IInAppBillingService;

public class TestInAppPurchase extends Activity {
    private final static String SERVICE_INTENT = "com.android.vending.billing.InAppBillingService.BIND";
    private static final String _TAG = "BILLING ACTIVITY";

    private final String _testSku = "android.test.purchased";
    //available skus
    static final String SKU_7DAYS = "7days";
    static final String SKU_30DAYS = "30days";

    private Button _7daysPurchase = null;
    private Button _30daysPurchase = null;
    private IInAppBillingService _service = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(_TAG, "created");

        _7daysPurchase = ( Button ) findViewById(R.id.sevendays_btn);
        _30daysPurchase = ( Button ) findViewById(R.id.thirtydays_btn);
        _7daysPurchase.setOnClickListener(_purchaseListener);
        _30daysPurchase.setOnClickListener(_purchaseListener);

    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    OnClickListener _purchaseListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            switch ( v.getId() ) {
            case R.id.sevendays_btn:
                doPurchase();
                break;
            case R.id.thirtydays_btn:
                break;
            }
        }
    };


    private ServiceConnection _serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {       
            _service = IInAppBillingService.Stub.asInterface( service );
            Log.d(_TAG, _service.toString());
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {     
            _service = null;
            Log.d(_TAG, "destroyed");
        }

    };

    private void doPurchase(){

        if ( _service == null) {
                Log.e( _TAG , "Billing failed: billing service is null ");
                return;
        }

        ArrayList testSku = new ArrayList( );
        testSku.add( _testSku );
        Bundle querySkus = new Bundle();
        querySkus.putStringArrayList("ITEM_ID_LIST", testSku);
        Bundle skuDetails ;
        try {
            skuDetails = _service.getSkuDetails(3, getPackageName(), "inapp", querySkus);
            int response = skuDetails.getInt("RESPONSE_CODE");
            if( response == 0 ){
                ArrayList<String> responseList = new ArrayList<String>( );
                responseList = skuDetails.getStringArrayList("DETAILS_LIST");
                for( String responseString : responseList ) {
                    JSONObject jobj = new JSONObject( responseString );
                    String sku = jobj.getString("productId");
                    if( sku.equals( _testSku )){
                         Bundle buyIntentBundle = _service.getBuyIntent(3, getPackageName(), sku ,"inapp","" );
                         PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
                         startIntentSenderForResult(pendingIntent.getIntentSender(),
                                 1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0),
                                 Integer.valueOf(0));
                    }
                }
            } else {
                Log.e( _TAG , "Failed " );
            }
        } catch (Exception e) {
            Log.e( _TAG, "Caught exception  !"+ e.getMessage() );
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == 1001 ){
            String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
            if( resultCode == RESULT_OK ){
                try{
                    JSONObject jobj = new JSONObject( purchaseData );
                    String sku = jobj.getString(_testSku);
                    String paid = jobj.getString("price");
                    Log.v("SKU DATA", sku +"============"+ paid);

                }catch( Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if( _serviceConnection != null ){
            unbindService( _serviceConnection );
        }
    }
}
Was it helpful?

Solution

Hi get to know about the solution for the prob mentioned above.To get rid of this you should clear the cache of Google play app on your android phone.When we make any in app purchase are details are maintained by the Google play services.So once the a product is purchased play Isolates the particular sku,to avoid duplicate purchase. Note - This is actually for testing purpose. Because Google play services maintains the record of all applications which have in app purchase or Oauth or any other facilities. Hope it would help some one who is facing this problem.

OTHER TIPS

When we try to purchase the already owned item we will get the null exception at Pending Intent.

So you need to check whether the product is purchased or not and then initiate the purchase only if the product is not purchased.

Product purchase state can be retrieved using the function

boolean haspurchase = inventory.hasPurchase(sku_id);

It worked for me..!!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top