3

我正在尝试通过示例应用程序实现应用程序内购买。我正在使用网络服务器验证购买并在那里进行验证。问题在于,无论交易结果如何,购买状态更改通知都不会停止。也就是说,我每分钟都会收到购买状态更改通知,直到我关闭应用程序,无论我进行的购买是成功、不成功还是被用户取消。

这是我正在使用的一些示例代码:

public class BillingReceiver extends BroadcastReceiver 
{
@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    Log.i(TAG, "Received action: " + action);
    if (ACTION_PURCHASE_STATE_CHANGED.equals(action)) {
        String signedData = intent.getStringExtra(INAPP_SIGNED_DATA);
        String signature = intent.getStringExtra(INAPP_SIGNATURE);
        purchaseStateChanged(context, signedData, signature);
    } else if (ACTION_NOTIFY.equals(action)) {
        String notifyId = intent.getStringExtra(NOTIFICATION_ID);
        notify(context, notifyId);
    } else if (ACTION_RESPONSE_CODE.equals(action)) {
        long requestId = intent.getLongExtra(INAPP_REQUEST_ID, -1);
        int responseCodeIndex = intent.getIntExtra(INAPP_RESPONSE_CODE, C.ResponseCode.RESULT_ERROR.ordinal());
        checkResponseCode(context, requestId, responseCodeIndex);
    } else {
       Log.e(TAG, "unexpected action: " + action);
    }
}

private void purchaseStateChanged(Context context, String signedData, String signature) {
    Log.i(TAG, "purchaseStateChanged got signedData: " + signedData);
    Log.i(TAG, "purchaseStateChanged got signature: " + signature);
    BillingHelper.verifyPurchase(signedData, signature);
}
}

计费助手:

ArrayList<VerifiedPurchase> purchases = BillingSecurity.verifyPurchase(mApp, signedData, signature);

    if(purchases != null && purchases.size() > 0)
    {
        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()?");
    }

计费安全:

public static ArrayList<VerifiedPurchase> verifyPurchase(Context context, String signedData, String signature) {
    if (signedData == null) {
        Log.e(TAG, "data is null");
    }
    Log.i(TAG, "signedData: " + signedData);
    boolean verified = false;
    if (!TextUtils.isEmpty(signature)) {

        try
        {
            boolean result = Server.verifyAndroidPurchase( signedData, signature);
            if(!result)
            {
                Log.d("VERIFY RESULT", "verification failed");
                                               return null;
            }               
            verified = true;
        }

    }

    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) {
    }

    if (!BillingSecurity.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;
}
4

2 回答 2

1

我假设您没有在应用程序中包含您的公钥,因为您正在远程服务器上进行验证。在这种情况下,lineBillingSecurity.verifyPurchase(mApp, signedData, signature); 将返回一个空数组列表。这不会让你确认任何事情。换句话说,你永远不会确认任何事情,谷歌会继续向你发送 IN_APP_NOTIFY 消息。

于 2012-01-25T02:57:52.033 回答
0

确保您的 BillingService.handleCommand( Intent intent, int startId ) 在 intent.getAction 为 Const.ACTION_CONFIRM_NOTIFICATION ("com.android.vending.billing.CONFIRM_NOTIFICATION") 时发送并运行 ConfirmNotification 请求

您可以通过触发 CONFIRM_NOTIFICATION 意图来启动 BillingService:

public void confirmPurchases( int intentId, String[] notificationIds ) {
    Intent intent = new Intent( Consts.ACTION_CONFIRM_NOTIFICATION );
    intent.setClass( context, BillingService.class );
    intent.putExtra(Consts.NOTIFICATION_ID, notificationIds);
    context.startService( intent );

}
于 2012-08-02T08:46:29.600 回答