NotificationCompat.setStyle() не может получить Notification.MediaStyle

Я обнаружил, что MediaStyle setStyle не работает, когда я использую NotificationCompat.builder(this) сделать уведомление.

Я имею в виду, при использовании этого на NotificationCompat.Builder(this):

.setStyle(new Notification.MediaStyle()
         .setMediaSession(mySession))

Он говорит, что хочет получить NotificationCompat.style вместо Notification.MediaStyle,

Можете ли вы помочь мне решить эту проблему? Есть ли замена для NotificationCompat?

Благодарю.

8 ответов

Для AndroidX в 2020 году вы можете использовать следующий код -

builder.setStyle(new androidx.media.app.NotificationCompat.MediaStyle());

не забудьте добавить зависимость в build.gradle(Module:app)

implementation "androidx.media:media:1.1.0"
В пакете v4 нет `NotificationCompat.MediaStyle`, однако он существует в пакете v7. Обязательно выполните импорт: import android.support.v7.app.NotificationCompat; вместо пакета v4. Это работает для меня с v22.2.0 библиотеки appcompat.

Начиная с версии 26.0.0, пакет v7 устарел. Тем не менее, все функции были добавлены в v4! Ура!

Источник

Временное исправление: с 11.09.2017 можно использовать полностью квалифицированный класс в качестве обходного пути. Протестировано с помощью Android 3.0 Beta 5 Preview, с инструментами сборки API 26.0.1

// The notification builder
import android.support.v4.app.NotificationCompat;

// The media style should be of type, has "media in the path
// android.support.v4.media.app.NotificationCompat.MediaStyle;

    Notification noti = new NotificationCompat.Builder(this, "Quiz")
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(getString(R.string.app_name))
            .setContentText("Hi this is a media notification")
            .setContentIntent(pendingIntent)
            .setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
                    .setMediaSession(mMediaSession.getSessionToken()))
            .build();

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

Сначала немного контекста...
Каждый вызов для настройки NotificationBuilder возвращает экземпляр компоновщика, который, в свою очередь, позволяет разработчику объединять вызовы конфигурации следующим образом:

    // NOTE: To re-iterate, the import you would be using is:
    import android.support.v7.app.NotificationCompat;

    NotificationCompat.Builder myBuilder = new NotificationCompat.Builder(currContext)
    .setSmallIcon(R.drawable.ic_notification_small)
    .setLargeIcon(BitmapFactory.decodeResource(currContext.getResources(), R.drawable.ic_notification_large))
    .setStyle(new NotificationCompat.MediaStyle().setMediaSession(sessionCompat.getSessionToken()));

Это очень обычный и удобный шаблон, единственная проблема в том, что возвращаемый экземпляр Builder имеет тип android.support.v4.app.NotificationCompat.Builder, а не тот android.support.v7.app.NotificationCompat.Builder, которым вы являетесь ожидая.

Так что исправление обманчиво просто... просто явно продолжайте использовать экземпляр v7 Builder при выполнении этих вызовов:)

    // NOTE: To re-iterate, the import you would be using is:
    import android.support.v7.app.NotificationCompat;
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(currContext);
    mBuilder.setSmallIcon(R.drawable.ic_notification_small);
    mBuilder.setLargeIcon(BitmapFactory.decodeResource(currContext.getResources(), R.drawable.ic_notification_large));
    mBuilder.setStyle(new NotificationCompat.MediaStyle().setMediaSession(sessionCompat.getSessionToken()));

Обновить

Эта проблема теперь устранена, если вы ссылаетесь в Библиотеке поддержки Android версии 22.2.1 (июль 2015 г.):

  • Предоставил [n] API для NotificationCompat.MediaStyle учебный класс

Старый обходной путь

Вот мой обходной путь для " Нет NotificationCompat.MediaStyle в библиотеке поддержки ".

Это позволяет избежать дублирования логики приложения и упрощает обходной путь, если / когда NotificationCompat поддерживает MediaStyle,

Цель: это облегчает использование MediaStyle в API 21+ (предлагая компактные и расширенные макеты уведомлений с кнопками) или обычную компоновку уведомлений на более старых версиях Android (всего одна макет с кнопками).

Примечание. Если ваша цель - поместить кнопки на экране блокировки в нескольких версиях Android, вы можете использовать этот подход для реализации уведомлений экрана блокировки для API 21+, а также для реализации виджета экрана блокировки для старых API.

Как: во- первых, создать новый пакет совместимости компоновщика уведомлений, начиная с интерфейса для альтернативных базовых реализаций. Детская кроватка от NotificationCompat.Builder, урезанный до необходимых функций:

public interface NotificationBuilder {
    public NotificationBuilder setWhen(long when);
    public NotificationBuilder setUsesChronometer(boolean b);
    public NotificationBuilder setSmallIcon(int icon);
    // ...

    /** Sets MediaStyle with setShowActionsInCompactView(). */
    public NotificationBuilder setMediaStyleActionsInCompactView(int... actions);

    public Notification build();
}

Во-вторых, сделать реализацию, основанную на NotificationCompat.Builder:

public class V20Builder implements NotificationBuilder {
    private NotificationCompat.Builder builder;

    public V20Builder(Context context) {
        builder = new NotificationCompat.Builder(context);
    }

    @Override
    public NotificationBuilder setWhen(long when) {
        builder.setWhen(when);
        return this;
    }

    @Override
    public NotificationBuilder setUsesChronometer(boolean b) {
        builder.setUsesChronometer(b);
        return this;
    }

    @Override
    public NotificationBuilder setSmallIcon(int icon) {
        builder.setSmallIcon(icon);
        return this;
    }

    // ...

    @Override
    public NotificationBuilder setMediaStyleActionsInCompactView(int... actions) {
        // Noop for Android API V20-.
        return this;
    }

    @Override
    public Notification build() {
        return builder.build();
    }
}

В-третьих, сделайте реализацию, построенную на Notification.Builder:

@TargetApi(21)
public class V21Builder implements NotificationBuilder {
    private Notification.Builder builder;

    public V21Builder(Context context) {
        builder = new Notification.Builder(context);
    }

    @Override
    public NotificationBuilder setWhen(long when) {
        builder.setWhen(when);
        return this;
    }

    @Override
    public NotificationBuilder setUsesChronometer(boolean b) {
        builder.setUsesChronometer(b);
        return this;
    }

    @Override
    public NotificationBuilder setSmallIcon(int icon) {
        builder.setSmallIcon(icon);
        return this;
    }

    // ...

    @Override
    public NotificationBuilder setMediaStyleActionsInCompactView(int... actions) {
        new Notification.MediaStyle(builder).setShowActionsInCompactView(actions);
        return this;
    }

    @Override
    public Notification build() {
        return builder.build();
    }
}

В-четвертых, добавьте метод фабрики, чтобы создать экземпляр правильного компоновщика:

public NotificationBuilder makeBuilder() {
  if (Build.VERSION.SDK_INT >= 21) { // Load the API V21 class only if the OS can load it.
      return new V21Builder(context);
  }
  return new V20Builder(context);
}

Для Androidx добавьте следующий код

  • В build.gradle(Module:app) добавьте эту зависимость
  implementation "androidx.media:media:1.1.0"
  • где бы вы ни использовали Notification.MediaStyle() в методе setStyle используйте следующий код
  builder.setStyle(new androidx.media.app.NotificationCompat.MediaStyle());

Там, похоже, нет бэкпорта MediaStyle в пакет поддержки Android на данный момент.

В конце концов, как только исходный код Android 5.0 станет доступным, кто-то может создать независимый бэкпорт. Или, возможно, пакет поддержки Android добавит бэкпорт в будущем.

Но, в настоящее время, AFAICT, вы не можете создать MediaStyle для использования с NotificationCompat,

      implementation 'androidx.media:media:1.6.0'

When you create a notification then use always androidX related imports for NotificationCompat 


 1. import androidx.media.app.NotificationCompat
 val mediaStyle = NotificationCompat.MediaStyle().setMediaSession(token)

 2. import android.support.v4.media.session.MediaSessionCompat
 val mediaSession = MediaSessionCompat(requireContext(), "session tag")


  val mediaSession = MediaSessionCompat(requireContext(), "session tag")
  val token = mediaSession.sessionToken
  val mediaStyle = NotificationCompat.MediaStyle().setMediaSession(token)
Другие вопросы по тегам