Este guia descreve como usar APIs conhecidas do Android para tocar áudio em apps do Wear OS.
Detectar dispositivos de áudio
Um app para Wear OS precisa primeiro detectar se o dispositivo wearable tem uma saída de áudio adequada. Os wearables geralmente têm pelo menos uma das seguintes saídas de áudio:
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
: em dispositivos com um alto-falante integrado.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP
: quando um fone de ouvido Bluetooth está pareado e conectado.AudioDeviceInfo.TYPE_BLE_BROADCAST
: quando um dispositivo do grupo de transmissão Bluetooth de baixa energia (BLE) estiver pareado e conectado.AudioDeviceInfo.TYPE_BLE_HEADSET
: quando um fone de ouvido BLE estiver pareado e conectado.AudioDeviceInfo.TYPE_BLE_SPEAKER
: quando um alto-falante BLE está pareado e conectado.
O exemplo a seguir usa o método getDevices()
com o valor FEATURE_AUDIO_OUTPUT
para verificar se um tipo de saída de áudio está disponível.
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 } }
Em seguida, use esse método para verificar se um tipo de saída de áudio está disponível.
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)
Para oferecer a melhor experiência ao usuário, toque mídia somente quando fones de ouvido ou alto-falantes Bluetooth estiverem conectados ao relógio.
Escolher o dispositivo preferido para saída de áudio
Dependendo do caso de uso do seu app e da importância do áudio para a experiência principal dele, escolha como os usuários interagem com a saída de áudio.
Permitir que o usuário escolha o dispositivo de saída de mídia
A partir do Wear OS 5, o sistema oferece uma interface que permite aos usuários escolher qual dispositivo reproduz mídia e mostra informações sobre o conteúdo em reprodução.
Se o app detectar que não há um fone de ouvido Bluetooth conectado quando você quiser
reproduzir áudio em dispositivos com Wear OS 5 ou mais recente, ofereça a opção de direcionar
o usuário diretamente para o seletor de saída de mídia. Em dispositivos que não oferecem suporte ao
seletor de saída de mídia, chame a ação intent
ACTION_BLUETOOTH_SETTINGS
, que leva o usuário à página do Bluetooth nas configurações do sistema.
O método launchOutputSelection()
, parte da biblioteca Horologist
no GitHub, demonstra como permitir que os usuários escolham o dispositivo de saída de mídia.
Fone de ouvido Bluetooth
Ao contrário dos alto-falantes integrados, que estão sempre disponíveis se estiverem presentes no dispositivo, um
fone de ouvido Bluetooth pode ser pareado ou não enquanto um app está em execução. Se o app
exigir um fone de ouvido para continuar, registre um callback para detectar quando o usuário
conecta e desconecta um fone de ouvido Bluetooth usando
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)
Se o app detectar que não há um fone de ouvido Bluetooth conectado quando você quiser
fornecer uma saída de áudio, não mostre uma mensagem de erro. Em vez disso, ofereça a opção de direcionar o
usuário diretamente às configurações do Bluetooth para facilitar a conexão. Para
fazer isso, envie uma intent com 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
Alto-falantes integrados
A maioria dos dispositivos Wear OS tem alto-falantes integrados. Se o app oferece um caso de uso que não é de mídia e usa som, considere usar alto-falantes para oferecer uma dimensão extra de engajamento. Por exemplo, um dispositivo Wear OS com alto-falantes pode acionar um alarme de relógio ou timer com uma notificação de áudio, e os apps fitness podem usar o alto-falante para fornecer instruções de exercício.
Consulte o WearSpeakerSample para mais detalhes.
Tocar o áudio
Depois de detectar e escolher uma saída de áudio adequada, o processo para tocar áudio no Wear OS é o mesmo usado em dispositivos móveis ou de outros tipos. Para mais informações, consulte Visão geral do MediaPlayer. Para facilitar o acesso a recursos avançados, como streaming e download de mídia, use o ExoPlayer. Siga as práticas recomendadas para apps de áudio, por exemplo, gerenciar a seleção de áudio.
Impedir a reprodução não intencional de mídia pelos alto-falantes integrados
Os apps de mídia podem seguir estas orientações para evitar que o app reproduza mídia de forma não intencional nos alto-falantes integrados do relógio. A orientação varia de acordo com o player usado pelo app.
ExoPlayer
Se o app usa o ExoPlayer:
- Chame o método
setSuppressPlaybackOnUnsuitableOutput(true)
ao criar a instância do ExoPlayer:
val exoPlayer = ExoPlayer.Builder(context) .setAudioAttributes(AudioAttributes.DEFAULT, true) .setSuppressPlaybackOnUnsuitableOutput(true) .build()
- Reaja ao evento de supressão de reprodução registrando o
listener
WearUnsuitableOutputPlaybackSuppressionResolverListener
como um listener da instância do ExoPlayer:
exoPlayer.addListener(WearUnsuitableOutputPlaybackSuppressionResolverListener(context))
Kit de ferramentas de mídia do Horologist
O Horologist MediaToolkit (link em inglês) já contém lógica para evitar a reprodução não intencional de mídia em alto-falantes integrados do relógio.
Outros players de mídia
- Garanta que o áudio de conteúdo de mídia só seja iniciado se um dispositivo de saída adequado, como um fone de ouvido ou alto-falantes externos, estiver conectado ao relógio. Confira a lista a seguir para descobrir os dispositivos de saída adequados para apps de música:
- Pause a reprodução se o AudioManager notificar seu app de que um dispositivo de saída de áudio externo foi desconectado do relógio.
- Quando o usuário tentar iniciar a reprodução de mídia, mas não tiver conectado um dispositivo de áudio externo, peça que ele conecte um dispositivo ao relógio.