无法在HUAWEI设备上扩展RemoteViews:MediaSessionCompat和NotificationCompat.MediaStyle

时间:2016-01-18 10:03:35

标签: android android-notifications android-mediasession

当我尝试在运行Android 5.0.1的HUAWEI P8 lite设备上显示通知时,我的应用程序崩溃(它在Nexus和Samsung设备上运行正常)。我的大部分代码都来自Ian Lake以正确方式播放的视频媒体播放(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)));

然后,应用程序不会崩溃,并显示带有图像和标题的通知。但缺少媒体操作按钮。

堆栈跟踪:

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

1 个答案:

答案 0 :(得分:1)

@KasperFinneNielsen在评论中建议的对我来说最好的解决方案是在非华为运行的设备上设置MediaStyle

Build.VERSION_CODES.LOLLIPOP_MR1 

Build.VERSION_CODES.LOLLIPOP

所以;

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