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.
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();
}
}