1

我正在为一个应用程序进行谷歌应用内购买。我创建了一个 id 为“app.test.item”的托管产品项目。我遵循了谷歌文档中指定的所有其他步骤。第一次购买应用程序运行良好。但是当我尝试卸载应用程序并再次安装时。该应用程序运行恢复事务请求。onRestoreTransactionsResponse() 方法被调用,我根据从市场返回的 RESULT_OK 使购买状态为真。我的疑问是应用程序如何知道只有名为“app.test.item”的项目被购买并因此被恢复。我还有其他一些项目,例如 "app.test.second.item" 。应用内计费如何看出两者之间的差异。我使用了 Google 提供的应用内结算代码。刚刚提到了一些共享偏好来存储购买状态。我在这里做错什么了吗。请指导我。

我也想在调试模式下测试这个应用程序,以便我可以追踪工作流程。但是应用程序应该使用发布版本进行签名。有什么方法可以在调试版本中完全运行这个应用程序(测试恢复事务)。我了解使用保留 productId 作为“android.test.purchased”进行一般购买的一般工作流程。但我需要测试 restoreTransactions()。任何帮助表示赞赏。

我在这里发布 PurchaseObserver 示例代码。

谢谢,

private class DungeonsPurchaseObserver extends PurchaseObserver {
    public DungeonsPurchaseObserver(Handler handler) {
        super(Dungeons.this, handler);
    }

    @Override
    public void onBillingSupported(boolean supported) {
        if (Consts.DEBUG) {
            Log.i(TAG, "supported: " + supported);
        }
        if (supported) {
            restoreDatabase();
        } else {
            showDialog(DIALOG_BILLING_NOT_SUPPORTED_ID);
        }
    }

    @Override
    public void onPurchaseStateChange(PurchaseState purchaseState, String itemId,
            int quantity, long purchaseTime, String developerPayload) {
        if (Consts.DEBUG) {
            Log.i(TAG, "onPurchaseStateChange() itemId: " + itemId + " " + purchaseState);
        }

        if (developerPayload == null) {
            logProductActivity(itemId, purchaseState.toString());
        } else {
            logProductActivity(itemId, purchaseState + "\n\t" + developerPayload);
        }

        if (purchaseState == PurchaseState.PURCHASED) {
            mOwnedItems.add(itemId);
            logProductActivity("APPLICATION", ": STATE PURCHASED");
            SharedPreferences pref = getSharedPreferences(PREF_FILE, MODE_PRIVATE);
            SharedPreferences.Editor editor = pref.edit();
            editor.putString(PURCHASE_STATUS, "ITEM PURCHASED");
            editor.commit();
        }
        if(purchaseState == PurchaseState.CANCELED)
        {
            logProductActivity("APPLICATION", ": STATE CANCELLED");
            SharedPreferences pref = getSharedPreferences(PREF_FILE, MODE_PRIVATE);
            SharedPreferences.Editor editor = pref.edit();
            editor.putString(PURCHASE_STATUS, "ITEM CANCELLED");
            editor.commit();
        }
        if(purchaseState == PurchaseState.REFUNDED)
        {
            logProductActivity("APPLICATION", ": STATE REFUNDED");
            SharedPreferences pref = getSharedPreferences(PREF_FILE, MODE_PRIVATE);
            SharedPreferences.Editor editor = pref.edit();
            editor.putString(PURCHASE_STATUS, "ITEM REFUNDED");
            editor.commit();
        }
    }

    @Override
    public void onRequestPurchaseResponse(RequestPurchase request,
            ResponseCode responseCode) {
        if (Consts.DEBUG) {
            Log.d(TAG, request.mProductId + ": " + responseCode);
        }
        if (responseCode == ResponseCode.RESULT_OK) {
            if (Consts.DEBUG) {
                Log.i(TAG, "purchase was successfully sent to server");
            }
            logProductActivity(request.mProductId, "sending purchase request");
        } else if (responseCode == ResponseCode.RESULT_USER_CANCELED) {
            if (Consts.DEBUG) {
                Log.i(TAG, "user canceled purchase");
            }
            logProductActivity(request.mProductId, "dismissed purchase dialog");
        } else {
            if (Consts.DEBUG) {
                Log.i(TAG, "purchase failed");
            }
            logProductActivity(request.mProductId, "request purchase returned " + responseCode);
        }
    }

    @Override
    public void onRestoreTransactionsResponse(RestoreTransactions request,
            ResponseCode responseCode) {
        if (responseCode == ResponseCode.RESULT_OK) {
            if (Consts.DEBUG) {
                Log.d(TAG, "completed RestoreTransactions request");
            }
            // Update the shared preferences so that we don't perform
            // a RestoreTransactions again.
            SharedPreferences prefs = getSharedPreferences(PREF_FILE, MODE_PRIVATE);
            SharedPreferences.Editor edit = prefs.edit();
            edit.putBoolean(DB_INITIALIZED, true);
            edit.putString(PURCHASE_STATUS, "ITEM PURCHASE RESTORED");
            edit.commit();
            logProductActivity("onRestoreTransactionsResponse() method in PurchaseObserver", "ITEM PURCHASE RESTORED");
        } else {
            if (Consts.DEBUG) {
                Log.d(TAG, "RestoreTransactions error: " + responseCode);
            }
        }
        logProductActivity("onRestoreTransactionsResponse() method in PurchaseObserver", responseCode.toString());
    }
}
4

2 回答 2

4

调试托管产品可能很困难,因为除非应用程序使用发布密钥签名,否则您无法使用它们。出于这个原因,我在测试 IAB 时使用我的发布密钥签署了我的调试版本。

对于多个产品,您需要检查项目ID。onPurchaseStateChange将为每个产品调用。

例如

public void onPurchaseStateChange(PurchaseState purchaseState, String itemId, int quantity, long purchaseTime, String developerPayload) {

    if (itemId.equals("app.test.item") {
        switch (purchaseState) {

        case PURCHASED:
            Log.i("Billing","Purchased app.test.item");
            break;

        default:
            Log.i("Billing","Something else");
            break;

        }
    }
于 2012-05-11T07:35:16.143 回答
0

如果您在 AndroidManifest.xml 中将 'debuggable' 标志设置为 true,您可以将调试器附加到您的应用程序。它使用发布密钥签名的事实与调试无关。至于应用程序如何知道是否购买了商品,如果您使用托管商品,它们会与您的谷歌帐户相关联。当您请求 RESTORE_TRANSACTIONS 时,您的帐户(GMail 地址)将发送到 Google Play/Market 服务器,并检查此人/帐户购买了哪些商品。如果使用非托管项,则需要自己跟踪项,不能使用 RESTORE_TRANSACTIONS。

于 2012-05-11T13:46:12.843 回答