Android 11:DecoratedMediaCustomViewStyle会忽略setCustomContentView

问题描述

我的Android应用用于远程控制媒体播放器(PC上的Winamp)。为了即使在Android应用程序当前未激活时也允许用户控制远程播放器,它使用与后台服务和系统通知关联的MediaSession。系统通知使用DecoratedMediaCustomViewStyle样式,我使用setCustomContentView()和setCustomBigContentView()方法设置自定义视图。我使用VolumeProviderCompat在MediaSession上调用setPlaybackToRemote()。这是一个重要的区别,因为媒体不是在Android设备上播放,而是在远程设备上播放。不,不是Chromecast,而是完全不同的东西(使用自定义协议的PC上的Winamp)。

这一切在11(API 30)之前的Android版本上均能正常运行。但是在Android 11上,完全忽略了自定义视图(“常规”视图和“大”视图)。这是“大”通知的屏幕截图,在API 27(与API 28和29相同)的顶部,然后是API 30。

Ampwifi notification API 27

Ampwifi notification API 30

请注意,最上面的一个没有两次提及“ Ampwifi”,并且右侧有一个“ X”按钮。该“ X”按钮非常重要,因为它允许用户关闭通知关闭后台服务。

搜索了文档和Android 11更改日志,但未找到任何相关信息。我也有一个来自Android“ R”预发行版的较旧的AVD图像,该图像的工作方式也与API 29及更早版本相同。我想知道这是否确实是Android的错误?如果没有,是否有人遇到过这个问题,并且有人对如何解决这个问题有任何建议吗?

我尝试过的一件事就是不将MediaSession与通知关联。这实际上还原了自定义视图,但是我失去了MediaSession的所有好处(蓝牙/ Google Assistant集成和通知操作按钮的自动着色)。因此,修复此问题确实非常好。

这是一些代码

/////

final ConnectionProfile profile = mSettings.getActiveConnectionProfile();
final String profileName = profile != null ? profile.name : "";
final RemoteViews contentView = getContent(profileName);
final RemoteViews bigContentView = getBigContent(profileName);

final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(ServiceBackgroundMediapPlayer.this,NotificationChannelBackgroundMediaPlayerServiceId)
        .setColorized(true)
        .setongoing(true)
        .setAutoCancel(false)
        .setContentIntent(getDefaultIntent())
        .setDeleteIntent(getDeleteIntent())
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setSmallIcon(R.drawable.ic_notification)
        .setLargeIcon(getBitmap())
        .setContentTitle("Ampwifi")
        .setContentText(profileName)
        .addAction(R.drawable.ic_media_prevIoUs,null,MediaButtonReceiver.buildMediaButtonPendingIntent(ServiceBackgroundMediapPlayer.this,PlaybackStateCompat.ACTION_SKIP_TO_PREVIoUS))
        .addAction(R.drawable.ic_media_play,PlaybackStateCompat.ACTION_PLAY))
        .addAction(R.drawable.ic_media_pause,PlaybackStateCompat.ACTION_PAUSE))
        .addAction(R.drawable.ic_media_stop,PlaybackStateCompat.ACTION_STOP))
        .addAction(R.drawable.ic_media_next,PlaybackStateCompat.ACTION_SKIP_TO_NEXT))
        .setStyle(getStyle())
        .setCustomContentView(contentView)
        .setCustomBigContentView(bigContentView)
        .setonlyAlertOnce(true);

mNotification = notificationBuilder.build();

notificationmanager notificationmanager = (notificationmanager) getSystemService(Context.NOTIFICATION_SERVICE);

notificationmanager.notify(R.id.ServiceBackgroundMediapPlayerNotification,mNotification);


/////

public NotificationCompat.Style getStyle() {
    return new androidx.media.app.NotificationCompat.DecoratedMediaCustomViewStyle()
        .setShowCancelButton(true)
        .setCancelButtonIntent(getDeleteIntent())
        .setShowActionsInCompactView(1,2,4)
        .setMediaSession(getMediaSessionToken());
}

public RemoteViews getContent(String title) {
    final RemoteViews layout = new RemoteViews("com.blitterhead.ampwifi",R.layout.notification_media);

    if (layout != null) {
        layout.setTextViewText(R.id.title,title);
    }

    return layout;
}


public RemoteViews getBigContent(String title) {
    final RemoteViews layout = new RemoteViews("com.blitterhead.ampwifi",R.layout.notification_media_big);

    if (layout != null) {
        layout.setTextViewText(R.id.title,title);
        layout.setonClickPendingIntent(R.id.dismiss,getDeleteIntent());
    }

    return layout;
}

private MediaSessionCompat.Token getMediaSessionToken() {
    if (_mediaSessionToken == null) {
        PlaybackStateCompat playbackState = mPlaybackStateBuilder
                .setActiveQueueItemId(1)
                .setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_STOP | PlaybackStateCompat.ACTION_SKIP_TO_PREVIoUS | PlaybackStateCompat.ACTION_SKIP_TO_NEXT)
                .setState(PlaybackStateCompat.STATE_PLAYING,1.0f)
                .build();

        ComponentName mediaButtonReceiver = new ComponentName(getApplicationContext(),MediaButtonReceiver.class);
        mMediaSession = new MediaSessionCompat(ServiceBackgroundMediapPlayer.this,MediaSessionTag,mediaButtonReceiver,null);
        mMediaSession.setPlaybackState(playbackState);
        mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
        mMediaSession.setMetadata(getMetaData());
        mMediaSession.setCallback(getMediaSessionCallback());
        mMediaSession.setActive(true);

        if (mSettings.getBackgroundMediaVolume()) {
            mMediaSession.setPlaybackToRemote(getVolumeProvider());
        }

        _mediaSessionToken = mMediaSession.getSessionToken();

        setSessionToken(_mediaSessionToken);
    }

    return _mediaSessionToken;
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)