如何确认android计费通知?

如何确认android计费通知?,android,in-app-purchase,in-app-billing,Android,In App Purchase,In App Billing,我正试图通过示例应用程序实现应用内购买。 我正在使用web服务器验证购买,并在那里进行验证。问题在于,无论交易结果如何,购买状态更改通知从未停止。 也就是说,在我关闭应用程序之前,我每分钟都会收到购买状态更改通知,无论我的购买成功、失败或被用户取消 下面是我正在使用的一些示例代码: public class BillingReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, I

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

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

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);
}
}
BillingHelper:

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()?");
    }
ArrayList purchases=BillingSecurity.VerifyPurchases(mApp,signedData,signature);
if(purchases!=null&&purchases.size()>0)
{
latestPurchase=purchases.get(0);
confirmTransaction(新字符串[]{latestPurchase.notificationId});
}
如果(mCompletedHandler!=null){
McCompletedHandler.sendEmptyMessage(0);
}否则{
Log.e(标记“verifyPurchase error.Handler未实例化。是否调用了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;
}
publicstaticarraylistverifypurchase(上下文上下文、字符串签名数据、字符串签名){
如果(signedData==null){
Log.e(标记“数据为空”);
}
Log.i(标记“signedData:+signedData”);
布尔验证=假;
如果(!TextUtils.isEmpty(签名)){
尝试
{
布尔结果=Server.verifyandridpurchase(signedData,signature);
如果(!结果)
{
Log.d(“验证结果”、“验证失败”);
返回null;
}               
验证=真实;
}
}
JSONObject jObject;
JSONArray jTransactionsArray=null;
int numTransactions=0;
长nonce=0L;
试一试{
jObject=新的JSONObject(signedData);
//如果用户退出购买页面,nonce可能为null。
nonce=jObject.optLong(“nonce”);
jTransactionsArray=jObject.optJSONArray(“订单”);
if(jTransactionsArray!=null){
numTransactions=jTransactionsArray.length();
}
}捕获(JSONException e){
}
如果(!BillingSecurity.isNonceKnown(nonce)){
Log.w(标记“未找到当前值:”+Nonce);
返回null;
}
ArrayList购买=新建ArrayList();
试一试{
for(int i=0;i
我假设您没有在应用程序中包含公钥,因为您正在远程服务器上进行验证。在这种情况下,行
BillingSecurity.verifyPurchase(mApp,signedData,signature)

将返回一个空数组列表。那你就没什么可确认的了。换句话说,你永远不会确认任何事情,谷歌会继续在APP中发送通知消息给你

确保当Intent.getAction为Const.ACTION\u CONFIRM\u通知(“com.android.vending.billing.CONFIRM\u通知”)时,您的BillingService.handleCommand(Intent Intent,int startId)发送并运行ConfirmNotification请求

您可以通过触发确认通知意图来启动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 );

}