BCR é um aplicativo simples de gravação de chamadas Android para dispositivos com acesso root ou dispositivos executando firmware personalizado. Uma vez ativado, ele fica fora do caminho e registra automaticamente as chamadas recebidas e efetuadas em segundo plano.
Como o nome indica, o BCR pretende ser o mais básico possível. O projeto terá alcançado seu objetivo se as únicas atualizações necessárias forem para compatibilidade com as novas versões do Android. Assim, muitos recursos potencialmente úteis nunca serão implementados, como:
VOICE_CALL
(por exemplo, usando microfone + viva-voz)Baixe a versão mais recente na página de lançamentos. Para verificar a assinatura digital, consulte a seção verificação de assinaturas digitais.
Instale o BCR como um aplicativo do sistema.
Para dispositivos com root no Magisk/KernelSU , basta atualizar o zip como um módulo Magisk/KernelSU de dentro do respectivo aplicativo.
.apk
do zip e instale-o manualmente antes de reiniciar. Isso é necessário para solucionar um bug no firmware em que o diretório de dados do aplicativo não é criado, fazendo com que o BCR abra uma tela em branco.Para firmware personalizado não rooteado , atualize o zip enquanto inicializa na recuperação.
READ_CALL_LOG
é totalmente restrita no Android 10+, o que impede que ela seja concedida, mesmo por meio das configurações do Android. Para remover esta restrição, execute via adb após reiniciar no Android: # If rooted, run inside of `su`:
CLASSPATH=/system/priv-app/com.chiller3.bcr/app-release.apk app_process / com.chiller3.bcr.standalone.RemoveHardRestrictionsKt
# If unrooted, install BCR as both a user app and a system app:
pm install /system/priv-app/com.chiller3.bcr/app-release.apk
system
do firmware personalizado estiver formatada com erofs
, o sistema de arquivos será somente leitura e não será possível usar este método.system/
no zip também funcionará, desde que os arquivos tenham permissões 644
e o rótulo u:object_r:system_file:s0
SELinux.Reinicie e abra o BCR.
Se outros gravadores de chamadas estiverem instalados, certifique-se de desativar a funcionalidade de gravação de chamadas telefônicas. Na maioria dos dispositivos, uma chamada não pode ser gravada por dois aplicativos ao mesmo tempo. No entanto, não há problema em fazer com que o BCR grave chamadas telefônicas e outro registro de aplicativo, por exemplo. Chamadas VOIP.
Habilite a gravação de chamadas e escolha um diretório de saída.
Se nenhum diretório de saída for selecionado ou se o diretório de saída não estiver mais acessível, as gravações serão salvas em /sdcard/Android/data/com.chiller3.bcr/files
. Observe que no Android 12+, /sdcard/Android/data/
só pode ser acessado via USB ou DocumentsUI (gerenciador de arquivos integrado do AOSP).
Ao ativar a gravação de chamadas pela primeira vez, o BCR solicitará microfone, notificação (Android 13+), registro de chamadas, contatos e permissões de telefone. Somente permissões de microfone e notificação são necessárias para a funcionalidade básica de gravação de chamadas. Se forem concedidas permissões adicionais, mais informações serão adicionadas ao nome do arquivo de saída. Por exemplo, a permissão de contatos permitirá que o nome do contato seja adicionado ao nome do arquivo.
Consulte a seção de permissões abaixo para obter mais detalhes sobre as permissões.
Para instalar atualizações futuras, existem alguns métodos:
.apk
também pode ser extraído do zip e instalado diretamente. Com esse método, a versão antiga existe como um aplicativo do sistema e a nova versão existe como uma atualização instalada pelo usuário para o aplicativo do sistema. Este método é mais conveniente se o BCR estiver incorporado à imagem do firmware do Android. Ao contrário da funcionalidade integrada de gravação de chamadas do aplicativo discador pré-instalado em alguns dispositivos, o BCR não anuncia que a chamada está sendo gravada para a outra parte. O BCR nunca envia áudio de qualquer tipo para o fluxo de áudio da chamada.
Quando o BCR estiver ativado, evite usar o gravador de chamadas integrado do discador. Há uma boa chance de que usá-lo cause um comportamento inesperado, como falha em ambas as gravações ou o discador anunciando que a chamada está sendo gravada.
Se você mora em uma jurisdição onde é necessário o consentimento de ambas as partes, você é responsável por informar a outra parte que a chamada está sendo gravada. Se necessário, regras de gravação automática podem ser usadas para descartar gravações por padrão. No entanto, observe que se você optar por preservar a gravação no meio da chamada, a gravação conterá a chamada completa, e não apenas a parte após o consentimento da outra parte.
O BCR tem reconhecimento de inicialização direta, o que significa que é capaz de executar e gravar chamadas antes que o dispositivo seja inicialmente desbloqueado após uma reinicialização. Nesse estado, a maior parte das funcionalidades do BCR ainda funcionará, exceto os recursos que exigem lista de contatos ou registro de chamadas. Na prática, isso significa:
No entanto, se o dispositivo for desbloqueado antes do término da chamada, nenhuma dessas limitações se aplicará.
Observe que o diretório de saída não está disponível antes do dispositivo ser desbloqueado pela primeira vez. As gravações feitas durante o estado são armazenadas em um diretório interno que não pode ser acessado pelo usuário. Depois que o dispositivo for desbloqueado, o BCR moverá os arquivos para o diretório de saída. Isso pode levar alguns minutos para ser concluído.
CAPTURE_AUDIO_OUTPUT
( concedido automaticamente pelas permissões do aplicativo do sistema )CONTROL_INCALL_EXPERIENCE
( concedido automaticamente pelas permissões do aplicativo do sistema )RECORD_AUDIO
( deve ser concedido pelo usuário )FOREGROUND_SERVICE
, FOREGROUND_SERVICE_MICROPHONE
( concedido automaticamente no momento da instalação )POST_NOTIFICATIONS
( deve ser concedido pelo usuário no Android 13+ )READ_CALL_LOG
( opcional )READ_CONTACTS
( opcional )RECEIVE_BOOT_COMPLETED
, FOREGROUND_SERVICE_SPECIAL_USE
( concedido automaticamente no momento da instalação )READ_PHONE_STATE
( opcional )REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
( opcional )VIBRATE
( concedido automaticamente no momento da instalação ) Observe que INTERNET
não está na lista. O BCR não acessa e nunca acessará a rede. O BCR também nunca se comunicará com outros aplicativos, exceto se o usuário tocar explicitamente nos botões Open
ou Share
na notificação mostrada quando uma gravação for concluída. Nesse cenário, o aplicativo de destino recebe acesso apenas a essa única gravação.
O BCR tem suporte limitado para aplicativos de redirecionamento de chamadas, como o Google Voice. As chamadas redirecionadas só poderão ser gravadas se o serviço de redirecionamento de chamadas usar chamadas telefônicas padrão nos bastidores (em vez de VOIP).
Existem várias limitações ao gravar chamadas redirecionadas em comparação com chamadas normais:
All other calls
.Essas limitações existem porque quando uma chamada é redirecionada, apenas o próprio aplicativo discador tem conhecimento do número de telefone original. O sistema de telefonia Android não está ciente disso. O BCR só consegue encontrar o número de telefone original pesquisando o registro de chamadas do sistema quando o discador adiciona a entrada no final da chamada.
O BCR oferece suporte à personalização do modelo usado para determinar os nomes dos arquivos de saída das gravações. O modelo padrão é:
{date}[_{direction}|][_sim{sim_slot}|][_{phone_number}|][_[{contact_name}|{caller_name}|{call_log_name}]|]
{var}
) são usadas para se referir a variáveis. As variáveis são substituídas pelo valor que representam. Por exemplo, {phone_number}
é substituído pelo número de telefone real da chamada.[{var}|default]
) são usados para especificar substitutos. Por exemplo, [{contact_name}|{caller_name}|Unknown]
irá inserir o nome do contato se o número estiver nos contatos. Caso contrário, ele retornará ao identificador de chamadas ou Unknown
se nem o nome do contato nem o ID do chamador existirem. Voltar para uma string vazia também é perfeitamente válido. Por exemplo, [{contact_name}|]
é avaliado como o nome do contato ou nada.{date}
: o carimbo de data/hora da chamada. O formato de carimbo de data/hora padrão tenta ser o mais inequívoco possível e está no formato: 20230414_215701.088-0400
. Um formato de carimbo de data/hora personalizado pode ser especificado com {date:<format string>}
. Por exemplo, {date:yyyy-MM-dd @ h.mm.ss a}
produziria 2023-04-14 @ 9.57.01 PM
. Uma lista completa de caracteres de formatação de carimbo de data/hora pode ser encontrada em: https://developer.android.com/reference/java/time/format/DateTimeFormatterBuilder#appendPattern(java.lang.String).{phone_number}{date}
fará com que a retenção de arquivos seja desativada, mas {phone_number} ({date})
funciona porque há algum texto (
entre as duas variáveis.yyMMdd_HHmmss
fosse alterado para HHmmss_yyMMdd
, os carimbos de data e hora dos nomes de arquivos da gravação antiga seriam analisados incorretamente e poderiam ser excluídos.{direction}
: [somente Android 10+] Para chamadas individuais, in
ou out
dependendo se a chamada for recebida ou efetuada. Se a chamada for uma chamada em conferência, conference
será usada.{sim_slot}
: [somente Android 11+] O número do slot SIM para a chamada (contando a partir de 1). Isso é definido apenas para dispositivos multi-SIM que possuem vários SIMs ativos e se o BCR receber a permissão Telefone.{sim_slot:always}
.{phone_number}
: o número de telefone da chamada. Isso é indefinido para chamadas privadas. Opções de formatação disponíveis:{phone_number:E.164}
: Padrão (o mesmo que apenas {phone_number}
). Número de telefone formatado no formato internacional E.164 ( +<country code><subscriber>
).{phone_number:digits_only}
: número de telefone apenas com dígitos (sem +
ou separadores).{phone_number:formatted}
: número de telefone formatado usando o estilo específico do país.{caller_name}
: o identificador de chamadas fornecido pelo CNAP da operadora.{contact_name}
O nome do (primeiro) contato associado ao número de telefone. Isso só será definido se o BCR receber a permissão de Contatos.{call_log_name}
: o nome mostrado no registro de chamadas. Isso pode incluir mais informações, como o nome da empresa, se o discador do sistema realizar pesquisas reversas. Isso só será definido se o BCR receber a permissão Ler registros de chamadas. O modelo de nome de arquivo suporta a especificação de subdiretórios usando o caractere /
. Barras são permitidas em qualquer lugar dentro do modelo de nome de arquivo, incluindo {date}
(por exemplo, {date:yyyy/MM/dd}
). No entanto, quaisquer barras que aparecerem após a expansão de outras variáveis serão substituídas por sublinhados. Por exemplo, se o identificador de chamada de uma chamada for First/Last
, então {caller_name}
será expandido para First_Last
.
Observe que, devido ao baixo desempenho do Android Storage Access Framework, o uso de subdiretórios pode retardar significativamente o salvamento da gravação em alguns dispositivos. Em versões Android com uma boa implementação de SAF, isso pode levar apenas alguns segundos. Na versão OEM do Android com a pior implementação SAF conhecida, isso pode levar vários minutos. O atraso é proporcional ao número de arquivos no diretório de saída.
Se a opção Write metadata file
estiver habilitada, o BCR gravará um arquivo JSON no diretório de saída contendo todos os detalhes que o BCR conhece sobre a chamada, bem como informações sobre o áudio gravado. O arquivo tem o mesmo nome do arquivo de áudio, exceto pela extensão .json
.
A estrutura JSON é mostrada no exemplo a seguir. Observe que apenas timestamp_unix_ms
, timestamp
e output.format.*
têm garantia de existência. Se o valor de um campo não puder ser determinado (por exemplo, quando ocorrer um erro ou uma permissão necessária for negada), ele será definido como null
.
{
// The timestamp represented as milliseconds since the Unix epoch in UTC.
"timestamp_unix_ms" : 1689817988931 ,
// The timestamp represented as ISO8601 (+ offset) in the local time zone.
"timestamp" : "2023-07-19T21:53:08.931-04:00" ,
// The call direction ("in", "out", or "conference").
// [Android 10+ only]
"direction" : "in" ,
// The SIM slot used for the call.
// [Android 11+ only; requires the Phone permission]
"sim_slot" : 1 ,
// The name shown in the dialer's call log. This may include the business'
// name for dialers that perform reverse lookups.
// [Requires the Call Log permission]
"call_log_name" : "John Doe" ,
// Details about the other party or parties in the call. There will be
// multiple entries for conference calls.
"calls" : [
{
// The raw phone number as reported by Android. For outgoing calls,
// this is usually what the user typed. For incoming calls, this is
// usually E.164 formatted. This will be null for private calls.
"phone_number" : "+11234567890" ,
// The phone number formatted using the country-specific style. This
// will be null for private calls or if Android cannot determine the
// country.
"phone_number_formatted" : "+1 123-456-7890" ,
// The caller name/ID as reported by CNAP from the carrier.
"caller_name" : "John Doe" ,
// The contact name associated with the phone number.
// [Requires the Contacts permission]
"contact_name" : "John Doe"
}
] ,
// Details about the output file.
"output" : {
// Details about the output file format.
"format" : {
// The audio encoding format.
"type" : "OGG/Opus" ,
// The MIME type of the container format (eg. OGG).
"mime_type_container" : "audio/ogg" ,
// The MIME type of the raw audio stream (eg. Opus).
"mime_type_audio" : "audio/opus" ,
// The type of the parameter value below. Either "bitrate",
// "compression_level", or "none".
"parameter_type" : "bitrate" ,
// The encoder quality/size parameter.
"parameter" : 48000 ,
} ,
// Details about the recording and encoding process. If the recording
// process fails, this is set to null.
"recording" : {
// The total number of audio frames that BCR read from the audio
// device. This includes the periods of time when the recording was
// paused or on hold.
// (Number of frames == number of samples * channel count)
"frames_total" : 96000 ,
// The number of audio frames that were actually saved to the output
// file. This excludes the periods of time when the recording was
// paused or on hold.
// (Number of frames == number of samples * channel count)
"frames_encoded" : 48000 ,
// The number of samples per second of audio.
"sample_rate" : 48000 ,
// The number of channels in the audio. This is currently always 1
// because no device supports stereo call audio.
"channel_count" : 1 ,
// The total time in seconds that BCR read from the audio device.
// (Equal to: frames_total / sample_rate / channel_count)
"duration_secs_total" : 2.0 ,
// The time in seconds of audio actually saved to the output file.
// (Equal to: frames_encoded / sample_rate / channel_count)
"duration_secs_encoded" : 1.0 ,
// The size of the recording buffer in frames. This is the maximum
// number of audio frames read from the audio driver before it is
// passed to the audio encoder.
"buffer_frames" : 640 ,
// The number of buffer overruns. This is the number of times that
// the CPU or storage couldn't keep up while encoding the raw audio,
// resulting in skips (loss of audio).
"buffer_overruns" : 0 ,
// Whether the call was ever paused by the user.
"was_ever_paused" : false ,
// Whether the call was ever placed on hold (call waiting).
"was_ever_holding" : false
}
}
}
Esta seção descreve os recursos avançados ocultos do BCR.
O BCR possui um modo de depuração oculto que pode ser ativado ou desativado pressionando longamente o número da versão.
Quando o modo de depuração estiver ativado, o BCR gravará um arquivo de log no diretório de saída após a conclusão da gravação de uma chamada. É nomeado da mesma forma que o arquivo de áudio. O arquivo de log contém as mesmas mensagens que adb logcat
mostraria, exceto que as mensagens não relevantes para o BCR são filtradas (o BCR não tem permissão para acessar essas mensagens de qualquer maneira).
Dentro do arquivo de log, o BCR pretende nunca registrar nenhuma informação confidencial. As informações sobre a chamada atual, como o número de telefone, são substituídas por espaços reservados, como <phone number>
. No entanto, outras informações que não podem ser facilmente editadas, desta forma serão truncadas. Por exemplo, quando o recurso de retenção de arquivos limpa arquivos antigos, nomes de arquivos como 20230101_010203.456+0000_out_1234567890_John_Doe.oga
são registrados como 20<...>ga
.
Ao relatar bugs, inclua o arquivo de log, pois é extremamente útil para identificar o que pode estar errado. (Mas verifique novamente o arquivo de log para garantir que não haja informações confidenciais!)
O BCR depende muito das permissões de aplicativos do sistema para funcionar corretamente. Isso se deve principalmente a duas permissões:
CONTROL_INCALL_EXPERIENCE
Essa permissão permite que o serviço de telefonia do Android se vincule ao InCallService
do BCR sem que o BCR seja um aplicativo complementar vestível, uma interface de carro ou o discador padrão. Uma vez vinculado, o serviço receberá retornos de chamada para eventos de mudança de chamada (por exemplo, chamada recebida no estado tocando). Este método é muito mais confiável do que usar a permissão READ_PHONE_STATE
e depender de transmissões android.intent.action.PHONE_STATE
.
Este método tem alguns benefícios adicionais. Devido à forma como o serviço de telefonia se liga ao InCallService
do BCR, o serviço pode entrar e sair do primeiro plano conforme necessário quando uma chamada está em andamento e acessar o fluxo de áudio sem atingir as limitações de acesso ao microfone em segundo plano do Android 12+. Também não exige que o serviço seja iniciado manualmente a partir de um receptor de transmissão ACTION_BOOT_COMPLETED
e, portanto, não é afetado pelos atrasos dessa transmissão durante a inicialização.
CAPTURE_AUDIO_OUTPUT
Esta permissão é usada para gravar o fluxo de áudio VOICE_CALL
. Este stream, junto com alguns outros, como VOICE_DOWNLINK
e VOICE_UPLINK
, não podem ser acessados sem a permissão do sistema.
Com essas duas permissões, o BCR pode detectar chamadas telefônicas com segurança e gravar o fluxo de áudio da chamada. O processo de gravação extrai áudio bruto PCM s16le e usa codificadores integrados do Android para produzir o arquivo de saída compactado.
Tanto o arquivo zip quanto o APK contido nele são assinados digitalmente. NOTA : O mecanismo de assinatura de arquivo zip mudou de GPG para SSH a partir da versão 1.31. Para verificar assinaturas de versões antigas, consulte README.md
da versão 1.30.
Para verificar as assinaturas digitais dos downloads, siga os passos aqui.
Primeiro, extraia o apk do zip e execute:
apksigner verify --print-certs system/priv-app/com.chiller3.bcr/app-release.apk
Em seguida, verifique se o resumo SHA-256 do certificado de assinatura do APK é:
d16f9b375df668c58ef4bb855eae959713d6d02e45f7f2c05ce2c27ae944f4f9
O BCR pode ser criado como a maioria dos outros aplicativos Android usando o Android Studio ou a linha de comando gradle.
Para construir o APK:
./gradlew assembleDebug
Para construir o módulo zip do Magisk (que executa automaticamente a tarefa assembleDebug
, se necessário):
./gradlew zipDebug
O arquivo de saída é gravado em app/build/distributions/debug/
. O APK será assinado com a chave de depuração padrão gerada automaticamente.
Para criar uma versão com uma chave de assinatura específica, configure as seguintes variáveis de ambiente:
export RELEASE_KEYSTORE=/path/to/keystore.jks
export RELEASE_KEY_ALIAS=alias_name
read -r -s RELEASE_KEYSTORE_PASSPHRASE
read -r -s RELEASE_KEY_PASSPHRASE
export RELEASE_KEYSTORE_PASSPHRASE
export RELEASE_KEY_PASSPHRASE
e, em seguida, crie o zip de lançamento:
./gradlew zipRelease
Correção de bugs e solicitações de tradução são bem-vindas e muito apreciadas!
Se você estiver interessado em implementar um novo recurso e gostaria de vê-lo incluído no BCR, abra um problema para discuti-lo primeiro. Pretendo que o BCR seja o mais simples e de baixa manutenção possível, por isso não estou muito inclinado a adicionar novos recursos, mas posso ser convencido do contrário.
BCR é licenciado sob GPLv3. Consulte LICENSE
para obter o texto completo da licença.