A entrada de áudio geralmente vem de um microfone integrado, externo ou de um de áudio do dispositivo conectada ao dispositivo. A entrada de áudio também pode vir uma conversa telefônica.
Às vezes, dois ou mais aplicativos podem querer "capturar" a mesma entrada de áudio. Eles podem estar executando tarefas diferentes. Por exemplo, alguns aplicativos que recebem áudio podem estar "gravando", como um simples gravador de voz, enquanto outros aplicativos podem "ouvir", como o Google Assistente ou um serviço de acessibilidade responder a comandos de voz.
De qualquer forma, os aplicativos querem receber a entrada de áudio. Usamos o termo "capturar" nesta página não importa se um está gravando ou apenas ouvindo.
Se dois ou mais apps quiserem capturar áudio ao mesmo tempo, pode haver um problema entregando o sinal de áudio da mesma origem para todos eles. Nesta página, descrevemos como o sistema Android compartilha a entrada de áudio entre vários apps que capturam áudio.
Comportamento anterior ao Android 10
Antes do Android 10, o stream de áudio de entrada só podia ser capturado por um aplicativo em um
tempo de resposta. Se algum app já estava gravando ou ouvindo áudio, talvez
criar um objeto AudioRecord
, mas um erro seria retornado ao chamar
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) tiveram a permissão
android.permission.CAPTURE_AUDIO_HOTWORD
e usaram uma fonte de áudio do tipo
HOTWORD
. Nesse caso, outro aplicativo poderia começar a gravar. Quando isso aconteceu,
app privilegiado encerrado e o novo app capturava a entrada.
Mais uma mudança foi adicionada no Android 9: apenas apps em execução em primeiro plano (ou um serviço em primeiro plano) poderia capturar a entrada de áudio. Quando um app sem um serviço em primeiro plano ou componente de interface em primeiro plano começou a ser capturado, o app continuou a funcionar, mas recebeu silêncio, mesmo se fosse o único aplicativo de captura áudio no momento.
Comportamento do Android 10
Antes do Android 10, o comportamento era "primeiro a chegar, primeiro a ser veiculado". Assim que um aplicativo começa a capturar áudio, nenhum outro aplicativo pode acessar o entrada de áudio até que o aplicativo que está capturando áudio seja interrompido.
O Android 10 impõe um esquema de prioridade que pode alternar o fluxo de áudio de entrada. entre apps enquanto estão em execução. Na maioria dos casos, se um novo app adquire a entrada de áudio, o aplicativo que estava fazendo a captura continua a ser executado, mas recebe silêncio. Em alguns nos casos em que o sistema pode continuar a enviar áudio para os dois aplicativos. Os vários cenários de compartilhamento são explicados a seguir.
Esse esquema é semelhante à forma como a seleção de áudio processa vários apps disputar pelo uso da saída de áudio. No entanto, a seleção de áudio é gerenciada solicitações programáticas para ganhar e liberar o foco, enquanto a troca 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:
- "Comum" são instalados pelo usuário.
- "Privilégio" que vêm pré-instalados no dispositivo. Esses últimos incluem o Google Assistente e todos os serviços de acessibilidade.
Além disso, um aplicativo é tratado de modo diferente
se ele usa a política fonte de áudio:
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 apps tentam capturar áudio, ambos podem receber o sinal de entrada ou um deles pode receber 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 vem pré-instalado e tem a função de
função 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 capturando.
O app recebe áudio, a menos que o Google Assistente tenha uma interface 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
requer uma declaração rígida.
O Android compartilha o áudio de entrada de acordo com estas regras:
Se a interface do serviço estiver na parte superior, o serviço e o aplicativo receberão entrada de áudio. Esse comportamento oferece funcionalidades como controlar uma ligação ou vídeo use comandos de voz para capturar.
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 app for sensível à privacidade, o app com uma interface na parte de cima recebe áudio. Se nenhum aplicativo tiver IU, o último a iniciar a captura receberá o áudio.
- Se um dos aplicativos for sensível à privacidade, ele receberá áudio e o Outro aplicativo fica em silêncio mesmo que tenha uma IU na parte superior ou tenha começado a capturar mais recentemente.
- Se os dois apps são confidenciais, o app que começou a capturar mais dados recentemente recebe áudio e a outra recebe silêncio.
Chamada de voz + aplicativo comum
Uma ligação ficará ativa se o modo de áudio retornado pelo
AudioManager.getMode()
é
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 aplicativo pode capturar áudio se for um serviço de acessibilidade.
O aplicativo pode capturar a ligação se for um usuário privilegiado (pré-instalado) com permissão
CAPTURE_AUDIO_OUTPUT
Para capturar o uplink (TX), o downlink (RX) ou ambos da ligação, o app precisa: especifique 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
descritas acima. Ela também fornece novos métodos em AudioRecord
, MediaRecorder
e
AAudioStream
que ativam e desativam a capacidade de capturar áudio simultaneamente;
seja qual for o 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 será particular e até
um Assistente com privilégios não pode capturar ao mesmo tempo. Essa configuração substitui
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 aplicativos estão capturando áudio simultaneamente, apenas um ou dois deles são “ativo” (recebimento de áudio); os outros estão silenciados (recebendo silêncio). Quando o os apps ativos mudarem, o framework de áudio poderá reconfigurar os caminhos de áudio de acordo com estas regras:
- O dispositivo de entrada de áudio para cada aplicativo ativo pode mudar (por exemplo, de o microfone integrado a um fone de ouvido Bluetooth conectado).
- O pré-processamento associado ao aplicativo ativo com a prioridade mais alta é habilitado. Todos outro pré-processamento é ignorado.
Como um app ativo pode ser silenciado quando outro de maior prioridade fica ativo,
é possível registrar
AudioManager.AudioRecordingCallback (link em inglês)
no AudioRecord
ou MediaRecorder
a ser notificado quando a configuração for alterada.
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ê deve 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 o seguinte
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()
. O framework realiza automaticamente a conversão necessária de formato, reamostragem, canal e formato do formato usado 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()