Android Media3 ExoPlayer如何移除通知栏控制按钮?
问题
如何移除通知栏中的播放/暂停按钮、上一曲按钮和下一曲按钮?直接移除整个通知窗口也可以。我正在结合MediaSession使用ExoPlayer。
我的代码
MyExoPlayerService 实现
import androidx.media3.common.MediaItem; import androidx.media3.common.Player; import androidx.media3.exoplayer.ExoPlayer; import androidx.media3.session.MediaSession; import androidx.media3.session.MediaSessionService; public class MyExoPlayerService extends MediaSessionService { private ExoPlayer myExoPlayer; private MediaSession mediaSession; @Override public void onCreate() { Log.d(Const.TAG, "Create media session service"); super.onCreate(); myExoPlayer = new ExoPlayer.Builder(this) .build(); if(mediaSession.getPlayer()==null) { Log.d(Const.TAG, "Player is null"); } } @Override public void onDestroy() { Log.d(Const.TAG, "Destroy media session service"); release(); super.onDestroy(); } public void setDisc(Uri uri) { // Build the media item. MediaItem mediaItem = MediaItem.fromUri(uri); // Set the media item to be played. mediaSession.getPlayer().setMediaItem(mediaItem); //Set repeat mode to loop mediaSession.getPlayer().setRepeatMode(Player.REPEAT_MODE_ALL); // Prepare the player. mediaSession.getPlayer().prepare(); // Start the playback. mediaSession.getPlayer().setPlayWhenReady(true); } public void release() { Log.d(Const.TAG, "Release media session service"); if(myExoPlayer!=null){ myExoPlayer.release(); } if(mediaSession!=null) { if(mediaSession.getPlayer()!=null) { mediaSession.getPlayer().release(); } mediaSession.release(); mediaSession = null; } } public void pause() { if(myExoPlayer!=null){ mediaSession.getPlayer().setPlayWhenReady(false); } } public void start() { if(myExoPlayer!=null){ mediaSession.getPlayer().setPlayWhenReady(true); } } public boolean isPlaying() { return mediaSession.getPlayer().getPlayWhenReady(); } @Override public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) { // This example always accepts the connection request return mediaSession; }
创建ExoPlayer服务的代码
private void prepareExoPlayerService() { // Set flag mediaControllerIsPrepared = new AtomicBoolean(); mediaControllerIsPrepared.set(false); // Build session token SessionToken sessionToken = new SessionToken(this, new ComponentName(this, MyExoPlayerService.class)); // Build media controller mediaControllerFuture = new MediaController.Builder(this, sessionToken).buildAsync(); mediaControllerFuture.addListener(() -> { // Call controllerFuture.get() to retrieve the MediaController. // MediaController implements the Player interface, so it can be // attached to the PlayerView UI component. //playerView.setPlayer(controllerFuture.get()); mediaControllerIsPrepared.set(true); }, MoreExecutors.directExecutor()); }
解决方案
注意:你的原代码onCreate方法中mediaSession未初始化,直接调用mediaSession.getPlayer()会触发空指针异常,以下方案会先修复这个问题。
方法一:彻底移除通知栏媒体窗口
通过配置MediaSession的通知提供者返回null,完全禁用媒体通知:
@Override public void onCreate() { Log.d(Const.TAG, "Create media session service"); super.onCreate(); myExoPlayer = new ExoPlayer.Builder(this) .build(); // 初始化MediaSession并禁用通知 MediaSession.Builder mediaSessionBuilder = new MediaSession.Builder(this, myExoPlayer); // 设置通知提供者返回null,不生成媒体通知 mediaSessionBuilder.setNotificationProvider((session, controller, mediaMetadata, playWhenReady, playbackState) -> null); mediaSession = mediaSessionBuilder.build(); }
配置后通知栏不会出现任何媒体控制窗口。
方法二:仅移除控制按钮(保留通知)
如果需要保留通知但隐藏播放/暂停、上下曲按钮,可通过限制MediaSession的可用命令实现:
@Override public void onCreate() { Log.d(Const.TAG, "Create media session service"); super.onCreate(); myExoPlayer = new ExoPlayer.Builder(this) .build(); MediaSession.Builder mediaSessionBuilder = new MediaSession.Builder(this, myExoPlayer); // 构建自定义命令集合,移除不需要的控制命令 SessionCommands.Builder commandsBuilder = new SessionCommands.Builder(); // 移除播放/暂停、上一曲、下一曲命令 commandsBuilder.removeCommand(SessionCommand.COMMAND_CODE_PLAY_PAUSE); commandsBuilder.removeCommand(SessionCommand.COMMAND_CODE_SKIP_TO_PREVIOUS); commandsBuilder.removeCommand(SessionCommand.COMMAND_CODE_SKIP_TO_NEXT); mediaSessionBuilder.setAvailableCommands(commandsBuilder.build()); mediaSession = mediaSessionBuilder.build(); }
配置后通知栏会保留,但播放控制按钮会被隐藏,因为MediaSession不再对外暴露这些控制动作。
内容的提问来源于stack exchange,提问作者skymedium
相关产品推荐
相关产品推荐

