android - developer - No se pudo expandir RemoteViews: MediaSessionCompat y NotificationCompat.MediaStyle en dispositivos HUAWEI
android developer audio (1)
La mejor solución para mí, según lo sugerido por @KasperFinneNielsen en los comentarios, fue establecer MediaStyle en dispositivos que no estén ejecutando Huawei.
Build.VERSION_CODES.LOLLIPOP_MR1
o
Build.VERSION_CODES.LOLLIPOP
Asi que;
boolean isLollipopHuawei = (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP_MR1 ||
android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) && Build.MANUFACTURER.equalsIgnoreCase("HUAWEI");
Mi aplicación falla cuando intento mostrar una Notificación en mi dispositivo HUAWEI P8 lite con Android 5.0.1 (funciona bien en dispositivos Nexus y Samsung). La mayoría de mi código está tomado de la reproducción de medios de video de la manera correcta (Big Android BBQ 2015) por Ian Lake. Todo mi código está dentro de un servicio de Android. Si elimino el código:
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)));
Entonces la aplicación no falla y se muestra una notificación con una imagen y un título. Pero faltan los botones de Media Action.
StackTrace:
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)
Código:
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;
}