IAB helper is not set up. Can't perform operation: queryInventory

匿名 (未验证) 提交于 2019-12-03 02:49:01

问题:

I am trying to implement in-app-billing API in my app but when I run my app it trows an exception. This is the first time that I am dealing with in-app-billing API so suggestions would be highly appreciated. This is the log of the exception that I am getting:

Process: koemdzhiev.com.quickshoppinglist, PID: 10604 java.lang.RuntimeException: Unable to start activity ComponentInfo{koemdzhiev.com.quickshoppinglist/koemdzhiev.com.quickshoppinglist.ui.MainActivity}: java.lang.IllegalStateException: IAB helper is not set up. Can't perform operation: queryInventory         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2329)         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)         at android.app.ActivityThread.access$900(ActivityThread.java:147)         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)         at android.os.Handler.dispatchMessage(Handler.java:102)         at android.os.Looper.loop(Looper.java:135)         at android.app.ActivityThread.main(ActivityThread.java:5254)         at java.lang.reflect.Method.invoke(Native Method)         at java.lang.reflect.Method.invoke(Method.java:372)         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)  Caused by: java.lang.IllegalStateException: IAB helper is not set up. Can't perform operation: queryInventory         at koemdzhiev.com.quickshoppinglist.utils.IabHelper.checkSetupDone(IabHelper.java:782)         at koemdzhiev.com.quickshoppinglist.utils.IabHelper.queryInventoryAsync(IabHelper.java:610)         at koemdzhiev.com.quickshoppinglist.utils.IabHelper.queryInventoryAsync(IabHelper.java:639)         at koemdzhiev.com.quickshoppinglist.ui.MainActivity.queryPurchasedItems(MainActivity.java:187)         at koemdzhiev.com.quickshoppinglist.ui.MainActivity.onStart(MainActivity.java:193)         at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1220) 

My code in main activity:

public class MainActivity extends AppCompatActivity { private static final String TAG =  MainActivity.class.getSimpleName(); private Toolbar mToolbar; private RecyclerView mRecyclerView; private ArrayList<String> shoppingListItems; private SharedPreferences mSharedPreferences; private SharedPreferences.Editor mEditor; private TextView mEmptyTextView; private ShoppingListAdapter adapter; private ActionButton actionButton; private MaterialDialog addItemdialog = null; private AdView mAdView; private IabHelper mHelper; private String SKU_REMOVE_ADDS = "remove_adds_sku"; private boolean mIsRemoveAdds = false; private IabHelper.OnIabPurchaseFinishedListener mPurchasedFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {     @Override     public void onIabPurchaseFinished(IabResult result, Purchase purchase) {         if (result.isFailure()) {             Log.d(TAG, "Error purchasing: " + result);             return;         }         else if (purchase.getSku().equals(SKU_REMOVE_ADDS)) {             // consume the gas and update the UI             mIsRemoveAdds = true;             mAdView.setVisibility(View.GONE);             Toast.makeText(MainActivity.this,"Purchase successful",Toast.LENGTH_LONG).show();         }     } }; @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main); String publicKey = s1+s2+s3+s4+s5;      mHelper = new IabHelper(this,publicKey);     mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {         @Override         public void onIabSetupFinished(IabResult result) {             if (!result.isSuccess()) {                 //error                 Log.d(TAG, "Proglem setting up in-app Billing: " + result);             }             //Horay, IAB is fully set up!             Log.d(TAG, "Horay, IAB is fully set up!");             queryPurchasedItems();         }     }); private void queryPurchasedItems() {     //check if user has bought "remove adds"     IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {         @Override         public void onQueryInventoryFinished(IabResult result, Inventory inventory) {             if (result.isFailure()) {                 // handle error here                 Toast.makeText(MainActivity.this,"error",Toast.LENGTH_LONG).show();             }             else{                 // does the user have the premium upgrade?                 mIsRemoveAdds = inventory.hasPurchase(SKU_REMOVE_ADDS);                 if(!mIsRemoveAdds) {                     Toast.makeText(MainActivity.this,"no premium",Toast.LENGTH_LONG).show();                     mAdView = (AdView) findViewById(R.id.adView);                     AdRequest adRequest = new AdRequest.Builder().build();                     mAdView.loadAd(adRequest);                 }else{                     mAdView.setVisibility(View.GONE);                     Toast.makeText(MainActivity.this,"premium",Toast.LENGTH_LONG).show();                 }              }         }     };     mHelper.queryInventoryAsync(mGotInventoryListener); } @Override protected void onStart() {     super.onStart();     queryPurchasedItems();     isListEmpty(); }  @Override protected void onResume() {     super.onResume();     queryPurchasedItems();     isListEmpty(); }  @Override protected void onDestroy() {     super.onDestroy();     if (mHelper != null) mHelper.dispose();     mHelper = null;     mAdView.destroy(); } 

回答1:

Finally after many hours of try and error, trying many suggested solutions I got the whole thing to work and not got this exception "IAB helper is not set up. Can't perform operation: queryInventory" or one more that I was getting "Can't start async operation (consume) because another async operation(consume) is in progress". The first thing that you have to do is to add 2 methods in the IabHelper.java class:

 public boolean isAsyncInProgress(){     return mAsyncInProgress; } public boolean isSetupDone (){     return mSetupDone; } 

and than on your main activity:

public class MainActivity extends AppCompatActivity { private   IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {     @Override     public void onQueryInventoryFinished(IabResult result, Inventory inventory) {         if (result.isFailure()) {             // handle error here             Toast.makeText(MainActivity.this,"error",Toast.LENGTH_LONG).show();         }         else{             // does the user have the premium upgrade?             mIsRemoveAdds = inventory.hasPurchase(SKU_REMOVE_ADDS);             if(!mIsRemoveAdds) {                 Toast.makeText(MainActivity.this,"no premium",Toast.LENGTH_LONG).show();                 mAdView = (AdView) findViewById(R.id.adView);                 AdRequest adRequest = new AdRequest.Builder().build();                 mAdView.loadAd(adRequest);             }else{                 mAdView.setVisibility(View.GONE);                 Toast.makeText(MainActivity.this,"premium",Toast.LENGTH_LONG).show();             }          }     } }; private IabHelper.OnIabPurchaseFinishedListener mPurchasedFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {     @Override     public void onIabPurchaseFinished(IabResult result, Purchase purchase) {         if (result.isFailure()) {             Log.d(TAG, "Error purchasing: " + result);             return;         }         else if (purchase.getSku().equals(SKU_REMOVE_ADDS)) {             // consume the gas and update the UI             mIsRemoveAdds = true;             mAdView.setVisibility(View.GONE);             Toast.makeText(MainActivity.this,"Purchase successful",Toast.LENGTH_LONG).show();         }     } };   @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main); String publicKey = s1+s2+s3+s4+s5;      mHelper = new IabHelper(this,publicKey);     mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {         @Override         public void onIabSetupFinished(IabResult result) {             if (!result.isSuccess()) {                 //error                 Log.d(TAG, "Proglem setting up in-app Billing: " + result);             }             if (result.isSuccess()) {                 //Horay, IAB is fully set up!                 Log.d(TAG, "Horay, IAB is fully set up!");                 //queryPurchasedItems;                 mHelper.queryInventoryAsync(mGotInventoryListener);             }         }     }); 

And now, as it is recommended in Google's guide for the API we have to check what items the user has bought in on start or on resume methods. Here we gonna need the 2 methods that we added in IabHelper.java class.

   private void queryPurchasedItems() {     //check if user has bought "remove adds"     if(mHelper.isSetupDone() && !mHelper.isAsyncInProgress()) {         mHelper.queryInventoryAsync(mGotInventoryListener);     } }  @Override protected void onStart() {     super.onStart();     queryPurchasedItems(); }  @Override protected void onResume() {     super.onResume();     queryPurchasedItems();     isListEmpty(); } 


回答2:

Your OnIabSetupFinishedListener checks for (!result.isSuccess())

but you don't return or abort here in case the resulst is NOT successful.

I think your mHelper.startSetup fails ,and you are not handling this failure.



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