Restore purchases in In-app Billing (IAB Version 3) android

点点圈 提交于 2019-12-30 03:02:06

问题


Google has upgraded to IAB3(In App Billing version 3). First what a issue in example code.. super.onDestroy() is missed.

I implemented v3 with the help of http://developer.android.com/google/play/billing/billing_integrate.html

It is tested on phone, does not work in emulator.It stuck in emulator.

My issue is, I did not see the API for restoring transactions. How can I restore purchases with IAB3? Is it mService.getPurchases(apiVersion, packageName, type, continuationToken). Has anyone tested this?? Does this returns purchased items from locally stored items or does it restore purchased items? Uninstalling application does not have continuationToken. Should it be null?

And What about when the purchase state changes??

Please help!

Thanks in advance.

EDIT :

Google has updated the In app billing library and solved the super.onDestroy() issue. They have also added some additional features.


回答1:


To make item consumable you have to sent a consume request and you have to do that in separate thread.

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 1111) {
        int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
        String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
        String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
        Logger.printMessage(TAG, "on activity result reponse"
                + responseCode, Logger.DEBUG);
        if (resultCode == RESULT_OK && responseCode == 0) {
            try {
                JSONObject jo = new JSONObject(purchaseData);
                String sku = jo.getString("productId");
                String title = jo.getString("title");
                addChipsToBalance(sku);
                final String token = jo.getString("purchaseToken");
                Toast.makeText(BuyChipsActivity.this,
                        "You have bought " + title + ". Enjoy the game!",
                        Toast.LENGTH_SHORT).show();

                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        Logger.printMessage(TAG, "inside run", Logger.DEBUG);
                        try {
                            int response = mService.consumePurchase(3,
                                    getPackageName(), token);
                            Logger.printMessage(TAG, "inside run response"
                                    + response, Logger.DEBUG);
                        } catch (RemoteException e) {
                            // TODO Auto-generated catch block
                            Logger.printMessage(TAG, "exception here 1",
                                    Logger.DEBUG);
                            e.printStackTrace();
                        }
                    }
                }).start();
                // alert("You have bought the " + sku +
                // ". Excellent choice,  adventurer!");
            } catch (JSONException e) {
                // alert("Failed to parse purchase data.");
                e.printStackTrace();
            }
        }
    }

But sometimes consume request is not completed on google end so you may want to query the purchased item list and consume it with the purchase token. I did like this

   private void showPreviousPurchases() {
    Logger.printMessage(TAG, "previous purchases", Logger.DEBUG);
    if (mService == null) {
        Toast.makeText(this, "Something Went Wrong. Try later",
                Toast.LENGTH_LONG).show();
        return;
    }
    Bundle ownedItems = null;
    ;
    try {
        ownedItems = mService.getPurchases(3, getPackageName(), "inapp",
                null);
    } catch (RemoteException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    if (ownedItems == null) {
        Logger.printMessage(TAG, "criical error ", Logger.DEBUG);
        return;
    }
    int response = ownedItems.getInt("RESPONSE_CODE");
    if (response == 0) {
        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");*/

        for (int i = 0; i < purchaseDataList.size(); ++i) {
            String purchaseData = purchaseDataList.get(i);
            Logger.printMessage(TAG, "json  = " + purchaseData,
                    Logger.DEBUG);
            // String signature = signatureList.get(i);
            String sku = ownedSkus.get(i);

            addChipsAndMakeItConsumable(purchaseData);
            // do something with this purchase information
            // e.g. display the updated list of products owned by user
        }

        // if continuationToken != null, call getPurchases again
        // and pass in the token to retrieve more items
    }

}

private void addChipsAndMakeItConsumable(String purchaseData) {

    try {
        JSONObject jo = new JSONObject(purchaseData);
        String sku = jo.getString("productId");
        // String title = jo.getString("title");
        addChipsToBalance(sku);
        final String token = jo.getString("purchaseToken");
        Logger.printMessage(TAG, "id  = " + sku, Logger.DEBUG);

        Logger.printMessage(TAG, "inside run", Logger.DEBUG);
        try {
            int response = mService.consumePurchase(3, getPackageName(),
                    token);
            Logger.printMessage(TAG, "inside run response" + response,
                    Logger.DEBUG);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            Logger.printMessage(TAG, "exception here 1", Logger.DEBUG);
            e.printStackTrace();
        }

        // alert("You have bought the " + sku +
        // ". Excellent choice,  adventurer!");
    } catch (JSONException e) {
        // alert("Failed to parse purchase data.");
        e.printStackTrace();
    }
}



回答2:


In your IabHelper.java which is an example in your /android-sdk/extras/google/play_billing/samples/ put this code to get all the item that has been purchased by the user. This will return an JSON array of purchased data. You can also used Purchase.java to parse with, which is available also in the samples folder.

     public ArrayList<String> getAllPurchases() throws RemoteException{
     Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName(),"inapp", null);

     int response = getResponseCodeFromBundle(ownedItems);
     logDebug("Owned items response: " + String.valueOf(response));
     if (response != BILLING_RESPONSE_RESULT_OK) {
         logDebug("getPurchases() failed: " + getResponseDesc(response));

     }
     if (!ownedItems.containsKey(RESPONSE_INAPP_ITEM_LIST)
             || !ownedItems.containsKey(RESPONSE_INAPP_PURCHASE_DATA_LIST)
             || !ownedItems.containsKey(RESPONSE_INAPP_SIGNATURE_LIST)) {
         logError("Bundle returned from getPurchases() doesn't contain required fields.");
     }

     ArrayList<String> purchaseDataList = ownedItems.getStringArrayList(RESPONSE_INAPP_PURCHASE_DATA_LIST);
     return purchaseDataList;
}

And into your Main activity

 public class MainActivity extends Activity{
  private IabHelper mHelper;
      private String arrayString;
      public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);

    mHelper = new IabHelper(this,"YOUR PUBLIC KEY" );
      mHelper.enableDebugLogging(true);
      mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {

        public void onIabSetupFinished(IabResult result) {

        if (!result.isSuccess()) { // Oh noes, there was a problem.
            Toast.makeText(this,"Problem setting up in-app billing: " + result,Toast.LENGTH_LONG).show();
              return;
          }

        arrayString=mHelper.getAllPurchases().toString();

        Log.d("Purchases: ",""+arrayString);


        array = new JSONArray(arrayString);

        for (int i = 0; i < array.length(); i++) {
            JSONObject row = array.getJSONObject(i);    
            productId=row.getString("productId");  //this will get the product id's that has been purchased.

            Log.e("To be restored:", " PRODUCT ID's "+productId);
        }

      });         
    }
}

I hope this will help you. ^_^ Thanks.



来源:https://stackoverflow.com/questions/13890007/restore-purchases-in-in-app-billing-iab-version-3-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!