在可穿戴设备上播放音频

本指南介绍了 Wear OS 上的应用如何使用熟悉的 Android API 播放音频。

检测音频设备

Wear OS 应用必须首先检测可穿戴设备是否有合适的音频输出。开发者可以预期可穿戴设备至少具有以下音频输出之一可用

在以下示例中,应用使用 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 }
}

// True if the device has a speaker
audioOutputAvailable(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER)

// True if a Bluetooth headset is paired and connected
audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP)

// True if a BLE broadcast group device is paired and connected
audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_BROADCAST)

// True if a BLE headset is paired and connected
audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_HEADSET)

// True if a BLE speaker is paired and connected
audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_SPEAKER)

为了提供最佳的用户体验,您的应用应确保仅在蓝牙耳机或扬声器连接到手表时播放媒体。

选择音频输出的首选设备

根据您的应用用例以及音频对应用核心体验的重要性,选择您希望用户如何与应用的音频输出交互。

允许用户选择媒体输出设备

从 Wear OS 5 开始,系统提供了一个 UI,允许用户选择哪个设备应播放媒体并显示有关当前播放的媒体内容的信息。

如果您的应用在运行 Wear OS 5 或更高版本的设备上需要提供音频播放时检测到未连接蓝牙耳机,请提供选项将用户直接带到媒体输出切换器。在不支持媒体输出切换器的设备上,调用 ACTION_BLUETOOTH_SETTINGS 意图操作,这会将用户带到系统设置中的蓝牙页面。

GitHub 上的 Horologist 库中的 launchOutputSelection() 方法演示了如何让用户选择其媒体输出设备。

蓝牙耳机

与设备上始终可用的内置扬声器不同,蓝牙耳机可以在应用运行期间配对或取消配对。如果应用需要耳机才能继续运行,请注册一个回调,以使用 registerAudioDeviceCallback 检测用户何时连接和断开蓝牙耳机。

audioManager.registerAudioDeviceCallback(object : AudioDeviceCallback() {
    override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>?) {
        super.onAudioDevicesAdded(addedDevices)
        if (audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP)
          || audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_BROADCAST)
          || audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_HEADSET)
          || audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_SPEAKER)) {
            // A Bluetooth or BLE device is connected and available for playback.
        }
    }
    override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>?) {
        super.onAudioDevicesRemoved(removedDevices)
        if (!(audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP))
          && !(audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_BROADCAST))
          && !(audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_HEADSET))
          && !(audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_SPEAKER))) {
            // No Bluetooth or BLE devices are connected anymore.
        }
    }
}, null)
  

如果您的应用在需要提供音频输出时检测到未连接蓝牙耳机,请不要显示错误消息。而是提供选项将用户直接带到蓝牙设置,以便他们更轻松地进行连接。这可以通过发送带有 ACTION_BLUETOOTH_SETTINGS 的意图来完成。

  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

  1. 在构建 ExoPlayer 实例时调用 setSuppressPlaybackOnUnsuitableOutput(true)

      ExoPlayer exoplayer = ExoPlayer.Builder(context)
              .setAudioAttributes(...)
              .setSuppressPlaybackWhenUnsuitableOutput(true)
              // ...
              .build()
          
  2. 通过注册 WearUnsuitableOutputPlaybackSuppressionResolverListener 作为 ExoPlayer 实例的侦听器来响应播放抑制事件。

  3.   exoPlayer.addListener(WearUnsuitableOutputPlaybackSuppressionResolverListener(context))
        

Horologist 媒体工具包

Horologist MediaToolkit 已经包含了防止意外在内置手表扬声器上播放媒体内容的逻辑。

其他媒体播放器