1

我正在使用 In App Billing 示例应用将此功能添加到我的应用程序中。在我完成将它添加到我的应用程序并测试所有工作后,我注意到这个安全类中的评论:

安全相关的方法。为了实现安全,所有这些代码都应该在与设备上的应用程序通信的服务器上实现。为了本示例的简单明了,此代码包含在此处并在设备上执行。如果您必须在手机上验证购买,您应该混淆此代码,以使攻击者更难将代码替换为将所有购买视为已验证的存根。

正如谷歌建议的那样,我在服务器端进行购买验证,所以我真的不需要我的项目中的安全类。问题是,我不知道如何删除 Security 类中的BillingService类依赖项。

我首先删除了 Security 类,并遵循了 BillingService 中的错误,并且我可以轻松删除大多数使用它的地方,除了一个地方:

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 回答