質問

I am implementing the In-App Billing service in my app. I set up in onCreate() the call to the IabHelper.queryInventoryAsync() to retrieve previous purchases. If the item is purchased, I set a global boolean variable to true. Meanwhile, in onCreateOptionsMenu(), I check that variable whether to remove a MenuItem or not. My problem is that onCreateOptionsMenu(), as expected, is sometimes called before the async task is done setting my boolean variable. I need a solution to tell onCreateOptionsMenu() to wait for that task to set the boolean value, so that it can create the menu accordingly. Here's the code in detail:

@Override
protected void onCreate(Bundle savedInstanceState) {  

//other  stuff...

   helper.queryInventoryAsync(new IabHelper.QueryInventoryFinishedListener() {
                public void onQueryInventoryFinished(IabResult result,
                                                     Inventory inventory) {

                    if (result.isFailure()) {
                        // handle error here   
                        return;                        
                    }

                    if (inventory.hasPurchase(REMOVE_ADS_SKU)) {  
                        //item purchased. set control variable
                        isNoAds = true;
                    } 

                }
            });
}

@Override
public boolean onCreateOptionsMenu(final Menu menu) {

    getMenuInflater().inflate(R.menu.main, menu);

    //if the control variable is true, remove the option to buy ad-free version
    if (isNoAds) menu.removeItem(R.id.action_remove_ads);

    return super.onCreateOptionsMenu(menu);
}
役に立ちましたか?

解決

I've found that the most robust way to do this is by invalidating the whole menu. So, when you get your async result (in onQueryInventoryFinished) just call:

invalidateOptionsMenu();

or, if you are using a FragmentActivity (SherlockFragmentActivity or ActionBarActivity)

supportInvalidateOptionsMenu();

In this way the menu will be recreated and you can safely add or remove items as you need.

他のヒント

Maybe using onPrepareOptionMenu might do the trick. The docs (http://developer.android.com/reference/android/app/Activity.html#onPrepareOptionsMenu%28android.view.Menu%29) states that it's used to prepare what should be displayed. You keep the xml inflate in the onCreateOptionsMenu and then do the following:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    menu.findItem(R.id.action_remove_ads).setVisible(!isNoAds);
    return super.onPrepareOptionsMenu(menu);
}

You still initialize the isNoAds variable to true in the onCreate method to be sure it's not displayed immediatly.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top