2

我正在尝试使用 IabHelper 实现 inApp 计费服务。我设法毫无问题地完成了整个购买过程。

//-----------------------------------------------
public void billingServiceLaunchPurchase(String item) {
//-----------------------------------------------
    if (isNetworkAvailableSync(getBaseContext())) {
        currBuyItem=item;
        billingConsummeType=1;
        mHelper.launchPurchaseFlow(BaseActivity.this, item, 10001, mPurchaseFinishedListener, "");
    }
    else {
        onBillingServiceFailed();  
    }
}

    //-----------------------------------------------
    mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    //-----------------------------------------------
        public void onIabPurchaseFinished(IabResult result, Purchase purchase) 
        {
           if (result.isFailure()) {
              // Handle error
              onBillingServiceFailed();                
              return;
         }      
         else if (purchase.getSku().equals(currBuyItem)) {
             billingServiceConsumeItem();
         }

        }
    }; 

@Override
//-----------------------------------------------------------------------    
protected void onActivityResult(int requestCode, int resultCode, Intent data)
//-----------------------------------------------------------------------
{
    if (billingServiceConnected) {
          if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {     
              super.onActivityResult(requestCode, resultCode, data);
          }
          else {
              // onActivityResult handled by IABUtil.
          }
    }
    else
           super.onActivityResult(requestCode, resultCode, data);

}    

但是,当用户启动购买时,我无法检测到该事件,然后在 Google 确认屏幕上按下“购买”按钮以中断它。

它既不会触发 onIabPurchaseFinished 失败,也不会触发 onActivityResult,因此我的应用程序处于中间状态。

请帮我解决我的问题。

4

5 回答 5

4

根据我对您的问题的理解,您正在应用计费中搜索购买取消事件。

您可以通过 onActivityResult() 方法触发此操作。将以下代码放入 onActivityResult() 方法中。有一个简单的 RESEULT_CANCEL 类型显示您的用户已取消购买。

    if (mHelper == null)
                return;

            if (requestCode == 10001) {

                int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
                String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
                Log.d("INAPP_PURCHASE_DATA", ">>>" + purchaseData);
                String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
                Log.d("INAPP_DATA_SIGNATURE", ">>>" + dataSignature);
                String continuationToken = data
                        .getStringExtra("INAPP_CONTINUATION_TOKEN");
                Log.d("INAPP_CONTINUATION_TOKEN", ">>>" + continuationToken);

                if (resultCode == RESULT_OK) {
                    try {
                        Log.d("purchaseData", ">>>"+purchaseData);
                        JSONObject jo = new JSONObject(purchaseData);
                        String sku = jo.getString("productId");
                        alert("You have bought the " + sku
                                + ". Excellent choice, adventurer!");
                    } catch (JSONException e) {
                        alert("Failed to parse purchase data.");
                        e.printStackTrace();
                    }
                } else if (resultCode == RESULT_CANCELED) {

                    Toast.makeText(AppMainTest.this,
                            "Sorry, you have canceled purchase Subscription.",
                            Toast.LENGTH_SHORT).show();

                } else if (resultCode == IabHelper.BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED) {
                    Toast.makeText(AppMainTest.this, "Item already owned",
                            Toast.LENGTH_SHORT).show();
                }

            }
}

或者

您也可以使用您的业务逻辑手动处理。检查用户是否取消购买产品,然后标记用户是否已购买,如果没有,则再次调用 launchPurchaseFlow() 方法。

编辑

onDestroy() method 

@Override
    public void onDestroy() {
        super.onDestroy();

        // very important:
        Log.d(TAG, "Destroying helper.");
        if (mHelper != null)
            mHelper.dispose();
        mHelper = null;
    }

如果您有按钮,那么您可以直接将 launchPurchaseFlow() 方法调用到 onClick 事件中,以便每次您的 mHelper 创建为新购买。

或者

如果您在 onCreate 方法中使用它并且您没有任何按钮单击事件来购买产品,那么根据我的知识,您必须将值设为 null。

希望它能解决你的问题。

于 2013-10-07T09:36:47.167 回答
2

当用户按下 BACK 或在对话框外按下时,购买流程仍在进行中,如果用户再次按下 PURCHASE 按钮,将出现异常“无法启动异步操作,因为另一个异步操作正在进行中”。

为了解决这个问题,我手动创建了一个标志来了解是否有正在进行的购买流程。而且由于 IABHelper 没有提供处理购买流程的方法,我必须处理 mHelper 并调用 initBilling()

boolean onPurchaseFlow = false; 
public void purchaseItem() {
        if (!onPurchaseFlow) {
            mHelper.launchPurchaseFlow(mActivity, SKU_PREMIUM, RC_REQUEST, mPurchaseFinishedListener, "");
            onPurchaseFlow = true;
        } else {
    //dispose mHelper       
    if (mHelper != null) {
            mHelper.dispose();
            mHelper = null;
            }

            initBilling(mActivity); // restart IABHelper, a code snippet will fire launchPurchaseFlow when onPurchaseFlow is true
        }
        }

另一个重要部分是在 onQueryInventoryFinished() 中调用 launchPurchaseFlow 以确保在所有 init 操作完成后(在用户的第二次请求中)调用它:

public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
        // YOUR CODE HERE
        if (onPurchaseFlow == true) {
        mHelper.launchPurchaseFlow(mActivity, SKU_PREMIUM, RC_REQUEST, mPurchaseFinishedListener, "");
        }
    }

请记住在 onIabPurchaseFinished() 中完成时重置标志 onPurchaseFlow = false

    public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
            Log.d(TAG, "Purchase successful.");

            if (purchase.getSku().equals(SKU_PREMIUM)) {
            // bought the premium upgrade!
            // YOUR CODE HERE
            onPurchaseFlow = false;
        }
}
于 2015-04-19T10:37:49.970 回答
2

您可以通过 IabResult 类访问结果代码,并将其与 IabHelper 类中的不同结果代码进行比较,并在您的 OnIabPurchaseFinishedListener 中使用它:

    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
        = new IabHelper.OnIabPurchaseFinishedListener() {
    public void onIabPurchaseFinished(IabResult result, Purchase purchase)
    {            

        if (result.isFailure()) {

            if (result.getResponse() == IabHelper.BILLING_RESPONSE_RESULT_USER_CANCELED  || result.getResponse() == IabHelper.IABHELPER_USER_CANCELLED){

                // user cancelled purchase

            } else {

            // any oder reasult

            }
            return;
        }

        else if (purchase.getSku().equals(SKU_SPIRIT_LEVEL)) {

            // no error, purchase succeeded                

        }
    }
};
于 2017-03-30T11:24:19.927 回答
0

您可以通过此方法检测后压覆盖

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
//do what you want to avoid going back while during transaction
Log.d("bak button pressed", "ture");
}
return super.onKeyDown(keyCode, event);
}

甚至检查一下,它可能会帮助你

检查是否在android中按下了返回键?

于 2013-10-07T08:56:24.417 回答
0

在 IabHelper 中有一个名为 handleActivityResult(...) 的方法。

如果您覆盖 onActivityResult (片段或活动)并在内部调用该方法(使用相同的参数调用它)。通过这种方式,助手管理所有回调并且可以重做购买流程而不会引发任何异常。

于 2016-06-14T15:57:50.847 回答