Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android OnIabPurchaseFinishedListener返回IABHELPER\u错误\u响应_Android_In App Purchase_In App Billing - Fatal编程技术网

Android OnIabPurchaseFinishedListener返回IABHELPER\u错误\u响应

Android OnIabPurchaseFinishedListener返回IABHELPER\u错误\u响应,android,in-app-purchase,in-app-billing,Android,In App Purchase,In App Billing,我已经设置了应用内计费和it服务,但在发送launchPurchaseFlow后,PurchaseFinishedListener会立即触发(甚至在我选择购买之前),并返回-1002(IABHELPER\u BAD\u响应) 如果我继续并单击“购买”进行购买。PurchaseFinishedListener再也不会被触发,但购买确实会被触发,我可以通过运行queryInventoryAsync来验证它是否被触发。这是我的密码 public class InAppBilling { privat

我已经设置了应用内计费和it服务,但在发送launchPurchaseFlow后,PurchaseFinishedListener会立即触发(甚至在我选择购买之前),并返回-1002(IABHELPER\u BAD\u响应)

如果我继续并单击“购买”进行购买。PurchaseFinishedListener再也不会被触发,但购买确实会被触发,我可以通过运行queryInventoryAsync来验证它是否被触发。这是我的密码

public class InAppBilling {

private static final String TAG = "IAB";
static final String SKU_PREMIUM = "full_version";
//   static final String ITEM_SKU = "android.test.purchased";
static final boolean DEBUG = true;

   // Does the user have the premium upgrade?
public boolean mIsPremium = false;
// (arbitrary) request code for the purchase flow
static final int RC_REQUEST = 10001;
// The helper object
IabHelper mHelper;
Context context;

public InAppBilling(Context cntxt) {
    this.context = cntxt;
    inAppBillingInit();
}



private void inAppBillingInit()
{

       // compute your public key and store it in base64EncodedPublicKey
       String base64EncodedPublicKey = mykey;

       mHelper = new IabHelper(context, base64EncodedPublicKey);

       mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
           @Override
        public void onIabSetupFinished(IabResult result) {
              if (!result.isSuccess()) {
                 // Oh noes, there was a problem.
                 Log.d(TAG, "Problem setting up In-app Billing: " + result);
              }            
                 // Hooray, IAB is fully set up!  
              // Have we been disposed of in the meantime? If so, quit.
                if (mHelper == null) return;

                // 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);
           }
        });        

}
   // Listener that's called when we finish querying the items and subscriptions we own
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
    @Override
    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
        Log.d(TAG, "Query inventory finished.");


        // Have we been disposed of in the meantime? If so, quit.
        if (mHelper == null) return;

        // Is it a failure?
        if (result.isFailure()) {
            Log.d(TAG, "Failed to query inventory: " + result);
            return;
        }

        if(inventory.hasPurchase(SKU_PREMIUM))
            {

            mHelper.consumeAsync(inventory.getPurchase(SKU_PREMIUM), new OnConsumeFinishedListener() {
                @Override
                public void onConsumeFinished(Purchase purchase, IabResult result) {
                }
            });
        }

        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().
         */
        // Do we have the premium upgrade?
        Purchase premiumPurchase = null;

//            if(DEBUG)
//              premiumPurchase = inventory.getPurchase(ITEM_SKU);
//            else
            premiumPurchase = inventory.getPurchase(SKU_PREMIUM);

       if(premiumPurchase == null)
       {
            Toast.makeText(context.getApplicationContext(), "premiumPurchase = null", Toast.LENGTH_LONG).show();
       }
       else
       {
           int pstate = premiumPurchase.getPurchaseState();  // 0 (purchased), 1 (canceled), or 2 (refunded).
            Toast.makeText(context.getApplicationContext(), "pstate = " + pstate, Toast.LENGTH_LONG).show();

       }
        mIsPremium = (premiumPurchase != null && verifyDeveloperPayload(premiumPurchase));
        Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));


        if(mIsPremium) updateUi();

    }
};

// 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);
        Toast.makeText(context.getApplicationContext(), "IAB_P_FinishedListener = " + result.getResponse(), Toast.LENGTH_LONG).show();

        // if we were disposed of in the meantime, quit.
        if (mHelper == null) return;

        if (result.isFailure()) {
           // complain("Error purchasing: " + result);
        //    setWaitScreen(false);
            return;
        }

        // Don't complain if cancelling
        if (result.getResponse() == IabHelper.IABHELPER_USER_CANCELLED) {
        return;
        }

        if (!verifyDeveloperPayload(purchase)) {
            complain("Error purchasing. Authenticity verification failed.");
          //  setWaitScreen(false);
            return;
        }

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

        if (purchase.getSku().equals(SKU_PREMIUM)) {
            // bought the premium upgrade!
            Log.d(TAG, "Purchase is premium upgrade. Congratulating user.");
            alert("Thank you for upgrading to premium!");
            mIsPremium = true;

            updateUi();
        //    setWaitScreen(false);
        }

    }
};


void complain(String message) {
    Log.e(TAG, "**** TrivialDrive Error: " + message);
    alert("Error: " + message);
}

void alert(String message) {
    AlertDialog.Builder bld = new AlertDialog.Builder(context);
    bld.setMessage(message);
    bld.setNeutralButton("OK", null);
    Log.d(TAG, "Showing alert dialog: " + message);
    bld.create().show();
}
/** Verifies the developer payload of a purchase. */
boolean verifyDeveloperPayload(Purchase p) {
    String payload = p.getDeveloperPayload();



    return true;
}    


public void purchaseProVersion()
{
//      disable_ad_kill = true;
//  sendMessageToService(MSG_DISABLE, disable_ad_kill);

    Log.d(TAG, "Upgrade button clicked; launching purchase flow for upgrade.");
 //   setWaitScreen(true);

    /* TODO: for security, generate your payload here for verification. See the comments on
     *        verifyDeveloperPayload() for more info. Since this is a SAMPLE, we just use
     *        an empty string, but on a production app you should carefully generate this. */
    String payload = "ProVersion";
    //billingHelper.launchPurchaseFlow(this, sku, 123, this);

//        if(DEBUG)
//            mHelper.launchPurchaseFlow((Activity)context, ITEM_SKU, 123,     mPurchaseFinishedListener);//, payload);                 
//        else
        mHelper.launchPurchaseFlow((Activity)context, SKU_PREMIUM, RC_REQUEST, mPurchaseFinishedListener, payload);                 

}



private void updateUi()
{
    Sketch s = (Sketch) context;
    if(mIsPremium) s.setToPro();
}



  public void Destroy() {

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

不确定这是否重要,但下面是调用puurchaseProvision()的类的HandLeachTivityResult


调用的方法purchaseProVersion()将在哪里?它是从我的主类调用的。我尝试将所有这些代码直接添加到主类中,它给出了相同的结果。我找到了答案。我的主要活动中有android:launchMode=“singleInstance”。我不太清楚为什么会这样,但我把它拿出来解决了问题。我必须做一些研究,看看它为什么会导致这个问题。
    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + ","   + data);
    // Pass on the activity result to the helper for handling
    try {
        if (!IAB.mHelper.handleActivityResult(requestCode, resultCode, data)) {
            // not handled, so handle it ourselves (here's where you'd
            // perform any handling of activity results not related to in-app
            // billing...
            Toast.makeText(this, "IAB.mHelper.handleActivityResult = false", Toast.LENGTH_LONG).show();
            super.onActivityResult(requestCode, resultCode, data);
        } else {
            Log.d(TAG, "onActivityResult handled by IABUtil.");
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}