如需在 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
对象中启用的操作显示播放控件。默认情况下,您的应用必须支持以下操作:
您的应用可以另外支持以下操作(如果它们与应用的内容相关):
此外,您还可以选择创建可向用户显示的播放队列。为此,请调用 setQueue
和 setQueueTitle
方法,启用 ACTION_SKIP_TO_QUEUE_ITEM
操作,并定义回调 onSkipToQueueItem
。
另外,添加对“闻曲知音”图标的支持,该图标用于指示正在播放的内容。为此,请调用 setActiveQueueItemId
方法并传递队列中正在播放的项目的 ID。每当队列发生变化时,您都需要更新 setActiveQueueItemId
。
Android Auto 和 AAOS 会显示每个已启用操作的按钮以及相应的播放队列。当用户点击这些按钮时,系统会从 MediaSessionCompat.Callback
调用对应的回调。
保留未使用的空间
Android Auto 和 AAOS 会在界面中为 ACTION_SKIP_TO_PREVIOUS
和 ACTION_SKIP_TO_NEXT
操作预留空间。如果您的应用不支持其中某一功能,Android Auto 和 AAOS 会使用对应的空间显示您创建的任何自定义操作。
如果您不希望让自定义操作占据这些空间,则可以保留这些空间。这样,在您的应用不支持相应功能时,Android Auto 和 AAOS 会使对应空间留空。
为此,请创建 extra 包以包含与保留功能对应的常量,然后使用以下 extra 包来调用 setExtras
方法。SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT
对应于 ACTION_SKIP_TO_NEXT
,SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV
对应于 ACTION_SKIP_TO_PREVIOUS
。使用这些常量作为软件包中的键,并使用布尔值 true
作为值。
设置初始播放状态
当 Android Auto 和 AAOS 与您的媒体浏览器服务通信时,媒体会话使用 PlaybackStateCompat
传达内容播放的状态。
当 AAOS 或 Android Auto 连接到您的媒体浏览器服务时,您的应用不应自动开始播放音乐。而是依靠 Android Auto 和 AAOS 根据汽车的状态或用户操作恢复或开始播放。
为此,请将媒体会话的初始 PlaybackStateCompat
设置为 STATE_STOPPED
、STATE_PAUSED
、STATE_NONE
或 STATE_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
的图标资源,从而使系统组件能够一致地呈现您的操作和其他播放操作。
您还必须指定图标资源。车载应用可能会以许多不同的屏幕尺寸和密度来运行,因此您提供的图标必须为矢量可绘制对象。使用矢量可绘制对象来缩放资源,而不会丢失细节。矢量可绘制对象可在较小的分辨率下将边和角对齐到像素边界。
如果某项自定义操作是有状态的(例如,可打开或关闭一项播放设置),请为不同的状态提供不同的图标,这样当用户选择该操作时便可看到变化。
为已停用的操作提供替代图标样式
如果自定义操作不适用于当前上下文,可将自定义操作图标替换为表明操作已被停用的替代图标。

指明音频格式
为了指明播放的媒体使用特殊的音频格式,您可以指定在支持此功能的汽车上呈现相应图标。您可以在当前播放的媒体项(传递给 MediaSession.setMetadata
)的 extra 包中设置 KEY_CONTENT_FORMAT_TINTABLE_LARGE_ICON_URI
和 KEY_CONTENT_FORMAT_TINTABLE_SMALL_ICON_URI
。为了适应不同的布局,请同时设置这两个 extra。
此外,您可以设置 KEY_IMMERSIVE_AUDIO
extra,告知汽车 OEM 这是沉浸式音频,以便他们判断应用音效是否可能会对沉浸式内容造成干扰,据此做出谨慎决定。
从当前正在播放的项中添加链接
您可以配置正在播放的媒体项,使其字幕和/或说明成为指向其他媒体项的链接。这让用户能够快速跳转到相关项;例如,用户可能会跳至同一音乐人的其他歌曲或播客的其他分集。如果汽车支持此功能,用户可点按该链接以浏览相应内容。
如需添加链接,请配置 KEY_SUBTITLE_LINK_MEDIA_ID
元数据(以从字幕中添加链接)或 KEY_DESCRIPTION_LINK_MEDIA_ID
(以从说明中添加链接)。如需了解详情,请查看这些元数据字段的参考文档。