机器人:Inapp计费:错误响应:7:项目已经拥有机器人、错误、项目、Inapp

2023-09-05 00:22:58 作者:忘不掉的她i

我学习来实现应用内计费我的应用程序,使得人们可以例如,捐出$时,preSS的捐赠按钮。

的用户被允许捐多于一个时间,即在购买是消耗品

在codeS下面是从TrivalDrive样品来源,并从网上一些教程:

code:

  IabHelper mHelper;
静态最后弦乐ITEM_SKU =android.test.purchased;

@覆盖
保护无效的onCreate(包savedInstanceState)
{
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_in_app_billing);

    buy10Button =(按钮)findViewById(R.id.buy10Button);
    buy15Button =(按钮)findViewById(R.id.buy15Button);
    buy20Button =(按钮)findViewById(R.id.buy20Button);

    字符串base64En codedPublicKey =keykeykey;

    mHelper =新IabHelper(这一点,base64En codedPublicKey);


    mHelper.startSetup(新IabHelper.OnIabSetupFinishedListener()
    {
          公共无效onIabSetupFinished(IabResult结果)
          {
            如果(!result.isSuccess())
            {
               Log.d(TAG,应用内计费设置失败:+结果);
               返回;
            }
            如果(mHelper == NULL)
            {
                返回;
            }
            Log.d(TAG,应用内计费设置OK);
          }
    });
}

公共无效buy10Click(查看视图)
{
    mHelper.launchPurchaseFlow(这一点,ITEM_SKU,10001,mPurchaseFinishedListener,);
}

公共无效buy15Click(查看视图)
{

}

公共无效buy20Click(查看视图)
{

}

@覆盖
保护无效onActivityResult(INT申请code,INT结果code,意图数据)
{
    如果(mHelper == NULL)回报;
    如果(!mHelper.handleActivityResult(要求code,因此code,数据))
    {
        super.onActivityResult(要求code,因此code,数据);
    }
}

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener =新IabHelper.OnIabPurchaseFinishedListener()
{
    公共无效onIabPurchaseFinished(IabResult结果,购购)
    {
        如果(mHelper == NULL)回报;
        如果(result.isFailure())
        {
           //处理错误
               返回;
        }
        否则,如果((purchase.getSku()。等于(ITEM_SKU)))
        {
           consumeItem();
        }
    }
};

公共无效consumeItem()
{
    mHelper.queryInventoryAsync(mReceivedInventoryListener);
}

IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener =新IabHelper.QueryInventoryFinishedListener()
{
    公共无效onQueryInventoryFinished(IabResult结果,库存盘点)
    {
        如果(mHelper == NULL)回报;
        如果(result.isFailure())
        {
            //处理失败
        }
        其他
        {
            mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),mConsumeFinishedListener);
        }
    }
};

IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =新IabHelper.OnConsumeFinishedListener()
{
    公共无效onConsumeFinished(购购,IabResult结果)
    {
        如果(mHelper == NULL)回报;
        如果(result.isSuccess())
        {
            Toast.makeText(InAppBillingActivity.this,谢谢您的捐款!,Toast.LENGTH_LONG).show();
        }
        其他
        {
            //处理错误
        }
    }
};
 

问:

不过,我一直在接受 E / IabHelper(13392):在应用内计费错误:无法购买物品,错误响应:7:项目已经拥有错误,并且在谷歌播放的支付对话只是没有弹出。

我已经研究并发现了许多类似的情况,有些人建议等待几分钟,然后购买将自行复位,但我已经等了将近一个小时,但仍然吮吸。

我还发现,有人建议改变IabResult 公共布尔isSuccess(){返回mResponse == IabHelper.BILLING_RESPONSE_RESULT_OK; } 也返回 BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED 作为isSuccess =真,但我不知道如何来修正这类...

怎么能这个问题能解决吗?谢谢!

解决方案

在这里查看我的跌破code:

我不明白,为什么你在购买完成监听器使用的查询库存的code。 ConsumeAsync()方法,而应该让你的SKU与您的要求的SKU是打电话。

  //回调时,购买完成
    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener =新IabHelper.OnIabPurchaseFinishedListener(){
        公共无效onIabPurchaseFinished(IabResult结果,购购){
            Log.d(TAG,购买完成:+结果+,购买
                    +购买);
            如果(result.isFailure()){
                抱怨(错误采购:+结果);
                返回;
            }
            如果(!verifyDeveloperPayload(购买)){
                抱怨(错误采购真实性验证失败。);
                返回;
            }

            Log.d(TAG,购买成功);

            如果(purchase.getSku()。等于(SKU_GAS)){

                 //从这里直接删除查询库存的方法,并把consumeAsync()
                mHelper.consumeAsync(购买,mConsumeFinishedListener);

            }

        }
    };
 

startSetup法

//你忘记打电话查询库存方法startSetup方法。

  mHelper.startSetup(新IabHelper.OnIabSetupFinishedListener(){
                公共无效onIabSetupFinished(IabResult结果){
                    Log.d(TAG,安装完毕。);

                    如果(!result.isSuccess()){
                        //呵呵不一,出现了问题。
                        抱怨(问题设置在应用内结算:+结果);
                        返回;
                    }

                    //万岁,IAB是完全成立。现在,让我们的清单
                    //我们自己的东西。
                    Log.d(TAG,设置成功查询库存。);
                    mHelper.queryInventoryAsync(mGotInventoryListener);
                }
            });
 
云宝机器人安卓版下载 云宝机器人appv1.2.1 最新版 腾牛安卓网

QueryInventoryFinishedListener

  

和还检查条件的购买是一样的,你的要求是   不等于空,开发商的有效载荷也是在查询相同   库存结束监听器。

 如果(gasPurchase = NULL和放大器;!&安培; verifyDeveloperPayload(gasPurchase)){
    // code
}
 

  //这就是所谓的,当我们完成查询项目监听器和
        //我们自己订阅
        IabHelper.QueryInventoryFinishedListener mGotInventoryListener =新IabHelper.QueryInventoryFinishedListener(){
            公共无效onQueryInventoryFinished(IabResult结果,
                    库存存货){
                Log.d(TAG,查询库存结束了。);
                如果(result.isFailure()){
                    抱怨(无法查询盘点:+结果);
                    返回;
                }

                Log.d(TAG,查询库存是成功的。);

                / *
                 *检查我们自己的项目。请注意,每次购买,我们检查
                 *开发的有效载荷,看它是否是正确的!看到
                 * verifyDeveloperPayload()。
                 * /

                // //检查气体输送 - 如果我们自己的气,我们要填补
                //坦克立即
                购买gasPurchase = inventory.getPurchase(SKU_GAS);
                如果(gasPurchase = NULL和放大器;!&安培; verifyDeveloperPayload(gasPurchase)){
                    Log.d(TAG,我们有天然气消费它。);
                    mHelper.consumeAsync(inventory.getPurchase(SKU_GAS)
                            mConsumeFinishedListener);
                    返回;
                }
            }
        };
 

释为什么可以出现:

当您购买消耗品谷歌Play商店将无法管理它购买的产品细节和其他的东西,在谷歌播放控制台。这就是为什么我们要调用consumeAsync()方法。当我们购买的物品,谷歌Play商店的保持纪录的项目已购买了一个时间,让你购买的第二次。

希望这本书能解决你的问题。

I am learning to implement an in-app billing for my app such that people can for example, donate $ when press the donate button.

The user is allowed to donate more than one time, i.e. the purchase is consumable.

The codes below are sourced from the TrivalDrive sample and some tutorials from the web:

Code:

IabHelper mHelper;
static final String ITEM_SKU = "android.test.purchased"; 

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_in_app_billing);

    buy10Button = (Button) findViewById(R.id.buy10Button); 
    buy15Button = (Button) findViewById(R.id.buy15Button); 
    buy20Button = (Button) findViewById(R.id.buy20Button);      

    String base64EncodedPublicKey = "keykeykey";

    mHelper = new IabHelper(this, base64EncodedPublicKey);


    mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() 
    {
          public void onIabSetupFinished(IabResult result) 
          {
            if (!result.isSuccess()) 
            {
               Log.d(TAG, "In-app Billing setup failed: " + result);
               return;
            } 
            if (mHelper == null) 
            {
                return;
            }          
            Log.d(TAG, "In-app Billing is set up OK");
          }
    });     
}

public void buy10Click(View view) 
{
    mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001,  mPurchaseFinishedListener, "");
}

public void buy15Click(View view) 
{

}

public void buy20Click(View view) 
{

}   

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{
    if (mHelper == null) return;  
    if (!mHelper.handleActivityResult(requestCode, resultCode, data)) 
    {     
        super.onActivityResult(requestCode, resultCode, data);
    }
}

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() 
{
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) 
    {
        if (mHelper == null) return;
        if (result.isFailure()) 
        {
           // Handle error
               return;
        }      
        else if ((purchase.getSku().equals(ITEM_SKU)))   
        {
           consumeItem();
        }              
    }
};

public void consumeItem() 
{
    mHelper.queryInventoryAsync(mReceivedInventoryListener);
}

IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener = new IabHelper.QueryInventoryFinishedListener() 
{
    public void onQueryInventoryFinished(IabResult result, Inventory inventory) 
    {
        if (mHelper == null) return;
        if (result.isFailure()) 
        {
            // Handle failure
        } 
        else 
        {
            mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU), mConsumeFinishedListener);
        }
    }
};

IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() 
{
    public void onConsumeFinished(Purchase purchase, IabResult result) 
    {
        if (mHelper == null) return;
        if (result.isSuccess()) 
        {
            Toast.makeText(InAppBillingActivity.this, "Thank you for your donation!!", Toast.LENGTH_LONG).show();   
        } 
        else 
        {
            // handle error
        }
    }
};

Question:

Yet I keep on receiving E/IabHelper(13392): In-app billing error: Unable to buy item, Error response: 7:Item Already Owned error and that the payment dialog of the Google Play just does not popup.

I have researched and found out many similar situations, some suggested to wait for a few minute and then the purchase will be reset by itself, but I have waited for almost an hour but it still sucks.

I have also found that someone suggest to change the IabResult public boolean isSuccess() { return mResponse == IabHelper.BILLING_RESPONSE_RESULT_OK; } to return also the BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED as isSuccess = true, yet i dont know how to amend such...

How could the problem be fixed? Thanks!!

解决方案

Check my below code here:

I don't understand in your code why have you used query inventory in purchase finish listener. ConsumeAsync() method should be call while you getting the sku same as your requested sku.

// Callback for when a purchase is finished
    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
            Log.d(TAG, "Purchase finished: " + result + ", purchase: "
                    + purchase);
            if (result.isFailure()) {
                complain("Error purchasing: " + result);
                return;
            }
            if (!verifyDeveloperPayload(purchase)) {
                complain("Error purchasing. Authenticity verification failed.");
                return;
            }

            Log.d(TAG, "Purchase successful.");

            if (purchase.getSku().equals(SKU_GAS)) {

                 // remove query inventory method from here and put consumeAsync() directly
                mHelper.consumeAsync(purchase, mConsumeFinishedListener);

            }

        }
    };

startSetup method

// you have forgot to call query inventory method in startSetup method.

 mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
                public void onIabSetupFinished(IabResult result) {
                    Log.d(TAG, "Setup finished.");

                    if (!result.isSuccess()) {
                        // Oh noes, there was a problem.
                        complain("Problem setting up in-app billing: " + result);
                        return;
                    }

                    // Hooray, IAB is fully set up. Now, let's get an inventory of
                    // stuff we own.
                    Log.d(TAG, "Setup successful. Querying inventory.");
                    mHelper.queryInventoryAsync(mGotInventoryListener);
                }
            });

QueryInventoryFinishedListener

And also check if condition purchase is same as you are requested is not equals to null and developer payload is also same in your query inventory finish listener.

if (gasPurchase != null && verifyDeveloperPayload(gasPurchase)){
    //code
}

// Listener that's called when we finish querying the items and
        // subscriptions we own
        IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
            public void onQueryInventoryFinished(IabResult result,
                    Inventory inventory) {
                Log.d(TAG, "Query inventory finished.");
                if (result.isFailure()) {
                    complain("Failed to query inventory: " + result);
                    return;
                }

                Log.d(TAG, "Query inventory was successful.");

                /*
                 * Check for items we own. Notice that for each purchase, we check
                 * the developer payload to see if it's correct! See
                 * verifyDeveloperPayload().
                 */

                // // Check for gas delivery -- if we own gas, we should fill up the
                // tank immediately
                Purchase gasPurchase = inventory.getPurchase(SKU_GAS);
                if (gasPurchase != null && verifyDeveloperPayload(gasPurchase)) {
                    Log.d(TAG, "We have gas. Consuming it.");
                    mHelper.consumeAsync(inventory.getPurchase(SKU_GAS),
                            mConsumeFinishedListener);
                    return;
                }
            }
        };

Explaination why it happends:

Whenever you purchased consumable item google play store will not be managed it's product purchased detail and other things in the Google play console. That's why we have to call consumeAsync() method. when we purchased item, Google play store keep record item has been purchased for the one time and allow you to purchased second time.

Hope it will solve your problem.

 
精彩推荐
图片推荐