In-App Billing: “Query items available for purchase” returns 0 items

允我心安 提交于 2019-12-03 00:21:32
Francisco Fernandes

I'm in the same boat. I'm waiting to see what happens.

In google documentation http://developer.android.com/training/in-app-billing/test-iab-app.html

there is a warning, perhaps this is the problem:

Warning: It may take up to 2-3 hours after uploading the APK for Google Play to recognize your updated APK version. If you try to test your application before your uploaded APK is recognized by Google Play, your application will receive a ‘purchase cancelled’ response with an error message “This version of the application is not enabled for In-app Billing.”

user3690202

I'm having the same problem. If you look at the IabHelper code, I think the issue is this:

Inside queryInventory:

if (querySkuDetails) {
    r = querySkuDetails(ITEM_TYPE_INAPP, inv, moreItemSkus);
    if (r != BILLING_RESPONSE_RESULT_OK) {
        throw new IabException(r, "Error refreshing inventory (querying prices of items).");
    }
}

But then the first few lines of querySkuDetails:

int querySkuDetails(String itemType, Inventory inv, List<String> moreSkus)
        throws RemoteException, JSONException {
    logDebug("Querying SKU details.");
    ArrayList<String> skuList = new ArrayList<String>();
    skuList.addAll(inv.getAllOwnedSkus(itemType));

Notice the last line populates the skuList with all owned skus. Not all available ones.

So the answer is that the IabHelper doesn't really support querying available purchases.

To get a list of available purchases with prices, you need to call queryInventoryAsync with the parameters - lists of shopping identifiers:

ArrayList<String> skuList = new ArrayList<String> ();
skuList.add("purchase1");
ArrayList<String> subsList = new ArrayList<String> ();
subsList.add("subscribe1");
mHelper.queryInventoryAsync(true, skuList, subsList, mGotInventoryListener);

I have tried above solution but it won't work for me and i got the solution from my another code, so i just want to share so may other will get help. For google in-app code please check this google github project

The difference is call queryInventoryAsync() with some more parameter that you have to pass and make sure that below method is call inside onIabSetupFinished() after IabHelper successfully initialized.

runOnUiThread(new Runnable() {
     @Override
     public void run() {
        refreshItemList();
     }
});

Prepare skurequest

private void refreshItemList() {
    List<String> itemSku = new ArrayList<>();
    List<String> subSku = new ArrayList<>();
    subSku.add(AppConstant.InApp.SKU_ONE_ID);
    mHelper.queryInventoryAsync(true, itemSku, subSku, mQotInventoryListener);
}

Below is the listener where you receive your SkuDetails

IabHelper.QueryInventoryFinishedListener mQotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
        @Override
        public void onQueryInventoryFinished(IabResult result, Inventory inv) {
            try {
                Log.d(TAG, "mQotInventoryListener 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.e(TAG, "mQotInventoryListener Failed to query inventory: " + result);
                    return;
                }

                Log.d(TAG, "mQotInventoryListener Query inventory was successful.");
                try {
                    //Here you just pass SKU_ID that you want its detail
                    SkuDetails skuDetails = inv.getSkuDetails(AppConstant.InApp.SKU_ONE_ID);
                    if (skuDetails != null) {
                      Log.d(TAG, "skuDetails are received"); 
                    } else {
                        Log.e(TAG, "skuDetails are null");
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

In order to have In-App Billing working, follow these steps:

  • Add <uses-permission android:name="com.android.vending.BILLING" /> permission to the AndroidManifest.xml .
  • Create a signed APK and upload it to the developer console, as alpha, beta or production.
  • Publish the APK or create a google group and add an alpha list of testers.
  • You have to wait some hours in order to see the in-app purchases in your app

Late to answer, I too ran into same problem. After reading whole documentation for 3 days, finally I found the culprit.

According to documentation:

Draft Apps are No Longer Supported.

Previously, you could publish a "draft" version of your app for testing. This functionality is no longer supported. Instead, there are two ways you can test how a pre-release app functions on the Google Play store:

You can publish an app to the alpha or beta distribution channels. This makes the app available on the Google Play store, but only to the testers you put on a "whitelist". In a few cases, you can test Google Play functionality with an unpublished app. For example, you can test an unpublished app's in-app billing support by using static responses, special reserved product IDs that always return a specific result (like "purchased" or "refunded").

Google should ease this process.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!