Lire du contenu audio sur des accessoires connectés

Ce guide explique comment utiliser des API Android bien connues pour lire du contenu audio dans les applications Wear OS.

Détecter les appareils audio

Une application Wear OS doit d'abord détecter si l'accessoire connecté est pourvu d'une sortie audio appropriée. Les accessoires connectés disposent généralement d'au moins l'une des sorties audio suivantes :

  • AudioDeviceInfo.TYPE_BUILTIN_SPEAKER : sur les appareils équipés d'un haut-parleur intégré.
  • AudioDeviceInfo.TYPE_BLUETOOTH_A2DP : lorsqu'un casque Bluetooth est associé et connecté.
  • AudioDeviceInfo.TYPE_BLE_BROADCAST : lorsqu'un appareil de groupe de broadcast Bluetooth à basse consommation (BLE) est associé et connecté.
  • AudioDeviceInfo.TYPE_BLE_HEADSET : lorsqu'un casque BLE est associé et connecté.
  • AudioDeviceInfo.TYPE_BLE_SPEAKER : lorsqu'une enceinte BLE est associée et connectée.

L'exemple suivant utilise la méthode getDevices() avec la valeur FEATURE_AUDIO_OUTPUT pour vérifier si un type de sortie audio est disponible.

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 }
}

Vous pouvez ensuite utiliser cette méthode pour vérifier si un type de sortie audio est disponible.

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)

Pour offrir une expérience utilisateur optimale, ne lisez les contenus multimédias que lorsque des écouteurs ou des enceintes Bluetooth sont connectés à la montre.

Sélectionner l'appareil par défaut pour la sortie audio

Choisissez la manière dont les utilisateurs interagissent avec la sortie audio de votre application en fonction du cas d'utilisation et de l'importance du son pour l'expérience de base.

Autoriser l'utilisateur à choisir un appareil de sortie média

À partir de Wear OS 5, le système fournit une UI qui permet aux utilisateurs de choisir l'appareil sur lequel le contenu multimédia est lu et d'afficher des informations sur le contenu multimédia en cours de lecture.

Si votre application détecte qu'aucun casque Bluetooth n'est connecté lorsque vous souhaitez fournir une lecture audio sur des appareils exécutant Wear OS 5 ou une version ultérieure, proposez à l'utilisateur d'accéder directement au sélecteur de sortie multimédia. Sur les appareils qui ne sont pas compatibles avec le sélecteur de sortie multimédia, appelez l'action d'intent ACTION_BLUETOOTH_SETTINGS, qui redirige l'utilisateur vers la page Bluetooth des paramètres système.

La méthode launchOutputSelection(), qui fait partie de la bibliothèque Horologist sur GitHub, montre comment permettre aux utilisateurs de choisir leur périphérique de sortie multimédia.

Casque Bluetooth

Contrairement aux haut-parleurs intégrés, qui sont toujours disponibles si l'appareil en est équipé, un casque Bluetooth peut être associé ou dissocié pendant l'exécution d'une application. Si votre application nécessite un casque pour continuer, enregistrez un rappel à l'aide de registerAudioDeviceCallback pour détecter le moment où l'utilisateur connecte et déconnecte le casque Bluetooth :

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)

Si votre application détecte qu'aucun casque Bluetooth n'est connecté lorsque vous souhaitez fournir une sortie audio, n'affichez pas de message d'erreur. Proposez plutôt de rediriger l'utilisateur directement vers les paramètres Bluetooth pour lui permettre de se connecter plus facilement. Pour ce faire, envoyez un intent avec 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

Haut-parleurs intégrés

La plupart des appareils Wear OS sont équipés de haut-parleurs intégrés. Si votre application propose un cas d'utilisation non multimédia qui utilise du son, envisagez d'utiliser des haut-parleurs pour ajouter une dimension supplémentaire et renforcer l'engagement. Par exemple, un appareil Wear OS équipé d'un haut-parleur peut déclencher une alarme ou un minuteur avec une notification audio. Les applications de fitness peuvent également utiliser le haut-parleur pour fournir des instructions sur un exercice.

Pour en savoir plus, consultez WearSpeakerSample.

Lire l'audio

Une fois que vous avez détecté et sélectionné une sortie audio appropriée, la lecture audio sur Wear OS est la même que sur un appareil mobile ou sur d'autres appareils. Pour en savoir plus, consultez Présentation de MediaPlayer. Pour accéder plus facilement à des fonctionnalités avancées, comme la lecture en streaming et le téléchargement de contenus multimédias, utilisez ExoPlayer. Suivez les bonnes pratiques pour les applications audio, par exemple gérer la priorité audio.

Empêcher la lecture involontaire de contenus multimédias sur les haut-parleurs intégrés

Vous pouvez suivre ces conseils pour éviter que votre application multimédia lance involontairement des contenus sur les haut-parleurs intégrés de la montre. Les instructions varient selon le lecteur utilisé par votre application.

ExoPlayer

Si votre application utilise ExoPlayer :

  1. Appelez la méthode setSuppressPlaybackOnUnsuitableOutput(true) lors de la création de l'instance ExoPlayer :

val exoPlayer = ExoPlayer.Builder(context)
    .setAudioAttributes(AudioAttributes.DEFAULT, true)
    .setSuppressPlaybackOnUnsuitableOutput(true)
    .build()

  1. Réagissez à l'événement de suppression de lecture en enregistrant l'écouteur WearUnsuitableOutputPlaybackSuppressionResolverListener comme écouteur de l'instance ExoPlayer :

exoPlayer.addListener(WearUnsuitableOutputPlaybackSuppressionResolverListener(context))

Kit d'outils Horologist Media

Le Kit d'outils Horologist Media contient déjà une logique permettant d'éviter la lecture involontaire de contenus multimédias sur les haut-parleurs intégrés de la montre.

Autres lecteurs multimédias