启用播放控制

如需在 Android Auto 和 Android Automotive OS (AAOS) 中启用媒体播放功能,请注册媒体会话并处理其回调方法,以实现播放控制。本页面将介绍如何执行以下操作:

  • 在媒体浏览器服务中注册 MediaSessionCompat 对象。

  • 实现 MediaSessionCompat.Callback 方法以响应用户播放请求。

  • 配置标准和自定义播放操作。

  • 为媒体会话设置初始播放状态。

  • 添加图标以指明音频格式。

  • 从正在播放的媒体内容中创建链接。

Android Auto 和 AAOS 通过服务的 MediaSessionCompat 发送播放控制命令。您必须注册会话并实现关联的回调方法。

注册媒体会话

在媒体浏览器服务的 onCreate 方法中,创建 MediaSessionCompat 的实例,然后调用 setSessionToken 来注册媒体会话。此代码段展示了如何创建和注册媒体会话:

Kotlin

override fun onCreate() {
    super.onCreate()
    ...
    // Start a new MediaSession.
    val session = MediaSessionCompat(this, "session tag").apply {
        // Set a callback object that implements MediaSession.Callback
        // to handle play control requests.
        setCallback(MyMediaSessionCallback())
    }
    sessionToken = session.sessionToken
    ...
}

Java

public void onCreate() {
    super.onCreate();
    ...
    // Start a new MediaSession.
    MediaSessionCompat session = new MediaSessionCompat(this, "session tag");
    setSessionToken(session.getSessionToken());

    // Set a callback object that implements MediaSession.Callback
    // to handle play control requests.
    session.setCallback(new MyMediaSessionCallback());
    ...
}

创建媒体会话对象时,您可以设置用于处理播放控制请求的回调对象。您可以为您的应用提供 MediaSessionCompat.Callback 类的实现来创建此回调对象。下一部分将介绍如何实现此对象。

实现播放命令

当用户从您的应用请求播放媒体项时,Android Automotive OS 和 Android Auto 会使用从应用的媒体浏览器服务获取的 MediaSessionCompat 对象的 MediaSessionCompat.Callback 类。当用户想要控制内容播放时,例如暂停播放或跳至下一曲目,Android Auto 和 Android Automotive OS 会调用其中一个回调对象的方法。

为了处理内容播放,您的应用必须扩展抽象 MediaSessionCompat.Callback 类,并实现应用支持的方法。

实现以下所有回调方法,这些方法适用于应用提供的内容类型:

onPrepare
当媒体来源发生变化时,AAOS 会调用此方法。
onPlay

当用户在未选择特定项的情况下选择播放时调用。您的应用必须播放其默认内容;或者,如果之前通过 onPause 暂停了播放,您的应用会继续播放。

onPlayFromMediaId

在用户选择播放特定项时调用。该方法会接收媒体浏览器服务为内容层次结构中的媒体项分配的 ID

onPlayFromSearch

在用户选择从搜索查询中播放时调用。应用必须根据传入的搜索字符串做出适当的选择。

onPause

在用户选择暂停播放时调用。

onSkipToNext

在用户选择跳至下一项时调用。

onSkipToPrevious

在用户选择跳至上一项时调用。

onStop

在用户选择停止播放时调用。在您的应用中替换这些方法,以提供所选结果。如果应用不支持某一方法的用途,则无需实现该方法。例如,如果您的应用用来直播节目(例如体育广播),则无需实现 onSkipToNext。请改用 onSkipToNext 的默认实现。

您的应用无需任何特殊逻辑即可通过汽车扬声器播放内容。当应用收到播放内容的请求时,会像通过用户的手机扬声器或耳机播放内容时一样播放音频。Android Auto 和 AAOS 会自动将音频内容发送到车载系统,以通过汽车扬声器播放。

如需详细了解如何播放音频内容,请参阅 MediaPlayer 概览音频应用概览和 ExoPlayer 概览

设置标准播放操作

Android Auto 和 AAOS 根据 PlaybackStateCompat 对象中启用的操作显示播放控件。默认情况下,您的应用必须支持以下操作:

您的应用可以另外支持以下操作(如果它们与应用的内容相关):

此外,您还可以选择创建可向用户显示的播放队列。为此,请调用 setQueuesetQueueTitle 方法,启用 ACTION_SKIP_TO_QUEUE_ITEM 操作,并定义回调 onSkipToQueueItem

另外,添加对“闻曲知音”图标的支持,该图标用于指示正在播放的内容。为此,请调用 setActiveQueueItemId 方法并传递队列中正在播放的项目的 ID。每当队列发生变化时,您都需要更新 setActiveQueueItemId

Android Auto 和 AAOS 会显示每个已启用操作的按钮以及相应的播放队列。当用户点击这些按钮时,系统会从 MediaSessionCompat.Callback 调用对应的回调。

保留未使用的空间

Android Auto 和 AAOS 会在界面中为 ACTION_SKIP_TO_PREVIOUSACTION_SKIP_TO_NEXT 操作预留空间。如果您的应用不支持其中某一功能,Android Auto 和 AAOS 会使用对应的空间显示您创建的任何自定义操作。

如果您不希望让自定义操作占据这些空间,则可以保留这些空间。这样,在您的应用不支持相应功能时,Android Auto 和 AAOS 会使对应空间留空。

为此,请创建 extra 包以包含与保留功能对应的常量,然后使用以下 extra 包来调用 setExtras 方法。SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT 对应于 ACTION_SKIP_TO_NEXTSESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV 对应于 ACTION_SKIP_TO_PREVIOUS。使用这些常量作为软件包中的键,并使用布尔值 true 作为值。

设置初始播放状态

当 Android Auto 和 AAOS 与您的媒体浏览器服务通信时,媒体会话使用 PlaybackStateCompat 传达内容播放的状态。

当 AAOS 或 Android Auto 连接到您的媒体浏览器服务时,您的应用不应自动开始播放音乐。而是依靠 Android Auto 和 AAOS 根据汽车的状态或用户操作恢复或开始播放。

为此,请将媒体会话的初始 PlaybackStateCompat 设置为 STATE_STOPPEDSTATE_PAUSEDSTATE_NONESTATE_ERROR

Android Auto 和 AAOS 中的媒体会话只在驾车期间持续有效,因此用户会频繁地开始和停止这些会话。为了提升前后两次驾车之间的无缝体验,请跟踪用户之前的会话状态,这样一来,当媒体应用收到恢复请求时,用户就可以自动从上次停下的地方继续播放。例如,上次播放的媒体项、PlaybackStateCompat 和队列。

添加自定义播放操作

您可以添加自定义播放操作来显示媒体应用支持的其他操作。如果空间允许(并且您未保留该空间),Android 会将自定义操作添加到传输控件中。否则,自定义操作会显示在溢出菜单中。Android 会按您将自定义操作添加到 PlaybackStateCompat 中的顺序显示这些操作。

使用自定义操作来提供与标准操作不同的行为。请勿使用此类操作来替换或重复标准操作。

如需添加自定义操作,请使用 PlaybackStateCompat.Builder 类中的 addCustomAction 方法。以下代码段展示了如何向“启动电台频道”添加自定义操作:

Kotlin

val customActionExtras = Bundle()
customActionExtras.putInt(
  androidx.media3.session.MediaConstants.EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT,
  androidx.media3.session.CommandButton.ICON_RADIO)

stateBuilder.addCustomAction(
    PlaybackStateCompat.CustomAction.Builder(
        CUSTOM_ACTION_START_RADIO_FROM_MEDIA,
        resources.getString(R.string.start_radio_from_media),
        startRadioFromMediaIcon // or R.drawable.media3_icon_radio
    ).run {
        setExtras(customActionExtras)
        build()
    }
)

Java

Bundle customActionExtras = new Bundle();
customActionExtras.putInt(
  androidx.media3.session.MediaConstants.EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT,
  androidx.media3.session.CommandButton.ICON_RADIO);

stateBuilder.addCustomAction(
    new PlaybackStateCompat.CustomAction.Builder(
        CUSTOM_ACTION_START_RADIO_FROM_MEDIA,
        resources.getString(R.string.start_radio_from_media),
        startRadioFromMediaIcon) // or R.drawable.media3_icon_radio
    .setExtras(customActionExtras)
    .build());

如需查看此方法更为详细的示例,请参阅 GitHub 上的通用 Android 音乐播放器示例应用中的 setCustomAction 方法。创建自定义操作后,媒体会话可以通过替换 onCustomAction 方法来响应该操作。

此代码段展示了您的应用如何响应“启动电台频道”操作:

Kotlin

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

Java

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

如需了解详情,请参阅 GitHub 上 Universal Android Music Player 示例应用中的 onCustomAction 方法。

为自定义操作创建图标

您创建的每个自定义操作都需要使用图标。

如果该图标的说明与某个 CommandButton.ICON_ 常量匹配,请为自定义操作的 extra 的 EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT 键设置整数值。在受支持的系统上,这样做会替换传递给 CustomAction.Builder 的图标资源,从而使系统组件能够一致地呈现您的操作和其他播放操作。

您还必须指定图标资源。车载应用可能会以许多不同的屏幕尺寸和密度来运行,因此您提供的图标必须为矢量可绘制对象。使用矢量可绘制对象来缩放资源,而不会丢失细节。矢量可绘制对象可在较小的分辨率下将边和角对齐到像素边界。

如果某项自定义操作是有状态的(例如,可打开或关闭一项播放设置),请为不同的状态提供不同的图标,这样当用户选择该操作时便可看到变化。

为已停用的操作提供替代图标样式

如果自定义操作不适用于当前上下文,可将自定义操作图标替换为表明操作已被停用的替代图标。

样式外自定义操作图标示例。
图 1. 样式外自定义操作图标示例。

指明音频格式

为了指明播放的媒体使用特殊的音频格式,您可以指定在支持此功能的汽车上呈现相应图标。您可以在当前播放的媒体项(传递给 MediaSession.setMetadata)的 extra 包中设置 KEY_CONTENT_FORMAT_TINTABLE_LARGE_ICON_URIKEY_CONTENT_FORMAT_TINTABLE_SMALL_ICON_URI。为了适应不同的布局,请同时设置这两个 extra。

此外,您可以设置 KEY_IMMERSIVE_AUDIO extra,告知汽车 OEM 这是沉浸式音频,以便他们判断应用音效是否可能会对沉浸式内容造成干扰,据此做出谨慎决定。

您可以配置正在播放的媒体项,使其字幕和/或说明成为指向其他媒体项的链接。这让用户能够快速跳转到相关项;例如,用户可能会跳至同一音乐人的其他歌曲或播客的其他分集。如果汽车支持此功能,用户可点按该链接以浏览相应内容。

如需添加链接,请配置 KEY_SUBTITLE_LINK_MEDIA_ID 元数据(以从字幕中添加链接)或 KEY_DESCRIPTION_LINK_MEDIA_ID(以从说明中添加链接)。如需了解详情,请查看这些元数据字段的参考文档。