CeejeeB
CeejeeB

Reputation: 3114

Cannot get the NotificationListenerService class to work

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?

Upvotes: 16

Views: 21515

Answers (9)

Nirav Khunt
Nirav Khunt

Reputation: 1

NLService will be working all the time as per android docs but in some cases it will be unbind from your specific app and may restarting your phone it will bind again . But in safer side you can have this check whenever your starts ,

// 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);
    }
}

Upvotes: 0

Olusegun Abiodun
Olusegun Abiodun

Reputation: 11

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.

Upvotes: 1

ProllyGeek
ProllyGeek

Reputation: 15856

Sometimes deleting build and rebuilding source might be the issue.

I Struggled with it for 3 days, and here is what I have done:

AndroidManifest.xml

Changes service name from just class example:

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

to

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

Navigate to your root directory > android , then delete build folder, allow your project to rebuild.

Upvotes: 0

Hugo
Hugo

Reputation: 1323

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.

Upvotes: 8

swooby
swooby

Reputation: 3145

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);
    }
}

Upvotes: 34

david72
david72

Reputation: 7307

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

https://github.com/yihongyuelan/NotificationListenerServiceDemo

Upvotes: 2

David V&#225;vra
David V&#225;vra

Reputation: 19149

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.

Upvotes: 4

CeejeeB
CeejeeB

Reputation: 3114

I have just come accross a great little example of this class in action:

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

One thing I learned from following this example is that the notification service I created starts automatically when permission is granted via the new notification access screen, meaning my application doesn't have to start the service manually.

Upvotes: -2

Hong Choi
Hong Choi

Reputation: 171

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. :)

Upvotes: 17

Related Questions