Java 在android应用内计费(IAB版本3)中恢复购买

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)。有人测试过这个吗??这是从本地存储的项目返回已购买的项目,还是还原已购买的项目? 卸载应

谷歌已经升级到IAB3(应用内计费版本3)。 首先,示例代码中存在什么问题<代码>super.ondestory()丢失

我在的帮助下实现了v3

它是在手机上测试的,在模拟器中不起作用。它在模拟器中卡住了

我的问题是,我没有看到用于恢复事务的API。如何使用IAB3恢复购买?是不是
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