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. Elle peut également provenir de une conversation téléphonique.
Parfois, deux applications ou plus peuvent vouloir "capturer" la même entrée audio. Elles peuvent effectuer des tâches différentes. 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. Sur cette page, nous utilisons le terme "capturer", qu'une application enregistre ou écoute simplement.
Si deux applications ou plus souhaitent capturer de l'audio en même temps, il peut être difficile de transmettre le 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 de l'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à de l'audio, votre application pouvait
créer un AudioRecord objet, mais une erreur était renvoyée lorsque vous appeliez
AudioRecord.startRecording()
et l'enregistrement ne démarrait pas.
Une exception à cette règle se produisait 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 pouvait commencer à enregistrer. L'application privilégiée s'arrêtait alors et la nouvelle application capturait l'entrée.
Une autre modification a été ajoutée 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'interface utilisateur de premier plan commençait à capturer, elle continuait à s'exécuter, mais recevait le silence, même si elle était la seule à capturer de l'audio à ce moment-là.
Comportement dans Android 10
Le comportement avant Android 10 est "premier arrivé, premier servi". Une fois qu'une application commence à capturer de l'audio, aucune autre application ne peut accéder à l'entrée audio tant que l'application qui capture de l'audio ne s'arrête pas.
Android 10 impose un schéma de priorité qui peut basculer le flux audio d'entrée entre les applications pendant leur exécution. Dans la plupart des cas, si une nouvelle application acquiert l'entrée audio, l'application qui capturait précédemment continue de s'exécuter, mais reçoit le silence. Dans certains cas, le système peut continuer à diffuser de l'audio vers 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 priorité audio gère plusieurs applications qui se disputent l'utilisation de la sortie audio. Toutefois, le focus audio est géré par des requêtes programmatiques pour gagner et libérer le focus, tandis que le schéma de commutation d'entrée décrit ici est basé sur une stratégie de priorisation qui est appliquée automatiquement chaque fois qu'une nouvelle application commence à capturer de l'audio.
Pour capturer de l'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. Il s'agit de l'Assistant Google et de tous les services d'accessibilité.
En outre, une application est traitée différemment
si elle utilise une source audio "sensible à la confidentialité" :
CAMCORDER
ou VOICE_COMMUNICATION.
Les règles de priorisation 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 avec des interfaces utilisateur de premier plan visibles ont une priorité plus élevée que les applications en arrière-plan.
- Les applications qui capturent de l'audio à partir d'une source sensible à la confidentialité ont une priorité plus élevée que celles qui ne le font pas.
- Deux applications ordinaires ne peuvent jamais capturer de l'audio en même temps.
- Dans certaines situations, une application privilégiée peut partager une entrée audio avec une autre application.
- Si deux applications en arrière-plan de même priorité capturent de l'audio, la dernière lancée a une priorité plus élevée.
Scénarios de partage
Lorsque deux applications tentent de capturer de l'audio, elles peuvent toutes deux recevoir le signal d'entrée, ou l'une d'elles peut recevoir le 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 possède 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'entrée audio selon les règles suivantes :
L'Assistant peut recevoir de l'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 de capture.
L'application reçoit de l'audio, sauf si l'Assistant dispose d'un composant d'interface utilisateur visible en haut de l'écran.
Notez que les deux applications ne reçoivent de l'audio que lorsque l'Assistant est en arrière-plan et que l'autre application ne capture pas à partir d'une source audio sensible à la confidentialité.
Service d'accessibilité + application ordinaire
Un AccessibilityService
nécessite une déclaration stricte.
Android partage l'entrée audio selon les règles suivantes :
Si l'interface utilisateur du service est en haut, le service et l'application reçoivent tous deux 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 avec des commandes vocales.
Si le service n'est pas en haut, ce cas est traité comme le cas ordinaire à deux applications ci-dessous.
Deux applications ordinaires
Lorsque deux applications capturent simultanément, une seule reçoit de l'audio et l'autre reçoit le silence.
Android partage l'entrée audio selon les règles suivantes :
- Si aucune des applications n'est sensible à la confidentialité, l'application dont l'interface utilisateur est en haut reçoit de l'audio. Si aucune des applications ne dispose d'une interface utilisateur, celle qui a commencé à capturer le plus récemment reçoit de l'audio.
- Si l'une des applications est sensible à la confidentialité, elle reçoit de l'audio et l'autre reçoit le silence, même si elle dispose d'une interface utilisateur en haut ou a commencé à capturer plus récemment.
- Si les deux applications sont sensibles à la confidentialité, celle qui a commencé à capturer le plus récemment reçoit de 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'entrée audio selon les règles suivantes :
- L'appel reçoit toujours de l'audio.
- L'application peut capturer de l'audio s'il 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) avec l'autorisation
CAPTURE_AUDIO_OUTPUT.Pour capturer la liaison montante (TX), la liaison descendante (RX) ou les deux de l'appel vocal, l'application doit spécifier les sources audio
MediaRecorder.AudioSource.VOICE_UPLINKouMediaRecorder.AudioSource.VOICE_DOWNLINK, et/ou l'appareilAudioDeviceInfo.TYPE_TELEPHONY.
Comportement dans 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 de 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 capturer simultanément. 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 de l'audio simultanément, une ou deux seulement sont "actives" (reçoivent de l'audio) ; les autres sont mises en sourdine (reçoivent le silence). Lorsque les applications actives changent, le framework audio peut reconfigurer les chemins audio selon les règles suivantes :
- 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 la plus prioritaire est activé. Tous les autres prétraitements sont ignorés.
Étant donné qu'une application active peut être mise en sourdine lorsqu'une application de priorité plus élevée devient active,
vous pouvez enregistrer un
AudioManager.AudioRecordingCallback
sur l'objet AudioRecord
ou MediaRecorder
pour être averti lorsque la configuration change.
Les modifications possibles sont les suivantes :
- Capture mise en sourdine ou non
- Appareil modifié
- Prétraitement modifié
- Propriétés du flux modifiées (fréquence 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 de l'audio et qu'une modification se produit.
La méthode onRecordingConfigChanged() renvoie une AudioRecordingConfiguration contenant l'état actuel de la capture audio. Utilisez les méthodes suivantes pour en savoir plus sur la modification :
isClientSilenced()- Renvoie la valeur "true" si l'audio renvoyé au client est actuellement mis en sourdine en raison de la stratégie 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 celui renvoyé par
getClientEffects()si le client n'est pas l'application active la plus prioritaire. 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 rééchantillonnage, le canal et la conversion de format nécessaires entre le format utilisé au niveau de l'interface matérielle et le format spécifié par le client. AudioRecord.getActiveRecordingConfiguration().- Renvoie la configuration d'enregistrement active.
Vous pouvez obtenir une vue générale de tous les enregistrements actifs sur l'appareil en appelant
AudioManager.getActiveRecordingConfigurations().