更新记录

1.0.3(2026-08-25)

优化录音文件获取方式

1.0.2(2026-08-24)

优化示例项目

1.0.1(2026-08-24)

修复已知问题

查看更多

平台兼容性

uni-app(4.76)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android Android插件版本 iOS 鸿蒙
- - × × × × 5.0 1.0.3 × ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × - × ×

uni-app x(4.76)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - - - - -

x-CallAutoRecord

安卓电话监听 · 通话记录 · 通话录音文件获取 UTS 原生插件

基于 uni-app UTS 实现的 Android 原生插件,提供电话状态监听、通话自动录音检测、通话记录读取、通话录音文件扫描与按时间匹配等能力。适用于需要在 App 内获取通话相关信息、自动定位并上传通话录音文件的业务场景。

  • 插件 ID:x-CallAutoRecord
  • 当前版本:1.0.2
  • 支持平台:仅 Android(minSdkVersion 21 / Android 5.0+),不支持 iOS / HarmonyOS / 小程序 / Web
  • 开发环境:HBuilderX 4.76+

目录结构

x-CallAutoRecord/
├── package.json                 # 插件元信息、权限声明、平台支持
├── changelog.md                 # 版本记录
├── README.md                    # 本文件
└── utssdk/
    ├── interface.uts            # 导出方法的类型定义(参数 / 返回值 / 回调)
    └── app-android/
        ├── index.uts            # Android 实现入口,导出全部方法
        ├── utils.uts            # 辅助函数(Settings 读取 / su 执行 / 录音目录扫描 / 时间格式化)
        └── config.json          # abi、minSdkVersion 等原生配置

权限要求

插件在 package.jsondcloudext.declaration.permissions 中声明了以下权限,需在 AndroidManifest.xml(或 HBuilderX 的 manifest 配置)中确认已包含:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

关于"所有文件访问"权限:读取一加氢OS 等写入 Android/data/ 私有目录的通话录音时,普通存储权限读不到,需引导用户授予 MANAGE_EXTERNAL_STORAGE(所有文件访问)。可先用 isExternalStorageManager 检测、用 openExternalStorageSetting 跳转授权页。


引入插件

// 在页面 / 逻辑文件中按插件路径引入
import * as XCallAutoRecord from "@/uni_modules/x-CallAutoRecord";

// 示例:检测"所有文件访问"权限
XCallAutoRecord.isExternalStorageManager((res) => {
  console.log("是否有所有文件访问权限", res.result);
});

API 一览

所有方法均为异步回调风格(callback 可选)。下表为方法签名与返回值说明。

方法 说明 关键参数 回调返回值
isExternalStorageManager(cb?) 是否有"所有文件访问"权限(Android 11+ 才有,以下恒为 true { result: boolean }
openExternalStorageSetting(cb?) 跳转系统设置页申请"所有文件访问"权限 { result: boolean }
CallState(cb?) 开始监听电话状态(持续回调,见下) { callState: string, incomingNumber: string }
stopCallState(cb?) 停止电话状态监听 { result: boolean }
checkAutoRecord(cb?) 检测系统通话自动录音是否开启 { result: boolean }
getSettingInfo(cb?) 读取系统 Settings(排查各厂商录音设置 key) { global, secure, system: SettingItem[] }
openAutoRecordSetting(cb?) 跳转拨号键盘页(不直接处理厂商设置链路) { result: boolean }
getAllRecordFileInfos(opts?, cb?) 获取全部通话录音文件信息 addSearchDirectorys?: string[] { fileInfos: RecordFileInfo[], directorys: string[] }
getCallHistory(opts?, cb?) 获取通话记录 selection?, sortOrder? { result: CallHistoryItem[] }
getRecordFileInfo(opts?, cb?) 按生成时间筛选单个录音文件 time?, interval?, addSearchDirectorys? { fileInfo: RecordFileInfo \| null, directorys: string[] }

方法详解

1. 电话状态监听

// 开始监听(持续回调 ringing / offhook / idle)
XCallAutoRecord.CallState((res) => {
  // res.callState: "ringing" | "offhook" | "idle"
  // res.incomingNumber: 来电号码(无则为空字符串)
  console.log(JSON.stringify(res));
});

// 停止监听
XCallAutoRecord.stopCallState((res) => {
  console.log("停止监听", res.result);
});

CallState 使用 @UTSJS.keepAlive 装饰(HBuilderX 4.27+ 支持),避免重复点击叠加多个监听器导致重复回调与内存泄漏。如需更换回调,请先调用 stopCallState 再重新 CallState

2. 自动录音检测与设置跳转

XCallAutoRecord.checkAutoRecord((res) => {
  console.log("通话自动录音是否开启", res.result);
});

XCallAutoRecord.openAutoRecordSetting((res) => {
  console.log("跳转结果", res.result);
});

// 各厂商自动录音的 Settings key 不同,可用 getSettingInfo 排查
XCallAutoRecord.getSettingInfo((res) => {
  console.log("Global", res.global, "Secure", res.secure, "System", res.system);
});

3. 获取全部录音文件

const dic = {
  // 可选:补充某机型专属的通话录音目录(相对外部存储根目录)
  addSearchDirectorys: ["MIUI/sound_recorder/call_rec"]
};
XCallAutoRecord.getAllRecordFileInfos(dic, (res) => {
  // res.fileInfos: 录音文件数组
  // res.directorys: 实际搜索过的目录路径数组
  console.log(JSON.stringify(res));
});

内置已覆盖小米 / 华为 / OPPO / vivo / 一加等常见通话录音目录。addSearchDirectorys 与内置目录合并时会按相对路径去重,重复路径不会重复扫描。

4. 按时间匹配单个录音文件

const dic = {
  time: "2026-08-24 10:38:05", // 录音生成的大概时间
  interval: 5,                  // 与 time 的容差(秒),默认 1
  addSearchDirectorys: []
};
XCallAutoRecord.getRecordFileInfo(dic, (res) => {
  // res.fileInfo: 匹配到的最接近文件,未找到为 null
  console.log(JSON.stringify(res));
});

5. 获取通话记录

const dic = {
  selection: "duration > 0",   // 可选,类似 SQL where
  sortOrder: "date DESC"       // 可选,排序
};
XCallAutoRecord.getCallHistory(dic, (res) => {
  // res.result: 通话记录数组
  console.log(JSON.stringify(res));
});

数据类型

RecordFileInfo — 录音文件信息

字段 类型 说明
absolutePath string 文件绝对路径
lastModDate string 最近修改时间(毫秒时间戳,字符串形式)
name string 文件名称

CallHistoryItem — 通话记录

字段 类型 说明
type number 呼叫类型:1=来电 2=已拨 3=未接
display_name string 联系人显示名(无则空串)
name string 联系人名称(同 display_name)
number string 电话号码
duration number 通话时长(秒)
date string 通话日期,格式 yyyy-MM-dd HH:mm:ss

SettingItem — 系统设置项

字段 类型 说明
name string 设置项 key 名
value string 设置项当前值

注意事项

  1. 平台限制:仅 Android 可用,iOS / HarmonyOS / 小程序 / Web 调用无效。
  2. 私有目录需特殊权限:一加氢OS / OxygenOS 的通话录音位于 Android/data/<拨号包名>/files/Record/PhoneRecord/... 私有目录(常见如 Android/data/com.oneplus.communication.data/...)。普通权限读不到,需"所有文件访问"权限;插件内部对 Android/data/ 前缀目录会自动走 su(root)兜底,无 root 时该部分返回空。
  3. 厂商碎片化:自动录音开关的 Settings key 各厂商不一致,建议先用 getSettingInfo 排查目标机型真实 key,再决定是否补充适配。安卓厂商设置链路碎片化严重,本插件 openAutoRecordSetting 仅跳转拨号键盘页,不深入各厂商设置页。
  4. 监听去重CallState 已做防叠加保护,更换回调前请先 stopCallState
  5. 目录去重addSearchDirectorys 与内置目录合并时按相对路径去重,无需担心重复。

调试

仓库内置示例调试页 pages/plugin-debug/plugin-debug.vue,包含上述每个方法的调用按钮与日志输出,可直接运行自定义基座验证各能力。


版本记录

changelog.md

隐私、权限声明

1. 本插件需要申请的系统权限列表:

<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: