[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7427":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":9,"rankLanguage":9,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":22,"hasPages":22,"topics":24,"createdAt":9,"pushedAt":9,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":15,"starSnapshotCount":15,"syncStatus":16,"lastSyncTime":28,"discoverSource":29},7427,"BCR","chenxiaolong\u002FBCR","chenxiaolong","A Basic Call Recorder for rooted Android devices",null,"Kotlin",2778,159,33,13,0,2,7,36,8,69.71,"GNU General Public License v3.0",false,"master",[],"2026-06-17 04:00:32","# Basic Call Recorder\n\n\u003Cimg src=\"app\u002Fimages\u002Ficon.svg\" alt=\"app icon\" width=\"72\" \u002F>\n\nBCR is a simple Android call recording app for rooted devices or devices running custom firmware. Once enabled, it stays out of the way and automatically records incoming and outgoing calls in the background.\n\n\u003Cimg src=\"app\u002Fimages\u002Flight.png\" alt=\"light mode screenshot\" width=\"200\" \u002F> \u003Cimg src=\"app\u002Fimages\u002Fdark.png\" alt=\"dark mode screenshot\" width=\"200\" \u002F>\n\n## Features\n\n* Supports Android 9 and newer\n* Supports output in various formats:\n  * OGG\u002FOpus - Lossy, smaller files, default on Android 10+\n  * M4A\u002FAAC - Lossy, smaller files, default on Android 9\n  * FLAC - Lossless, larger files\n  * WAV\u002FPCM - Lossless, largest files, least CPU usage\n  * AMR-WB\u002FAMR-NB - Lossy, smallest files, mono-only\n* Supports stereo recording (separate uplink and downlink channels)\n  * NOTE: This is only known to work on Pixel devices running newer versions of Android. Other devices may have unexpected behavior, such as lack of separation between uplink and downlink or even no audio at all. Try recording test calls before relying on this feature.\n* Supports Android's Storage Access Framework (can record to SD cards, USB devices, etc.)\n* Direct boot aware (records calls prior to first unlock after a reboot)\n* Auto-record rules\n* Quick settings toggle\n* No persistent notification unless a recording is in progress\n* No network access permission\n* Supports both Magisk and KernelSU\n\n## Non-features\n\nAs the name alludes, BCR intends to be a basic as possible. The project will have succeeded at its goal if the only updates it ever needs are for compatibility with new Android versions. Thus, many potentially useful features will never be implemented, such as:\n\n* Support for old Android versions (support is dropped as soon as maintenance becomes cumbersome)\n* Workarounds for [OEM-specific battery optimization and app killing behavior](https:\u002F\u002Fdontkillmyapp.com\u002F)\n* Workarounds for devices that don't support the [`VOICE_CALL` audio source](https:\u002F\u002Fdeveloper.android.com\u002Freference\u002Fandroid\u002Fmedia\u002FMediaRecorder.AudioSource#VOICE_CALL) (eg. using microphone + speakerphone)\n* Support for stock, unrooted firmware\n\n## Usage\n\n1. Download the latest version from the [releases page](https:\u002F\u002Fgithub.com\u002Fchenxiaolong\u002FBCR\u002Freleases). To verify the digital signature, see the [verifying digital signatures](#verifying-digital-signatures) section.\n\n2. Install BCR as a system app.\n\n    * **For devices rooted with Magisk\u002FKernelSU**, simply flash the zip as a Magisk\u002FKernelSU module from within the respective application.\n        * **If you use any type of root hiding feature**, also extract the `.apk` from the zip and install it manually before rebooting. This works around crashes and other issues caused by BCR's APK being hidden from the system.\n\n    * **For unrooted custom firmware**, flash the zip while booted into recovery.\n        * **NOTE**: The `READ_CALL_LOG` permission is hard restricted in Android 10+, which prevents it from being granted, even via Android's settings. To remove this restriction, run via adb after rebooting back into Android:\n          ```bash\n          # If rooted, run inside of `su`:\n          CLASSPATH=\u002Fsystem\u002Fpriv-app\u002Fcom.chiller3.bcr\u002Fapp-release.apk app_process \u002F com.chiller3.bcr.standalone.RemoveHardRestrictionsKt\n\n          # If unrooted, install BCR as both a user app and a system app:\n          pm install \u002Fsystem\u002Fpriv-app\u002Fcom.chiller3.bcr\u002Fapp-release.apk\n          ```\n        * **NOTE**: If the custom firmware's `system` partition is formatted with `erofs`, then the filesystem is read-only and it is not possible to use this method.\n        * Manually extracting the files from the `system\u002F` folder in the zip will also work as long as the files have `644` permissions and the `u:object_r:system_file:s0` SELinux label.\n\n3. Reboot and open BCR.\n\n    If other call recorders are installed, make sure to disable their phone call recording functionality. On most devices, a phone call cannot be recorded by two apps at the same time. However, it is fine to have BCR record phone calls and another app record eg. VOIP calls.\n\n    Also, disable any AI-related functionality in the dialer app. These features also rely on Android's call recording APIs.\n\n4. Enable call recording and pick an output directory.\n\n    If no output directory is selected or if the output directory is no longer accessible, then recordings will be saved to `\u002Fsdcard\u002FAndroid\u002Fdata\u002Fcom.chiller3.bcr\u002Ffiles`. Note that on Android 12+, `\u002Fsdcard\u002FAndroid\u002Fdata\u002F` is only accessible via USB or DocumentsUI (AOSP's built in file manager). The output directory can be opened in the system file manager by long pressing the output directory setting.\n\n    When enabling call recording the first time, BCR will prompt for microphone, notification (Android 13+), call log, contacts, and phone permissions. Only microphone and notification permissions are required for basic call recording functionality. If additional permissions are granted, more information is added to the output filename. For example, the contacts permission will allow the contact name to be added to the filename.\n\n    See the [permissions section](#permissions) below for more details about the permissions.\n\n## Recording announcement\n\nUnlike the built-in call recording functionality of the preinstalled dialer app on some devices, BCR does not announce that the call is being recorded to the other party. BCR never outputs audio of any kind to the call audio stream.\n\nWhen BCR is enabled, avoid using the dialer's built-in call recorder at all. There's a very good chance that using it will cause unexpected behavior, like both recordings failing or the dialer announcing that the call is being recorded.\n\nIf you live in a jurisdiction where two-party consent is required, you are responsible for informing the other party that the call is being recorded. If needed, auto-record rules can be used to discard recordings by default. However, note that if you choose to preserve the recording during the middle of the call, the recording will contain full call, not just the portion after the other party consented.\n\n## Direct boot\n\nBCR is direct boot aware, meaning that it's capable of running and recording calls before the device is initially unlocked following a reboot. In this state, most of BCR's functionality will still work, aside from features that require the contact list or call log. In practice, this means:\n\n* If auto-record rules are set up, the contact and contact group conditions will not match.\n* It's not possible to manually preserve the recording if an auto-record rule is set to discard it because BCR's notification is not accessible before the initial unlock.\n* The output filename, if using the default template, will only contain the caller ID, not the contact name or call log name.\n\nHowever, if the device is unlocked before the call ends, then none of these limitations apply.\n\nNote that the output directory is not available before the device is unlocked for the first time. Recordings made while in the state are stored in an internal directory that's not accessible by the user. After the device is unlocked, BCR will move the files to the output directory. This may take a few moments to complete.\n\n## Permissions\n\n* `CAPTURE_AUDIO_OUTPUT` (**automatically granted by system app permissions**)\n  * Needed to capture the call audio stream.\n* `CONTROL_INCALL_EXPERIENCE` (**automatically granted by system app permissions**)\n  * Needed to monitor the phone call state for starting and stopping the recording and gathering call information for the output filename.\n* `RECORD_AUDIO` (**must be granted by the user**)\n  * Needed to capture the call audio stream.\n* `FOREGROUND_SERVICE`, `FOREGROUND_SERVICE_MICROPHONE` (**automatically granted at install time**)\n  * Needed to run the call recording service.\n* `POST_NOTIFICATIONS` (**must be granted by the user on Android 13+**)\n  * Needed to show notifications.\n  * A notification is required for running the call recording service in foreground mode or else Android will not allow access to the call audio stream.\n* `READ_CALL_LOG` (**optional**)\n  * If allowed, the name as shown in the call log can be added to the output filename.\n  * This is also required to show the correct phone number when using call redirection apps.\n* `READ_CONTACTS` (**optional**)\n  * If allowed, the contact name can be added to the output filename. It also allows auto-record rules to match contacts and contact groups.\n* `RECEIVE_BOOT_COMPLETED`, `FOREGROUND_SERVICE_SPECIAL_USE` (**automatically granted at install time**)\n  * Needed to automatically move recordings made before the initial device unlock to the output directory.\n* `READ_PHONE_STATE` (**optional**)\n  * If allowed, the SIM slot for devices with multiple active SIMs is added to the output filename.\n* `VIBRATE` (**automatically granted at install time**)\n  * If vibration is enabled for BCR's notifications in Android's settings, BCR will perform the vibration. Android itself does not respect the vibration option when a phone call is active.\n\nNote that `INTERNET` is _not_ in the list. BCR does not and will never access the network. BCR will never communicate with other apps either, except if the user explicitly taps on the `Open` or `Share` buttons in the notification shown when a recording completes. In that scenario, the target app is granted access to that single recording only.\n\n## Call redirection\n\nBCR has limited support for call redirection apps, like Google Voice. Redirected calls can be recorded only if the call redirection service uses standard telephone calls behind the scenes (instead of VOIP).\n\nThere are several limitations when recording redirected calls compared to regular calls:\n\n* The call must not be a conference call. Otherwise, the filename will only show the call redirection service's proxy phone number.\n* Auto-record rules will not work properly. Redirected calls will never match any rules for specified contacts and will only match the `All other calls` rule.\n* During the call, BCR's notification will only show the call redirection service's proxy phone number.\n* BCR must be granted the call logs permission.\n* The dialer app must put the original phone number into the system call log. The AOSP and Google dialer apps do, but other OEM dialer apps might not.\n\nThese limitations exist because when a call is redirected, only the dialer app itself is aware of the original phone number. The Android telephony system is not aware of it. BCR can only find the original phone number by searching the system call log when the dialer adds the entry at the end of the call.\n\n## Filename template\n\nBCR supports customizing the template used for determining the output filenames of recordings. The default template is:\n\n```\n{date}[_{direction}|][_sim{sim_slot}|][_{phone_number}|][_[{contact_name}|{caller_name}|{call_log_name}]|]\n```\n\n### Template syntax\n\n* Curly braces (`{var}`) are used to refer to variables. Variables are replaced by the value they represent. For example, `{phone_number}` is replaced by the actual phone number of the call.\n* Square brackets (`[{var}|default]`) are used for specifying fallbacks. For example, `[{contact_name}|{caller_name}|Unknown]` will insert the contact name if the number is in the contacts. Otherwise, it'll fall back to the caller ID or `Unknown` if neither the contact name nor caller ID exist. Falling back to an empty string is perfectly valid too. For example, `[{contact_name}|]` evaluates to either the contact name or nothing.\n\n### Template variables\n\n* `{date}`: The timestamp of the call. The default timestamp format tries to be as unambiguous as possible and is in the form: `20230414_215701.088-0400`. A custom timestamp format can be specified with `{date:\u003Cformat string>}`. For example, `{date:yyyy-MM-dd @ h.mm.ss a}` would produce `2023-04-14 @ 9.57.01 PM`. A full list of timestamp formatting characters can be found in [Android's documentation](https:\u002F\u002Fdeveloper.android.com\u002Freference\u002Fjava\u002Ftime\u002Fformat\u002FDateTimeFormatterBuilder#appendPattern(java.lang.String)).\n  * The special `{date:unix_s}` and `{date:unix_ms}` variables can be used for Unix timestamps in seconds and milliseconds, respectively.\n  * For the file retention feature to work, the date must not immediately follow another variable. For example, `{phone_number}{date}` will cause file retention to be disabled, but `{phone_number} ({date})` works because there's some text ` (` between the two variables.\n  * If the date format is changed, the old recordings should be manually renamed or moved to another directory to ensure that they won't inadvertently be deleted. For example, if `yyMMdd_HHmmss` was changed to `HHmmss_yyMMdd`, the timestamps from the old recording's filenames would be parsed incorrectly and may get deleted.\n* `{direction}`: **[Android 10+ only]** For 1-on-1 calls, either `in` or `out` depending on if the call is an incoming or outgoing call. If the call is a conference call, then `conference` is used instead.\n* `{sim_slot}`: **[Android 11+ only]** The SIM slot number for the call (counting from 1). This is only defined for multi-SIM devices that have multiple SIMs active and if BCR is granted the Phone permission.\n  * To include the SIM slot even if there's only one active SIM, use `{sim_slot:always}`.\n* `{phone_number}`: The phone number for the call. This is undefined for private calls. The default formatting is unspecified and the number is presented however Android decides to do so. To format with a specific format:\n  * `{phone_number:E.164}`: International E.164 format (`+\u003Ccountry code>\u003Csubscriber>` with no whitespace or separators).\n  * `{phone_number:international}`: Country code followed by country-specific style.\n  * `{phone_number:national}`: Country-specific style without country code.\n  * Sometimes, there is not enough information to format the phone number in these specific formats. It's best to specify a fallback to the default format, such as `[{phone_number:E.164}|{phone_number}|]`.\n* `{caller_name}`: The caller ID as provided by CNAP from the carrier.\n* `{contact_name}` The name of the (first) contact associated with the phone number. This is only defined if BCR is granted the Contacts permission.\n* `{call_log_name}`: The name shown in the call log. This may include more information, like the name of the business, if the system dialer performs reverse lookups. This is only defined if BCR is granted the Read Call Logs permission.\n\n### Subdirectories\n\nThe filename template supports specifying subdirectories using the `\u002F` character. Slashes are allowed anywhere inside the filename template, including `{date}` (eg. `{date:yyyy\u002FMM\u002Fdd}`). However, any slashes that appear after expanding other variables will be replaced with underscores. For example, if the caller ID for a call is `First\u002FLast`, then `{caller_name}` is expanded to `First_Last`.\n\nNote that due to Android Storage Access Framework's poor performance, using subdirectories may significantly slow down the saving of the recording on some devices. On Android builds with a good SAF implementation, this may only be a few seconds. On the OEM Android build with the worst known SAF implementation, this could take several minutes. The delay is proportional to the number of files in the output directory.\n\n## Metadata file\n\nIf the `Write metadata file` option is enabled, BCR will write a JSON file to the output directory containing all of the details that BCR knows about the call as well as information about the recorded audio. The file has the same name as the audio file, except with a `.json` extension.\n\nThe JSON structure is shown in the following example. Note that only `timestamp_unix_ms`, `timestamp`, and `output.format.*` are guaranteed to exist. If the value for a field can't be determined (eg. when an error occurs or a required permission is denied), then it is set to `null`.\n\n```jsonc\n{\n    \u002F\u002F The timestamp represented as milliseconds since the Unix epoch in UTC.\n    \"timestamp_unix_ms\": 1689817988931,\n\n    \u002F\u002F The timestamp represented as ISO8601 (+ offset) in the local time zone.\n    \"timestamp\": \"2023-07-19T21:53:08.931-04:00\",\n\n    \u002F\u002F The Android app handling the call. \"com.android.phone\" is a native\n    \u002F\u002F cellular call.\n    \"package_name\": \"com.android.phone\",\n\n    \u002F\u002F The call direction (\"in\", \"out\", or \"conference\").\n    \u002F\u002F [Android 10+ only]\n    \"direction\": \"in\",\n\n    \u002F\u002F The SIM slot used for the call.\n    \u002F\u002F [Android 11+ only; requires the Phone permission]\n    \"sim_slot\": 1,\n\n    \u002F\u002F The name shown in the dialer's call log. This may include the business'\n    \u002F\u002F name for dialers that perform reverse lookups.\n    \u002F\u002F [Requires the Call Log permission]\n    \"call_log_name\": \"John Doe\",\n\n    \u002F\u002F Details about the other party or parties in the call. There will be\n    \u002F\u002F multiple entries for conference calls.\n    \"calls\": [\n        {\n            \u002F\u002F The raw phone number as reported by Android. For outgoing calls,\n            \u002F\u002F this is usually what the user typed. For incoming calls, this is\n            \u002F\u002F usually E.164 formatted. This will be null for private calls.\n            \"phone_number\": \"+11234567890\",\n\n            \u002F\u002F The phone number formatted using the country-specific style. This\n            \u002F\u002F will be null for private calls or if Android cannot determine the\n            \u002F\u002F country.\n            \"phone_number_formatted\": \"(123) 456-7890\",\n\n            \u002F\u002F The caller name\u002FID as reported by CNAP from the carrier.\n            \"caller_name\": \"John Doe\",\n\n            \u002F\u002F The contact name associated with the phone number.\n            \u002F\u002F [Requires the Contacts permission]\n            \"contact_name\": \"John Doe\"\n        }\n    ],\n\n    \u002F\u002F Details about the output file.\n    \"output\": {\n        \u002F\u002F Details about the output file format.\n        \"format\": {\n            \u002F\u002F The audio encoding format.\n            \"type\": \"OGG\u002FOpus\",\n\n            \u002F\u002F The MIME type of the container format (eg. OGG).\n            \"mime_type_container\": \"audio\u002Fogg\",\n\n            \u002F\u002F The MIME type of the raw audio stream (eg. Opus).\n            \"mime_type_audio\": \"audio\u002Fopus\",\n\n            \u002F\u002F The type of the parameter value below. Either \"bitrate\",\n            \u002F\u002F \"compression_level\", or \"none\".\n            \"parameter_type\": \"bitrate\",\n\n            \u002F\u002F The encoder quality\u002Fsize parameter.\n            \"parameter\": 48000\n        },\n\n        \u002F\u002F Details about the recording and encoding process. If the recording\n        \u002F\u002F process fails, this is set to null.\n        \"recording\": {\n            \u002F\u002F The total number of audio frames that BCR read from the audio\n            \u002F\u002F device. A frame is defined as a bundle of samples, with one\n            \u002F\u002F sample per channel. This value includes the periods of time where\n            \u002F\u002F the recording was paused or on hold.\n            \"frames_total\": 40000,\n\n            \u002F\u002F The number of audio frames that were actually saved to the output\n            \u002F\u002F file. A frame is defined as a bundle of samples, with one sample\n            \u002F\u002F per channel. This value excludes the periods of time where the\n            \u002F\u002F recording was paused or on hold.\n            \"frames_encoded\": 32000,\n\n            \u002F\u002F The number of samples per second of audio.\n            \"sample_rate\": 16000,\n\n            \u002F\u002F The number of channels in the audio.\n            \"channel_count\": 1,\n\n            \u002F\u002F The total wall time from when the recording process began to when\n            \u002F\u002F it ended. If duration_secs_total is significantly lower than this\n            \u002F\u002F value, then Android sent less audio to BCR than expected.\n            \"duration_secs_wall\": 3.0,\n\n            \u002F\u002F The total time in seconds that BCR read from the audio device.\n            \u002F\u002F (Equal to: frames_total \u002F sample_rate)\n            \"duration_secs_total\": 2.5,\n\n            \u002F\u002F The time in seconds of audio actually saved to the output file.\n            \u002F\u002F (Equal to: frames_encoded \u002F sample_rate)\n            \"duration_secs_encoded\": 2.0,\n\n            \u002F\u002F The size of the recording buffer in frames. This is the maximum\n            \u002F\u002F number of audio frames read from the audio driver before it is\n            \u002F\u002F passed to the audio encoder.\n            \"buffer_frames\": 3840,\n\n            \u002F\u002F The number of buffer overruns. This is the number of times that\n            \u002F\u002F the CPU or storage couldn't keep up while encoding the raw audio,\n            \u002F\u002F resulting in skips (loss of audio). This value cannot be\n            \u002F\u002F calculated accurately and is just an estimate.\n            \"buffer_overruns\": 0,\n\n            \u002F\u002F Whether the call was ever paused by the user.\n            \"was_ever_paused\": false,\n\n            \u002F\u002F Whether the call was ever placed on hold (call waiting).\n            \"was_ever_holding\": false\n        }\n    }\n}\n```\n\n## Advanced features\n\nThis section describes BCR's hidden advanced features.\n\n### Debug mode\n\nBCR has a hidden debug mode that can be enabled or disabled by long pressing the version number.\n\nWhen debug mode is enabled, BCR will write a log file to the output directory after a call recording completes. It is named the same way as the audio file. The log file contains the same messages as what `adb logcat` would show, except messages not relevant to BCR are filtered out (BCR does not have permission to access those messages anyway).\n\nWithin the log file, BCR aims to never log any sensitive information. Information about the current call, like the phone number, are replaced with placeholders instead, like `\u003Cphone number>`. However, other information can't be easily redacted this way will be truncated instead. For example, when the file retention feature cleans up old files, filenames like `20230101_010203.456+0000_out_1234567890_John_Doe.oga` are logged as `20\u003C...>ga`.\n\nWhen reporting bugs, please include the log file as it is extremely helpful for identifying what might be wrong. (But please double check the log file to ensure there's no sensitive information!)\n\n## How it works\n\nBCR relies heavily on system app permissions in order to function properly. This is primarily because of two permissions:\n\n* `CONTROL_INCALL_EXPERIENCE`\n\n    This permission allows Android's telephony service to bind to BCR's `InCallService` without BCR being a wearable companion app, a car UI, or the default dialer. Once bound, the service will receive callbacks for call change events (eg. incoming call in the ringing state). This method is much more reliable than using the `READ_PHONE_STATE` permission and relying on `android.intent.action.PHONE_STATE` broadcasts.\n\n    This method has a couple additional benefits. Due to the way that the telephony service binds to BCR's `InCallService`, the service can bring itself in and out of the foreground as needed when a call is in progress and access the audio stream without hitting Android 12+'s background microphone access limitations. It also does not require the service to be manually started from an `ACTION_BOOT_COMPLETED` broadcast receiver and thus is not affected by that broadcast's delays during initial boot.\n\n* `CAPTURE_AUDIO_OUTPUT`\n\n    This permission is used to record from the `VOICE_CALL` audio stream. This stream, along with some others, like `VOICE_DOWNLINK` and `VOICE_UPLINK`, cannot be accessed without this system permission.\n\nWith these two permissions, BCR can reliably detect phone calls and record from the call's audio stream. The recording process pulls PCM s16le raw audio and uses Android's built-in encoders to produce the compressed output file.\n\n## Verifying digital signatures\n\nBoth the zip file and the APK contained within are digitally signed. **NOTE**: The zip file signing mechanism switched from GPG to SSH as of version 1.31. To verify signatures for old versions, see version 1.30's [`README.md`](https:\u002F\u002Fgithub.com\u002Fchenxiaolong\u002FBCR\u002Fblob\u002Fv1.30\u002FREADME.md#verifying-digital-signatures).\n\n### Verifying zip file signature\n\nTo verify the digital signatures of the downloads, follow [the steps here](https:\u002F\u002Fgithub.com\u002Fchenxiaolong\u002Fchenxiaolong\u002Fblob\u002Fmaster\u002FVERIFY_SSH_SIGNATURES.md).\n\n### Verifying apk signature\n\nFirst, extract the apk from the zip and then run:\n\n```\napksigner verify --print-certs system\u002Fpriv-app\u002Fcom.chiller3.bcr\u002Fapp-release.apk\n```\n\nThen, check that the SHA-256 digest of the APK signing certificate is:\n\n```\nd16f9b375df668c58ef4bb855eae959713d6d02e45f7f2c05ce2c27ae944f4f9\n```\n\n## Building from source\n\nBCR can be built like most other Android apps using Android Studio or the gradle command line.\n\nTo build the APK:\n\n```bash\n.\u002Fgradlew assembleDebug\n```\n\nTo build the Magisk module zip (which automatically runs the `assembleDebug` task if needed):\n\n```bash\n.\u002Fgradlew zipDebug\n```\n\nThe output file is written to `app\u002Fbuild\u002Fdistributions\u002Fdebug\u002F`. The APK will be signed with the default autogenerated debug key.\n\nTo create a release build with a specific signing key, set up the following environment variables:\n\n```bash\nexport RELEASE_KEYSTORE=\u002Fpath\u002Fto\u002Fkeystore.jks\nexport RELEASE_KEY_ALIAS=alias_name\n\nread -r -s RELEASE_KEYSTORE_PASSPHRASE\nread -r -s RELEASE_KEY_PASSPHRASE\nexport RELEASE_KEYSTORE_PASSPHRASE\nexport RELEASE_KEY_PASSPHRASE\n```\n\nand then build the release zip:\n\n```bash\n.\u002Fgradlew zipRelease\n```\n\n## Contributing\n\nBug fix and translation pull requests are welcome and much appreciated!\n\nIf you are interested in implementing a new feature and would like to see it included in BCR, please open an issue to discuss it first. I intend for BCR to be as simple and low-maintenance as possible, so I am not too inclined to add any new features, but I could be convinced otherwise.\n\n## License\n\nBCR is licensed under GPL-3.0-only. Please see [`LICENSE`](.\u002FLICENSE) for the full license text.\n","BCR 是一款适用于已root的Android设备或运行定制固件设备的基础通话录音应用。该应用使用Kotlin编写，支持Android 9及以上版本，并能自动在后台记录来电和去电。它提供多种输出格式（如OGG\u002FOpus、M4A\u002FAAC等），满足不同用户需求；同时支持立体声录制（上行和下行通道分离）、直接启动感知功能以及通过Android存储访问框架将录音保存至SD卡或USB设备等功能。此外，BCR还具备快速设置切换及无网络访问权限的特点。此工具特别适合需要对通话内容进行记录存档的个人或企业用户，在确保隐私安全的前提下实现高效管理。","2026-06-17 03:12:24","top_language"]