BCR est une simple application d'enregistrement d'appels Android pour les appareils rootés ou les appareils exécutant un micrologiciel personnalisé. Une fois activé, il reste à l'écart et enregistre automatiquement les appels entrants et sortants en arrière-plan.
Comme son nom l'indique, BCR entend être le plus basique possible. Le projet aura atteint son objectif si les seules mises à jour dont il a besoin concernent la compatibilité avec les nouvelles versions d'Android. Ainsi, de nombreuses fonctionnalités potentiellement utiles ne seront jamais implémentées, telles que :
VOICE_CALL
(par exemple, en utilisant un microphone + un haut-parleur)Téléchargez la dernière version depuis la page des versions. Pour vérifier la signature numérique, consultez la section vérification des signatures numériques.
Installez BCR en tant qu'application système.
Pour les appareils rootés avec Magisk/KernelSU , flashez simplement le zip en tant que module Magisk/KernelSU à partir de l'application respective.
.apk
du zip et installez-le manuellement avant de redémarrer. Cela est nécessaire pour contourner un bogue dans le micrologiciel où le répertoire de données de l'application n'est pas créé, ce qui entraîne l'ouverture de BCR sur un écran vide.Pour le micrologiciel personnalisé non rooté , flashez le zip lors du démarrage en mode récupération.
READ_CALL_LOG
est strictement restreinte dans Android 10+, ce qui empêche son octroi, même via les paramètres d'Android. Pour supprimer cette restriction, exécutez via adb après avoir redémarré sous 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
du micrologiciel personnalisé est formatée avec erofs
, alors le système de fichiers est en lecture seule et il n'est pas possible d'utiliser cette méthode.system/
dans le zip fonctionnera également tant que les fichiers disposent des autorisations 644
et de l'étiquette u:object_r:system_file:s0
SELinux.Redémarrez et ouvrez BCR.
Si d'autres enregistreurs d'appels sont installés, assurez-vous de désactiver leur fonctionnalité d'enregistrement des appels téléphoniques. Sur la plupart des appareils, un appel téléphonique ne peut pas être enregistré par deux applications en même temps. Cependant, il est possible que BCR enregistre les appels téléphoniques et qu'une autre application enregistre, par exemple. Appels VOIP.
Activez l’enregistrement des appels et choisissez un répertoire de sortie.
Si aucun répertoire de sortie n'est sélectionné ou si le répertoire de sortie n'est plus accessible, alors les enregistrements seront enregistrés dans /sdcard/Android/data/com.chiller3.bcr/files
. Notez que sur Android 12+, /sdcard/Android/data/
n'est accessible que via USB ou DocumentsUI (le gestionnaire de fichiers intégré d'AOSP).
Lors de la première activation de l'enregistrement des appels, BCR vous demandera le microphone, la notification (Android 13+), le journal des appels, les contacts et les autorisations du téléphone. Seules les autorisations de microphone et de notification sont requises pour la fonctionnalité d'enregistrement d'appels de base. Si des autorisations supplémentaires sont accordées, des informations supplémentaires sont ajoutées au nom du fichier de sortie. Par exemple, l'autorisation des contacts permettra d'ajouter le nom du contact au nom du fichier.
Consultez la section autorisations ci-dessous pour plus de détails sur les autorisations.
Pour installer les futures mises à jour, il existe plusieurs méthodes :
.apk
peut également être extrait du zip et être directement installé. Avec cette méthode, l'ancienne version existe en tant qu'application système et la nouvelle version existe en tant que mise à jour installée par l'utilisateur de l'application système. Cette méthode est plus pratique si le BCR est intégré à l'image du micrologiciel Android. Contrairement à la fonctionnalité d'enregistrement d'appel intégrée de l'application de numérotation préinstallée sur certains appareils, BCR n'annonce pas que l'appel est en cours d'enregistrement à l'autre partie. BCR ne produit jamais d'audio d'aucune sorte dans le flux audio de l'appel.
Lorsque BCR est activé, évitez du tout d’utiliser l’enregistreur d’appels intégré du composeur. Il y a de très fortes chances que son utilisation provoque un comportement inattendu, comme l'échec des deux enregistrements ou l'annonce par le composeur que l'appel est en cours d'enregistrement.
Si vous résidez dans une juridiction où le consentement des deux parties est requis, vous êtes responsable d'informer l'autre partie que l'appel est en cours d'enregistrement. Si nécessaire, des règles d'enregistrement automatique peuvent être utilisées pour supprimer les enregistrements par défaut. Cependant, notez que si vous choisissez de conserver l'enregistrement au milieu de l'appel, l'enregistrement contiendra l'appel complet, et pas seulement la partie après le consentement de l'autre partie.
BCR prend en charge le démarrage direct, ce qui signifie qu'il est capable d'exécuter et d'enregistrer des appels avant que l'appareil ne soit initialement déverrouillé après un redémarrage. Dans cet état, la plupart des fonctionnalités de BCR fonctionneront toujours, à l'exception des fonctionnalités qui nécessitent la liste de contacts ou le journal des appels. En pratique, cela signifie :
Toutefois, si l'appareil est déverrouillé avant la fin de l'appel, aucune de ces limitations ne s'applique.
Notez que le répertoire de sortie n'est pas disponible avant le premier déverrouillage de l'appareil. Les enregistrements effectués dans l'état sont stockés dans un répertoire interne non accessible à l'utilisateur. Une fois l'appareil déverrouillé, BCR déplacera les fichiers vers le répertoire de sortie. Cela peut prendre quelques instants.
CAPTURE_AUDIO_OUTPUT
( automatiquement accordé par les autorisations de l'application système )CONTROL_INCALL_EXPERIENCE
( automatiquement accordé par les autorisations de l'application système )RECORD_AUDIO
( doit être accordé par l'utilisateur )FOREGROUND_SERVICE
, FOREGROUND_SERVICE_MICROPHONE
( automatiquement accordé au moment de l'installation )POST_NOTIFICATIONS
( doit être accordé par l'utilisateur sur Android 13+ )READ_CALL_LOG
( facultatif )READ_CONTACTS
( facultatif )RECEIVE_BOOT_COMPLETED
, FOREGROUND_SERVICE_SPECIAL_USE
( automatiquement accordé au moment de l'installation )READ_PHONE_STATE
( facultatif )REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
( facultatif )VIBRATE
( automatiquement accordé au moment de l'installation ) Notez INTERNET
n'est pas dans la liste. BCR n’accède pas et n’accédera jamais au réseau. BCR ne communiquera jamais non plus avec d'autres applications, sauf si l'utilisateur appuie explicitement sur les boutons Open
ou Share
dans la notification affichée lorsqu'un enregistrement est terminé. Dans ce scénario, l’application cible n’a accès qu’à cet enregistrement unique.
BCR a une prise en charge limitée pour les applications de redirection d'appels, comme Google Voice. Les appels redirigés ne peuvent être enregistrés que si le service de redirection d'appels utilise des appels téléphoniques standard en coulisses (au lieu de la VOIP).
Il existe plusieurs limitations lors de l'enregistrement des appels redirigés par rapport aux appels normaux :
All other calls
.Ces limitations existent car lorsqu'un appel est redirigé, seule l'application de numérotation elle-même connaît le numéro de téléphone d'origine. Le système de téléphonie Android n’en est pas conscient. BCR ne peut trouver le numéro de téléphone d'origine qu'en recherchant dans le journal des appels système lorsque le composeur ajoute l'entrée à la fin de l'appel.
BCR prend en charge la personnalisation du modèle utilisé pour déterminer les noms de fichiers de sortie des enregistrements. Le modèle par défaut est :
{date}[_{direction}|][_sim{sim_slot}|][_{phone_number}|][_[{contact_name}|{caller_name}|{call_log_name}]|]
{var}
) sont utilisées pour faire référence aux variables. Les variables sont remplacées par la valeur qu'elles représentent. Par exemple, {phone_number}
est remplacé par le numéro de téléphone réel de l'appel.[{var}|default]
) sont utilisés pour spécifier des solutions de secours. Par exemple, [{contact_name}|{caller_name}|Unknown]
insérera le nom du contact si le numéro est dans les contacts. Sinon, il reviendra à l'ID de l'appelant ou Unknown
si ni le nom du contact ni l'ID de l'appelant n'existent. Revenir à une chaîne vide est également parfaitement valable. Par exemple, [{contact_name}|]
renvoie soit le nom du contact, soit rien.{date}
: L'horodatage de l'appel. Le format d'horodatage par défaut essaie d'être aussi clair que possible et se présente sous la forme : 20230414_215701.088-0400
. Un format d'horodatage personnalisé peut être spécifié avec {date:<format string>}
. Par exemple, {date:yyyy-MM-dd @ h.mm.ss a}
produirait 2023-04-14 @ 9.57.01 PM
. Une liste complète des caractères de formatage d'horodatage est disponible à l'adresse : https://developer.android.com/reference/java/time/format/DateTimeFormatterBuilder#appendPattern(java.lang.String).{phone_number}{date}
entraînera la désactivation de la conservation des fichiers, mais {phone_number} ({date})
fonctionne car il y a du texte (
entre les deux variables.yyMMdd_HHmmss
était remplacé par HHmmss_yyMMdd
, les horodatages des noms de fichiers de l'ancien enregistrement seraient mal analysés et pourraient être supprimés.{direction}
: [Android 10+ uniquement] Pour les appels individuels, in
ou out
selon qu'il s'agit d'un appel entrant ou sortant. Si l'appel est une conférence téléphonique, conference
est utilisée à la place.{sim_slot}
: [Android 11+ uniquement] Le numéro de l'emplacement SIM pour l'appel (en comptant à partir de 1). Ceci n'est défini que pour les appareils multi-SIM sur lesquels plusieurs cartes SIM sont actives et si BCR dispose de l'autorisation Téléphone.{sim_slot:always}
.{phone_number}
: Le numéro de téléphone de l'appel. Ceci n'est pas défini pour les appels privés. Options de formatage disponibles :{phone_number:E.164}
: valeur par défaut (identique à {phone_number}
). Numéro de téléphone au format international E.164 ( +<country code><subscriber>
).{phone_number:digits_only}
: Numéro de téléphone avec des chiffres uniquement (pas +
ni de séparateurs).{phone_number:formatted}
: numéro de téléphone formaté à l'aide du style spécifique au pays.{caller_name}
: identifiant de l'appelant tel que fourni par CNAP auprès de l'opérateur.{contact_name}
Le nom du (premier) contact associé au numéro de téléphone. Ceci n'est défini que si BCR dispose de l'autorisation Contacts.{call_log_name}
: Le nom affiché dans le journal des appels. Cela peut inclure plus d'informations, comme le nom de l'entreprise, si le numéroteur système effectue des recherches inversées. Ceci n’est défini que si BCR dispose de l’autorisation Lire les journaux d’appels. Le modèle de nom de fichier prend en charge la spécification de sous-répertoires à l'aide du caractère /
. Les barres obliques sont autorisées n'importe où dans le modèle de nom de fichier, y compris {date}
(par exemple {date:yyyy/MM/dd}
). Cependant, toutes les barres obliques qui apparaissent après le développement d'autres variables seront remplacées par des traits de soulignement. Par exemple, si l'ID de l'appelant pour un appel est First/Last
, alors {caller_name}
est étendu à First_Last
.
Notez qu'en raison des mauvaises performances d'Android Storage Access Framework, l'utilisation de sous-répertoires peut ralentir considérablement la sauvegarde de l'enregistrement sur certains appareils. Sur les versions Android avec une bonne implémentation SAF, cela peut ne prendre que quelques secondes. Sur la version OEM Android avec la pire implémentation SAF connue, cela peut prendre plusieurs minutes. Le délai est proportionnel au nombre de fichiers dans le répertoire de sortie.
Si l'option Write metadata file
est activée, BCR écrira un fichier JSON dans le répertoire de sortie contenant tous les détails que BCR connaît sur l'appel ainsi que des informations sur l'audio enregistré. Le fichier porte le même nom que le fichier audio, sauf avec une extension .json
.
La structure JSON est illustrée dans l'exemple suivant. Notez que seuls timestamp_unix_ms
, timestamp
et output.format.*
sont garantis d'exister. Si la valeur d'un champ ne peut pas être déterminée (par exemple lorsqu'une erreur se produit ou qu'une autorisation requise est refusée), alors elle est définie sur 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
}
}
}
Cette section décrit les fonctionnalités avancées cachées de BCR.
BCR dispose d'un mode de débogage caché qui peut être activé ou désactivé en appuyant longuement sur le numéro de version.
Lorsque le mode débogage est activé, BCR écrira un fichier journal dans le répertoire de sortie une fois l'enregistrement d'un appel terminé. Il porte le même nom que le fichier audio. Le fichier journal contient les mêmes messages que ce que adb logcat
afficherait, sauf que les messages non pertinents pour BCR sont filtrés (BCR n'a de toute façon pas l'autorisation d'accéder à ces messages).
Dans le fichier journal, BCR vise à ne jamais enregistrer d'informations sensibles. Les informations sur l'appel en cours, comme le numéro de téléphone, sont remplacées par des espaces réservés, comme <phone number>
. Cependant, les autres informations qui ne peuvent pas être facilement expurgées de cette manière seront tronquées. Par exemple, lorsque la fonctionnalité de conservation des fichiers nettoie les anciens fichiers, les noms de fichiers tels que 20230101_010203.456+0000_out_1234567890_John_Doe.oga
sont enregistrés comme 20<...>ga
.
Lorsque vous signalez des bogues, veuillez inclure le fichier journal car il est extrêmement utile pour identifier ce qui pourrait ne pas fonctionner. (Mais veuillez vérifier le fichier journal pour vous assurer qu’il ne contient aucune information sensible !)
BCR s'appuie fortement sur les autorisations des applications système pour fonctionner correctement. Cela est principalement dû à deux autorisations :
CONTROL_INCALL_EXPERIENCE
Cette autorisation permet au service de téléphonie Android de se lier au InCallService
de BCR sans que BCR soit une application compagnon portable, une interface utilisateur de voiture ou le numéroteur par défaut. Une fois lié, le service recevra des rappels pour les événements de changement d'appel (par exemple, appel entrant en état de sonnerie). Cette méthode est beaucoup plus fiable que d'utiliser l'autorisation READ_PHONE_STATE
et de s'appuyer sur les diffusions android.intent.action.PHONE_STATE
.
Cette méthode présente quelques avantages supplémentaires. En raison de la façon dont le service de téléphonie se lie au InCallService
de BCR, le service peut se mettre au premier plan selon les besoins lorsqu'un appel est en cours et accéder au flux audio sans toucher aux limitations d'accès au microphone d'arrière-plan d'Android 12+. Il ne nécessite pas non plus que le service soit démarré manuellement à partir d'un récepteur de diffusion ACTION_BOOT_COMPLETED
et n'est donc pas affecté par les retards de cette diffusion lors du démarrage initial.
CAPTURE_AUDIO_OUTPUT
Cette autorisation est utilisée pour enregistrer à partir du flux audio VOICE_CALL
. Ce flux, ainsi que d'autres, comme VOICE_DOWNLINK
et VOICE_UPLINK
, n'est pas accessible sans cette autorisation du système.
Avec ces deux autorisations, BCR peut détecter de manière fiable les appels téléphoniques et enregistrer à partir du flux audio de l'appel. Le processus d'enregistrement extrait l'audio brut PCM s16le et utilise les encodeurs intégrés d'Android pour produire le fichier de sortie compressé.
Le fichier zip et l’APK qu’il contient sont signés numériquement. NOTE : Le mécanisme de signature des fichiers zip est passé de GPG à SSH à partir de la version 1.31. Pour vérifier les signatures des anciennes versions, consultez README.md
de la version 1.30.
Pour vérifier les signatures numériques des téléchargements, suivez les étapes ici.
Tout d’abord, extrayez l’apk du zip, puis exécutez :
apksigner verify --print-certs system/priv-app/com.chiller3.bcr/app-release.apk
Ensuite, vérifiez que le résumé SHA-256 du certificat de signature APK est :
d16f9b375df668c58ef4bb855eae959713d6d02e45f7f2c05ce2c27ae944f4f9
BCR peut être créé comme la plupart des autres applications Android à l'aide d'Android Studio ou de la ligne de commande Gradle.
Pour créer l'APK :
./gradlew assembleDebug
Pour construire le module zip Magisk (qui exécute automatiquement la tâche assembleDebug
si nécessaire) :
./gradlew zipDebug
Le fichier de sortie est écrit dans app/build/distributions/debug/
. L'APK sera signé avec la clé de débogage générée automatiquement par défaut.
Pour créer une version de version avec une clé de signature spécifique, configurez les variables d'environnement suivantes :
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
puis créez le zip de version :
./gradlew zipRelease
Les demandes de correction de bugs et de traduction sont les bienvenues et très appréciées !
Si vous êtes intéressé par la mise en œuvre d'une nouvelle fonctionnalité et souhaitez la voir incluse dans BCR, veuillez d'abord ouvrir un problème pour en discuter. J'ai l'intention que BCR soit aussi simple et nécessitant peu de maintenance que possible, donc je ne suis pas trop enclin à ajouter de nouvelles fonctionnalités, mais je pourrais être convaincu du contraire.
BCR est sous licence GPLv3. Veuillez consulter LICENSE
pour le texte complet de la licence.