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"
Начиная с версии 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)