A entrada de áudio normalmente é proveniente de um microfone integrado, externo ou de uma interface de áudio anexada ao dispositivo. A entrada de áudio também pode vir de uma conversa telefônica.
Às vezes, dois ou mais apps podem querer "capturar" a mesma entrada de áudio. Eles podem estar executando tarefas diferentes. Por exemplo, alguns apps que recebem áudio podem estar "gravando", como um gravador de voz simples, enquanto outros podem estar "ouvindo", como o Google Assistente ou um serviço de acessibilidade que responda a comandos de voz.
De qualquer forma, os aplicativos querem receber a entrada de áudio. No decorrer desta página, usamos o termo "capturar" independentemente do fato de um app estar gravando ou só ouvindo.
Se dois ou mais apps quiserem capturar o áudio ao mesmo tempo, poderá haver um problema na entrega do sinal de áudio da mesma fonte para todos eles. Esta página descreve como o sistema Android compartilha a entrada de áudio entre vários apps que fazem a captura do áudio.
Comportamento anterior ao Android 10
Antes do Android 10, o stream de áudio de entrada só podia ser capturado por um app de cada vez. Caso um app já estivesse gravando ou ouvindo um áudio, seu app poderia
criar um objeto AudioRecord
, mas um erro seria retornado quando você chamasse
AudioRecord.startRecording()
e a gravação não seria iniciada.
Uma exceção a essa regra era quando um app privilegiado (como o Google Assistente ou um
serviço de acessibilidade) tinha a permissão
android.permission.CAPTURE_AUDIO_HOTWORD
e usava uma fonte de áudio do tipo
HOTWORD
. Nesse caso, outro aplicativo poderia começar a gravar. Quando isso acontecia, o
app privilegiado era encerrado e o novo app capturava a entrada.
Mais uma mudança foi adicionada no Android 9: somente apps em primeiro plano (ou um serviço em primeiro plano) podiam capturar a entrada de áudio. Quando um app sem componente de IU ou serviço em primeiro plano começava a capturar, o app continuava em execução, mas recebia silêncio, mesmo que fosse o único a capturar áudio no momento.
Comportamento do Android 10
O comportamento anterior ao Android 10 é "o primeiro a chegar é o primeiro a receber". Quando um app começa a capturar áudio, nenhum outro app pode acessar a entrada de áudio até que o app que está capturando áudio pare.
O Android 10 impõe um esquema de prioridade que pode trocar o stream do áudio de entrada entre apps em execução. Na maioria dos casos, se um novo app acessar a entrada de áudio, o que estava fazendo a captura continuará a operar, mas receberá silêncio. Em alguns casos, o sistema pode continuar a fornecer áudio para os dois apps. Os diversos cenários de compartilhamento são explicados abaixo.
Esse esquema é semelhante à forma com que a seleção de áudio processa vários aplicativos que disputam o uso da saída de áudio. No entanto, a seleção de áudio é gerenciada por solicitações programáticas para ganhar e liberar foco, enquanto o esquema de alternância de entrada descrito aqui é baseado em uma política de priorização que é aplicada automaticamente sempre que um novo app começa a capturar áudio.
Com a finalidade de capturar o áudio, o Android diferencia dois tipos de aplicativos:
- Os apps "comuns" são instalados pelo usuário.
- Apps "privilegiados" vêm pré-instalados no dispositivo. Esses últimos incluem o Google Assistente e todos os serviços de acessibilidade.
Além disso, um app é tratado de maneira diferenciada
se usa uma fonte de áudio "sensível à privacidade":
CAMCORDER
ou VOICE_COMMUNICATION
.
As regras de priorização para uso e compartilhamento de entrada de áudio são as seguintes:
- Os aplicativos privilegiados têm prioridade mais alta do que os comuns.
- Os aplicativos com IUs em primeiro plano visíveis têm prioridade mais alta do que aqueles em segundo plano.
- Os aplicativos que capturam áudio de uma fonte sensível à privacidade têm prioridade mais alta do que aqueles que não fazem isso.
- Não é possível a dois aplicativos comuns capturarem áudio ao mesmo tempo.
- Em algumas situações, um aplicativo privilegiado pode compartilhar a entrada de áudio com outro aplicativo.
- Se dois aplicativos em segundo plano da mesma prioridade estiverem capturando áudio, o último a ser iniciado terá prioridade mais alta.
Cenários de compartilhamento
Quando dois aplicativos tentam capturar o áudio, pode ser que ambos recebam o sinal de entrada ou um deles receba silêncio.
Estes são os quatro cenários principais:
- Assistente + aplicativo comum
- Serviço de acessibilidade + aplicativo comum
- Dois aplicativos comuns
- Chamada de voz + aplicativo comum
Assistente + aplicativo comum
O Google Assistente é um app privilegiado porque é pré-instalado e tem o
papel RoleManager.ROLE_ASSISTANT
.
Qualquer outro aplicativo pré-instalado com esse papel é tratado de modo semelhante.
O Android compartilha o áudio de entrada de acordo com estas regras:
O Google Assistente pode receber áudio, esteja em primeiro ou segundo plano, a menos que outro app que use uma fonte de áudio sensível à privacidade já esteja fazendo a captura.
O app recebe o áudio, a não ser que o Assistente tenha um componente da IU visível na parte superior da tela.
Os dois apps recebem áudio somente quando o Google Assistente está em segundo plano e o outro app não está capturando de uma fonte de áudio sensível à privacidade.
Serviço de acessibilidade + aplicativo comum
Um AccessibilityService
exige uma declaração rígida.
O Android compartilha o áudio de entrada de acordo com estas regras:
Se a IU do serviço estiver na parte de cima, o serviço e o app vão receber a entrada de áudio. Esse comportamento oferece funcionalidades como controlar uma ligação ou captura de vídeo com comandos de voz.
Caso o serviço não esteja na parte superior, esse caso será tratado como quando há dois aplicativos comuns, conforme exibido abaixo.
Dois aplicativos comuns
Quando dois aplicativos estão capturando simultaneamente, somente um deles recebe áudio. O outro recebe silêncio.
O Android compartilha o áudio de entrada de acordo com estas regras:
- Se nenhum aplicativo for sensível à privacidade, o app com uma IU na parte de cima vai receber o áudio. Se nenhum aplicativo tiver IU, o último a iniciar a captura receberá o áudio.
- Se um dos apps for sensível à privacidade, ele vai receber o áudio. O outro vai receber silêncio, mesmo que tenha uma IU na parte superior ou que seja o último a iniciar a captura.
- Se os dois aplicativos forem sensíveis à privacidade, o último a iniciar a captura receberá o áudio e o outro receberá silêncio.
Chamada de voz + aplicativo comum
Uma chamada de voz está ativa se o modo de áudio retornado por
AudioManager.getMode()
for
MODE_IN_CALL
ou
MODE_IN_COMMUNICATION
.
O Android compartilha o áudio de entrada de acordo com estas regras:
- A chamada sempre recebe o áudio.
- O app poderá capturar áudio se for um serviço de acessibilidade.
O app poderá capturar a chamada de voz se ele for privilegiado (pré-instalado) com permissão
CAPTURE_AUDIO_OUTPUT
.Para capturar o uplink (TX), o downlink (RX) ou ambos os itens da chamada de voz, o app precisa especificar as fontes de áudio
MediaRecorder.AudioSource.VOICE_UPLINK
ouMediaRecorder.AudioSource.VOICE_DOWNLINK
, e/ou o dispositivoAudioDeviceInfo.TYPE_TELEPHONY
.
Comportamento do Android 11
O Android 11 (API de nível 30) observa o esquema de prioridade do Android 10
descrito acima. Ele também oferece novos métodos em AudioRecord
, MediaRecorder
e
AAudioStream
que ativam e desativam a capacidade de capturar áudio simultaneamente,
independentemente do caso de uso selecionado.
Os novos métodos são:
AudioRecord.Builder.setPrivacySensitive()
AudioRecord.isPrivacySensitive()
MediaRecorder.setPrivacySensitive()
MediaRecorder.isPrivacySensitive()
AAudioStreamBuilder_setPrivacySensitive()
AAudioStream_isPrivacySensitive()
Quando setPrivacySensitive()
for true
, o caso de uso de captura é particular e nem mesmo
um Assistente privilegiado pode gravar simultaneamente. Essa configuração modifica o
comportamento padrão que depende da fonte de áudio. Por exemplo,
VOICE_COMMUNICATION
é particular por padrão, mas UNPROCESSED
não é.
Mudanças de configuração
Quando vários apps capturam áudio simultaneamente, apenas um ou dois deles estão "ativos" (recebendo áudio), os outros estão silenciados (recebendo silêncio). Quando os apps ativos mudam, a estrutura de áudio pode reconfigurar os caminhos do áudio de acordo com estas regras:
- O dispositivo de entrada de áudio para cada app ativo pode mudar (por exemplo, do microfone integrado para um fone de ouvido Bluetooth anexado).
- O pré-processamento associado ao aplicativo ativo com a prioridade mais alta é habilitado. Todos os outros pré-processamentos são ignorados.
Como um app ativo pode ser silenciado quando um app de prioridade mais alta é ativado,
é possível registrar um
AudioManager.AudioRecordingCallback
no objeto AudioRecord
ou MediaRecorder
para receber uma notificação quando a configuração mudar.
Veja algumas possíveis alterações:
- Captura silenciada ou com áudio ativado
- Alteração no dispositivo
- Alteração no pré-processamento
- Alteração nas propriedades de stream (taxa de amostragem, máscara de canal, formato de exemplo)
Você precisa chamar
AudioRecord.registerAudioRecordingCallback()
antes do início da captura.
O callback é executado somente quando o aplicativo está recebendo áudio e ocorre uma alteração.
O método onRecordingConfigChanged()
retorna um AudioRecordingConfiguration
contendo o estado atual da captura de áudio. Use os seguintes
métodos para saber mais sobre a mudança:
isClientSilenced()
- Retorna verdadeiro se o áudio retornado ao cliente estiver sendo silenciado devido à política de captura.
getAudioDevice()
- Retorna o dispositivo de áudio ativo.
getEffects()
- Retorna o efeito de pré-processamento ativo. O efeito ativo pode não ser o mesmo retornado por
getClientEffects()
se o cliente não for o app ativo de maior prioridade. getFormat()
- Retorna as propriedades do stream. Os dados de áudio reais recebidos pelo cliente sempre respeitam o formato exigido retornado por
getClientFormat()
. A biblioteca executa automaticamente a conversão necessária de formato, canal e reamostragem usados na interface de hardware para o formato especificado pelo cliente. AudioRecord.getActiveRecordingConfiguration()
.- Retorna a configuração de gravação ativa.
Para ter uma visão geral de todas as gravações ativas no dispositivo, chame
AudioManager.getActiveRecordingConfigurations()
.