Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android IAB - Activity destroyed after successful purchase

I am pulling my hair out! At one point in the last week, I had this working.

I have an Android app that I am trying to add in-ap billing to. I followed the sample TrivialDrive, and my code worked a few times. Now it doesn't.

I am creating a simple trivia game that has a number of free questions, and the option to upgrade to get more questions. When the user completes the list of free questions, they are taken to a "Game Over" screen where they can erase their answers and start again, or upgrade.

When I click the "Upgrade" button, I can make a successful purchase, but as soon as the Google "Payment Successful" dialog goes away, my activity is destroyed and I am sent back to my main activity.

When I try to go back and do my purchase again, my code catches the error ("You already own this item") and handles it appropriately. My code explains to the user that they already own the upgrade, and allows them to click a button to continue playing. So it looks like the OnIabPurchaseFinishedListener is firing at this point.

I have updated the Google helper code with the latest files.

Any help or suggestions as to where to look for answers is much appreciated.

Thanks.

This is the relevant code for my activity:

public class GameOverActivity extends BaseActivity
{

    private IabHelper       mHelper;
    private String          m_base64EncodedPublicKey;
    private static String   THE_UPGRADE_SKU = "upgrade52";
    public static int BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED = 7;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game_over);

        setTitle("Game Over");

        Button butPlay = (Button) findViewById(R.id.buttonPlay);
        butPlay.setVisibility(View.INVISIBLE);

        PrepareIAB();
    }

    @Override
    protected void onResume()
    {
        super.onResume();
        CURRENT_ACTIVITY = ACTIVITY_GAME_OVER;
        SetMainText();
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        try
        {
            if (mHelper != null)
            {
                mHelper.dispose();
                mHelper = null;
            }
        }
        catch (Exception e)
        {
        }       
    }

    private void PrepareIAB()
    {
        m_base64EncodedPublicKey = "MyKey";

        // compute your public key and store it in base64EncodedPublicKey
        mHelper = new IabHelper(this, m_base64EncodedPublicKey);
        mHelper.enableDebugLogging( true, TAG);

        mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener()
        {
            public void onIabSetupFinished(IabResult result)
            {
                if (!result.isSuccess())
                {

                    ShowMessage("There was an error connecting to the Google Play Store.");
                }
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {           
         try 
         {
            // 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.");
                }    
         }
         catch (Exception e)
         {
             super.onActivityResult(requestCode, resultCode, data); 
         }
    }



    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener   = 
            new IabHelper.OnIabPurchaseFinishedListener()
            {
                public void onIabPurchaseFinished(IabResult result, Purchase purchase)
                {
                    try 
                    {
                        if (result.isFailure())
                        {                       
                            if (result.mResponse==7)
                            {
                                UpgradeComplete();
                                ShowMessage("Thank you for upgrading.\r\n\r\nThis version has 400 more questions.");        
                            }
                            else
                            {

                                ShowMessage("Error purchasing: " + String.valueOf(result.mResponse));                           
                                UpgradeError();

                                return;
                            }

                        }
                        else if (purchase.getSku().equals(THE_UPGRADE_SKU))
                        {               
                            UpgradeComplete();
                            ShowMessage("Thank you for upgrading.\r\n\r\nThis version has 400 more questions.");                                        
                        }
                        else
                        {
                            ShowMessage("Something else happened. ");
                        }
                    }
                    catch (Exception e)
                    {
                        Log.e(TAG, e.getLocalizedMessage());
                    }

                }
            };

    private void HideUpgrade()
    {
        try 
        {
            Button btnUpgrade = (Button) findViewById(R.id.buttonUpgrade);
            if (btnUpgrade != null)
            {
                btnUpgrade.setVisibility(View.INVISIBLE);
            }           

            TextView txtMessage = (TextView) findViewById(R.id.txtUpgradeFromGameOver);
            if (txtMessage!=null)
            {
                txtMessage.setVisibility(View.INVISIBLE);   
            }   
        }
        catch (Exception e)
        {

        }        
    }

    public void onQuitButtonClick(View view)
    {
        finish();
    }

    public void onResetDBButtonClick(View view)
    {
        ConfirmResetDatabase();
    }

    private void ConfirmResetDatabase()
    {
        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                switch (which)
                {
                    case DialogInterface.BUTTON_POSITIVE:

                        ResetDatabase();

                        Intent gameActivity = new Intent(getApplicationContext(), GameActivity.class);

                        gameActivity.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                        // startActivityForResult(gameActivity, ACTIVITY_GAME);
                        startActivity(gameActivity);
                        break;

                    case DialogInterface.BUTTON_NEGATIVE:
                        // No button clicked
                        break;
                }
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("Do you want to erase your score and start over?").setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", dialogClickListener).show();
    }


    public void onUpgradeButtonClick(View view)
    {           
        try 
        {
            if (mHelper != null)
            {
                mHelper.launchPurchaseFlow(this, THE_UPGRADE_SKU, 10001, mPurchaseFinishedListener, m_TriviaAppInstance.AppInstallID());
            }
            else
            {
                ShowMessage("Unable to connect to Google Play Store.");         
            }   
        }
        catch (Exception e)
        {
            ShowMessage("Unable to connect to Google Play Store.");
            SendErrorMessage(e.getLocalizedMessage());          
        }
    }



    private void UpgradeComplete()
    {
        try
        {    
            HideUpgrade();

            Button butPlay = (Button) findViewById(R.id.buttonPlay);
            if (butPlay!=null)
            {
                butPlay.setVisibility(View.VISIBLE);    
            }

            TextView txtReset = (TextView) findViewById(R.id.txtGameOverRestDB);
            if (txtReset!=null)
            {
                txtReset.setVisibility(View.INVISIBLE); 
            }

            Button btnReset = (Button)findViewById(R.id.buttonResetDB);
            if (btnReset!=null)
            {
                btnReset.setVisibility(View.INVISIBLE);
            }

            m_TriviaAppInstance.SetUpgradedStatus(true);

        }
        catch (Exception e)
        {

        }

        //

    }

    private void UpgradeError()
    {
        try
        {
            Button butUpgrade;
            butUpgrade = (Button) findViewById(R.id.buttonUpgrade);
            butUpgrade.setVisibility(View.INVISIBLE);

            TextView txtMessage = (TextView) findViewById(R.id.txtUpgradeScreen);
            txtMessage.setText(R.string.upgradeScreenTextError);
        }
        catch (Exception e)
        {
        }
    }


    public void onPlayButtonClick(View view)
    {
        Intent myIntent = new Intent(view.getContext(), GameActivity.class);
        myIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        startActivityForResult(myIntent, ACTIVITY_GAME);
    }

    public void SetMainText()
    {
        TextView txt = (TextView) findViewById(R.id.txtScoreGlobal);
        txt.setText(Integer.toString(m_TriviaAppInstance.getGlobal()) + "%");
        SetPlayerScore(1);

        if (m_TriviaAppInstance.getUpgradedStatus() == true)
        {           
            HideUpgrade();          
        }       
    }

}
like image 997
Jay MacDonald Avatar asked Jun 30 '13 17:06

Jay MacDonald


3 Answers

FYI: I think I have this figured out - for anyone else that may come across it.

The activity that I was using to launch "In App Billing" was called with a "FLAG_ACTIVITY_NO_HISTORY". I did this because I didn't want the user to be able to click to go back to this "Game Over" activity.

BUT, this causes grief with "In App Billing". So, make sure you don't try to launch "In App Billing" from an activity that has had the "FLAG_ACTIVITY_NO_HISTORY" set.

My original code:

private void GameOver()
    {
        m_TriviaAppInstance.setGameOver(true);
        Intent gameOver = new Intent(getApplicationContext(), GameOverActivity.class);
        gameOver.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        startActivity(gameOver);
    }

Updated code:

private void GameOver()
    {
        m_TriviaAppInstance.setGameOver(true);
        Intent gameOver = new Intent(getApplicationContext(), GameOverActivity.class);       
        startActivity(gameOver);
    }

Peace

like image 78
Jay MacDonald Avatar answered Oct 29 '22 07:10

Jay MacDonald


I'm not high enough to comment, but bless you. I had

android:noHistory="true"

set in AndroidManifest.xml for my activity and was experiencing the same problem.

Took it out and IAB is working. Yay!

like image 8
Mark Avatar answered Oct 29 '22 06:10

Mark


Do not forget that your IabHelper.OnIabPurchaseFinishedListener is called on a different thread and before onResume() is called on your Activity!

So your UpgradeComplete() or UpgradeError() can cause a crash on older devices (Crashed every time on my Gingerbread Sony Xperia Mini Pro and worked without any trouble on Samsung Galaxy S4 (Android 4.2.2)

Caused a 3 day delay on my game..

like image 1
Marek Halmo Avatar answered Oct 29 '22 05:10

Marek Halmo