Вопрос по android, java – Встроенные покупки в Google Android «Доставка контента» Как правильно доставлять контент?

4

В настоящее время я пытаюсь закодировать покупки в приложении. Я искал документацию, информацию, учебные пособия по передовым методам для некоторых вещей, которые Google не обрабатывает.

Что я сделал до сих пор:

У меня запущена служба биллинга, которая поддерживает общение с Google Play. Эта услуга может заполнить «образец» транзакции и мое приложение получает сообщение.

Я хочу сейчас доставить контент на устройство. Что я думаю должно произойти дальше:

My app needs to contact my server and show some proof of the successful transaction. Do some Cert hand shaking or some such nonsense.

Then I will download the content and place that content into a database. I should probably encrypt the database with a device unique encryption of some sort.

Я жду, чтобы узнать, как сделать 2 вышеупомянутых вещи и все остальное, что нужно сделать. Я хотел бы разумное количество безопасности / шифрования. Любая документация / учебные пособия / примеры проектов были бы хорошими, я попытался найти этот материал и не нашел то, что искал.

Ваш Ответ

1   ответ
3

службы из примера.

Во-первых, вам следует позвонить на сервер, чтобы получить одноразовый номер, который будет использоваться либо для RestoreTransactions, либо для совершения покупки, чтобы сделать вещи максимально безопасными.

Давайте следовать тому, что происходит. Вот BillingReceiver, который вызывается из Google Play:

/**
 * 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);
}

Если вы посмотрите на handleCommand в BillingService.java, он обрабатывает это намерение:

/**
 * 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);
    }
}

Затем вызывается функция PurchaseStateChanged. Эта функция должна быть заменена вызовом на ваш сервер, чтобы создать сеанс для доставки вашего контента. Код из 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.

Спасибо, у меня еще есть работа. Это очень поможет. naradlov
Спасибо! Несколько других вопросов: Должен ли я просто сбросить BillingSecurity.java на сервер где-нибудь? И как мне подключиться к нему, чтобы получить существительное, сравнить открытые ключи и т. Д.? naradlov
Я уже вставил экземпляр AppEngine, так что это мой опыт. Вы должны обратиться к своему серверу, чтобы сохранить одноразовый номер в БД (на стороне сервера) и связать его с проводимой транзакцией. Я обычно использую комбинацию метки времени и некоторых данных, которые я получаю с телефона, например ANDROID_ID. Затем этот одноразовый номер отправляется клиенту для выставления счетов. Модуль Security.java содержит код для проверки подписи на основе вашего открытого ключа с панели инструментов разработчика.
Что если я сначала куплю предмет, а затем через некоторое время захочу его загрузить (приложение не было переустановлено)? Да, я могу указать в своем приложении, что предмет куплен, и приложение позволит загружать этот контент, только если он помечен как купленный. Но это выглядит небезопасно, потому что «куплен» Статус хранится на стороне клиента.

Похожие вопросы