title: In-app billing workflow in a ListView
body: <p>I implemented in-app billing in Android application, have like 6 product they are like coins the user will buy in order to buy items in my app.
  The setup and the testing for in-app works perfectly I read all google documents and did what they said but my problem is that my product are shown in a listView i called the function <code>mHelper.launchPurchaseFlow</code> according to the position in the list in the activity but the items are always consumed or owned here is my code:</p>
  
  <pre><code>IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
      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()) {
              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().
           */
  
          // Do we have the 100 coins upgrade?
          Purchase hundrendCoin = inventory.getPurchase(SKU_hundred);
          if(hundrendCoin != null &amp;&amp; verifyDeveloperPayload(hundrendCoin));
          {
              Log.d(TAG, "User have it ");
              mHelper.consumeAsync(inventory.getPurchase(SKU_hundred), mConsumeFinishedListener);
          }
  
          // Do we have the 225 coins upgrade?
          Purchase two_hundred_twenty_fiveCoin = inventory.getPurchase(SKU_two_hundred_twenty_five);
          if(two_hundred_twenty_fiveCoin != null &amp;&amp; verifyDeveloperPayload(two_hundred_twenty_fiveCoin));
          {
              Log.d(TAG, "User have it ");
              mHelper.consumeAsync(inventory.getPurchase(SKU_two_hundred_twenty_five), mConsumeFinishedListener);
          }
  
          // Do we have the 350 coins upgrade?
          Purchase three_hundred_fiftyCoin = inventory.getPurchase(SKU_three_hundred_fifty);
          if(three_hundred_fiftyCoin != null &amp;&amp; verifyDeveloperPayload(three_hundred_fiftyCoin));
          {
              Log.d(TAG, "User have it ");
              mHelper.consumeAsync(inventory.getPurchase(SKU_three_hundred_fifty), mConsumeFinishedListener);
          }
  
          // Do we have the 475 coins upgrade?
          Purchase four_hundred_seventy_fiveCoin = inventory.getPurchase(SKU_four_hundred_seventy_five);
          if(four_hundred_seventy_fiveCoin != null &amp;&amp; verifyDeveloperPayload(four_hundred_seventy_fiveCoin));
          {
              Log.d(TAG, "User have it ");
              mHelper.consumeAsync(inventory.getPurchase(SKU_four_hundred_seventy_five), mConsumeFinishedListener);
          }
  
          // Do we have the 600 coins upgrade?
          Purchase six_hundredCoin = inventory.getPurchase(SKU_six_hundred);
          if(six_hundredCoin != null &amp;&amp; verifyDeveloperPayload(six_hundredCoin));
          {
              Log.d(TAG, "User have it");
              mHelper.consumeAsync(inventory.getPurchase(SKU_six_hundred), mConsumeFinishedListener);
          }
  
          // Do we have the 1225 coins upgrade?
          Purchase one_thousand_two_hundred_twenty_fiveCoin = inventory.getPurchase(SKU_one_thousand_two_hundred_twenty_five);
          if(one_thousand_two_hundred_twenty_fiveCoin != null &amp;&amp; verifyDeveloperPayload(one_thousand_two_hundred_twenty_fiveCoin));
          {
              Log.d(TAG, "User have it ");
              mHelper.consumeAsync(inventory.getPurchase(SKU_one_thousand_two_hundred_twenty_five), mConsumeFinishedListener);
          }
  
          mHelper.flagEndAsync();
  
          Log.d(TAG, "Initial inventory query finished; enabling main UI.");
      }
  };
  list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  
                  @Override
                  public void onItemClick(AdapterView&lt;?&gt; parent, View view, int position, long id) {
  
                      BankClass currentItem = BankList.get(position);
                      CoinItemID = currentItem.itemID;
                      if (currentItem.quantity == 100)
                      {
                          CoinItemID = currentItem.itemID;
                          String payload = "";
                          mHelper.launchPurchaseFlow(BankActivity.this, SKU_hundred, RC_REQUEST,
                                  mPurchaseFinishedListener, payload);
  
                      } else if (currentItem.quantity == 225)
                      {
                          CoinItemID = currentItem.itemID;
                          String payload = "";
                          mHelper.launchPurchaseFlow(BankActivity.this, SKU_two_hundred_twenty_five, RC_REQUEST,
                                  mPurchaseFinishedListener, payload);
  
                      } else if (currentItem.quantity == 350) {
                          CoinItemID = currentItem.itemID;
                          String payload = "";
                          mHelper.launchPurchaseFlow(BankActivity.this, SKU_three_hundred_fifty, RC_REQUEST,
                                  mPurchaseFinishedListener, payload);
                      } else if (currentItem.quantity == 475) {
                          CoinItemID = currentItem.itemID;
                          String payload = "";
                          mHelper.launchPurchaseFlow(BankActivity.this, SKU_four_hundred_seventy_five, RC_REQUEST,
                                  mPurchaseFinishedListener, payload);
  
                      } else if (currentItem.quantity == 600) {
                          CoinItemID = currentItem.itemID;
                          String payload = "";
                          mHelper.launchPurchaseFlow(BankActivity.this, SKU_six_hundred, RC_REQUEST,
                                  mPurchaseFinishedListener, payload);
  
                      } else if (currentItem.quantity == 1225) {
                          CoinItemID = currentItem.itemID;
                          String payload = "";
                          mHelper.launchPurchaseFlow(BankActivity.this, SKU_one_thousand_two_hundred_twenty_five, RC_REQUEST,
                                  mPurchaseFinishedListener, payload);
  
                      }
                  }
              });
       @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data)
  {
      Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
      if (mHelper == null) return;
  
      // Pass on the activity result to the helper for handling
      if (!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...
          super.onActivityResult(requestCode, resultCode, data);
      }
      else
      {
          Log.d(TAG, "onActivityResult handled by IABUtil.");
      }
  }
  boolean verifyDeveloperPayload(Purchase p)
  {
      String payload = p.getDeveloperPayload();
  
      /*
       * TODO: verify that the developer payload of the purchase is correct. It will be
       * the same one that you sent when initiating the purchase.
       *
       * WARNING: Locally generating a random string when starting a purchase and
       * verifying it here might seem like a good approach, but this will fail in the
       * case where the user purchases an item on one device and then uses your app on
       * a different device, because on the other device you will not have access to the
       * random string you originally generated.
       *
       * So a good developer payload has these characteristics:
       *
       * 1. If two different users purchase an item, the payload is different between them,
       *    so that one user's purchase can't be replayed to another user.
       *
       * 2. The payload must be such that you can verify it even when the app wasn't the
       *    one who initiated the purchase flow (so that items purchased by the user on
       *    one device work on other devices owned by the user).
       *
       * Using your own server to store and verify developer payloads across app
       * installations is recommended.
       */
  
      return true;
  }
  
  // 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 we were disposed of in the meantime, quit.
          if (mHelper == null) return;
  
          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_hundred)) {
              // bought 1/4 tank of gas. So consume it.
              Log.d(TAG, "Purchase is 100 Coins. Starting consumption.");
              mHelper.consumeAsync(purchase, mConsumeFinishedListener);
  
          }
          else if (purchase.getSku().equals(SKU_two_hundred_twenty_five)) {
              Log.d(TAG, "Purchase is 225 Coins. Starting consumption.");
              mHelper.consumeAsync(purchase, mConsumeFinishedListener);
  
          }
          else if (purchase.getSku().equals(SKU_three_hundred_fifty)) {
              Log.d(TAG, "Purchase is 350 Coins. Starting consumption.");
              mHelper.consumeAsync(purchase, mConsumeFinishedListener);
  
          }
          else if (purchase.getSku().equals(SKU_four_hundred_seventy_five)) {
              Log.d(TAG, "Purchase is 475 Coins. Starting consumption.");
              mHelper.consumeAsync(purchase, mConsumeFinishedListener);
  
          }
          else if (purchase.getSku().equals(SKU_six_hundred)) {
              Log.d(TAG, "Purchase is 600 Coins. Starting consumption.");
              mHelper.consumeAsync(purchase, mConsumeFinishedListener);
  
          }
          else if (purchase.getSku().equals(SKU_one_thousand_two_hundred_twenty_five)) {
              Log.d(TAG, "Purchase is 1225 Coins. Starting consumption.");
              mHelper.consumeAsync(purchase, mConsumeFinishedListener);
  
          }
  
      }
  };
  
  // Called when consumption is complete
  IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
      public void onConsumeFinished(Purchase purchase, IabResult result) {
          Log.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result);
  
          // if we were disposed of in the meantime, quit.
          if (mHelper == null) return;
  
          // We know this is the "gas" sku because it's the only one we consume,
          // so we don't check which sku was consumed. If you have more than one
          // sku, you probably should check...
          if (result.isSuccess())
          {
              // successfully consumed, so we apply the effects of the item in our
              // game world's logic, which in our case means filling the gas tank a bit
              (new BuyCoinsTask()).execute();
              Log.d(TAG, "Consumption successful. Provisioning.");
          }
          else
          {
              complain("Error while consuming: " + result);
          }
  
          Log.d(TAG, "End consumption flow.");
      }
  };
  </code></pre>
  
  <p>Any help would be appreciated.</p>
  
  <p><code>Bank</code> class:</p>
  
  <pre><code>public class BankClass
  {
    public int itemID;
    public int quantity;
    public String price;
    public BankClass(int itemID,int quantity,String price)
    {
        this.itemID=itemID;
        this.quantity=quantity;
        this.price=price;
    }
  }
  </code></pre>
  
  <p>Here is what i did with multi consuming .</p>
  
  <pre><code>List&lt;Purchase&gt; purchases = new ArrayList&lt;&gt;();
          purchases.add(inventory.getPurchase(SKU_hundred));
          purchases.add(inventory.getPurchase(SKU_two_hundred_twenty_five));
          purchases.add(inventory.getPurchase(SKU_three_hundred_fifty));
          purchases.add(inventory.getPurchase(SKU_four_hundred_seventy_five));
          purchases.add(inventory.getPurchase(SKU_six_hundred));
          purchases.add(inventory.getPurchase(SKU_one_thousand_two_hundred_twenty_five));
  
          IabHelper.OnConsumeMultiFinishedListener onCusumeListner = new IabHelper.OnConsumeMultiFinishedListener()
          {
  
              @Override
              public void onConsumeMultiFinished(List&lt;Purchase&gt; purchases, List&lt;IabResult&gt; results)
              {
                  Log.d(TAG, "Consumption finished. Purchase: " + purchases + ", result: " + results);
  
                  // if we were disposed of in the meantime, quit.
                  if (mHelper == null) return;
  
                  // We know this is the "gas" sku because it's the only one we consume,
                  // so we don't check which sku was consumed. If you have more than one
                  // sku, you probably should check...
                  for(int i=0;i&lt;results.size();i++)
                  {
                      if (results.get(i).isSuccess())
                      {
                          // successfully consumed, so we apply the effects of the item in our
                          // game world's logic, which in our case means filling the gas tank a bit
  
                          Log.d(TAG, "Consumption successful. Provisioning.");
                      } else {
                          complain("Error while consuming: " + results);
                      }
                  }
                  Log.d(TAG, "End consumption flow.");
              }
  
          };
          mHelper.consumeAsync(purchases, onCusumeListner);
  </code></pre>
  
  <p>but in the result i don't know how to handle the success of the result for all items according to there position should i run a for loop for it or there is another way but still its crashing in all ways.</p>
  
  <p>Logcat output:</p>
  
  <pre><code> 04-17 13:01:31.083    8312-8964/net.httpiamheroic.herioc    E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-3333
    Process: net.httpiamheroic.herioc, PID: 8312
  java.lang.NullPointerException: Attempt to read from field   'java.lang.String   net.httpiamheroic.herioc.net.httpiamherioc.util.Purchase.mItemType' on a   null object reference
          at   net.httpiamheroic.herioc.net.httpiamherioc.util.IabHelper.consume(IabHelper.java:660)
          at net.httpiamheroic.herioc.net.httpiamherioc.util.IabHelper$3.run(IabHelper.java:953)
          at java.lang.Thread.run(Thread.java:818)
  </code></pre>