2012-05-03 14 views
4

我目前正在嘗試編寫應用內購買代碼。我正在尋找文檔,信息和教程,介紹Google無法處理的一些內容的最佳做法。Google Android應用內購買「Content Delivery」如何正確提供內容?

我迄今所做的:

我有一個處理談論谷歌播放計費服務運行。此服務可以完成「示例」交易,我的應用程序收到該消息。

我想現在交付內容的設備。我覺得需要接下來會發生什麼:

  1. 我的應用程序需要聯繫我的服務器,並顯示交易成功的一些證據。做一些證書搖手或一些這樣的廢話。

  2. 然後,我將下載的內容和地方內容到數據庫中。我應該用某種設備的唯一加密來加密數據庫。

我期待着學習如何做上述2件事和其他需要做的事情。我想要一個合理數量的安全/加密。任何文檔/教程/示例項目都會很棒,我試着搜索這些東西,但沒有找到我想要的東西。

回答

3

你必須做出一些改變,從樣品的計費服務的客戶端代碼。

首先,你應該打電話給你的服務器,以獲取將用於或者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文件。

+0

謝謝!其他幾個問題:我是否將BillingSecurity.java轉儲到某個服務器上?然後,我如何連接它來獲取聲明並比較公鑰等? – naradlov

+0

之前我已經放入了一個AppEngine實例,所以這是我的經驗。您應該打電話給您的服務器以將臨時數據存入數據庫(在服務器端)並將其與手頭的交易相關聯。我通常使用時間戳和手機中的一些數據的組合,例如ANDROID_ID。然後該nonce被髮送到帳單客戶端。 Security.java模塊包含用於根據開發人員儀表板中的公鑰驗證簽名的代碼。 – dagalpin

+0

謝謝,我還有一些工作要做。這會幫助很多。 – naradlov