Android NDK开发详解Wear之在穿戴式设备上播放音频
本指南将介绍 Wear OS 上的应用如何使用熟悉的 Android API 播放音频。
检测音频设备
Wear OS 应用首先必须检测穿戴式设备是否具有合适的音频输出方式。对开发者来说,穿戴式设备可能会具有以下音频输出方式中的一种或两种:
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:在具有内置扬声器的设备上
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP:如果蓝牙耳机已配对并连接
在以下示例中,应用结合使用 getDevices() 方法与 FEATURE_AUDIO_OUTPUT 的值,枚举所有音频输出方式。
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
fun audioOutputAvailable(type: Int): Boolean {
if (!packageManager.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
return false
}
return audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS).any { it.type == type }
}
audioOutputAvailable(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) // True if the device has a speaker
audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) // True if a Bluetooth headset is connected
为了提供最佳用户体验,您的应用应确保仅在有蓝牙耳机或音箱连接到手表时播放媒体。
选择用于输出音频的首选设备
根据应用的使用情形以及音频对应用核心体验的重要性,选择您希望用户与应用音频输出之间的互动方式。
蓝牙耳机
与内置音箱(只要设备配备便始终可用)不同,蓝牙耳机可在应用运行时配对或取消配对。如果应用需要使用耳机才能继续操作,
注册一个回调,以检测用户何时使用 registerAudioDeviceCallback 连接和断开蓝牙耳机:
audioManager.registerAudioDeviceCallback(object : AudioDeviceCallback() {
override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>?) {
super.onAudioDevicesAdded(addedDevices)
if (audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP)) {
// A Bluetooth headset has just been connected
}
}
override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>?) {
super.onAudioDevicesRemoved(removedDevices)
if (!(audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP))) {
// A Bluetooth headset is no longer connected
}
}
}, null)
如果您的应用在您想提供音频输出时检测到未连接蓝牙耳机,请不要显示错误消息,而是要提议将用户直接转到蓝牙设置,以便他们更轻松地建立连接。使用 ACTION_BLUETOOTH_SETTINGS 发送 intent 可以做到这一点:
val intent = with (Intent(Settings.ACTION_BLUETOOTH_SETTINGS)) {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
putExtra("EXTRA_CONNECTION_ONLY", true)
putExtra("EXTRA_CLOSE_ON_CONNECT", true)
putExtra("android.bluetooth.devicepicker.extra.FILTER_TYPE", 1)
}
startActivity(intent)
音箱
大多数 Wear OS 设备都配有音箱。如果您的应用提供包含声音的非媒体使用情形,请考虑使用音箱来增加与用户互动的途径。例如,配有音箱的 Wear OS 设备可能会触发时钟闹钟或计时器闹钟,并辅以音频通知;健身应用可能会使用音箱提供锻炼指示。
注意:音箱并非专为此用途而设计,所以无法提供最佳媒体内容收听体验。
如需了解详情,请参阅 WearSpeakerSample。
播放音频
检测到并选择合适的音频输出方式后,在 Wear OS 上播放音频的过程和在移动设备或其他设备上播放音频相同。如需了解详情,请参阅 MediaPlayer 概览。如果想更轻松地使用更为高级的功能(例如在线播放和下载媒体内容),不妨使用 ExoPlayer。请务必遵循针对音频应用的最佳实践,例如管理音频焦点
防止通过音箱意外播放媒体
媒体应用可遵循下列指南,以确保应用不会在无意中通过内置手表音箱播放媒体内容。具体指南因应用使用的播放器而异。
ExoPlayer
如果您的应用使用 ExoPlayer:
在构建 ExoPlayer 实例时,调用 setSuppressPlaybackOnUnseeableOutput(true):
ExoPlayer exoplayer = ExoPlayer.Builder(context)
.setAudioAttributes(...)
.setSuppressPlaybackWhenUnsuitableOutput(true)
// ...
.build()
通过将 WearUnsureableOutputPlaybackSuppressionResolverListener 注册为 ExoPlayer 实例的监听器,以响应播放禁止事件:
exoPlayer.addListener(WearUnsuitableOutputPlaybackSuppressionResolverListener(context))
Horologist Media 工具包
Horologist Media 工具包已含有相应逻辑,可防止通过内置手表音箱意外播放媒体。
其他媒体播放器
确保媒体音频播放不会启动,除非手表已连接合适的输出设备(例如耳机或一组外部音箱)。您可以检查设备的类型是否为 TYPE_BLUETOOTH_A2DP。
如果 AudioManager 告知您的应用,外部音频输出设备突然与手表断开连接,则应暂停播放。
当用户尝试启动媒体播放但尚未连接外部音频设备时,请提示用户将一部此类设备连接到手表。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2023-11-20。