В этом руководстве описано, как использовать привычные 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-гарнитуры пользователем с помощью 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, чтобы упростить подключение. Это можно сделать, отправив Intent с параметром 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:
- При создании экземпляра ExoPlayer вызовите метод
setSuppressPlaybackOnUnsuitableOutput(true):
val exoPlayer = ExoPlayer.Builder(context) .setAudioAttributes(AudioAttributes.DEFAULT, true) .setSuppressPlaybackOnUnsuitableOutput(true) .build()
- Для реагирования на событие подавления воспроизведения зарегистрируйте слушатель
WearUnsuitableOutputPlaybackSuppressionResolverListenerв качестве слушателя экземпляра ExoPlayer:
exoPlayer.addListener(WearUnsuitableOutputPlaybackSuppressionResolverListener(context))
Набор инструментов для специалистов по часовому делу и СМИ
В Horologist MediaToolkit уже содержится логика, предотвращающая непреднамеренное воспроизведение мультимедиа через встроенные динамики часов.
Другие участники медиа-рынка
- Убедитесь, что воспроизведение аудиофайлов начинается только при подключении к часам подходящего устройства вывода, например, гарнитуры или внешних динамиков. Ниже приведен список подходящих устройств вывода для мультимедийных приложений:
- Если
AudioManagerуведомит ваше приложение о том, что внешнее устройство вывода звука отключилось от часов , приостановите воспроизведение. - Если пользователь пытается начать воспроизведение мультимедиа, но не подключил внешнее аудиоустройство, предложите ему подключить устройство к часам.