来自 Intent Service 的 LVL 许可证检查

发布于 2024-12-14 11:18:20 字数 2402 浏览 2 评论 0原文

我有一个免费的应用程序,其中还包含专业版功能,如果用户在 Android 市场中购买我的应用程序的专业版密钥,就可以使用该功能。我在专业密钥应用程序中设置了一个接收器,在主应用程序中设置了另一个接收器。当用户单击主应用程序中的“验证密钥”按钮时,意图将被广播到密钥应用程序中的接收器,然后接收器会启动 IntentService 以检查专业密钥许可证是否有效。然后,IntentService 向主应用程序接收器广播一个意图,其中包含来自 LVL 检查的额外“响应”。

我快到了。仅当我尝试在 IntentService 中进行 LVL 检查时,出现错误:

W/MessageQueue(2652): java.lang.RuntimeException: Handler{4052de20} sending message to a Handler on a dead thread
W/MessageQueue(2773):   at com.android.vending.licensing.LicenseChecker$ResultListener.verifyLicense(LicenseChecker.java:207)

有什么建议吗?

IntentService 来源:

public class CheckerService extends IntentService {

private static final byte[] SALT = ....;
private static final String BASE64_PUBLIC_KEY = ...;
private String device_id;

public CheckerService() {
    super("CheckerService");
}

@Override
protected void onHandleIntent(Intent intent) {
    SharedPreferences data = getSharedPreferences("data", MODE_PRIVATE);
    device_id = data.getString("device_id", null);

    if (device_id == null) {
        SharedPreferences.Editor editor = data.edit();
        device_id = new DeviceId().generate(this);
        editor.putString("device_id", device_id);
        editor.commit();
    }

    ServerManagedPolicy smp = new ServerManagedPolicy(this,
            new AESObfuscator(SALT, getPackageName(), device_id));
    LicenseChecker checker = new LicenseChecker(this, smp, BASE64_PUBLIC_KEY);
    checker.checkAccess(new LicenseCheckerCallback(){

        public void allow() {
            Intent i = new Intent();                
            i.setAction("com.mainapp.intent.action.LICENSE_RESPONSE");
            i.putExtra("response", "LICENSE_OK");
            sendBroadcast(i);
        }

        public void dontAllow() {
            Intent i = new Intent();                
            i.setAction("com.mainapp.intent.action.LICENSE_RESPONSE");
            i.putExtra("response", "LICENSE_NOT_OK");
            sendBroadcast(i);
        }

        public void applicationError(ApplicationErrorCode errorCode) {
            Intent i = new Intent();                
            i.setAction("com.mainapp.intent.action.LICENSE_RESPONSE");
            i.putExtra("response", "LICENSE_ERROR");
            sendBroadcast(i);
        }});

}


@Override
public void onDestroy() {
    super.onDestroy();
    checker.onDestroy();
}
}

I have a free app which also contains pro functionality, which will be available to the user if they buy a pro key for my app in the Android Market. I have set up a receiver in the pro key app and another one in the main app. When the user clicks a "Validate key" button in the main app, an intent gets broadcasted to the receiver in the key app, which then fires up an IntentService to check if the pro key license is valid. Then the IntentService broadcasts an intent to the main app receiver containing a "response" extra from the LVL check.

I'm almost there. Only when I tried to do the LVL check in the IntentService, I got an error:

W/MessageQueue(2652): java.lang.RuntimeException: Handler{4052de20} sending message to a Handler on a dead thread
W/MessageQueue(2773):   at com.android.vending.licensing.LicenseChecker$ResultListener.verifyLicense(LicenseChecker.java:207)

Any suggestions?

the IntentService source:

public class CheckerService extends IntentService {

private static final byte[] SALT = ....;
private static final String BASE64_PUBLIC_KEY = ...;
private String device_id;

public CheckerService() {
    super("CheckerService");
}

@Override
protected void onHandleIntent(Intent intent) {
    SharedPreferences data = getSharedPreferences("data", MODE_PRIVATE);
    device_id = data.getString("device_id", null);

    if (device_id == null) {
        SharedPreferences.Editor editor = data.edit();
        device_id = new DeviceId().generate(this);
        editor.putString("device_id", device_id);
        editor.commit();
    }

    ServerManagedPolicy smp = new ServerManagedPolicy(this,
            new AESObfuscator(SALT, getPackageName(), device_id));
    LicenseChecker checker = new LicenseChecker(this, smp, BASE64_PUBLIC_KEY);
    checker.checkAccess(new LicenseCheckerCallback(){

        public void allow() {
            Intent i = new Intent();                
            i.setAction("com.mainapp.intent.action.LICENSE_RESPONSE");
            i.putExtra("response", "LICENSE_OK");
            sendBroadcast(i);
        }

        public void dontAllow() {
            Intent i = new Intent();                
            i.setAction("com.mainapp.intent.action.LICENSE_RESPONSE");
            i.putExtra("response", "LICENSE_NOT_OK");
            sendBroadcast(i);
        }

        public void applicationError(ApplicationErrorCode errorCode) {
            Intent i = new Intent();                
            i.setAction("com.mainapp.intent.action.LICENSE_RESPONSE");
            i.putExtra("response", "LICENSE_ERROR");
            sendBroadcast(i);
        }});

}


@Override
public void onDestroy() {
    super.onDestroy();
    checker.onDestroy();
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

坚持沉默 2024-12-21 11:18:21

我相信这个问题出在 IntentService 上。 IntentService 管理它自己的生命周期。本质上它只是一个在非 UI 线程上运行的服务。服务在回调被处理之前就被销毁了,因此当回调发生时,不存在任何东西可以“回调”。

您可以尝试在具有 START_STICKY 或 START_NOT_STICKY 的服务中运行它并自行管理生命周期。

I believe this problem is with the IntentService. An IntentService manages it's own lifecycle. Essentially it is just a service that runs on a non-UI thread. The service is destroyed before the callback can be handled, so when the callback occurs nothing exists for it to 'callback' to.

You could try to run it in a service with START_STICKY or START_NOT_STICKY and manage the lifecycle yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文