Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot get the NotificationListenerService class to work

Tags:

android

I have a android application that is trying to use the new NotificationListenerService class from api 18. I have created my own service class that inherits from this class and overrode the onNotificationPosted and onNotificationRemoved events and although my service seems to start just fine these 2 events never seem to be called when I get or remove a notification.

Has anyone had any success with this class or possibly any source code they are will to share demonstrating exactly how to use this class?

like image 268
CeejeeB Avatar asked Jul 28 '13 19:07

CeejeeB


6 Answers

In my experience, almost all of these answers are so damn close to the right solution!

The CORE problem seems to happen during development; as you are developing your code the "Notification access" settings stop being honored when you update your app between debug sessions.

If your APK/binary changes and your NotificationListenerService stops:

  • Rebooting fixes it.
  • Going back in to "Notification access" and disabling and re-enabling your app it fixes it.

Hopefully this isn't a problem when updating your app through Google Play.

As a best practice, for my app I add an overflow menu option that only shows up in non-release builds that allows me easy access to the settings:

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);
    }
}
like image 197
swooby Avatar answered Oct 13 '22 00:10

swooby


After installing a app configured properly, you should grant it.

You can find the name of the app at "Settings > Security > Notification access", then be sure the check box is filled. :)

like image 34
Hong Choi Avatar answered Oct 13 '22 00:10

Hong Choi


update: 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 notification

check which service is living.

com.android.server.notification.ManagedServices#rebindServices

toggleNotificationListenerService() trigger system invoke this method.

like image 30
Hugo Avatar answered Oct 12 '22 23:10

Hugo


I have encountered this bug:

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

And notifications started coming to my service only after I rebooted my phone.

like image 37
David Vávra Avatar answered Oct 13 '22 01:10

David Vávra


After many hours of researching, I finally found sample code that actually works:

https://github.com/yihongyuelan/NotificationListenerServiceDemo

like image 31
david72 Avatar answered Oct 13 '22 01:10

david72


After debugging multiple times to a device, renaming your NotificationListener class helps fix the problem. It doesn't matter what you rename it to, just changing it to something different from the previous name. I've always had to do this over and over again.

like image 30
Olusegun Abiodun Avatar answered Oct 13 '22 01:10

Olusegun Abiodun