首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安卓NotificationListenerService抛出DeadObjectException

安卓NotificationListenerService抛出DeadObjectException
EN

Stack Overflow用户
提问于 2013-09-14 13:08:27
回答 2查看 6K关注 0票数 7

我有一个简单的NotificationListenerService实现来测试新的4.3API。该处本身曾经运作过。之后,我在添加特定包的通知时添加了发送广播的内容。现在,一旦我启动服务,它就会抛出一个DeadObjectException。这是堆栈跟踪:

代码语言:javascript
复制
    E/NotificationService﹕ unable to notify listener (posted): android.service.notification.INotificationListener$Stub$Proxy@42c047a0
    android.os.DeadObjectException
    at android.os.BinderProxy.transact(Native Method)
    at android.service.notification.INotificationListener$Stub$Proxy.onNotificationPosted(INotificationListener.java:102)
    at com.android.server.NotificationManagerService$NotificationListenerInfo.notifyPostedIfUserMatch(NotificationManagerService.java:241)
    at com.android.server.NotificationManagerService$2.run(NotificationManagerService.java:814)
    at android.os.Handler.handleCallback(Handler.java:730)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at com.android.server.ServerThread.run(SystemServer.java:1000)

我就是这样开始服务的

代码语言:javascript
复制
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_start_service:
            startService(new Intent(this, ConnectService.class));
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

我可以验证服务是否启动,因为我会记录它的onCreate()onDestroy()。如果需要的话,下面是如何处理通知的发布:

代码语言:javascript
复制
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
    Log.i(TAG, sbn.getNotification().toString());
    if (sbn != null && sbn.getPackageName().equalsIgnoreCase(PKG)) {
        Intent intent = new Intent(ConnectService.NOTIFY);
        intent.putExtra("notification", sbn.getNotification().toString());
        bManager.sendBroadcast(intent);
    }
}

最糟糕的是堆栈跟踪没有任何用处。出什么问题了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-06 00:01:37

试着不要自己开始服务。如果您在安全设置中启用了NotificationListenerService,系统应该自动绑定到它。

或者,检查您的崩溃日志,以查看您的服务是否崩溃或其进程是否已被终止。我相信有一个错误,如果您的NotificaitonListerService死亡,系统将不会重新绑定,直到您重新启动您的手机或切换通知权限在安全设置。

票数 7
EN

Stack Overflow用户

发布于 2014-03-18 01:12:50

我想分享我的答案,因为我收集的信息,从不同的主题,在堆栈溢出和我自己的测试。如果您的NotificationListenerService失败(异常,如IllegalStateException),系统将杀死它,而不会再次恢复它。您可以在logcat中看到:

代码语言:javascript
复制
592-592/? E/NotificationService﹕ unable to notify listener (posted): android.service.notification.INotificationListener$Stub$Proxy@4291d008 
android.os.DeadObjectException
....

如果用户转到“安全”、“通知”、“禁用”和“启用应用程序”,它仍然无法工作。为什么?因为只有在用户重新启动手机或用户重新启用选项时才会重新启动,但是将通过以下方式遍历应用程序:

代码语言:javascript
复制
startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));

因此,我们需要检查两件事,首先,如果启用了选项:

代码语言:javascript
复制
private boolean checkNotificationSetting() {

    ContentResolver contentResolver = getContentResolver();
    String enabledNotificationListeners = Settings.Secure.getString(contentResolver, "enabled_notification_listeners");
    String packageName = getPackageName();

    return !(enabledNotificationListeners == null || !enabledNotificationListeners.contains(packageName));
}

如果启用了该服务,我们将检查该服务是否为Death:

代码语言:javascript
复制
private boolean isNLServiceCrashed() {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningServiceInfo> runningServiceInfos = manager.getRunningServices(Integer.MAX_VALUE);

    if (runningServiceInfos != null) {
        for (ActivityManager.RunningServiceInfo service : runningServiceInfos) {

            //NotificationListener.class is the name of my class (the one that has to extend from NotificationListenerService)
            if (NotificationListener.class.getName().equals(service.service.getClassName())) {

                if (service.crashCount > 0) {
                    // in this situation we know that the notification listener service is not working for the app
                    return true;
                }
                return false;
            }
        }
    }
    return false;
}

这是什么service.crashCount?文件上说:

服务运行时服务进程崩溃的次数。

如果它超过0,就意味着它已经死亡了。因此,在这两种情况下,我们都必须警告用户,并根据我之前发布的意图提供重新启动服务的可能性:

代码语言:javascript
复制
startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));

当然,如果服务崩溃,最好也检测为什么和何时防止它。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18802076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档