Мое приложение падает, когда я пытаюсь отобразить уведомление на моем устройстве HUAWEI P8 lite под управлением Android 5.0.1 (он отлично работает на устройствах Nexus и Samsung). Большая часть моего кода взята из видео Media Media в правильном направлении (Big Android BBQ 2015) Яна Лейка. Весь мой код находится в службе Android. Если я удалю код:
builder.setStyle(new android.support.v7.app.NotificationCompat.MediaStyle()
.setShowActionsInCompactView(0, 1)
.setMediaSession(mMediaSessionCompat.getSessionToken()).setShowCancelButton(true)
.setCancelButtonIntent(MediaStyleHelper.getActionIntent(this, KeyEvent.KEYCODE_MEDIA_STOP)));
Затем приложение не сбой и уведомление отображается с изображением и заголовком. Но кнопки Media Action отсутствуют.
Трассировки стека:
FATAL EXCEPTION:
main Process: com.app.debug, PID: 21600 android.app.RemoteServiceException:
Bad notification posted from package com.app.demo.debug: Couldn't expand RemoteViews for:
StatusBarNotification(pkg=com.app.demo.debug user=UserHandle{0} id=1344663 tag=null score=0 key=0|com.app.demo.debug|1344663|null|10121: Notification(pri=0 contentView=com.app.demo.debug/0x109007f vibrate=null sound=null defaults=0x0 flags=0x62 color=0x00000000 category=transport actions=2 vis=PUBLIC))
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1534)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5538)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Код:
private void setUpAsForeground(Book book)
{
updateMetaData(book);
startForeground(NOTIFICATION_ID, setupAudioNotification());
}
public void updateMetaData(Book book)
{
if(mMediaSessionCompat!=null)
{
MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
Bitmap bitmap = null;
if(!TextUtils.isEmpty(book.imageUrl))
{
bitmap = getBookCover(book.imageUrl);
if (bitmap != null) {
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap);
builder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, book.imageUrl);
}
}
if(bitmap == null && !TextUtils.isEmpty(book.imageUrlList))
{
bitmap = getBookCover(book.imageUrlList);
if (bitmap != null) {
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap);
builder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, book.imageUrlList);
}
}
builder.putText(MediaMetadataCompat.METADATA_KEY_AUTHOR, book.authers);
builder.putText(MediaMetadataCompat.METADATA_KEY_TITLE, book.title);
builder.putText(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, getString(R.string.app_name));
//builder.putText(MediaMetadataCompat.METADATA_KEY_DISPLAY_DESCRIPTION, "");
long duration = getDuration();
if(duration!=-1)
{
builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration);
}
mMediaSessionCompat.setMetadata(builder.build());
}
}
private Notification setupAudioNotification()
{
android.support.v7.app.NotificationCompat.Builder builder = MediaStyleHelper.from(this, mMediaSessionCompat);
builder.setColor(ContextCompat.getColor(this, R.color.my_black));
builder.setSmallIcon(R.drawable.ic_stat_notify);
setNotificationButtons(builder);
builder.setStyle(new android.support.v7.app.NotificationCompat.MediaStyle()
.setShowActionsInCompactView(0, 1)
.setMediaSession(mMediaSessionCompat.getSessionToken()).setShowCancelButton(true)
.setCancelButtonIntent(MediaStyleHelper.getActionIntent(this, KeyEvent.KEYCODE_MEDIA_STOP)));
mNotification = builder.build();
return mNotification;
}
private void setNotificationButtons(android.support.v7.app.NotificationCompat.Builder builder)
{
if(isPlaying())
{
builder.addAction(new NotificationCompat.Action(getStopIcon(), getString(R.string.player_stop_accessibility), MediaStyleHelper.getActionIntent(this, KeyEvent.KEYCODE_MEDIA_STOP)));
builder.addAction(new NotificationCompat.Action(getPauseIcon(), getString(R.string.player_pause_accessibility), MediaStyleHelper.getActionIntent(this, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)));
}
else
{
builder.addAction(new NotificationCompat.Action(getStopIcon(), getString(R.string.player_stop_accessibility), MediaStyleHelper.getActionIntent(this, KeyEvent.KEYCODE_MEDIA_STOP)));
builder.addAction(new NotificationCompat.Action(getPlayIcon(), getString(R.string.player_play_accessibility), MediaStyleHelper.getActionIntent(this, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)));
}
}
private int getStopIcon()
{
if(AppConstants.SUPPORTS_LOLLIPOP)
{
return R.drawable.notification_btn_stop_black;
}
else
{
return R.drawable.notification_btn_stop_white;
}
}
private int getPlayIcon()
{
if(AppConstants.SUPPORTS_LOLLIPOP)
{
return R.drawable.notification_btn_play_black;
}
else
{
return R.drawable.notification_btn_play_white;
}
}
private int getPauseIcon()
{
if(AppConstants.SUPPORTS_LOLLIPOP)
{
return R.drawable.notification_btn_pause_black;
}
else
{
return R.drawable.notification_btn_pause_white;
}
}
public static NotificationCompat.Builder from(
Context context, MediaSessionCompat mediaSession)
{
MediaControllerCompat controller = mediaSession.getController();
MediaMetadataCompat mediaMetadata = controller.getMetadata();
MediaDescriptionCompat description = mediaMetadata.getDescription();
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder
.setContentTitle(description.getTitle())
.setContentText(description.getSubtitle())
.setSubText(description.getDescription())
.setLargeIcon(description.getIconBitmap())
.setContentIntent(controller.getSessionActivity())
.setDeleteIntent(getActionIntent(context, KeyEvent.KEYCODE_MEDIA_STOP))
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
return builder;
}