java - 购买 IAP 完成后更新 GUI,IAPv3 - Android

标签 java android in-app-purchase in-app-billing

我终于弄明白了如何在 InAppBilling API 的 v3 中使用 IAP。用户现在可以随心所欲地消费任意数量的产品。

现在我希望在确认购买完成后更新用户的 GUI。我已经将 Toasts 放在下面的代码中,以尝试找出更新 GUI 的位置,但我还没有出现 Toast。但请记住,使用 IAP 是有效的。

我已在我的代码下方确定了为用户更新 GUI 的 fragment 。该代码 fragment 是我希望在成功购买完成后运行的代码。

所以我的问题是将该代码 fragment 放在哪里,以便在成功购买后为用户更新 GUI。

public class Levels extends SwarmActivity {

    //static final String SKU_BUYLIVES = "buy5lives";
    static final String SKU_BUYLIVES = "android.test.purchased";

    IabHelper mHelper;
    IInAppBillingService mService;

    @Override
    public void onCreate(Bundle savedInstanceState) {

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

        moreLives.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                buyLives();
            }
        });
     }

    public void buyLives() {

        final Dialog dialog = new Dialog(c);
        dialog.setContentView(R.layout.buylives);

        String base64EncodedPublicKey = a + b + d + e + f + g + h + i + j + k;

        TextView title = (TextView)dialog.findViewById(R.id.question);
        Button no = (Button)dialog.findViewById(R.id.no);
        Button yes = (Button)dialog.findViewById(R.id.yes);

        title.setText(c.getResources().getString(R.string.buyLivesQuestion));
        no.setText(c.getResources().getString(R.string.maybelater));
        yes.setText(c.getResources().getString(R.string.buy));

        // Create the helper, passing it our context and the public key to verify signatures with
        mHelper = new IabHelper(Levels.this, base64EncodedPublicKey);

        // start setup. this is asynchronous and the specified listener will be called once setup completes.
        mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
            public void onIabSetupFinished(IabResult result) {

                if (!result.isSuccess()) {
                    // there was a problem.
                    complain("An error has occurred.  We apologize for the inconvenience.    " + c.getResources().getString(R.string.problem1) + " " + result);
                    return;
                }

                // IAB is fully set up. Now, let's get an inventory of stuff we own.
                mHelper.queryInventoryAsync(mGotInventoryListener);                
            }
        });

        yes.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {                
                mHelper.launchPurchaseFlow(Levels.this, SKU_BUYLIVES, 10001, mPurchaseFinishedListener, "payload");
                dialog.dismiss();

// the below ~14 lines is the code that I want to call to update the GUI for the user.  this block of code has been all over the place.  this is just the last spot I tested it at.
                SharedPreferences settings = getSharedPreferences("level_SP", 0);
                livesCount = settings.getInt("livesTotal1", 0);
                remainderTimeStamp = settings.getLong("remainderTimeStamp1", 0);

                livesCount = 5;
                remainderTimeStamp = 0;

                SharedPreferences.Editor editor = settings.edit();
                editor.putInt("livesTotal1", livesCount);
                editor.putLong("remainderTimeStamp1", remainderTimeStamp);
                editor.commit();

                livesCountTV.setText(c.getResources().getString(R.string.livesCount) + "  " + livesCount);
                livesCounterTV.setText(c.getResources().getString(R.string.livesCounter) + "  FULL!");
            }
        });

        no.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                dialog.dismiss();
            }
        });
        dialog.show();
    }

    // listener that's called when we finish querying the items and subscriptions we own.
    IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
        public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
            if(result.isFailure()) {

                complain(c.getResources().getString(R.string.sorryerror) + c.getResources().getString(R.string.failedtoquery) + " " + result);
                return;
            } else if(inventory.hasPurchase(SKU_BUYLIVES)) {
                mHelper.consumeAsync(inventory.getPurchase(SKU_BUYLIVES), null);
            }
        }
    };

    // callback for when a purchase is finished
    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result, Purchase purchase) {

            // this appears to the user immediately after purchasing.
            if(result.isFailure()) {

                complain(c.getResources().getString(R.string.sorryerror) + result);

            } else if(purchase.getSku().equals(SKU_BUYLIVES)) {

                alert(c.getResources().getString(R.string.livesbought));

                try {
                    Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
                    int response = ownedItems.getInt("RESPONSE_CODE");

                    if (response == 0) {
                        // success
                        Toast.makeText(Levels.this, "SUCCESS", Toast.LENGTH_LONG).show();

                        try {
                            mService.consumePurchase(3, getPackageName(), SKU_BUYLIVES);

// this Toast is never seen.
                            Toast t = Toast.makeText(Levels.this, "PURCHASE CONSUMED", Toast.LENGTH_LONG);
                            t.setGravity(Gravity.CENTER, 0, 0);
                            t.show();
                        } catch (RemoteException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }                       
                    } else {
                        // error
// this Toast is never seen.
                        Toast.makeText(Levels.this, "ERROR", Toast.LENGTH_LONG).show();
                    }

                } catch (RemoteException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }       
            }
            return;
        }
    };

    void complain(String message) {
        alert("Error: " + message);
    }

    void alert(String message) {
        AlertDialog.Builder bld = new AlertDialog.Builder(this);
        bld.setMessage(message);
        bld.setNeutralButton("OK", null);
        bld.create().show();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if(mHelper != null) mHelper.dispose();
        mHelper = null;
    }
}

最佳答案

要打开 Google Play 购买对话框,您应该对购买意向使用 startIntentSenderForResult() 方法。用户完成此对话框后,onActivityResult() 将在您的 Activity 中被调用。如果需要,您应该在此处验证购买和更新 GUI。

这是您如何打开购买对话框的示例。

public void buyProduct() {
    PendingIntent buyIntent = ... // create your intent here
    IntentSender sender = buyIntent.getIntentSender();
    try {
        startIntentSenderForResult(sender, REQ_BUY_PRODUCT, new Intent(), 0, 0, 0);
    } catch (SendIntentException e) {
        Log.e(TAG, "", e);
    }
}

这是如何处理购买意向的示例

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQ_BUY_PRODUCT && resultCode == Activity.RESULT_OK) {
        // here you verify data intent and update your GUI
        ...
        return;
    }
}

这两种方法都属于您的 Activity 。

关于java - 购买 IAP 完成后更新 GUI,IAPv3 - Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18362107/

相关文章:

java - 使用sqlite数据库按列获取特定数据

android - 我可以在 Android 应用程序中嵌入自定义字体吗?

android - Android Automotive 支持 Jetpack Compose 吗?

Android——是否可以扭曲 TextView?

java - 刷新库存时出错。应用内结算

iphone - 我可以从我的服务器获取应用内购买的价格吗?

java - 从 eclipse 迁移到 vim 有什么好的教程吗?

java - 可扩展 ListView - subview 和组 View 之间的空间

java - Heroku 上的 Dropwizard DataSourceFactory 只有 DATABASE_URL

android - Google Play 中的测试订单会在五分钟后自动退款