Не удается заставить класс NotificationListenerService работать

У меня есть приложение для Android, которое пытается использовать новый класс NotificationListenerService из api 18. Я создал свой собственный класс сервиса, который наследует этот класс и переопределяет события onNotificationPosted и onNotificationRemoved, и хотя моя служба, похоже, начинает просто штрафовать эти 2 события никогда не вызываются, когда я получаю или удаляю уведомление.

Кто-нибудь имел успех в этом классе или, возможно, какой-либо исходный код, который они будут использовать, чтобы продемонстрировать, как именно использовать этот класс?

Ответы

Ответ 1

По моему опыту, почти все эти ответы настолько чертовски близки к правильному решению!

Проблема 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);
    }
}

Ответ 2

После установки приложения, настроенного правильно, вы должны предоставить его.

Вы можете найти имя приложения в разделе "Настройки > Безопасность > Доступ к уведомлению", а затем установите флажок.:)

Ответ 3

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

}

введите описание изображения здесь

уведомление об отключении оболочки adb

проверить, какое обслуживание живет.

com.android.server.notification.ManagedServices # rebindServices

toggleNotificationListenerService() запускает этот метод.

Ответ 4

Я столкнулся с этой ошибкой:

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

И уведомления начали приходить на мою службу только после того, как я перезагрузил свой телефон.

Ответ 6

Иногда может возникнуть проблема с удалением источника сборки и восстановления.

Я сражался с ним в течение 3 дней, и вот что я сделал:

AndroidManifest.xml

Изменяет имя службы только из примера класса:

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

к

 <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>

Перейдите в свой корневой каталог > андроид, затем удалите папку сборки, чтобы ваш проект мог перестроить.

Ответ 7

Я только что пришел к большому небольшому примеру этого класса в действии:

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

Одна вещь, которую я узнал из приведенного ниже примера, - это то, что созданная служба уведомлений запускается автоматически, когда разрешение предоставляется через новый экран доступа к уведомлению, то есть мое приложение не должно запускать службу вручную.