Android应用内结算获取购买问题

时间:2016-08-25 20:23:24

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

我的应用内应用结算存在问题。我认为它在上周运作良好,但我得到了意想不到的结果。

我有大约10件待售物品。购买时,每个项目将共享的pref值设置为true,如果已购买则查询库存。一个项目是“全部购买”按钮,当购买时,它假设将所有其他的值设置为真。这很好用,当我添加新商品时会出现问题。 “全部购买”也可以访问这些,但似乎不是。

我会尝试让代码尽可能简单,同时仍然显示所需的信息: BaseActivity.java(所有应用内购买设置):

//SKU FOR our products
static final String SKU_W31 = "workout_31";
static final String SKU_W32 = "workout_32";
static final String SKU_W37 = "workout_37";
static final String SKU_ALL = "all_workouts";

//is paid?
public boolean m31paid = false;
public boolean m32paid = false;
public boolean m37paid = false;
public boolean mAllPaid = false;

IabHelper mHelper;
IabBroadcastReceiver mBroadcastReceiver;

    @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0);
mHelper = new IabHelper(this, base64EncodedPublicKey);
    //SET FALSE FOR LIVE APP
    mHelper.enableDebugLogging(false);

    mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
        public void onIabSetupFinished(IabResult result) {
            if (!result.isSuccess()) {
                Log.d(LOG, "Problem setting up in app billing: " + result);
            } else Log.d(LOG, "set up correctly!");
            if (mHelper == null) return;

            mBroadcastReceiver = new IabBroadcastReceiver(BaseActivity.this);
            IntentFilter broadcastFilter = new IntentFilter(IabBroadcastReceiver.ACTION);
            registerReceiver(mBroadcastReceiver, broadcastFilter);

            // IAB is fully set up. Now, let's get an inventory of stuff we own.
            Log.d(LOG, "Setup successful. Querying inventory.");

            try {
                mHelper.queryInventoryAsync(mGotInventoryListener);
            } catch (IabHelper.IabAsyncInProgressException e) {
                complain("Error querying inventory. Another async operation in progress.");
            }
        }
    });
}

IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
        Log.d(LOG, "Query inventory finished.");
        SharedPreferences.Editor editor = getSharedPreferences("my_pref", MODE_PRIVATE).edit();

        // Have we been disposed of in the meantime? If so, quit.
        if (mHelper == null) return;


Purchase w37Purchase = inventory.getPurchase(SKU_W37);
        m37paid = (w37Purchase != null && verifyDeveloperPayload(w37Purchase));
        Log.d(LOG, "User has workout 37" + (m37paid ? "BOUGHT" : "NOT BOUGHT"));
        if (w37Purchase != null) {
            editor.putBoolean("workout37", true);
            editor.apply();
        }

Purchase w32Purchase = inventory.getPurchase(SKU_W32);
        m32paid = (w32Purchase != null && verifyDeveloperPayload(w32Purchase));
        Log.d(LOG, "User has workout 32" + (m32paid ? "BOUGHT" : "NOT BOUGHT"));
        if (w32Purchase != null) {
            editor.putBoolean("workout32", true);
            editor.apply();
        }

Purchase w31Purchase = inventory.getPurchase(SKU_W31);
        m31paid = (w31Purchase != null && verifyDeveloperPayload(w31Purchase));
        Log.d(LOG, "User has workout 31" + (m31paid ? "BOUGHT" : "NOT BOUGHT"));
        if (w31Purchase != null) {
            editor.putBoolean("workout31", true);
            editor.apply();
        }

Purchase wAllPurchase = inventory.getPurchase(SKU_ALL);
        mAllPaid = (wAllPurchase != null && verifyDeveloperPayload(wAllPurchase));
        Log.d(LOG, "User has " + (mAllPaid ? "BOUGHT" : "NOT BOUGHT"));
        if (wAllPurchase != null) {
            editor.putBoolean("workout31", true);
            editor.putBoolean("workout32", true);
            editor.putBoolean("workout37", true);
            editor.apply();
        }

    }};

然后我有购买的方法,我把它放在相应按钮的onClick上:

public void onBuy31ButtonClicked (View arg0) {
    Log.d(LOG, "Buy 31 button clicked.");
    if (m31paid) {
        Toast.makeText(getApplicationContext(), R.string.already_bought, Toast.LENGTH_LONG).show();
        return;
    }
    Log.d(LOG, "launching purchase for 31");
    String payload = "";
    try {
        mHelper.launchPurchaseFlow(this, SKU_W31, RC_REQUEST, mPurchaseFinishedListener, payload);
    } catch (IabHelper.IabAsyncInProgressException e) {
        Toast.makeText(getApplicationContext(), R.string.purchase_error, Toast.LENGTH_LONG).show();
    }
}
public void onBuy32ButtonClicked (View arg0) {
    Log.d(LOG, "Buy 32 button clicked.");
    if (m32paid) {
        Toast.makeText(getApplicationContext(), R.string.already_bought, Toast.LENGTH_LONG).show();
        return;
    }
    Log.d(LOG, "launching purchase for 32");
    String payload = "";
    try {
        mHelper.launchPurchaseFlow(this, SKU_W32, RC_REQUEST, mPurchaseFinishedListener, payload);
    } catch (IabHelper.IabAsyncInProgressException e) {
        Toast.makeText(getApplicationContext(), R.string.purchase_error, Toast.LENGTH_LONG).show();
    }
}
public void onBuy37ButtonClicked (View arg0) {
    Log.d(LOG, "Buy 37 button clicked.");
    if (m37paid) {
        Toast.makeText(getApplicationContext(), R.string.already_bought, Toast.LENGTH_LONG).show();
        return;
    }
    Log.d(LOG, "launching purchase for 37");
    String payload = "";
    try {
        mHelper.launchPurchaseFlow(this, SKU_W37, RC_REQUEST, mPurchaseFinishedListener, payload);
    } catch (IabHelper.IabAsyncInProgressException e) {
        Toast.makeText(getApplicationContext(), R.string.purchase_error, Toast.LENGTH_LONG).show();
    }
}
public void onBuyAllButtonClicked (View arg0) {
    Log.d(LOG, "Buy all button clicked.");
    if (m32paid) {
        Toast.makeText(getApplicationContext(), R.string.already_bought, Toast.LENGTH_LONG).show();
        return;
    }
    Log.d(LOG, "launching purchase for all");
    String payload = "";
    try {
        mHelper.launchPurchaseFlow(this, SKU_ALL, RC_REQUEST, mPurchaseFinishedListener, payload);
    } catch (IabHelper.IabAsyncInProgressException e) {
        Toast.makeText(getApplicationContext(), R.string.purchase_error, Toast.LENGTH_LONG).show();
    }
}

我的mPurchaseFinishedListener:

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
        Log.d(LOG, "Purchase finished: " + result + ", purchase: " + purchase);
        SharedPreferences.Editor editor = getSharedPreferences("my_pref", MODE_PRIVATE).edit();

        // if we were disposed of in the meantime, quit.
        if (mHelper == null) return;

        if (result.isFailure()) {
            complain("Error purchasing: " + result);

            return;
        }
        if (purchase.getSku().equals(SKU_W30)) {
            editor.putBoolean("workout30", true);
            editor.apply();
            return;
        }
        if (purchase.getSku().equals(SKU_W31)) {
            editor.putBoolean("workout31", true);
            editor.apply();
            return;
        }
        if (purchase.getSku().equals(SKU_W32)) {
            editor.putBoolean("workout32", true);
            editor.apply();
            return;
        }
        if (purchase.getSku().equals(SKU_W37)) {
            editor.putBoolean("workout37", true);
            editor.apply();
            return;
       if(purchase.getSku().equals(SKU_ALL)) {
            editor.putBoolean("workout31", true);
            editor.putBoolean("workout32", true);
            editor.putBoolean("workout37", true);
            editor.apply();
            return;
        }

然后在数据的位置,我只需要一个if语句来检查布尔值:

xpandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
        SharedPreferences pref = getApplicationContext().getSharedPreferences("my_pref", MODE_PRIVATE);
        boolean w31 = pref.getBoolean("workout31", false);
        boolean w32 = pref.getBoolean("workout32", false);
        boolean w37 = pref.getBoolean("workout37", false);

if (groupPosition == 2) {
                if(w31 == true) {
                    if (childPosition == 0) {
                        Intent intent = new Intent(getApplicationContext(), WorkoutDaysActivity.class);
                        intent.putExtra("workout", "w31w1");
                        startActivity(intent);
                    }
                    if (childPosition == 1) {
                        Intent intent = new Intent(getApplicationContext(), WorkoutDaysActivity.class);
                        intent.putExtra("workout", "w31w2");
                        startActivity(intent);
                    }
                }else Toast.makeText(getApplicationContext(), "Sorry, but you need to purchase these workouts from the menu.", Toast.LENGTH_LONG).show();
        }

所有子项都具有与上面相同的代码,用w32和w37切换w31。

我已经购买了大部分商品以尝试削减代码但仍然明白了,但基本上发生的事情是之前添加了31和32,然后我使用了购买全部按钮,他们工作。但是我在稍后的更新中添加了37,我的理论是当它查询所有锻炼并看到它被购买时,布尔值会改变它。实际上,当我在可扩展列表视图中点击37时,我得到了需要购买的祝酒词,当我进入购买页面并点击“全部购买”时,我得知它已经购买了。

有人看到我的代码有什么问题吗?非常感谢,这造成了巨大的问题!

1 个答案:

答案 0 :(得分:0)

异步操作的原因您可能遇到竞争条件。您的可扩展列表视图活动应注册到SharedPreferences

中的所有更改