无法使NotificationListenerService类工作

时间:2013-07-28 19:14:30

标签: android

我有一个Android应用程序正在尝试使用api 18中的新NotificationListenerService类。我创建了自己的服务类,它继承自这个类并覆盖了onNotificationPosted和onNotificationRemoved事件,尽管我的服务似乎开始很好这些当我收到或删除通知时,似乎永远不会调用2个事件。

有没有人在这个课程上取得任何成功,或者他们可能分享的任何源代码是否会成功展示如何使用这个课程?

9 个答案:

答案 0 :(得分:27)

根据我的经验,几乎所有这些答案都非常接近正确的解决方案!

CORE 问题似乎在开发期间发生;当您正在开发代码时,"通知访问"当您在调试会话之间更新您的应用时,设置将不再受到尊重。

如果您的APK /二进制文件发生更改且NotificationListenerService停止:

  • 重新启动修复它。
  • 返回"通知访问"并且禁用并重新启用您的应用程序它会修复它。

希望通过Google Play更新您的应用时不会出现问题。

作为最佳做法,对于我的应用程序,我添加了一个溢出菜单选项,该选项仅显示在非发布版本中,以便我轻松访问设置:

NotificationListener.java:

public class NotificationListener
    extends NotificationListenerService
    implements RemoteController.OnClientUpdateListener
{
    private static final int VERSION_SDK_INT = VERSION.SDK_INT;

    public static boolean supportsNotificationListenerSettings()
    {
        return VERSION_SDK_INT >= 19;
    }

    @SuppressLint("InlinedApi")
    @TargetApi(19)
    public static Intent getIntentNotificationListenerSettings()
    {
        final String ACTION_NOTIFICATION_LISTENER_SETTINGS;
        if (VERSION_SDK_INT >= 22)
        {
            ACTION_NOTIFICATION_LISTENER_SETTINGS = Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS;
        }
        else
        {
            ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
        }

        return new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS);
    }

    ...
}

menu_my_activity.xml:

<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MyActivity"
    >

    <item
        android:id="@+id/action_application_info"
        android:title="@string/action_application_info"
        app:showAsAction="never"
        />

    <item
        android:id="@+id/action_notification_settings"
        android:title="Notification Settings"
        app:showAsAction="never"
        />

</menu>

MyActivity.java:

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    getMenuInflater().inflate(R.menu.menu_my_activity, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
    MenuItem menuItem;
    menuItem = menu.findItem(R.id.action_application_info);
    if (menuItem != null)
    {
        menuItem.setVisible(BuildConfig.DEBUG);
    }
    menuItem = menu.findItem(R.id.action_notification_settings);
    if (menuItem != null)
    {
        menuItem.setVisible(BuildConfig.DEBUG && NotificationListener.supportsNotificationListenerSettings());
    }
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    switch (item.getItemId())
    {
        case R.id.action_application_info:
            startActivity(new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName())));
            return true;
        case R.id.action_notification_settings:
            startActivity(NotificationListener.getIntentNotificationListenerSettings());
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

答案 1 :(得分:14)

安装正确配置的应用后,您应该授予它。

您可以在“设置&gt;安全性&gt;通知访问权限”中找到该应用的名称,然后确保该复选框已填写。 :)

答案 2 :(得分:8)

更新:https://gist.github.com/xinghui/b2ddd8cffe55c4b62f5d8846d5545bf9

private void toggleNotificationListenerService() {
    PackageManager pm = getPackageManager();
    pm.setComponentEnabledSetting(new ComponentName(this, com.xinghui.notificationlistenerservicedemo.NotificationListenerServiceImpl.class),
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

    pm.setComponentEnabledSetting(new ComponentName(this, com.xinghui.notificationlistenerservicedemo.NotificationListenerServiceImpl.class),
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

}

enter image description here

  

adb shell dumpsys通知

检查哪个服务正在生活。

  

com.android.server.notification.ManagedServices#rebindServices

toggleNotificationListenerService()触发系统调用此方法。

答案 3 :(得分:4)

我遇到过这个错误:

https://code.google.com/p/android/issues/detail?id=59044

只有在重新启动手机后,通知才开始进入我的服务。

答案 4 :(得分:2)

经过几个小时的研究,我终于找到了实际可行的示例代码:

https://github.com/yihongyuelan/NotificationListenerServiceDemo

答案 5 :(得分:1)

多次调试到设备后,重命名NotificationListener类有助于解决问题。重命名它并不重要,只需将其更改为与以前名称不同的内容即可。我一直都要一遍又一遍地做这件事。

答案 6 :(得分:0)

有时删除构建和重建源可能是个问题。

我挣扎了3天,这就是我所做的:

<强>的AndroidManifest.xml

仅从类示例更改服务名称:

4
Sheet 1

<service
          android:name=".NotificationListener"
          android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
          <intent-filter>
              <action android:name="android.service.notification.NotificationListenerService" />
          </intent-filter>
      </service>

导航到您的根目录&gt; android,然后删除build文件夹,允许你的项目重建。

答案 7 :(得分:0)

NLService会一直按照android docs运作,但在某些情况下,它将与您的特定应用解除绑定,并且可能会重新启动您的手机,并再次绑定。但是从更安全的角度来看,您可以在每次启动时进行检查,

// check NLsettings
private void checkNLSettings() {
    //check notification access
    if (!NotificationUtils.isNotificationServiceEnabled(this)) {
        //start NLsetting activity
        Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
        startActivityForResult(intent, REQUEST_ACCESSIBLITYCODE);
        finish();
    }
    //check isNLservice running
    if (!isNLServiceRunning()) {
        enableNotificationListenerService(this);
    }

    Toast.makeText(this, "NLS == " + isNLServiceRunning(), Toast.LENGTH_SHORT).show();
}

private boolean isNLServiceRunning() {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service :
            manager.getRunningServices(Integer.MAX_VALUE)) {
        if (NLService.class.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

/**
 * enable notification service.
 *
 * @param context context
 */
public static void enableNotificationListenerService(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        NotificationListenerService.requestRebind(new ComponentName(context.getPackageName(),
                COMPONENT_NLSERVICE));
    } else {
        PackageManager pm = context.getPackageManager();
        pm.setComponentEnabledSetting(new ComponentName(context.getPackageName(),
                        COMPONENT_NLSERVICE),
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
    }
}

答案 8 :(得分:-1)

我刚刚参加了这个班级的一个很好的例子:

http://www.kpbird.com/2013/07/android-notificationlistenerservice.html

我从以下示例中学到的一件事是,我创建的通知服务在通过新的通知访问屏幕授予权限时自动启动,这意味着我的应用程序不必手动启动服务。