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

 ̄綄美尐妖づ 提交于 2019-12-20 10:33:19

问题


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. 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, 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 are going to need the two 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.



来源:https://stackoverflow.com/questions/31035222/iab-helper-is-not-set-up-cant-perform-operation-queryinventory

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