BCR ist eine einfache Android-Anrufaufzeichnungs-App für gerootete Geräte oder Geräte mit benutzerdefinierter Firmware. Sobald es aktiviert ist, stört es nicht und zeichnet eingehende und ausgehende Anrufe automatisch im Hintergrund auf.
Wie der Name schon sagt, soll BCR möglichst einfach sein. Das Projekt hat sein Ziel erreicht, wenn die einzigen Aktualisierungen, die es jemals benötigt, die Kompatibilität mit neuen Android-Versionen betreffen. Daher werden viele potenziell nützliche Funktionen nie implementiert, wie zum Beispiel:
VOICE_CALL
nicht unterstützen (z. B. Verwendung von Mikrofon + Freisprecheinrichtung)Laden Sie die neueste Version von der Release-Seite herunter. Informationen zur Überprüfung der digitalen Signatur finden Sie im Abschnitt „Überprüfung digitaler Signaturen“.
Installieren Sie BCR als System-App.
Bei Geräten, die mit Magisk/KernelSU gerootet sind , flashen Sie einfach die Zip-Datei als Magisk/KernelSU-Modul aus der jeweiligen Anwendung heraus.
.apk
aus der ZIP-Datei und installieren Sie sie vor dem Neustart manuell. Dies ist notwendig, um einen Fehler in der Firmware zu umgehen, bei dem das App-Datenverzeichnis nicht erstellt wird, was dazu führt, dass BCR mit einem leeren Bildschirm geöffnet wird.Flashen Sie bei nicht gerooteter benutzerdefinierter Firmware die Zip-Datei, während Sie in die Wiederherstellung booten.
READ_CALL_LOG
ist in Android 10+ stark eingeschränkt, was verhindert, dass sie gewährt wird, selbst über die Android-Einstellungen. Um diese Einschränkung aufzuheben, führen Sie nach dem Neustart von Android Folgendes über adb aus: # 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
der benutzerdefinierten Firmware mit erofs
formatiert ist, ist das Dateisystem schreibgeschützt und es ist nicht möglich, diese Methode zu verwenden.system/
-Ordner in der ZIP-Datei funktioniert ebenfalls, solange die Dateien über 644
Berechtigungen und das SELinux-Label u:object_r:system_file:s0
verfügen.Starten Sie BCR neu und öffnen Sie es.
Wenn andere Anrufaufzeichnungsgeräte installiert sind, stellen Sie sicher, dass Sie deren Funktion zur Anrufaufzeichnung deaktivieren. Auf den meisten Geräten kann ein Telefongespräch nicht von zwei Apps gleichzeitig aufgezeichnet werden. Es ist jedoch in Ordnung, dass BCR Telefonanrufe aufzeichnet und eine andere App z. B. aufzeichnet. VOIP-Anrufe.
Aktivieren Sie die Anrufaufzeichnung und wählen Sie ein Ausgabeverzeichnis aus.
Wenn kein Ausgabeverzeichnis ausgewählt ist oder das Ausgabeverzeichnis nicht mehr zugänglich ist, werden Aufzeichnungen unter /sdcard/Android/data/com.chiller3.bcr/files
gespeichert. Beachten Sie, dass auf Android 12+ auf /sdcard/Android/data/
nur über USB oder DocumentsUI (der integrierte Dateimanager von AOSP) zugegriffen werden kann.
Wenn Sie die Anrufaufzeichnung zum ersten Mal aktivieren, fordert BCR zur Eingabe von Mikrofon, Benachrichtigung (Android 13+), Anrufprotokoll, Kontakten und Telefonberechtigungen auf. Für die grundlegende Anrufaufzeichnungsfunktion sind nur Mikrofon- und Benachrichtigungsberechtigungen erforderlich. Wenn zusätzliche Berechtigungen erteilt werden, werden dem Ausgabedateinamen weitere Informationen hinzugefügt. Mit der Berechtigung „Kontakte“ kann beispielsweise der Kontaktname zum Dateinamen hinzugefügt werden.
Weitere Einzelheiten zu den Berechtigungen finden Sie im Abschnitt „Berechtigungen“ weiter unten.
Um zukünftige Updates zu installieren, gibt es mehrere Methoden:
.apk
kann auch aus der Zip-Datei extrahiert und direkt installiert werden. Bei dieser Methode existiert die alte Version als System-App und die neue Version als vom Benutzer installiertes Update der System-App. Diese Methode ist praktischer, wenn BCR in das Android-Firmware-Image integriert ist. Im Gegensatz zur integrierten Anrufaufzeichnungsfunktion der vorinstallierten Dialer-App auf einigen Geräten gibt BCR dem anderen Teilnehmer nicht bekannt, dass der Anruf aufgezeichnet wird. BCR gibt niemals Audiosignale jeglicher Art an den Audiostream des Anrufs aus.
Wenn BCR aktiviert ist, vermeiden Sie die Verwendung des integrierten Anrufrekorders des Dialers überhaupt. Es besteht eine sehr hohe Wahrscheinlichkeit, dass die Verwendung zu unerwartetem Verhalten führt, z. B. zum Fehlschlagen beider Aufzeichnungen oder zu einer Meldung des Dialers, dass der Anruf aufgezeichnet wird.
Wenn Sie in einem Land leben, in dem die Zustimmung beider Parteien erforderlich ist, sind Sie dafür verantwortlich, die andere Partei darüber zu informieren, dass der Anruf aufgezeichnet wird. Bei Bedarf können automatische Aufzeichnungsregeln verwendet werden, um Aufzeichnungen standardmäßig zu verwerfen. Beachten Sie jedoch, dass, wenn Sie sich dafür entscheiden, die Aufzeichnung während des Anrufs aufzubewahren, die Aufzeichnung den gesamten Anruf enthält und nicht nur den Teil, nachdem der andere Teilnehmer zugestimmt hat.
BCR ist direkt bootfähig, was bedeutet, dass es Anrufe ausführen und aufzeichnen kann, bevor das Gerät nach einem Neustart zum ersten Mal entsperrt wird. In diesem Zustand funktionieren die meisten BCR-Funktionen weiterhin, mit Ausnahme der Funktionen, die die Kontaktliste oder das Anrufprotokoll erfordern. In der Praxis bedeutet das:
Wenn das Gerät jedoch vor Ende des Anrufs entsperrt wird, gilt keine dieser Einschränkungen.
Beachten Sie, dass das Ausgabeverzeichnis erst verfügbar ist, wenn das Gerät zum ersten Mal entsperrt wird. Während des Aufenthalts gemachte Aufzeichnungen werden in einem internen Verzeichnis gespeichert, auf das der Benutzer nicht zugreifen kann. Nachdem das Gerät entsperrt wurde, verschiebt BCR die Dateien in das Ausgabeverzeichnis. Dies kann einige Augenblicke dauern.
CAPTURE_AUDIO_OUTPUT
( automatisch durch System-App-Berechtigungen gewährt )CONTROL_INCALL_EXPERIENCE
( automatisch durch System-App-Berechtigungen gewährt )RECORD_AUDIO
( muss vom Benutzer gewährt werden )FOREGROUND_SERVICE
, FOREGROUND_SERVICE_MICROPHONE
( wird automatisch bei der Installation gewährt )POST_NOTIFICATIONS
( muss vom Benutzer auf Android 13+ gewährt werden )READ_CALL_LOG
( optional )READ_CONTACTS
( optional )RECEIVE_BOOT_COMPLETED
, FOREGROUND_SERVICE_SPECIAL_USE
( wird automatisch bei der Installation gewährt )READ_PHONE_STATE
( optional )REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
( optional )VIBRATE
( wird automatisch bei der Installation gewährt ) Beachten Sie, dass INTERNET
nicht in der Liste enthalten ist. BCR greift nicht auf das Netzwerk zu und wird dies auch nie tun. BCR kommuniziert auch niemals mit anderen Apps, es sei denn, der Benutzer tippt explizit auf die Schaltflächen Open
oder Share
in der Benachrichtigung, die nach Abschluss einer Aufzeichnung angezeigt wird. In diesem Szenario wird der Ziel-App nur Zugriff auf diese einzelne Aufzeichnung gewährt.
BCR bietet eingeschränkte Unterstützung für Anrufumleitungs-Apps wie Google Voice. Umgeleitete Anrufe können nur aufgezeichnet werden, wenn der Anrufumleitungsdienst hinter den Kulissen Standardtelefonanrufe (anstelle von VOIP) verwendet.
Bei der Aufzeichnung umgeleiteter Anrufe gibt es im Vergleich zu regulären Anrufen mehrere Einschränkungen:
All other calls
.Diese Einschränkungen bestehen, da bei der Umleitung eines Anrufs nur die Dialer-App selbst die ursprüngliche Telefonnummer kennt. Das Android-Telefonsystem ist sich dessen nicht bewusst. BCR kann die ursprüngliche Telefonnummer nur durch Durchsuchen des Systemanrufprotokolls finden, wenn der Dialer den Eintrag am Ende des Anrufs hinzufügt.
BCR unterstützt das Anpassen der Vorlage, die zum Bestimmen der Ausgabedateinamen von Aufzeichnungen verwendet wird. Die Standardvorlage ist:
{date}[_{direction}|][_sim{sim_slot}|][_{phone_number}|][_[{contact_name}|{caller_name}|{call_log_name}]|]
{var}
) werden verwendet, um auf Variablen zu verweisen. Variablen werden durch den Wert ersetzt, den sie darstellen. Beispielsweise wird {phone_number}
durch die tatsächliche Telefonnummer des Anrufs ersetzt.[{var}|default]
) werden zur Angabe von Fallbacks verwendet. Beispielsweise fügt [{contact_name}|{caller_name}|Unknown]
den Kontaktnamen ein, wenn die Nummer in den Kontakten enthalten ist. Andernfalls wird auf die Anrufer-ID oder Unknown
zurückgegriffen, wenn weder der Kontaktname noch die Anrufer-ID vorhanden sind. Auch das Zurückgreifen auf eine leere Zeichenfolge ist vollkommen zulässig. Beispielsweise ergibt [{contact_name}|]
entweder den Namen des Kontakts oder nichts.{date}
: Der Zeitstempel des Anrufs. Das Standard-Zeitstempelformat versucht so eindeutig wie möglich zu sein und hat die Form: 20230414_215701.088-0400
. Mit {date:<format string>}
kann ein benutzerdefiniertes Zeitstempelformat angegeben werden. Beispielsweise würde {date:yyyy-MM-dd @ h.mm.ss a}
2023-04-14 @ 9.57.01 PM
ergeben. Eine vollständige Liste der Zeitstempel-Formatierungszeichen finden Sie unter: https://developer.android.com/reference/java/time/format/DateTimeFormatterBuilder#appendPattern(java.lang.String).{phone_number}{date}
führt dazu, dass die Dateiaufbewahrung deaktiviert wird, aber {phone_number} ({date})
funktioniert, weil zwischen den beiden Variablen Text (
steht.yyMMdd_HHmmss
in HHmmss_yyMMdd
geändert wurde, würden die Zeitstempel der Dateinamen der alten Aufzeichnung falsch analysiert und möglicherweise gelöscht.{direction}
: [Nur Android 10+] Für 1-zu-1-Anrufe, entweder in
oder out
je nachdem, ob es sich um einen eingehenden oder ausgehenden Anruf handelt. Wenn es sich bei dem Anruf um eine Telefonkonferenz handelt, wird stattdessen conference
verwendet.{sim_slot}
: [Nur Android 11+] Die SIM-Steckplatznummer für den Anruf (ab 1 gezählt). Dies ist nur für Multi-SIM-Geräte definiert, bei denen mehrere SIMs aktiv sind und wenn BCR die Telefonberechtigung erteilt wurde.{sim_slot:always}
.{phone_number}
: Die Telefonnummer für den Anruf. Dies ist für private Anrufe nicht definiert. Verfügbare Formatierungsoptionen:{phone_number:E.164}
: Standard (dasselbe wie nur {phone_number}
). Telefonnummer im internationalen E.164-Format ( +<country code><subscriber>
).{phone_number:digits_only}
: Telefonnummer nur mit Ziffern (kein +
oder Trennzeichen).{phone_number:formatted}
: Telefonnummer im länderspezifischen Stil formatiert.{caller_name}
: Die Anrufer-ID, wie sie von CNAP vom Netzbetreiber bereitgestellt wird.{contact_name}
Der Name des (ersten) Kontakts, der der Telefonnummer zugeordnet ist. Dies ist nur definiert, wenn BCR die Berechtigung „Kontakte“ erhalten hat.{call_log_name}
: Der im Anrufprotokoll angezeigte Name. Dies kann weitere Informationen wie den Namen des Unternehmens umfassen, wenn der Systemwähler Reverse-Lookups durchführt. Dies ist nur definiert, wenn BCR die Berechtigung „Anrufprotokolle lesen“ erhalten hat. Die Dateinamenvorlage unterstützt die Angabe von Unterverzeichnissen mit dem Zeichen /
. Schrägstriche sind überall in der Dateinamenvorlage zulässig, einschließlich {date}
(z. B. {date:yyyy/MM/dd}
). Allerdings werden alle Schrägstriche, die nach dem Erweitern anderer Variablen erscheinen, durch Unterstriche ersetzt. Wenn die Anrufer-ID für einen Anruf beispielsweise First/Last
lautet, wird {caller_name}
zu First_Last
erweitert.
Beachten Sie, dass die Verwendung von Unterverzeichnissen aufgrund der schlechten Leistung des Android Storage Access Framework das Speichern der Aufzeichnung auf einigen Geräten erheblich verlangsamen kann. Bei Android-Builds mit einer guten SAF-Implementierung kann dies nur ein paar Sekunden dauern. Beim OEM-Android-Build mit der schlechtesten bekannten SAF-Implementierung kann dies mehrere Minuten dauern. Die Verzögerung ist proportional zur Anzahl der Dateien im Ausgabeverzeichnis.
Wenn die Option Write metadata file
aktiviert ist, schreibt BCR eine JSON-Datei in das Ausgabeverzeichnis, die alle Details enthält, die BCR über den Anruf weiß, sowie Informationen über das aufgezeichnete Audio. Die Datei hat denselben Namen wie die Audiodatei, außer mit der Erweiterung .json
.
Die JSON-Struktur wird im folgenden Beispiel gezeigt. Beachten Sie, dass garantiert nur timestamp_unix_ms
, timestamp
und output.format.*
vorhanden sind. Wenn der Wert für ein Feld nicht ermittelt werden kann (z. B. wenn ein Fehler auftritt oder eine erforderliche Berechtigung verweigert wird), wird er auf null
gesetzt.
{
// 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
}
}
}
In diesem Abschnitt werden die versteckten erweiterten Funktionen von BCR beschrieben.
BCR verfügt über einen versteckten Debug-Modus, der durch langes Drücken der Versionsnummer aktiviert oder deaktiviert werden kann.
Wenn der Debug-Modus aktiviert ist, schreibt BCR nach Abschluss einer Anrufaufzeichnung eine Protokolldatei in das Ausgabeverzeichnis. Der Name entspricht dem der Audiodatei. Die Protokolldatei enthält die gleichen Meldungen wie adb logcat
, mit der Ausnahme, dass Meldungen, die für BCR nicht relevant sind, herausgefiltert werden (BCR hat ohnehin keine Berechtigung, auf diese Meldungen zuzugreifen).
BCR ist bestrebt, in der Protokolldatei niemals vertrauliche Informationen zu protokollieren. Informationen zum aktuellen Anruf, wie z. B. die Telefonnummer, werden stattdessen durch Platzhalter ersetzt, z. B. <phone number>
. Andere Informationen können jedoch nicht einfach auf diese Weise geschwärzt werden und werden stattdessen gekürzt. Wenn beispielsweise die Dateiaufbewahrungsfunktion alte Dateien bereinigt, werden Dateinamen wie 20230101_010203.456+0000_out_1234567890_John_Doe.oga
als 20<...>ga
protokolliert.
Wenn Sie Fehler melden, fügen Sie bitte die Protokolldatei bei, da diese äußerst hilfreich ist, um zu ermitteln, was möglicherweise falsch ist. (Bitte überprüfen Sie die Protokolldatei jedoch noch einmal, um sicherzustellen, dass keine vertraulichen Informationen enthalten sind!)
Um ordnungsgemäß zu funktionieren, ist BCR stark auf System-App-Berechtigungen angewiesen. Dies liegt vor allem an zwei Berechtigungen:
CONTROL_INCALL_EXPERIENCE
Diese Berechtigung ermöglicht es dem Telefondienst von Android, sich an InCallService
von BCR zu binden, ohne dass BCR eine tragbare Begleit-App, eine Auto-Benutzeroberfläche oder der Standard-Wähler ist. Nach der Bindung empfängt der Dienst Rückrufe bei Anrufänderungsereignissen (z. B. eingehender Anruf im Klingelzustand). Diese Methode ist viel zuverlässiger als die Verwendung der READ_PHONE_STATE
Berechtigung und die Verwendung von android.intent.action.PHONE_STATE
-Broadcasts.
Diese Methode hat einige zusätzliche Vorteile. Aufgrund der Art und Weise, wie der Telefoniedienst an InCallService
von BCR bindet, kann sich der Dienst bei Bedarf bei einem laufenden Anruf in den Vordergrund ein- und ausschalten und auf den Audiostream zugreifen, ohne auf die Zugriffsbeschränkungen für Hintergrundmikrofone von Android 12+ zu stoßen. Der Dienst muss außerdem nicht manuell von einem ACTION_BOOT_COMPLETED
-Broadcast-Empfänger gestartet werden und ist daher nicht von den Verzögerungen dieses Broadcasts beim ersten Start betroffen.
CAPTURE_AUDIO_OUTPUT
Diese Berechtigung wird zum Aufzeichnen des VOICE_CALL
Audiostreams verwendet. Auf diesen Stream und einige andere wie VOICE_DOWNLINK
und VOICE_UPLINK
kann ohne diese Systemberechtigung nicht zugegriffen werden.
Mit diesen beiden Berechtigungen kann BCR Telefonanrufe zuverlässig erkennen und aus dem Audiostream des Anrufs aufzeichnen. Der Aufnahmevorgang ruft PCM-s16le-Rohaudio ab und verwendet die integrierten Encoder von Android, um die komprimierte Ausgabedatei zu erstellen.
Sowohl die Zip-Datei als auch die darin enthaltene APK sind digital signiert. HINWEIS : Der Signaturmechanismus für Zip-Dateien wurde ab Version 1.31 von GPG auf SSH umgestellt. Informationen zum Überprüfen von Signaturen für alte Versionen finden Sie README.md
der Version 1.30.
Um die digitalen Signaturen der Downloads zu überprüfen, befolgen Sie die Schritte hier.
Extrahieren Sie zuerst die APK aus der Zip-Datei und führen Sie dann Folgendes aus:
apksigner verify --print-certs system/priv-app/com.chiller3.bcr/app-release.apk
Überprüfen Sie dann, ob der SHA-256-Digest des APK-Signaturzertifikats wie folgt lautet:
d16f9b375df668c58ef4bb855eae959713d6d02e45f7f2c05ce2c27ae944f4f9
BCR kann wie die meisten anderen Android-Apps mit Android Studio oder der Gradle-Befehlszeile erstellt werden.
So erstellen Sie die APK:
./gradlew assembleDebug
So erstellen Sie die ZIP-Datei des Magisk-Moduls (die bei Bedarf automatisch die assembleDebug
Aufgabe ausführt):
./gradlew zipDebug
Die Ausgabedatei wird in app/build/distributions/debug/
geschrieben. Das APK wird mit dem standardmäßig automatisch generierten Debug-Schlüssel signiert.
Um einen Release-Build mit einem bestimmten Signaturschlüssel zu erstellen, richten Sie die folgenden Umgebungsvariablen ein:
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
und dann die Release-Zip erstellen:
./gradlew zipRelease
Bugfix- und Übersetzungs-Pull-Anfragen sind willkommen und werden sehr geschätzt!
Wenn Sie an der Implementierung einer neuen Funktion interessiert sind und diese in BCR enthalten sehen möchten, öffnen Sie bitte zunächst ein Problem, um es zu besprechen. Ich möchte, dass BCR so einfach und wartungsarm wie möglich ist, daher bin ich nicht zu geneigt, neue Funktionen hinzuzufügen, aber ich könnte vom Gegenteil überzeugt werden.
BCR ist unter GPLv3 lizenziert. Den vollständigen Lizenztext finden Sie unter LICENSE
.