Este guia descreve como usar APIs conhecidas do Android para tocar áudio em apps para Wear OS.
Detectar dispositivos de áudio
Os apps para Wear OS precisam primeiro detectar se o dispositivo wearable tem uma saída de áudio adequada. Os dispositivos 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 estiver 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 estiver 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 do usuário, toque mídia somente quando fones de ouvido com Bluetooth ou alto-falantes 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 você quer que os usuários interajam 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 toca mídia e mostra informações sobre o conteúdo de mídia em reprodução.
Se o app detectar que não há um fone de ouvido Bluetooth conectado quando você quiser fornecer reprodução de áudio em dispositivos com o 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 de ACTION_BLUETOOTH_SETTINGS intent, que leva o usuário à página do Bluetooth nas configurações do sistema.
O launchOutputSelection() método, que faz parte da biblioteca Horologist
no GitHub (link em inglês), 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 que um fone de ouvido seja conectado para continuar, registre um callback para detectar quando o usuário conecta e desconecta o 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 às configurações de 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, use alto-falantes para oferecer uma dimensão extra de engajamento. Por exemplo, um dispositivo Wear OS com alto-falantes pode acionar alarmes de relógio ou timers com notificações de áudio, e os apps fitness podem usar o alto-falante para fornecer instruções de exercício.
Consulte WearSpeakerSample (link em inglês) 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 saber mais, consulte Visão geral da MediaPlayer. Para facilitar o acesso a recursos avançados, por exemplo, 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 toque mídia de forma não intencional nos alto-falantes integrados do relógio. As orientações variam dependendo do player usado pelo app.
ExoPlayer
Se o app usa o ExoPlayer:
- Chame
setSuppressPlaybackOnUnsuitableOutput(true)método 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
WearUnsuitableOutputPlaybackSuppressionResolverListenerlistener como um listener da instância do ExoPlayer:
exoPlayer.addListener(WearUnsuitableOutputPlaybackSuppressionResolverListener(context))
Kit de ferramentas de mídia do Horologist
O Horologist MediaToolkit 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 quando um dispositivo de saída adequado, por exemplo, um fone de ouvido ou alto-falantes externos, estiver conectado ao relógio. A lista a seguir mostra dispositivos de saída adequados para apps de mídia:
- Se o
AudioManagernotificar seu app de que um dispositivo de saída de áudio externo foi desconectado do relógio, pause a reprodução. - 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.