使用媒体会话

媒体会话提供了一种与音频或视频进行互动的通用方式 。通过告知 Android 媒体正在应用中播放, 可以委托给应用。与媒体会话集成可允许 用于在外部通告媒体播放以及接收播放命令的应用 来自外部来源的数据。这些来源可以是实体按钮(例如“播放”按钮) 耳机或电视遥控器上的按钮)或间接命令(例如, 指示“pause”Google 助理)。然后,媒体会话会将这些 将这些命令应用到应用中,从而将这些命令应用到 命令的来源是透明的

媒体会话与其管理的播放器共存。您应该创建 并在 activity 的 onCreate() 方法中初始化媒体会话,或者 拥有媒体会话及其关联播放器的 Google Cloud 服务。

初始化媒体会话

新创建的媒体会话没有功能。您必须通过执行以下步骤来初始化会话:

  • 设置标记,以便媒体会话可以接收来自媒体控制器和媒体按钮的回调。
  • 创建并初始化 PlaybackStateCompat 的实例,并将其分配给会话。播放状态在整个会话过程中会发生变化,因此我们建议您缓存 PlaybackStateCompat.Builder 以便重复使用。
  • 创建 MediaSessionCompat.Callback 的实例并将其分配给会话(下文详述回调)。

您应在onCreate() 活动 或拥有该会话的服务

如何使媒体按钮正常运行 当应用新初始化(或停止)时,其 PlaybackState 必须 包含与媒体按钮发送的 intent 匹配的播放操作。这是 为什么在 将 ACTION_PLAY 分配给会话状态时 初始化。有关详情,请参阅响应媒体 按钮

保持播放状态和元数据

有两个类表示媒体会话的状态。

通过 PlaybackStateCompat 类用于描述播放器的当前运行状态。其中包括:

  • 传输状态(播放器是否正在播放/暂停/缓冲等。请参阅 getState()
  • 错误代码和可选的错误消息(适用时)。(请参阅 getErrorCode() 并阅读下文中的状态和错误。)
  • 播放器位置
  • 可在当前状态下处理的有效控制器操作

MediaMetadataCompat 类描述了正在播放的材料:

  • 音乐人、专辑和曲目的名称
  • 曲目时长
  • 要在锁定屏幕上显示的专辑封面。图片为位图,最大尺寸为 320x320dp(如果尺寸较大,则会按比例缩小)。
  • 指向较大版本封面的 ContentUris 实例

播放器状态和元数据在媒体会话的整个生命周期内会发生变化。每当状态或元数据发生更改时,您都必须为每个类(PlaybackStateCompat.Builder()MediaMetadataCompat.Builder())使用相应的构建器,然后通过调用 setPlaybackState()setMetaData()。 要减少这些频繁操作的总体内存消耗,最好一次性创建构建器,并在整个会话生命周期内重复使用它们。

状态和错误

请注意,PlaybackState 是一个对象,其中包含用于 会话的播放状态 (getState()) 必要时,还可提供相关的错误代码 (getErrorCode())。 错误可以是严重错误,也可以是非严重错误:

只要播放中断,您应该生成严重错误: 将状态传输到 STATE_ERROR,并指定与 setErrorMessage(int, CharSequence) 相关联的错误。 只要播放被错误阻止,PlaybackState 就会继续 以报告 STATE_ERROR 和错误。

如果您的应用无法处理请求,但可以继续播放,就会发生非严重错误: 运输仍然处于“正常”状态,状态(例如 STATE_PLAYING),但 PlaybackState 包含错误代码。 例如,如果正在播放最后一首歌曲,并且用户请求跳至下一首歌曲, 播放可以继续,但您应创建一个新的 PlaybackState,并设置错误代码 ERROR_CODE_END_OF_QUEUE, 然后调用 setPlaybackState()。连接到会话的媒体控制器将收到回调 onPlaybackStateChanged(),并向用户说明所发生的情况。非严重错误应仅在出现时报告一次。下次会话更新时,PlaybackState 不会再次设置相同的非严重错误(除非因响应新请求而出现错误)。

媒体会话锁定屏幕

从 Android 4.0(API 级别 14)开始,系统可以访问媒体会话的 播放状态和元数据这就是锁定屏幕如何显示媒体控件 以及图片。该行为因 Android 版本。

专辑封面

在 Android 4.0(API 级别 14)到 Android 10(API 级别 29)中,后台 的锁定屏幕上会显示专辑封面 - 但仅限媒体会话 元数据包含背景位图。

传输控件

在 Android 4.0(API 级别 14)到 Android 4.4(API 级别 19)中,当媒体会话处于活动状态且媒体会话元数据包含背景位图时,锁定屏幕会自动显示传输控件。

在 Android 5.0(API 级别 21)或更高版本中,系统不提供传输 控制。相反,您应该使用 MediaStyle 通知 显示传输控件。

添加自定义操作

媒体应用可以定义自定义操作;例如:“我喜欢”、“喜欢”或 快退 30 秒。自定义操作应实现全新的行为。正确做法 不使用自定义操作来代替某个标准传输控制操作 定义于 PlaybackStateCompat

使用 addCustomAction() 添加自定义操作。以下示例展示了如何为“我喜欢”操作添加控件:

Kotlin

stateBuilder.addCustomAction(
        PlaybackStateCompat.CustomAction.Builder(
                CUSTOM_ACTION_THUMBS_UP,
                resources.getString(R.string.thumbs_up),
                thumbsUpIcon
        ).run {
            setExtras(customActionExtras)
            build()
        }
)

Java

stateBuilder.addCustomAction(new PlaybackStateCompat.CustomAction.Builder(
    CUSTOM_ACTION_THUMBS_UP, resources.getString(R.string.thumbs_up), thumbsUpIcon)
    .setExtras(customActionExtras)
    .build());

有关完整示例,请参阅 Universal Music Player

您通过 onCustomAction() 响应操作。

Kotlin

override fun onCustomAction(action: String, extras: Bundle?) {
    when(action) {
        CUSTOM_ACTION_THUMBS_UP -> {
            ...
        }
    }
}

Java

@Override
public void onCustomAction(@NonNull String action, Bundle extras) {
    if (CUSTOM_ACTION_THUMBS_UP.equals(action)) {
        ...
    }
}

另请参阅 Universal Music Player

媒体会话回调

主媒体会话回调方法为 onPlay()onPause()onStop()。 您可以在此处添加控制播放器的代码。

由于您在运行时实例化并设置了会话的回调(在 onCreate() 中),您的应用可以定义使用不同播放器的备用回调,并根据设备和/或系统级别选择合适的回调/播放器组合。您可以在不更改应用的其余部分的情况下更改播放器。例如,在 Android 4.1(API 级别 16)或更高版本上运行时,您可以使用 ExoPlayer,在早期的系统中,您可以使用 MediaPlayer

除了控制播放器和管理媒体会话状态转换之外,回调还会启用和停用应用的功能,并控制其与其他应用和设备硬件的活动方式。(请参阅控制音频输出)。

媒体会话回调方法的实现取决于应用的结构。 请参阅介绍如何在 音频应用视频应用 介绍了应如何为各类应用实现回调。