3

サンプルアプリを見つめてアプリ内購入を実装しようとしています。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);
}
}

請求ヘルパー:

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); は空の配列リストを返します。そうすれば、確認することは何もありません。つまり、あなたは何も確認せず、Google は IN_APP_NOTIFY メッセージを送信し続けます。

于 2012-01-25T02:57:52.033 に答える
0

Intent.getAction が Const.ACTION_CONFIRM_NOTIFICATION ("com.android.vending.billing.CONFIRM_NOTIFICATION") の場合、 BillingService.handleCommand( Intent intent, int startId ) が 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 に答える