Android InApp结算:如何检测反向印刷中断购买流程?

时间:2013-10-07 07:59:27

标签: android in-app-purchase in-app-billing billing android-billing

我正在尝试使用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,因此我的应用程序保持中间状态。

请帮我解决问题。

5 个答案:

答案 0 :(得分: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   根据我的知识。

希望它能解决你的问题。

答案 1 :(得分: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;
        }
}

答案 2 :(得分: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                

        }
    }
};

答案 3 :(得分: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);
}

即使检查出来,它也可以帮到你

Check if back key was pressed in android?

答案 4 :(得分:0)

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

如果覆盖onActivityResult(Fragment或Activity)并在其中调用该方法(使用相同的参数调用它)。通过这种方式,帮助程序可以管理所有回调,并且可以在不启动任何异常的情况下重做购买流程。