Android IAB - 成功购买后Activity销毁

10
我正在抓狂!上星期某个时候,这还能用。
我正在尝试为Android应用添加应用内购买功能。我按照TrivialDrive的示例进行操作,我的代码有时可以正常工作。但现在它不行了。
我正在创建一个简单的问答游戏,其中包含一些免费问题以及升级以获取更多问题的选项。当用户完成免费问题列表时,他们将被带到“游戏结束”屏幕,在该屏幕上,他们可以擦除答案并重新开始或升级。
当我点击“升级”按钮时,我可以进行成功的购买,但是一旦Google的“付款成功”对话框消失后,我的活动就被销毁,然后我被送回到主活动。
当我尝试返回并再次进行购买时,我的代码捕获错误(“您已拥有此项目”),并适当地处理它。我的代码向用户解释他们已经拥有升级,并允许他们点击一个按钮继续玩。因此,看起来OnIabPurchaseFinishedListener此时正在触发。
我使用最新的Google助手代码更新了代码文件。
非常感谢任何帮助或建议,以便寻找答案。
谢谢。
以下是我的活动相关代码:
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();          
        }       
    }

}

更新:我的代码一定做对了些什么。我的测试购买已经出现在我的Google商家账户中。但是仍然有些问题,因为成功的购买并没有被告知给用户(也就是我)。 - Jay MacDonald
成功购买后,onIabPurchaseFinished事件根本不触发。但是,如果用户已经拥有该物品,则会触发该事件。 - Jay MacDonald
1
FYI:我想我已经弄清楚了 - 对于其他可能遇到此问题的人来说。 我使用的启动Google Play商店的活动被称为“FLAG_ACTIVITY_NO_HISTORY”。我这样做是因为我不希望用户能够点击返回到这个“游戏结束”活动。 但是,这会给“应用内计费”带来麻烦。因此,请确保您不要尝试从已设置“FLAG_ACTIVITY_NO_HISTORY”的活动中启动“应用内计费”。祝好! - Jay MacDonald
3个回答

13

提供信息:我想我已经解决了这个问题 - 如果有其他人遇到同样的问题,可以看一下。

我用来启动“应用内购买”的活动被调用时,带有“FLAG_ACTIVITY_NO_HISTORY”标志。我这样做是因为我不希望用户能够点击返回到这个“游戏结束”活动。

但是,这会导致“应用内购买”出现问题。所以,请确保不要从已设置“FLAG_ACTIVITY_NO_HISTORY”的活动中尝试启动“应用内购买”。

我的原始代码:

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

更新的代码:

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

和平


1
哇,你是我的英雄!解决了我很多麻烦。这是从2013年开始的,Google还没有修复这个问题吗?甚至没有记录它。 - Johan Paul
你,你,你!我的朋友,你值得热烈的掌声!我已经苦苦挣扎了将近两个小时了。而移除那一个微小的标志解决了一切!!!想想看,现在一切都变得如此简单。(另外,奇怪的巧合是,我已经在这个项目上工作了两个月了,今天是我第一次尝试从同一个活动中尝试两个“startActivityForResult”,这是我以前从未做过的。我疯了,非常感谢!) - IcyFlame

8

我不够专业,但还是要祝福你。我的AndroidManifest.xml文件中设置了android:noHistory="true"属性,并且也遇到了同样的问题。

后来我把这个属性删掉了,现在内置应用购买功能可以正常使用了。太棒了!


1
不要忘记你的IabHelper.OnIabPurchaseFinishedListener是在另一个线程上调用,并且在Activity的onResume()方法之前被调用!因此,UpgradeComplete()或UpgradeError()可能会在旧设备上导致崩溃(在我的Gingerbread Sony Xperia Mini Pro上每次都崩溃,在Samsung Galaxy S4(Android 4.2.2)上没有任何问题)。这导致我的游戏延迟了3天。

那你是如何解决在Gingerbread上运行的问题的呢?我现在也遇到了同样的问题。我的想法是,我是否需要在UIThread上更新UI相关的内容呢?这可能会解决问题。非常感谢你已经提供的指针。 - Souvik Ghosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接