java 在应用内结算(IAB 版本 3)android 中恢复购买
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13890007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Restore purchases in In-app Billing (IAB Version 3) android
提问by Bhavesh Hirpara
Google has upgraded to IAB3(In App Billing version 3).
First what a issue in example code.. super.onDestroy()
is missed.
Google 已升级到 IAB3(In App Billing 版本 3)。首先,super.onDestroy()
错过了示例代码中的一个问题。
I implemented v3 with the help of http://developer.android.com/google/play/billing/billing_integrate.html
我在http://developer.android.com/google/play/billing/billing_integrate.html的帮助下实现了 v3
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
?
我的问题是,我没有看到用于恢复交易的 API。如何使用 IAB3 恢复购买?是吗mService.getPurchases(apiVersion, packageName, type, continuationToken)
。有没有人测试过这个??这是从本地存储的物品中退回购买的物品还是恢复购买的物品?卸载应用程序没有continuationToken
。应该是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.
谷歌更新了应用内计费库并解决了这个super.onDestroy()
问题。他们还添加了一些附加功能。
回答by Deepanshu
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();
}
}
回答by Cjames
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.
在您的 IabHelper.java 中,这是您 /android-sdk/extras/google/play_billing/samples/ 中的一个示例,将此代码用于获取用户已购买的所有项目。这将返回购买数据的 JSON 数组。您还可以使用 Purchase.java 进行解析,它也可以在示例文件夹中找到。
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.
我希望这能帮到您。^_^ 谢谢。