你必須做出一些改變,從樣品的計費服務的客戶端代碼。
首先,你應該打電話給你的服務器,以獲取將用於或者RestoreTransactions或進行購買的隨機數,把事情儘可能的安全。
讓我們跟隨發生了什麼。下面是得到由谷歌播放稱爲BillingReceiver:
/**
* This is called when Android Market sends information about a purchase state
* change. The signedData parameter is a plaintext JSON string that is
* signed by the server with the developer's private key. The signature
* for the signed data is passed in the signature parameter.
* @param context the context
* @param signedData the (unencrypted) JSON string
* @param signature the signature for the signedData
*/
private void purchaseStateChanged(Context context, String signedData, String signature) {
Intent intent = new Intent(Consts.ACTION_PURCHASE_STATE_CHANGED);
intent.setClass(context, BillingService.class);
intent.putExtra(Consts.INAPP_SIGNED_DATA, signedData);
intent.putExtra(Consts.INAPP_SIGNATURE, signature);
context.startService(intent);
}
如果你看看內BillingService.java handleCommand,它處理這個意圖:
/**
* The {@link BillingReceiver} sends messages to this service using intents.
* Each intent has an action and some extra arguments specific to that action.
* @param intent the intent containing one of the supported actions
* @param startId an identifier for the invocation instance of this service
*/
public void handleCommand(Intent intent, int startId) {
String action = intent.getAction();
if (Consts.DEBUG) {
Log.i(TAG, "handleCommand() action: " + action);
}
if (Consts.ACTION_CONFIRM_NOTIFICATION.equals(action)) {
String[] notifyIds = intent.getStringArrayExtra(Consts.NOTIFICATION_ID);
confirmNotifications(startId, notifyIds);
} else if (Consts.ACTION_GET_PURCHASE_INFORMATION.equals(action)) {
String notifyId = intent.getStringExtra(Consts.NOTIFICATION_ID);
getPurchaseInformation(startId, new String[] { notifyId });
} else if (Consts.ACTION_PURCHASE_STATE_CHANGED.equals(action)) {
String signedData = intent.getStringExtra(Consts.INAPP_SIGNED_DATA);
String signature = intent.getStringExtra(Consts.INAPP_SIGNATURE);
purchaseStateChanged(startId, signedData, signature);
} else if (Consts.ACTION_RESPONSE_CODE.equals(action)) {
long requestId = intent.getLongExtra(Consts.INAPP_REQUEST_ID, -1);
int responseCodeIndex = intent.getIntExtra(Consts.INAPP_RESPONSE_CODE,
ResponseCode.RESULT_ERROR.ordinal());
ResponseCode responseCode = ResponseCode.valueOf(responseCodeIndex);
checkResponseCode(requestId, responseCode);
}
}
這就要求thePurchaseStateChanged功能。此功能應該由您的服務器調用來爲您的內容傳送創建一個會話。來自Security.java的代碼應該移植到服務器端以驗證雲中的事務。
/**
* Verifies that the data was signed with the given signature, and calls
* {@link ResponseHandler#purchaseResponse(Context, PurchaseState, String, String, long)}
* for each verified purchase.
* @param startId an identifier for the invocation instance of this service
* @param signedData the signed JSON string (signed, not encrypted)
* @param signature the signature for the data, signed with the private key
*/
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);
}
}
確保把你的公鑰在服務器端的移植Security.java文件。
謝謝!其他幾個問題:我是否將BillingSecurity.java轉儲到某個服務器上?然後,我如何連接它來獲取聲明並比較公鑰等? – naradlov
之前我已經放入了一個AppEngine實例,所以這是我的經驗。您應該打電話給您的服務器以將臨時數據存入數據庫(在服務器端)並將其與手頭的交易相關聯。我通常使用時間戳和手機中的一些數據的組合,例如ANDROID_ID。然後該nonce被髮送到帳單客戶端。 Security.java模塊包含用於根據開發人員儀表板中的公鑰驗證簽名的代碼。 – dagalpin
謝謝,我還有一些工作要做。這會幫助很多。 – naradlov