为啥 android-inapp-billing-v3 库需要两次尝试购买?

Posted

技术标签:

【中文标题】为啥 android-inapp-billing-v3 库需要两次尝试购买?【英文标题】:Why android-inapp-billing-v3 library needs two attempts to purchase?为什么 android-inapp-billing-v3 库需要两次尝试购买? 【发布时间】:2015-02-05 09:10:44 【问题描述】:

我正在尝试使用 android-inapp-billing-v3 库在我的简单应用中实现应用内购买。我正在使用这个库(https://github.com/anjlab/android-inapp-billing-v3)

我遇到了一个奇怪的问题:您需要点击“购买”按钮两次才能购买此产品。让我一步一步解释我的意思。

我们的产品没有被购买,我们点击“购买”按钮 并出现 Google Play 窗口 在这里我们点击“购买”并看到我们的交易成功完成 然后我们点击任意位置以使 Google Play 窗口消失,而不是输入 onProductPurchased(..) nothnig hapens。 好的,我们再次点击“购买”按钮,并且无需任何其他 Google Play 窗口就可以访问 onProductPUrchased。 我不知道这是否是库中或我的实现中的某种错误。 (对不起我的英语)

这是我的代码:

public class BillingActivity extends Activity implements BillingProcessor.IBillingHandler 
    BillingProcessor bp;


    public final static String EXTRA_MESSAGE = "kepard***.client.MESSAGE";
    private String LOG_TAG = "BillingActivity";


    int mFlag;
    private String mResult;
    private String mEmail;
    private String mPassword;
    private Functions mFunctions;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        mFlag = intent.getFlags();
        mEmail = intent.getStringExtra(MainActivity.EMAIL);
        mFunctions = Globals.mFunctions;


        mPassword = intent.getStringExtra(MainActivity.PASSWORD);

        bp = new BillingProcessor(this, null, this);

        mFunctions.AddLog(2, LOG_TAG, "onCreate");
    

    // IBillingHandler implementation

    @Override
    public void onBillingInitialized() 
        /*
         * Called then BillingProcessor was initialized and its ready to purchase
         */
        mFunctions.AddLog(2, LOG_TAG, "onBillignInitilized ");
        try 
            switch (mFlag) 
                case 0: 
                    mFunctions.AddLog(2, LOG_TAG, "pay_per_month");
                    bp.purchase(this, "pay_per_month");
                
                break;
                case 1: 
                    mFunctions.AddLog(2, LOG_TAG, "pay_per_month");
                    bp.purchase(this, "pay_per_year");
                
                break;
            
         catch (Exception e) 
            mFunctions.AddLog(2, LOG_TAG, "onBillingInitialized exception:" + e.getMessage());
        
    

    @Override
    public void onProductPurchased(String productId, TransactionDetails details) 
          /*
           * Called then requested PRODUCT ID was successfully purchased
           */
        mFunctions.AddLog(2, LOG_TAG, "Product successfully puchased");
        try 
            if (bp.consumePurchase(productId))  // imediatly after puchase consume product
            
                mFunctions.AddLog(2, LOG_TAG, "onProductPurchased " + "product have been consumed");
                String obj = StringToJsonObject("action", "checkPayment", "email", mEmail, "password", mPassword,
                        "d", "android", "responseData", java.net.URLEncoder.encode(details.purchaseInfo.responseData, "utf-8"),
                        "signature", java.net.URLEncoder.encode(details.purchaseInfo.signature, "utf-8"), "response", "text");

                mFunctions.setPaymentResponseData(details.purchaseInfo.responseData);
                mFunctions.setPaymentSignature(details.purchaseInfo.signature);
                mFunctions.ActivatePayAccountTask(obj);
                //mFunctions.updatePreferences();

             else // product could not have been consumed
            
                mFunctions.AddLog(2, LOG_TAG, "onProductPurchased " + "product could not have been consumed");
            
         catch (Exception e) 
            mFunctions.AddLog(2, LOG_TAG, "onProductPurchased exception:" + e.getMessage());

        
        ;

    

    @Override
    public void onBillingError(int errorCode, Throwable error) 

        switch (errorCode) 
            case Constants.BILLING_RESPONSE_RESULT_DEVELOPER_ERROR:

                mFunctions.AddLog(2, LOG_TAG, "onBillingError," + "Invalid arguments provided to the API." + "Error code:" + errorCode);
                break;
            case Constants.BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE:
                sendMessage(getString(R.string.billing_not_supported_message));
                break;
            case Constants.BILLING_RESPONSE_RESULT_USER_CANCELED:
                mFunctions.AddLog(2, LOG_TAG, "onBillingError," + "User canceled purchase");
                break;
        
        mFunctions.AddLog(2, LOG_TAG, "Error code:" + errorCode);
    


    @Override
    public void onDestroy() 
        if (bp != null)
            bp.release();
        mFunctions.AddLog(2, LOG_TAG, "onDestroy");
        super.onDestroy();
    

    @Override
    public void onPurchaseHistoryRestored() 
        /*
         * Called then purchase history was restored and the list of all owned PRODUCT ID's
         * was loaded from Google Play
         */
        mFunctions.AddLog(2, LOG_TAG, "onPurchasedHistoryRestored");
    

    void sendMessage(String message)         
        mFunctions.ShowError(message);
    

    public String StringToJsonObject(String... val) 
        JSONObject obj = new JSONObject();
        try 
            for (int i = 0; i < val.length - 1; i += 2) 
                obj.put(val[i], val[i + 1]);
            
         catch (Exception e) 
        
        return obj.toString();
    


【问题讨论】:

【参考方案1】:

你必须添加

   @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    if (!bp.handleActivityResult(requestCode, resultCode, data))
        super.onActivityResult(requestCode, resultCode, data);

【讨论】:

以上是关于为啥 android-inapp-billing-v3 库需要两次尝试购买?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥 CAP 定理中的 RDBMS 分区不能容忍,为啥它可用?