简体   繁体   中英

In-App purchase crashing after payment

I've wrote an in app purchase test app to learn how to implement it in an application i've made. I adapted the code from the TrivialDrive sample provided by google. But it doesn't work, after my friend makes the payment the app crashes. The code looks like this

public class MainActivity extends Activity {



    String TAG = "AppPurchaseTest";
    IabHelper mHelper;
    boolean mIsPremium = false;
    static final String SKU_PREMIUM = "premium";
    static final int RC_REQUEST = 10001;


 // User clicked the "Upgrade to Premium" button.
    public void onUpgradeAppButtonClicked(View arg0) {
        Log.d(TAG, "Upgrade button clicked; launching purchase flow for upgrade.");
   //     setWaitScreen(true);
        mHelper.launchPurchaseFlow(this, SKU_PREMIUM, RC_REQUEST, mPurchaseFinishedListener);
    }


    //this is not working

 // 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);

            int duration = Toast.LENGTH_SHORT;
            if (result.isFailure()) {
                // Oh noes!
             //   complain("Error purchasing: " + result);
             //   setWaitScreen(false);
                Toast.makeText(getBaseContext(), "Fail :(", duration).show();
                return;
            }

            Log.d(TAG, "Purchase successful.");

            if (purchase.getSku().equals(SKU_PREMIUM)) {
                // bought the premium upgrade!
                Log.d(TAG, "Purchase is premium upgrade. Congratulating user.");
              //  alert("Thank you for upgrading to premium!");
                mIsPremium = true;

                Toast.makeText(getBaseContext(), "Successo: adesso sei premium", duration).show();
                Button test = (Button) findViewById(R.id.test);
                test.setVisibility(View.INVISIBLE);
              //  updateUi();
             //   setWaitScreen(false);
            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String base64EncodedPublicKey = null;

        // compute your public key and store it in base64EncodedPublicKey
        mHelper = new IabHelper(this, base64EncodedPublicKey);

        mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
            public void onIabSetupFinished(IabResult result) {
               if (!result.isSuccess()) {
                  // Oh noes, there was a problem.
                  Log.d(TAG, "Problem setting up In-app Billing: " + result);
               }            
                  // Hooray, IAB is fully set up!  
            }
         });
    }


    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();

        if (mHelper != null) {
            Log.d(TAG, "mHelper doesn't = null ");
        mHelper.dispose();
        mHelper = null;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);

        // 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.");
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }


}

Can you spot something wrong? Something i forgot?

Also this tutorial https://developer.android.com/google/play/billing/billing_integrate.html looks much simpler, but i don't understand how to implement it, is there a sample or something from which i can see how it's implemented? I just need a simple upgrade to premium purchase

It's very hard to make it work since i can't test it personally and everytime i test it i lose money :(

Took a long time to figure out on my project but you have to understand that your mPurchaseFinishedListener is called on a non rendering thread and before your application onResume() is called (just check the IabHelper code.

So if you try to do any rendering there it CAN crash because the rendering context is not restored yet.

In your case it is likely that:

Toast.makeText(getBaseContext(), "Successo: adesso sei premium", duration).show();

will crash, the same goes for

Button test = (Button) findViewById(R.id.test);

if you check the trivia example the textButton visibility is set to true, but the button itself is a class property that is assigned in the onCreate() method.

Let me know if this helps..

Per TrivialDrive You also need (this will fix it):

 // We're being destroyed. It's important to dispose of the helper here!
    @Override
    public void onDestroy() {
        super.onDestroy();

        // very important:
        if (mBroadcastReceiver != null) {
            unregisterReceiver(mBroadcastReceiver);
        }

        // very important:
        Log.d(TAG, "Destroying helper.");
        if (mHelper != null) {
            mHelper.disposeWhenFinished();
            mHelper = null;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM