BCR adalah aplikasi perekaman panggilan Android sederhana untuk perangkat yang di-rooting atau perangkat yang menjalankan firmware khusus. Setelah diaktifkan, ini tidak mengganggu dan secara otomatis mencatat panggilan masuk dan keluar di latar belakang.
Sesuai dengan namanya, BCR bermaksud menjadi yang paling mendasar. Proyek ini akan berhasil mencapai tujuannya jika satu-satunya pembaruan yang diperlukan adalah kompatibilitas dengan versi Android baru. Oleh karena itu, banyak fitur yang berpotensi berguna tidak akan pernah diterapkan, seperti:
VOICE_CALL
(mis. menggunakan mikrofon + speaker ponsel)Unduh versi terbaru dari halaman rilis. Untuk memverifikasi tanda tangan digital, lihat bagian verifikasi tanda tangan digital.
Instal BCR sebagai aplikasi sistem.
Untuk perangkat yang di-rooting dengan Magisk/KernelSU , cukup flash zip sebagai modul Magisk/KernelSU dari dalam aplikasi masing-masing.
.apk
dari zip dan instal secara manual sebelum melakukan boot ulang. Hal ini diperlukan untuk mengatasi bug di firmware di mana direktori data aplikasi tidak dibuat, menyebabkan BCR membuka layar kosong.Untuk firmware khusus yang tidak di-root , flash zip saat boot ke pemulihan.
READ_CALL_LOG
sangat dibatasi di Android 10+, sehingga izin tersebut tidak dapat diberikan, bahkan melalui pengaturan Android. Untuk menghapus batasan ini, jalankan melalui adb setelah reboot kembali ke 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
firmware khusus diformat dengan erofs
, maka sistem file bersifat read-only dan metode ini tidak dapat digunakan.system/
di zip juga akan berfungsi selama file tersebut memiliki izin 644
dan label SELinux u:object_r:system_file:s0
.Nyalakan ulang dan buka BCR.
Jika perekam panggilan lain dipasang, pastikan untuk menonaktifkan fungsi perekaman panggilan teleponnya. Di sebagian besar perangkat, panggilan telepon tidak dapat direkam oleh dua aplikasi secara bersamaan. Namun, boleh saja jika BCR merekam panggilan telepon dan merekam aplikasi lain, misalnya. panggilan VOIP.
Aktifkan rekaman panggilan dan pilih direktori keluaran.
Jika tidak ada direktori keluaran yang dipilih atau jika direktori keluaran tidak lagi dapat diakses, maka rekaman akan disimpan ke /sdcard/Android/data/com.chiller3.bcr/files
. Perhatikan bahwa di Android 12+, /sdcard/Android/data/
hanya dapat diakses melalui USB atau DocumentsUI (manajer file bawaan AOSP).
Saat mengaktifkan perekaman panggilan pertama kali, BCR akan meminta mikrofon, notifikasi (Android 13+), log panggilan, kontak, dan izin telepon. Hanya izin mikrofon dan notifikasi yang diperlukan untuk fungsi perekaman panggilan dasar. Jika izin tambahan diberikan, informasi lebih lanjut akan ditambahkan ke nama file keluaran. Misalnya, izin kontak akan memungkinkan nama kontak ditambahkan ke nama file.
Lihat bagian izin di bawah untuk detail selengkapnya tentang izin.
Untuk menginstal pembaruan di masa mendatang, ada beberapa metode:
.apk
juga dapat diekstraksi dari zip dan langsung diinstal. Dengan metode ini, versi lama ada sebagai aplikasi sistem dan versi baru ada sebagai pembaruan yang diinstal pengguna untuk aplikasi sistem. Metode ini lebih nyaman jika BCR dimasukkan ke dalam image firmware Android. Berbeda dengan fungsi perekaman panggilan bawaan pada aplikasi telepon yang sudah diinstal sebelumnya pada beberapa perangkat, BCR tidak mengumumkan bahwa panggilan tersebut direkam ke pihak lain. BCR tidak pernah mengeluarkan audio apa pun ke aliran audio panggilan.
Bila BCR diaktifkan, hindari penggunaan perekam panggilan bawaan telepon sama sekali. Ada kemungkinan besar bahwa menggunakannya akan menyebabkan perilaku yang tidak terduga, seperti rekaman gagal atau dialer mengumumkan bahwa panggilan sedang direkam.
Jika Anda tinggal di yurisdiksi yang mewajibkan persetujuan dua pihak, Anda bertanggung jawab untuk memberi tahu pihak lain bahwa panggilan tersebut direkam. Jika diperlukan, aturan perekaman otomatis dapat digunakan untuk membuang rekaman secara default. Namun, perhatikan bahwa jika Anda memilih untuk menyimpan rekaman di tengah-tengah panggilan, rekaman tersebut akan berisi panggilan penuh, bukan hanya sebagian setelah pihak lain menyetujuinya.
BCR sadar akan boot langsung, artinya ia mampu menjalankan dan merekam panggilan sebelum perangkat dibuka kuncinya setelah reboot. Dalam keadaan ini, sebagian besar fungsi BCR akan tetap berfungsi, selain fitur yang memerlukan daftar kontak atau log panggilan. Dalam praktiknya, ini berarti:
Namun, jika perangkat dibuka kuncinya sebelum panggilan berakhir, batasan ini tidak berlaku.
Perhatikan bahwa direktori keluaran tidak tersedia sebelum perangkat dibuka kuncinya untuk pertama kalinya. Rekaman yang dibuat saat berada di negara bagian disimpan dalam direktori internal yang tidak dapat diakses oleh pengguna. Setelah perangkat dibuka kuncinya, BCR akan memindahkan file ke direktori keluaran. Ini mungkin memerlukan waktu beberapa saat untuk diselesaikan.
CAPTURE_AUDIO_OUTPUT
( secara otomatis diberikan oleh izin aplikasi sistem )CONTROL_INCALL_EXPERIENCE
( secara otomatis diberikan oleh izin aplikasi sistem )RECORD_AUDIO
( harus diberikan oleh pengguna )FOREGROUND_SERVICE
, FOREGROUND_SERVICE_MICROPHONE
( secara otomatis diberikan pada waktu instalasi )POST_NOTIFICATIONS
( harus diberikan oleh pengguna di Android 13+ )READ_CALL_LOG
( opsional )READ_CONTACTS
( opsional )RECEIVE_BOOT_COMPLETED
, FOREGROUND_SERVICE_SPECIAL_USE
( otomatis diberikan pada waktu instalasi )READ_PHONE_STATE
( opsional )REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
( opsional )VIBRATE
( secara otomatis diberikan pada waktu instalasi ) Perhatikan bahwa INTERNET
tidak ada dalam daftar. BCR tidak dan tidak akan pernah mengakses jaringan. BCR juga tidak akan pernah berkomunikasi dengan aplikasi lain, kecuali jika pengguna secara eksplisit mengetuk tombol Open
atau Share
di notifikasi yang ditampilkan saat perekaman selesai. Dalam skenario tersebut, aplikasi target hanya diberikan akses ke rekaman tunggal tersebut.
BCR memiliki dukungan terbatas untuk aplikasi pengalihan panggilan, seperti Google Voice. Panggilan yang dialihkan hanya dapat direkam jika layanan pengalihan panggilan menggunakan panggilan telepon standar di belakang layar (bukan VOIP).
Ada beberapa batasan saat merekam panggilan yang dialihkan dibandingkan dengan panggilan biasa:
All other calls
.Batasan ini ada karena ketika panggilan dialihkan, hanya aplikasi telepon itu sendiri yang mengetahui nomor telepon aslinya. Sistem telepon Android tidak menyadarinya. BCR hanya dapat menemukan nomor telepon asli dengan mencari log panggilan sistem ketika dialer menambahkan entri di akhir panggilan.
BCR mendukung penyesuaian templat yang digunakan untuk menentukan nama file keluaran rekaman. Templat defaultnya adalah:
{date}[_{direction}|][_sim{sim_slot}|][_{phone_number}|][_[{contact_name}|{caller_name}|{call_log_name}]|]
{var}
) digunakan untuk merujuk pada variabel. Variabel diganti dengan nilai yang diwakilinya. Misalnya, {phone_number}
diganti dengan nomor telepon panggilan sebenarnya.[{var}|default]
) digunakan untuk menentukan fallback. Misalnya, [{contact_name}|{caller_name}|Unknown]
akan memasukkan nama kontak jika nomor tersebut ada di dalam kontak. Jika tidak, itu akan kembali ke ID penelepon atau Unknown
jika nama kontak atau ID penelepon tidak ada. Kembali ke string kosong juga valid. Misalnya, [{contact_name}|]
mengevaluasi nama kontak atau tidak sama sekali.{date}
: Stempel waktu panggilan. Format stempel waktu default berusaha sejelas mungkin dan berbentuk: 20230414_215701.088-0400
. Format stempel waktu khusus dapat ditentukan dengan {date:<format string>}
. Misalnya, {date:yyyy-MM-dd @ h.mm.ss a}
akan menghasilkan 2023-04-14 @ 9.57.01 PM
. Daftar lengkap karakter pemformatan stempel waktu dapat ditemukan di: https://developer.android.com/reference/java/time/format/DateTimeFormatterBuilder#appendPattern(java.lang.String).{phone_number}{date}
akan menyebabkan penyimpanan file dinonaktifkan, namun {phone_number} ({date})
berfungsi karena ada beberapa teks (
di antara kedua variabel.yyMMdd_HHmmss
diubah menjadi HHmmss_yyMMdd
, stempel waktu dari nama file rekaman lama akan salah diurai dan mungkin terhapus.{direction}
: [Khusus Android 10+] Untuk panggilan 1 lawan 1, in
atau out
tergantung pada apakah panggilan tersebut merupakan panggilan masuk atau keluar. Jika panggilan tersebut adalah panggilan konferensi, maka conference
yang digunakan.{sim_slot}
: [Khusus Android 11+] Nomor slot SIM untuk panggilan (dihitung dari 1). Ini hanya ditentukan untuk perangkat multi-SIM yang memiliki beberapa SIM aktif dan jika BCR diberikan izin Telepon.{sim_slot:always}
.{phone_number}
: Nomor telepon untuk panggilan tersebut. Ini tidak ditentukan untuk panggilan pribadi. Opsi pemformatan yang tersedia:{phone_number:E.164}
: Default (sama seperti {phone_number}
). Nomor telepon diformat dalam format internasional E.164 ( +<country code><subscriber>
).{phone_number:digits_only}
: Nomor telepon dengan angka saja (tanpa +
atau pemisah).{phone_number:formatted}
: Nomor telepon diformat menggunakan gaya khusus negara.{caller_name}
: ID penelepon yang diberikan oleh CNAP dari operator.{contact_name}
Nama kontak (pertama) yang dikaitkan dengan nomor telepon. Ini hanya ditentukan jika BCR diberikan izin Kontak.{call_log_name}
: Nama yang ditampilkan di log panggilan. Ini mungkin mencakup lebih banyak informasi, seperti nama bisnis, jika sistem dialer melakukan pencarian terbalik. Ini hanya ditentukan jika BCR diberikan izin Baca Log Panggilan. Templat nama file mendukung penentuan subdirektori menggunakan karakter /
. Garis miring diperbolehkan di mana saja di dalam templat nama file, termasuk {date}
(mis. {date:yyyy/MM/dd}
). Namun, setiap garis miring yang muncul setelah variabel lain diperluas akan diganti dengan garis bawah. Misalnya, jika ID penelepon untuk suatu panggilan adalah First/Last
, maka {caller_name}
diperluas menjadi First_Last
.
Perhatikan bahwa karena kinerja Android Storage Access Framework yang buruk, penggunaan subdirektori dapat memperlambat penyimpanan rekaman di beberapa perangkat secara signifikan. Pada Android yang dibuat dengan implementasi SAF yang baik, ini mungkin hanya membutuhkan waktu beberapa detik. Pada versi OEM Android dengan penerapan SAF yang paling buruk, proses ini dapat memakan waktu beberapa menit. Penundaannya sebanding dengan jumlah file di direktori keluaran.
Jika opsi Write metadata file
diaktifkan, BCR akan menulis file JSON ke direktori keluaran yang berisi semua detail yang diketahui BCR tentang panggilan tersebut serta informasi tentang rekaman audio. File tersebut memiliki nama yang sama dengan file audio, kecuali dengan ekstensi .json
.
Struktur JSON ditunjukkan pada contoh berikut. Perhatikan bahwa hanya timestamp_unix_ms
, timestamp
, dan output.format.*
yang dijamin ada. Jika nilai suatu bidang tidak dapat ditentukan (misalnya ketika terjadi kesalahan atau izin yang diperlukan ditolak), maka nilai tersebut disetel ke 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
}
}
}
Bagian ini menjelaskan fitur-fitur canggih BCR yang tersembunyi.
BCR memiliki mode debug tersembunyi yang dapat diaktifkan atau dinonaktifkan dengan menekan lama nomor versi.
Ketika mode debug diaktifkan, BCR akan menulis file log ke direktori output setelah perekaman panggilan selesai. Namanya sama dengan file audio. File log berisi pesan yang sama seperti yang ditampilkan adb logcat
, kecuali pesan yang tidak relevan dengan BCR disaring (BCR tidak memiliki izin untuk mengakses pesan tersebut).
Di dalam file log, BCR bertujuan untuk tidak pernah mencatat informasi sensitif apa pun. Informasi tentang panggilan saat ini, seperti nomor telepon, diganti dengan placeholder, seperti <phone number>
. Namun, informasi lain yang tidak dapat dengan mudah disunting dengan cara ini akan terpotong. Misalnya, ketika fitur penyimpanan file membersihkan file lama, nama file seperti 20230101_010203.456+0000_out_1234567890_John_Doe.oga
dicatat sebagai 20<...>ga
.
Saat melaporkan bug, harap sertakan file log karena sangat membantu untuk mengidentifikasi apa yang mungkin salah. (Tetapi harap periksa kembali file log untuk memastikan tidak ada informasi sensitif!)
BCR sangat bergantung pada izin aplikasi sistem agar dapat berfungsi dengan baik. Hal ini terutama disebabkan oleh dua izin:
CONTROL_INCALL_EXPERIENCE
Izin ini memungkinkan layanan telepon Android untuk mengikat InCallService
BCR tanpa BCR menjadi aplikasi pendamping yang dapat dikenakan, UI mobil, atau telepon default. Setelah terikat, layanan akan menerima panggilan balik untuk peristiwa perubahan panggilan (misalnya panggilan masuk dalam keadaan berdering). Cara ini jauh lebih dapat diandalkan dibandingkan menggunakan izin READ_PHONE_STATE
dan mengandalkan siaran android.intent.action.PHONE_STATE
.
Metode ini memiliki beberapa manfaat tambahan. Karena cara layanan telepon terikat dengan InCallService
BCR, layanan ini dapat masuk dan keluar dari latar depan sesuai kebutuhan saat panggilan sedang berlangsung dan mengakses aliran audio tanpa melanggar batasan akses mikrofon latar belakang Android 12+. Ini juga tidak memerlukan layanan untuk dimulai secara manual dari penerima siaran ACTION_BOOT_COMPLETED
dan dengan demikian tidak terpengaruh oleh penundaan siaran tersebut selama booting awal.
CAPTURE_AUDIO_OUTPUT
Izin ini digunakan untuk merekam dari aliran audio VOICE_CALL
. Aliran ini, bersama aliran lainnya, seperti VOICE_DOWNLINK
dan VOICE_UPLINK
, tidak dapat diakses tanpa izin sistem ini.
Dengan dua izin ini, BCR dapat mendeteksi panggilan telepon dengan andal dan merekam dari aliran audio panggilan tersebut. Proses perekaman mengambil audio mentah PCM s16le dan menggunakan encoder bawaan Android untuk menghasilkan file keluaran terkompresi.
File zip dan APK yang ada di dalamnya ditandatangani secara digital. CATATAN : Mekanisme penandatanganan file zip beralih dari GPG ke SSH pada versi 1.31. Untuk memverifikasi tanda tangan versi lama, lihat README.md
versi 1.30.
Untuk memverifikasi tanda tangan digital unduhan, ikuti langkah-langkah di sini.
Pertama, ekstrak apk dari zip lalu jalankan:
apksigner verify --print-certs system/priv-app/com.chiller3.bcr/app-release.apk
Lalu, periksa apakah intisari SHA-256 dari sertifikat penandatanganan APK adalah:
d16f9b375df668c58ef4bb855eae959713d6d02e45f7f2c05ce2c27ae944f4f9
BCR dapat dibuat seperti kebanyakan aplikasi Android lainnya menggunakan Android Studio atau baris perintah gradle.
Untuk membuat APK:
./gradlew assembleDebug
Untuk membuat zip modul Magisk (yang secara otomatis menjalankan tugas assembleDebug
jika diperlukan):
./gradlew zipDebug
File keluaran ditulis ke app/build/distributions/debug/
. APK akan ditandatangani dengan kunci debug default yang dibuat secara otomatis.
Untuk membuat build rilis dengan kunci penandatanganan tertentu, siapkan variabel lingkungan berikut:
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
dan kemudian buat zip rilis:
./gradlew zipRelease
Perbaikan bug dan permintaan penarikan terjemahan dipersilakan dan sangat dihargai!
Jika Anda tertarik untuk menerapkan fitur baru dan ingin melihatnya disertakan dalam BCR, silakan buka terbitan untuk mendiskusikannya terlebih dahulu. Saya bermaksud agar BCR dibuat sesederhana dan serendah mungkin dalam pemeliharaan, jadi saya tidak terlalu ingin menambahkan fitur baru, namun saya yakin sebaliknya.
BCR dilisensikan di bawah GPLv3. Silakan lihat LICENSE
untuk teks lisensi lengkap.