В этом руководстве описывается, как использовать знакомые API Android для воспроизведения звука в приложениях Wear OS.
Обнаружение аудиоустройств
Приложение Wear OS должно сначала определить, есть ли у носимого устройства соответствующий аудиовыход. Обычно носимые устройства имеют как минимум один из следующих аудиовыходов:
-
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
: на устройствах со встроенным динамиком. -
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP
: когда гарнитура Bluetooth сопряжена и подключена. -
AudioDeviceInfo.TYPE_BLE_BROADCAST
: когда сопряжено и подключено устройство группы вещания Bluetooth Low Energy (BLE). -
AudioDeviceInfo.TYPE_BLE_HEADSET
: когда гарнитура BLE сопряжена и подключена. -
AudioDeviceInfo.TYPE_BLE_SPEAKER
: когда динамик BLE сопряжен и подключен.
В следующем примере метод getDevices()
используется со значением FEATURE_AUDIO_OUTPUT
для проверки доступности типа аудиовыхода.
private val audioManager: AudioManager by lazy { getSystemService(AUDIO_SERVICE) as AudioManager } 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 } }
Затем вы можете использовать этот метод для проверки доступности типа аудиовыхода.
val hasSpeaker = audioOutputAvailable(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) val hasBluetoothHeadset = audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) val hasBLEBroadcast = audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_BROADCAST) val hasBLEHeadset = audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_HEADSET) val hasBLESpeaker = audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_SPEAKER)
Для обеспечения наилучшего пользовательского опыта воспроизводите медиафайлы только при подключенных к часам наушниках или динамиках Bluetooth.
Выберите предпочтительное устройство для вывода звука
В зависимости от варианта использования вашего приложения и важности звука для его основного опыта выберите, как пользователи будут взаимодействовать с аудиовыходом вашего приложения.
Разрешить пользователю выбирать устройство вывода мультимедиа
Начиная с Wear OS 5, система предоставляет пользовательский интерфейс, который позволяет пользователям выбирать, на каком устройстве воспроизводится медиа, и отображает информацию о текущем воспроизводимом медиаконтенте.
Если ваше приложение обнаруживает отсутствие подключенной Bluetooth-гарнитуры при воспроизведении звука на устройствах с Wear OS 5 или более поздней версии, предложите пользователю перейти непосредственно к переключателю выходных медиафайлов. На устройствах, не поддерживающих переключатель выходных медиафайлов, вызовите намерение ACTION_BLUETOOTH_SETTINGS
, которое перенаправит пользователя на страницу Bluetooth в системных настройках.
Метод launchOutputSelection()
, входящий в библиотеку Horologist на GitHub, демонстрирует, как предоставить пользователям возможность выбирать устройство вывода мультимедиа.
Bluetooth-гарнитура
В отличие от встроенных динамиков, которые всегда доступны при их наличии на устройстве, Bluetooth-гарнитуру можно подключить или отключить во время работы приложения. Если вашему приложению требуется гарнитура для продолжения работы, зарегистрируйте обратный вызов для отслеживания подключения и отключения Bluetooth-гарнитуры пользователем с помощью registerAudioDeviceCallback
:
val audioDeviceCallback = 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. } } } audioManager.registerAudioDeviceCallback(audioDeviceCallback, /*handler=*/ null)
Если ваше приложение обнаруживает отсутствие подключенной Bluetooth-гарнитуры, когда вы хотите обеспечить аудиовыход, не показывайте сообщение об ошибке. Вместо этого предложите пользователю перейти непосредственно к настройкам Bluetooth, чтобы упростить подключение. Это можно сделать, отправив намерение с помощью ACTION_BLUETOOTH_SETTINGS
:
fun Context.launchBluetoothSettings(closeOnConnect: Boolean = true) { 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) if (closeOnConnect) { putExtra("EXTRA_CLOSE_ON_CONNECT", true) } putExtra("android.bluetooth.devicepicker.extra.FILTER_TYPE", FILTER_TYPE_AUDIO) } startActivity(intent) } internal const val FILTER_TYPE_AUDIO = 1
Встроенные динамики
Большинство устройств Wear OS оснащены встроенными динамиками. Если ваше приложение предназначено для использования без использования медиа, но со звуком, рассмотрите возможность использования динамиков для создания дополнительного уровня взаимодействия. Например, устройство Wear OS с динамиками может активировать звуковой сигнал часов или таймера, а фитнес-приложения могут использовать динамик для предоставления инструкций по тренировкам.
Подробности смотрите в WearSpeakerSample .
Воспроизвести аудио
После определения и выбора подходящего аудиовыхода воспроизведение звука на Wear OS происходит так же, как на мобильных устройствах или других устройствах. Подробнее см. в разделе «Обзор MediaPlayer» . Для более удобного доступа к расширенным функциям, например, потоковой передаче и загрузке медиафайлов, используйте ExoPlayer . Следуйте рекомендациям для аудиоприложений, например, по управлению аудиофокусом .
Предотвращение непреднамеренного воспроизведения медиафайлов через встроенные динамики
Приложения для воспроизведения мультимедиа могут следовать этим рекомендациям, чтобы предотвратить непреднамеренное воспроизведение медиаконтента на встроенных динамиках часов. Инструкции различаются в зависимости от используемого приложения проигрывателя.
ExoPlayer
Если ваше приложение использует ExoPlayer:
- Вызовите метод
setSuppressPlaybackOnUnsuitableOutput(true)
при создании экземпляра ExoPlayer:
val exoPlayer = ExoPlayer.Builder(context) .setAudioAttributes(AudioAttributes.DEFAULT, true) .setSuppressPlaybackOnUnsuitableOutput(true) .build()
- Отреагируйте на событие подавления воспроизведения, зарегистрировав прослушиватель
WearUnsuitableOutputPlaybackSuppressionResolverListener
в качестве прослушивателя экземпляра ExoPlayer:
exoPlayer.addListener(WearUnsuitableOutputPlaybackSuppressionResolverListener(context))
Инструментарий Horologist Media
Horologist MediaToolkit уже содержит логику, предотвращающую непреднамеренное воспроизведение мультимедиа на встроенных динамиках часов.
Другие медиаплееры
- Убедитесь, что воспроизведение звука из медиафайлов начинается только при подключении к часам подходящего устройства вывода, например, гарнитуры или внешних динамиков. В следующем списке представлены подходящие устройства вывода для медиаприложений:
- Приостановите воспроизведение, если AudioManager уведомит ваше приложение об отключении внешнего аудиоустройства от часов .
- Если пользователь пытается начать воспроизведение мультимедиа, но не подключил внешнее аудиоустройство, предложите ему подключить устройство к часам.