11

似乎如果 Android 手机没有登录到 Google Play,checkAccess-call 会抛出 NullPointerException 并最终导致应用程序崩溃:

// user not logged in to Google Play
LicenseChecker licenseChecker = new LicenseChecker(...);
licenseChecker.checkAccess(...) // throws a nullpointer exception and crasches the app

NullPointerException 发生在 Android 框架深处的一个单独线程中:

FATAL EXCEPTION: background thread
java.lang.NullPointerException
com.google.android.vending.licensing.LicenseValidator.verify()

因此,应用程序似乎无法捕获它并避免崩溃。

任何想法如何避免这种崩溃?(t应该是不能登录Google Play的合法情况)

我能想到的唯一方法是在调用 checkAccess 之前检查 Google Play 登录状态。

4

4 回答 4

9

我修改了方法 LicenseValidator.verify(),在开头添加了保护检查:

public void verify(PublicKey publicKey, int responseCode, String signedData, String signature) {
    if (signedData==null){
        handleInvalidResponse();
        return;
    }
    ...
}
于 2013-09-09T11:00:49.333 回答
3

如果您只是尝试在 android 模拟器上运行您的代码,您也可以打开并登录 Google Play 商店,这将更新 Google Play 服务并解决问题

于 2017-11-23T00:43:35.840 回答
2

我不赞成@Ben Lee 的回答。

基于上面@jssingh 提出的建议,我采用了以下解决方案:

public void verify(PublicKey publicKey, int responseCode, String signedData, String signature) {
    String userId = null;
    // Skip signature check for unsuccessful requests
    ResponseData data = null;
    if (signedData != null && (responseCode == LICENSED || responseCode == NOT_LICENSED ||
            responseCode == LICENSED_OLD_KEY)) {
        // Verify signature.
        try {
            Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
            sig.initVerify(publicKey);
            sig.update(signedData.getBytes());
        ....
        }
    }

    ........

    if (signedData == null) {
        Crashlytics.logException(new Exception("Licensing signedData is null - responseCode=" + responseCode));
    }

    switch (responseCode) {
        case LICENSED:
        case LICENSED_OLD_KEY:
            int limiterResponse = mDeviceLimiter.isDeviceAllowed(userId);
            handleResponse(limiterResponse, data);
            break;
        .....
    }

我利用 Crashlytics 日志记录来验证您不能仅在 signedData 为空时假设 NOT_LICENSED 的声明。

事实上,这是我看到我的代码在执行此附加检查时所采用的条件:

        case ERROR_CONTACTING_SERVER:
            Log.w(TAG, "Error contacting licensing server.");
            handleResponse(Policy.RETRY, data);
            break;

似乎是合法的 :)

于 2017-12-15T23:19:18.767 回答
0

使用“扩展文件”时我也遇到了同样的问题。这可能是因为服务器在检查许可证时响应不佳。因此它在 LicenceChecker 类中发送“ SignedData= null 和 Signature=null ”。

这最终会影响 MainActivity 的onActivityResult(int requestCode, int resultCode, Intent data)。这里我们得到 data=null。所以试试下面的代码-->

public onActivityResult(int requestCode, int resultCode, Intent data)
{    
    if (data != null) {
        fromWhere = data.getExtras().getInt("yourInt");
        done = data.getExtras().getInt("yourdata");
    } 
    else {
        //Your Default Value..
        fromWhere = 1;
        done = 0;
    }
}

希望这会帮助一些人。好运!!

于 2014-03-04T08:15:58.323 回答