L'entrée audio provient généralement du micro intégré, d'un micro externe ou d'une interface audio connectée à l'appareil. L'entrée audio peut également provenir d'une conversation téléphonique.
Il peut arriver que deux applications ou plus souhaitent "capturer" la même entrée audio. Ils peuvent effectuer différentes tâches. Par exemple, certaines applications qui reçoivent de l'audio peuvent "enregistrer", comme un simple enregistreur vocal, tandis que d'autres peuvent "écouter", comme l'Assistant Google ou un service d'accessibilité qui répond aux commandes vocales.
Dans les deux cas, ces applications souhaitent recevoir une entrée audio. Tout au long de cette page, nous utilisons le terme "capture", que l'application enregistre ou écoute simplement.
Si deux applications ou plus souhaitent capturer l'audio en même temps, il peut y avoir un problème de diffusion du signal audio de la même source à toutes. Cette page explique comment le système Android partage l'entrée audio entre plusieurs applications qui capturent du contenu audio.
Comportement avant Android 10
Avant Android 10, le flux audio d'entrée ne pouvait être capturé que par une seule application à la fois. Si une application enregistrait ou écoutait déjà du contenu audio, votre application pouvait créer un objet AudioRecord
, mais une erreur était renvoyée lorsque vous appeliez AudioRecord.startRecording()
et l'enregistrement ne démarrait pas.
Une exception à cette règle était lorsqu'une application privilégiée (comme l'Assistant Google ou un service d'accessibilité) disposait de l'autorisation android.permission.CAPTURE_AUDIO_HOTWORD
et utilisait une source audio de type HOTWORD
. Dans ce cas, une autre application peut commencer à enregistrer. Dans ce cas, l'application privilégiée s'est arrêtée et la nouvelle application a capturé l'entrée.
Un autre changement a été ajouté dans Android 9: seules les applications exécutées au premier plan (ou un service de premier plan) pouvaient capturer l'entrée audio. Lorsqu'une application sans service de premier plan ni composant d'UI de premier plan commençait à effectuer une capture, elle continuait à s'exécuter, mais ne recevait aucun son, même si elle était la seule à capturer l'audio à ce moment-là.
Comportement d'Android 10
Avant Android 10, le comportement était "premier arrivé, premier servi". Une fois qu'une application commence à enregistrer du contenu audio, aucune autre application ne peut y accéder tant que l'application qui enregistre du contenu audio ne s'arrête pas.
Android 10 impose un schéma de priorité qui peut commuter le flux audio d'entrée entre les applications lorsqu'elles sont en cours d'exécution. Dans la plupart des cas, si une nouvelle application acquiert l'entrée audio, l'application qui effectuait la capture précédemment continue de s'exécuter, mais ne reçoit aucun son. Dans certains cas, le système peut continuer à diffuser l'audio dans les deux applications. Les différents scénarios de partage sont expliqués ci-dessous.
Ce schéma est semblable à la façon dont la sélection audio gère plusieurs applications qui s'affrontent pour utiliser la sortie audio. Toutefois, la priorité audio est gérée par des requêtes programmatiques pour obtenir et libérer la priorité, tandis que le schéma de commutation d'entrée décrit ici est basé sur une stratégie de priorisation appliquée automatiquement chaque fois qu'une nouvelle application commence à capturer l'audio.
Pour la capture audio, Android distingue deux types d'applications:
- Les applications "ordinaires" sont installées par l'utilisateur.
- Les applications "privilégiées" sont préinstallées sur l'appareil. Cela inclut l'Assistant Google et tous les services d'accessibilité.
De plus, une application est traitée différemment si elle utilise une source audio "sensible à la confidentialité" : CAMCORDER
ou VOICE_COMMUNICATION
.
Les règles de priorité pour l'utilisation et le partage de l'entrée audio sont les suivantes:
- Les applications privilégiées ont une priorité plus élevée que les applications ordinaires.
- Les applications dont l'UI de premier plan est visible ont une priorité plus élevée que les applications en arrière-plan.
- Les applications qui capturent du contenu audio à partir d'une source sensible à la confidentialité ont une priorité plus élevée que les applications qui ne le font pas.
- Deux applications ordinaires ne peuvent jamais capturer l'audio en même temps.
- Dans certains cas, une application privilégiée peut partager l'entrée audio avec une autre application.
- Si deux applications en arrière-plan de même priorité capturent l'audio, la dernière lancée a la priorité la plus élevée.
Scénarios de partage
Lorsque deux applications tentent de capturer du son, il est possible qu'elles puissent toutes les deux recevoir le signal d'entrée, ou qu'une d'entre elles ne reçoive que du silence.
Il existe quatre scénarios principaux:
- Assistant + application ordinaire
- Service d'accessibilité + application ordinaire
- Deux applications ordinaires
- Appel vocal + application ordinaire
Assistant + application ordinaire
L'Assistant est une application privilégiée, car elle est préinstallée et détient le rôle RoleManager.ROLE_ASSISTANT
.
Toute autre application préinstallée avec ce rôle est traitée de la même manière.
Android partage l'audio de l'entrée selon les règles suivantes:
L'Assistant peut recevoir du contenu audio (qu'il soit au premier plan ou en arrière-plan) sauf si une autre application utilisant une source audio sensible à la confidentialité est déjà en cours d'enregistrement.
L'application reçoit l'audio, sauf si l'Assistant dispose d'un composant d'UI visible en haut de l'écran.
Notez que les deux applications ne reçoivent du contenu audio que lorsque l'Assistant est en arrière-plan et que l'autre application ne capture pas de source audio sensible à la confidentialité.
Service d'accessibilité + application ordinaire
Un AccessibilityService
nécessite une déclaration stricte.
Android partage l'audio de l'entrée selon les règles suivantes:
Si l'interface utilisateur du service est en haut, le service et l'application reçoivent une entrée audio. Ce comportement offre des fonctionnalités telles que le contrôle d'un appel vocal ou d'une capture vidéo à l'aide de commandes vocales.
Si le service ne se trouve pas en haut, ce cas est traité comme le cas ordinaire à deux applications ci-dessous.
Deux applications ordinaires
Lorsque deux applications effectuent une capture en même temps, une seule reçoit du son, l'autre n'en reçoit pas.
Android partage l'audio de l'entrée selon les règles suivantes:
- Si aucune des applications n'est sensible à la confidentialité, l'application dont l'UI est en haut reçoit l'audio. Si aucune des applications n'a d'UI, celle qui a commencé la capture la plus récemment reçoit l'audio.
- Si l'une des applications est sensible à la confidentialité, elle reçoit l'audio et l'autre application reçoit le silence, même si elle dispose d'une UI en superposition ou a commencé à enregistrer plus récemment.
- Si les deux applications sont sensibles à la confidentialité, l'application qui a commencé à enregistrer le plus récemment reçoit l'audio et l'autre reçoit le silence.
Appel vocal + application ordinaire
Un appel vocal est actif si le mode audio renvoyé par AudioManager.getMode()
est MODE_IN_CALL
ou MODE_IN_COMMUNICATION
.
Android partage l'audio de l'entrée selon les règles suivantes:
- L'appel reçoit toujours de l'audio.
- L'application peut capturer l'audio si elle s'agit d'un service d'accessibilité.
L'application peut capturer l'appel vocal s'il s'agit d'une application privilégiée (préinstallée) disposant de l'autorisation
CAPTURE_AUDIO_OUTPUT
.Pour capturer l'encapsulation montante (TX) ou descendante (RX) de l'appel vocal, ou les deux, l'application doit spécifier les sources audio
MediaRecorder.AudioSource.VOICE_UPLINK
ouMediaRecorder.AudioSource.VOICE_DOWNLINK
, et/ou l'appareilAudioDeviceInfo.TYPE_TELEPHONY
.
Comportement d'Android 11
Android 11 (niveau d'API 30) respecte le schéma de priorité Android 10 décrit ci-dessus. Il fournit également de nouvelles méthodes dans AudioRecord
, MediaRecorder
et AAudioStream
qui activent et désactivent la possibilité de capturer l'audio simultanément, quel que soit le cas d'utilisation sélectionné.
Les nouvelles méthodes sont les suivantes:
AudioRecord.Builder.setPrivacySensitive()
AudioRecord.isPrivacySensitive()
MediaRecorder.setPrivacySensitive()
MediaRecorder.isPrivacySensitive()
AAudioStreamBuilder_setPrivacySensitive()
AAudioStream_isPrivacySensitive()
Lorsque setPrivacySensitive()
est true
, le cas d'utilisation de la capture est privé et même un Assistant privilégié ne peut pas effectuer de capture en même temps. Ce paramètre remplace le comportement par défaut qui dépend de la source audio. Par exemple, VOICE_COMMUNICATION
est privé par défaut, mais UNPROCESSED
ne l'est pas.
Modifications de configuration
Lorsque plusieurs applications capturent du son simultanément, une ou deux d'entre elles sont "actives" (elles reçoivent du son) et les autres sont mises en sourdine (elles reçoivent du silence). Lorsque les applications actives changent, le framework audio peut reconfigurer les chemins audio conformément à ces règles:
- L'appareil d'entrée audio de chaque application active peut changer (par exemple, du micro intégré à un casque Bluetooth connecté).
- Le prétraitement associé à l'application active de priorité la plus élevée est activé. Tout autre prétraitement est ignoré.
Étant donné qu'une application active peut être mise en sourdine lorsqu'une application de priorité supérieure devient active, vous pouvez enregistrer un AudioManager.AudioRecordingCallback sur l'objet AudioRecord
ou MediaRecorder
pour être informé lorsque la configuration change.
Les modifications possibles sont les suivantes:
- Capture avec le son coupé ou réactivé
- Appareil modifié
- Prétraitement modifié
- Les propriétés du flux ont changé (taux d'échantillonnage, masque de canal, format d'échantillon)
Vous devez appeler AudioRecord.registerAudioRecordingCallback()
avant le début de la capture.
Le rappel n'est exécuté que lorsque l'application reçoit du contenu audio et qu'un changement se produit.
La méthode onRecordingConfigChanged()
renvoie un AudioRecordingConfiguration
contenant l'état actuel de la capture audio. Pour en savoir plus sur ce changement, utilisez les méthodes suivantes:
isClientSilenced()
- Renvoie la valeur "true" si l'audio renvoyé au client est actuellement coupé en raison de la règle de capture.
getAudioDevice()
- Renvoie l'appareil audio actif.
getEffects()
- Renvoie l'effet de prétraitement actif. Notez que l'effet actif peut ne pas être le même que ceux renvoyés par
getClientEffects()
si le client n'est pas l'application active de priorité la plus élevée. getFormat()
- Renvoie les propriétés du flux. Notez que les données audio réelles reçues par le client respectent toujours le format requis renvoyé par
getClientFormat()
. Le framework effectue automatiquement le reéchantillonnage, le canal et la conversion de format nécessaires du format utilisé à l'interface matérielle au format spécifié par le client. AudioRecord.getActiveRecordingConfiguration()
.- Renvoie la configuration de l'enregistrement actif.
Vous pouvez obtenir une vue d'ensemble de tous les enregistrements actifs sur l'appareil en appelant AudioManager.getActiveRecordingConfigurations()
.