Java 在android应用内计费(IAB版本3)中恢复购买
谷歌已经升级到IAB3(应用内计费版本3)。 首先,示例代码中存在什么问题<代码>super.ondestory()丢失 我在的帮助下实现了v3 它是在手机上测试的,在模拟器中不起作用。它在模拟器中卡住了 我的问题是,我没有看到用于恢复事务的API。如何使用IAB3恢复购买?是不是Java 在android应用内计费(IAB版本3)中恢复购买,java,android,in-app-purchase,in-app-billing,Java,Android,In App Purchase,In App Billing,谷歌已经升级到IAB3(应用内计费版本3)。 首先,示例代码中存在什么问题super.ondestory()丢失 我在的帮助下实现了v3 它是在手机上测试的,在模拟器中不起作用。它在模拟器中卡住了 我的问题是,我没有看到用于恢复事务的API。如何使用IAB3恢复购买?是不是mService.getPurchases(apiVersion、packageName、type、continuationToken)。有人测试过这个吗??这是从本地存储的项目返回已购买的项目,还是还原已购买的项目? 卸载应
mService.getPurchases(apiVersion、packageName、type、continuationToken)
。有人测试过这个吗??这是从本地存储的项目返回已购买的项目,还是还原已购买的项目?
卸载应用程序没有continuationToken
。是否应该为null
那么当购买状态发生变化时呢
请帮忙
提前谢谢
编辑:
谷歌已经更新了应用内计费库,并解决了super.onDestroy()
问题。
他们还添加了一些附加功能。要使物品可消费,您必须发送一个消费请求,并且必须在单独的线程中执行
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();
}
}
}
但有时消费请求在google端没有完成,所以您可能需要查询购买的物品列表,并使用购买令牌进行消费。我确实喜欢这个
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();
}
}
private void showPreviousPurchases(){
Logger.printMessage(标记“以前的购买”,Logger.DEBUG);
if(mService==null){
Toast.makeText(这是“出错了,请稍后再试”,
Toast.LENGTH_LONG).show();
返回;
}
Bundle ownedItems=null;
;
试一试{
ownedItems=mService.getPurchases(3,getPackageName(),“inapp”,
无效);
}捕获(远程异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
如果(ownedItems==null){
Logger.printMessage(标记“critical error”,Logger.DEBUG);
返回;
}
int response=ownedItems.getInt(“响应代码”);
如果(响应==0){
ArrayList ownedSkus=ownedItems
.getStringArrayList(“INAPP采购项目清单”);
ArrayList purchaseDataList=ownedItems
.getStringArrayList(“INAPP采购数据列表”);
/*ArrayList signatureList=ownedItems
.getStringArrayList(“INAPP_数据_签名”);
字符串continuationToken=ownedItems
.getString(“INAPP_延续_标记”)*/
对于(int i=0;i
在您的IabHelper.java中,它是/android sdk/extras/google/play\u billing/samples/put中的一个示例,该代码用于获取用户购买的所有项目。这将返回购买数据的JSON数组。您还可以使用Purchase.java进行解析,也可以在samples文件夹中找到
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;
}
public ArrayList getAllPurchases()引发RemoteException{
Bundle ownedItems=mService.getPurchases(3,mContext.getPackageName(),“inapp”,null);
int response=getResponseCodeFromBundle(ownedItems);
logDebug(“所属项目响应:+String.valueOf(响应));
如果(响应!=计费\u响应\u结果\u确定){
logDebug(“getPurchases()失败:“+getResponseDesc(response));
}
如果(!ownedItems.containsKey)(应用项列表中的响应)
||!ownedItems.containsKey(应用程序采购数据列表中的响应)
||!ownedItems.containsKey(在应用程序签名列表中的响应)){
logError(“从getPurchases()返回的包不包含必填字段。”);
}
ArrayList purchaseDataList=ownedItems.getStringArrayList(在app\u purchaseDataList中的响应);
返回purchaseDataList;
}
然后进入你的主要活动
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);
}
});
}
}
公共类MainActivity扩展活动{
私人助理员;
私有字符串数组;
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mHelper=new IabHelper(这是“您的公钥”);
mHelper.enableDebugLogging(true);
mHelper.startSetup(新的IabHelper.OnIabSetupFinishedListener(){
已完成公共void ONIBS设置(IAB结果){
如果(!result.issucess()){//Oh noes,则出现问题。
Toast.makeText(这是“设置应用内账单的问题:”+res