implementing in app purchase on android

308 views Asked by At

I am in the process of implementing in purchases for my app on eclipse but Im stuck on this part where you have to call getSkuDetails

Bundle skuDetails = mService.getSkuDetails(3, getPackageName(), "inapp", querySkus);

The android implementation guide -> http://developer.android.com/google/play/billing/billing_integrate.html

Tells me

"Warning: Do not call the getSkuDetails method on the main thread. Calling this method triggers a network request which could block your main thread. Instead, create a separate thread and call the getSkuDetails method from inside that thread."

My only problem is I dont know how to call another thread inside my main activity or how to go about doing it since I've never done it before, thanks to anybody who can help me been stuck on this for the past week

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    connection = new ServiceConnection() {

           @Override
           public void onServiceDisconnected(ComponentName name) {

               mService = null;

           }

           @Override
           public void onServiceConnected(ComponentName name, IBinder service) {

               mService = IInAppBillingService.Stub.asInterface(service);

           }
        };


        Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");

        serviceIntent.setPackage("com.android.vending");
        bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE);


}

public void levelTwoButtonClicked(){

    Assets.click.play(1.00f);

    new LoadIconTask().execute();

}

class LoadIconTask extends AsyncTask<Integer, Integer, Long> {

    @Override
    protected Long doInBackground(Integer... params) {

        ArrayList<String> skuList = new ArrayList<String>();
        skuList.add(inappid);
        Bundle querySkus = new Bundle();
        querySkus.putStringArrayList("ITEM_ID_LIST", skuList);
        Bundle skuDetails;      

    try{

            skuDetails = mService.getSkuDetails(3, getPackageName(), "inapp", querySkus);

            int response = skuDetails.getInt("RESPONSE_CODE");
            if(response == 0){

                ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");

                for(String thisResponse : responseList){

                    JSONObject object = new JSONObject(thisResponse);
                    String sku = object.getString("productID");
                    String price = object.getString("price");

                    if(sku.equals(inappid)){

                        System.out.println("price" + price);
                        Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(), sku, "inapp", "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
                        PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
                        startIntentSenderForResult(pendingIntent.getIntentSender(), 1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));

                    }

                }

            }
        } catch (RemoteException e){
            e.printStackTrace();
        } catch (JSONException e){
            e.printStackTrace();
        } catch (SendIntentException e){
            e.printStackTrace();
        }


        return null;
    }


}

Each time I run and click on my Buy level two button I get this error

06-07 20:16:26.102: E/AndroidRuntime(19783): FATAL EXCEPTION: AsyncTask #2
06-07 20:16:26.102: E/AndroidRuntime(19783): java.lang.RuntimeException: An error occured while executing doInBackground()
06-07 20:16:26.102: E/AndroidRuntime(19783):    at android.os.AsyncTask$3.done(AsyncTask.java:278)
06-07 20:16:26.102: E/AndroidRuntime(19783):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
06-07 20:16:26.102: E/AndroidRuntime(19783):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
06-07 20:16:26.102: E/AndroidRuntime(19783):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
06-07 20:16:26.102: E/AndroidRuntime(19783):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
06-07 20:16:26.102: E/AndroidRuntime(19783):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
06-07 20:16:26.102: E/AndroidRuntime(19783):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-07 20:16:26.102: E/AndroidRuntime(19783):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-07 20:16:26.102: E/AndroidRuntime(19783):    at java.lang.Thread.run(Thread.java:856)
06-07 20:16:26.102: E/AndroidRuntime(19783): Caused by: java.lang.NullPointerException
06-07 20:16:26.102: E/AndroidRuntime(19783):    at com.izzymachado.framework.implementation.AndroidGame$LoadIconTask.doInBackground(AndroidGame.java:198)
06-07 20:16:26.102: E/AndroidRuntime(19783):    at com.izzymachado.framework.implementation.AndroidGame$LoadIconTask.doInBackground(AndroidGame.java:1)
06-07 20:16:26.102: E/AndroidRuntime(19783):    at android.os.AsyncTask$2.call(AsyncTask.java:264)
06-07 20:16:26.102: E/AndroidRuntime(19783):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

line 198 is skuDetails = mService.getSkuDetails(3, getPackageName(), "inapp", querySkus);

1

There are 1 answers

13
Booger On BEST ANSWER

You are not allowed to make network calls on the main thread, this is due to the fact that you don't want to block the user from performing actions while this is happenning.

So, you should use an AsyncTask for this operation, which will make the network call in the background, then notify you, so you can make changes to the UI (back on the UI thread).