1

この機能をアプリケーションに追加するために、アプリ内課金のサンプルアプリを使用しています。アプリへの追加が完了し、すべての動作をテストした後、このセキュリティクラスのコメントに気づきました。

セキュリティ関連の方法。安全な実装のために、このコードはすべて、デバイス上のアプリケーションと通信するサーバーに実装する必要があります。この例をわかりやすくするために、このコードはここに含まれており、デバイス上で実行されます。電話で購入を確認する必要がある場合は、このコードを難読化して、攻撃者がすべての購入を確認済みとして扱うスタブにコードを置き換えないようにする必要があります。

Googleが提案しているように、私はサーバー側で購入確認を行うので、プロジェクトにセキュリティクラスは本当に必要ありません。問題は、SecurityクラスのBillingServiceクラスの依存関係を削除する方法がわからないことです。

まず、Securityクラスを削除し、BillingServiceとそれが使用されているほとんどの場所のエラーを追跡しました。ただし、1つの場所を除いて簡単に削除できます。

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クラスを使用せずに(アプリ内課金サンプルアプリに基づいて)自分のpurchaseStateChangedメソッドを共有できるといいのですが。

4

1 に答える 1

1

だからここに私がやったことです。最初に BillingService への呼び出しがアプリケーションのメイン スレッドで発生するため、バックグラウンド スレッドでサーバー呼び出しを発行する必要があります。バックグラウンド スレッドで「confirmNotifications」などのメソッドを呼び出すとどのような影響があるかわからなかったので、メイン スレッドで処理を終了することにしました。

リモート呼び出しの完了後にメイン スレッドにディスパッチできるコールバック インターフェイス VerifyTransactionCompletion を作成しました。

サンプルで最初に実行したことの代わりに、Security クラスを保持し、サーバーへの呼び出しを管理するようにします。したがって、Security への呼び出しが表示されたら、ここでサーバーを呼び出して署名の検証を実行します。

/**
 * Callback interface to <em>finish</em> processing a transaction once the remote
 * servers have processed it.
 */
public interface VerifyTransactionCompletion {
    public void transactionVerified(List<Security.VerifiedPurchase> purchases);
}

private void purchaseStateChanged(final int startId, String signedData, String signature) {
    // verifyPurchase issues remote call to server (in a background thread), then
    // calls transactionVerified on the main thread to continue processing.
    Security.verifyPurchase(signedData, signature, new VerifyTransactionCompletion() {

        @Override
    public void transactionVerified(List<VerifiedPurchase> purchases) {
            if (purchases == null) {
                return;
            }

            ArrayList<String> notifyList = new ArrayList<String>();
            for (VerifiedPurchase vp : purchases) {
                if (vp.notificationId != null) {
                    notifyList.add(vp.notificationId);
                }
                ResponseHandler.purchaseResponse(BillingService.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);
            }
        }

});        

}

于 2012-08-27T19:48:58.310 に答える