InApp购买RESTORE_TRANSACTIONS,我无法找出代码

时间:2011-12-26 19:46:37

标签: android in-app-purchase

我在我的编码中添加了一个应用内购买,它在购买时运行良好,但当我尝试在删除应用程序并再次安装时添加Restore_Transaction代码时出现错误并关闭应用程序,我已添加以下编码

我写的onCreate

startService(new Intent(mContext, BillingService.class));
        BillingHelper.setCompletedHandler(mTransactionHandler);

        if (BillingHelper.isBillingSupported()) {
            BillingHelper.restoreTransactionInformation(BillingSecurity
                    .generateNonce());
        }

然后我使用

调用处理程序
public Handler mTransactionHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            if (BillingHelper.latestPurchase.isPurchased()) {
                showItem();
            }
        };
    };

    private void showItem() {
        purchased = Purchased.getPurchaseInfo(getApplicationContext());
        if (purchased == null) {
            Date d = new Date();
            Toast.makeText(getApplicationContext(), "--- Upgrated ---",
                    Toast.LENGTH_LONG).show();
            purchased = new Purchased(getApplicationContext());
            purchased.isPurchased = 1;
            purchased.purchasedDate = d.getTime();
            purchased.save();
            Intent intent = new Intent(ActorGenieActivity.this,
                    SplashScreen.class);
            startActivity(intent);
        }
    }

3 个答案:

答案 0 :(得分:5)

我找到了问题的答案,而不是anddev

您必须检查购买是否为空

public static void verifyPurchase(String signedData, String signature) {
    ArrayList<VerifiedPurchase> purchases = BillingSecurity.verifyPurchase(
            signedData, signature);
    if (purchases != null && !purchases.isEmpty()) {
        latestPurchase = purchases.get(0);
        confirmTransaction(new String[] { latestPurchase.notificationId });
        if (mCompletedHandler != null) {
            mCompletedHandler.sendEmptyMessage(0);
        } else {
            Log
                    .e(
                            TAG,
                            "verifyPurchase error. Handler not instantiated. Have you called setCompletedHandler()?");
        }
    }
}

并且在Confirm_Notification中你要检查

if (notifyIds[0] != null)

答案 1 :(得分:1)

按照:

    confirmTransaction(new String[] { latestPurchase.notificationId });

在这里并执行此操作:

protected static void confirmTransaction(String[] notifyIds) {
        if (amIDead()) {
            return;
        }
        // there isn't a notifyid then this was the restore transaction call and this should be skipped 
        if (notifyIds[0] != null){
        Log.i(TAG, "confirmTransaction()");
        Bundle request = makeRequestBundle("CONFIRM_NOTIFICATIONS");
             ......
             ......
}

像我的魅力一样工作..谢谢你们......

答案 2 :(得分:1)

您可以使用以下代码获取购买历史记录:

public static ArrayList<VerifiedPurchase> verifyPurchase(String signedData,
            String signature) {
        if (signedData == null) {
            //Log.e(TAG, "data is null");
            return null;
        }
        if (Constans.DEBUG) {
            //Log.i(TAG, "signedData: " + signedData);
        }
        boolean verified = false;
        if (!TextUtils.isEmpty(signature)) {
            /**
             * Compute your public key (that you got from the Android Market
             * publisher site).
             * 
             * Instead of just storing the entire literal string here embedded
             * in the program, construct the key at runtime from pieces or use
             * bit manipulation (for example, XOR with some other string) to
             * hide the actual key. The key itself is not secret information,
             * but we don't want to make it easy for an adversary to replace the
             * public key with one of their own and then fake messages from the
             * server.
             * 
             * Generally, encryption keys / passwords should only be kept in
             * memory long enough to perform the operation they need to perform.
             */
            String base64EncodedPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKgldGQPL/xV9WKLmY62UVgEm7gsPI/T/nQxRKpYN17m8Sq3gO9nWD17wXew4oNaHmMAmArS7s7eFi3Z+XiyWil1iZvEOdBOdZD502BzujPoBa4Fu9eITPBO9tzBEdvNLXf8amnsRj53TA4bcxB2O6OcXrQIv3t3n5Dg5Nn+rJpoKSNUv7NEzJagG/2NhyjIysAObbvQ5SBQ5NgRtZlvhsTeQJPMLhRAoRcTK/+47VkhrxM3PppeGjoNRryn6d+RhMjs/nydvoQtP2V76UcUu4m+daDnK3PxOnwLt50hNtQhNf3VgixVrSKfHUWp240uEz9MHstjj8BWPH9BFF/TewIDAQAB";
            PublicKey key = Security.generatePublicKey(base64EncodedPublicKey);
            verified = Security.verify(key, signedData, signature);
            if (!verified) {
                //Log.w(TAG, "signature does not match data.");
                return null;
            }
        }

        JSONObject jObject;
        JSONArray jTransactionsArray = null;
        int numTransactions = 0;
        long nonce = 0L;
        try {
            jObject = new JSONObject(signedData);

            // The nonce might be null if the user backed out of the buy page.
            nonce = jObject.optLong("nonce");
            jTransactionsArray = jObject.optJSONArray("orders");
            if (jTransactionsArray != null) {
                numTransactions = jTransactionsArray.length();
            }
        } catch (JSONException e) {
            return null;
        }

        if (!Security.isNonceKnown(nonce)) {
            //Log.w(TAG, "Nonce not found: " + nonce);
            return null;
        }

        ArrayList<VerifiedPurchase> purchases = new ArrayList<VerifiedPurchase>();
        try {
            for (int i = 0; i < numTransactions; i++) {
                JSONObject jElement = jTransactionsArray.getJSONObject(i);
                int response = jElement.getInt("purchaseState");
                PurchaseState purchaseState = PurchaseState.valueOf(response);
                String productId = jElement.getString("productId");
                String packageName = jElement.getString("packageName");
                long purchaseTime = jElement.getLong("purchaseTime");
                String orderId = jElement.optString("orderId", "");
                String notifyId = null;
                if (jElement.has("notificationId")) {
                    notifyId = jElement.getString("notificationId");
                }
                String developerPayload = jElement.optString(
                        "developerPayload", null);

                // If the purchase state is PURCHASED, then we require a
                // verified nonce.
                if (purchaseState == PurchaseState.PURCHASED && !verified) {
                    continue;
                }
                purchases.add(new VerifiedPurchase(purchaseState, notifyId,
                        productId, orderId, purchaseTime, developerPayload));
            }
        } catch (JSONException e) {
            //Log.e(TAG, "JSON exception: ", e);
            return null;
        }
        removeNonce(nonce);
        return purchases;
    }

您可以在BillingService类中使用以下方法调用此方法:

private void purchaseStateChanged(int startId, String signedData,
            String signature) {
        ArrayList<Security.VerifiedPurchase> purchases;
        purchases = Security.verifyPurchase(signedData, signature);
        if (purchases == null) {
            return;
        }

        ArrayList<String> notifyList = new ArrayList<String>();
        for (VerifiedPurchase vp : purchases) {
            if (vp.notificationId != null) {
                notifyList.add(vp.notificationId);
            }
            ResponseHandler.purchaseResponse(this, vp.purchaseState,
                    vp.productId, vp.orderId, vp.purchaseTime,
                    vp.developerPayload);
        }
        if (!notifyList.isEmpty()) {
            String[] notifyIds = notifyList.toArray(new String[notifyList
                    .size()]);
            confirmNotifications(startId, notifyIds);
        }
    }