更新记录

1.3.0(2023-11-12)

本次主要更新: 1.新增 getSettingInfo获取系统应用设置的相关字段,主要用来判断是否开启通话录音权限

1.2.0(2023-07-25)

本次主要更新: 1.增加 设置搜索扩展名 方法 2.getCallHistory,获取通话记录 优化和增加参数

1.1.0(2023-03-30)

本次主要更新: 1.增加搜索通话录音的路径参数 2.获取通话记录方法 增加 搜索条件和排序方式 参数

查看更多

平台兼容性

Android Android CPU类型 iOS
适用版本区间:4.4 - 12.0 armeabi-v7a:支持,arm64-v8a:支持,x86:支持 ×

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios

注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择


KJ-CallAutoRecord

通话状态监听、通话录音文件获取、自带通话自动录音、通话记录获取、录音上传

注意

1.Google Play上架需要注意:请求所有文件访问权限,国内使用没有什么影响,但是在Google Play上需要说明为什么已有的SAF或MediaStore不满足你的应用需求,
审核通过才允许上架使用,谷歌市场只允许文件管理app可以申请这个权限。

使用

<template>
    <view class="content">
        <button type="primary" @click="isExternalStorageManager">是否有“所有文件访问”权限</button>
        <button type="primary" @click="openExternalStorageSetting">打开“所有文件访问”设置页面</button>

        <button type="primary" @click="CallState">电话监听状态</button>

        <button type="primary" @click="checkAutoRecord">检查通话自动录音是否开启</button>
        <button type="primary" @click="getSettingInfo">获取手机系统设置信息</button>
        <button type="primary" @click="openAutoRecordSetting">跳转通话自动录音设置页面</button>

        <button type="primary" @click="setSearchExtensions">设置搜索扩展名</button>

        <button type="primary" @click="getAllRecordFileInfos">获取所有录音文件信息</button>
        <button type="primary" @click="getRecordFileInfo2">根据时间筛选录音文件信息</button>

        <button type="primary" @click="getSDAllAudioFileInfos">获取SD卡所有音频文件信息</button>
        <button type="primary" @click="getSDAudioFileInfo2">根据时间筛选SD卡音频文件信息</button>

        <button type="primary" @click="getCallHistory">获取通话记录</button>

    </view>
</template>

<script>
    Date.prototype.Format = function(fmt) {
        var o = {
            "M+": this.getMonth() + 1, //月份 
            "d+": this.getDate(), //日 
            "h+": this.getHours(), //小时 
            "m+": this.getMinutes(), //分 
            "s+": this.getSeconds(), //秒 
            "q+": Math.floor((this.getMonth() + 3) / 3), //季度 
            "S": this.getMilliseconds() //毫秒 
        };
        if (/(y+)/.test(fmt))
            fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o) {
            if (new RegExp("(" + k + ")").test(fmt)) {
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k])
                    .length)));
            }
        }
        return fmt;
    }
    const KJCallAutoRecord = uni.requireNativePlugin('KJ-CallAutoRecord');
    export default {
        data() {
            return {
                title: 'Hello'
            }
        },
        onShow() {
            if (plus.os.name == 'Android') {
                plus.android.requestPermissions(
                    ["android.permission.READ_PHONE_STATE", //监听电话状态 需要这个权限
                        "android.permission.READ_CALL_LOG", //获取号码需要这个权限
                        "android.permission.READ_CONTACTS", //获取联系人
                        "android.permission.READ_EXTERNAL_STORAGE" //读取存储卡内容
                    ],
                    (resultObj) => {
                        var result = 0;
                        for (var i = 0; i < resultObj.granted.length; i++) {
                            var grantedPermission = resultObj.granted[i];
                            if (grantedPermission == "android.permission.READ_PHONE_STATE") {
                                this.CallState();
                            }
                            console.log('已获取的权限:' + grantedPermission);
                            result = 1
                        }
                        for (var i = 0; i < resultObj.deniedPresent.length; i++) {
                            var deniedPresentPermission = resultObj.deniedPresent[i];
                            console.log('拒绝本次申请的权限:' + deniedPresentPermission);
                            result = 0
                        }
                        for (var i = 0; i < resultObj.deniedAlways.length; i++) {
                            var deniedAlwaysPermission = resultObj.deniedAlways[i];
                            console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
                            result = -1
                        }
                    },
                    (error) => {
                        console.log('申请权限错误:' + error.code + " = " + error.message);
                    }
                );
                this.isExternalStorageManager();
            }
        },
        methods: {
            CallState() {
                //电话状态监听
                var is_offhook = false;
                KJCallAutoRecord.CallState((res) => {
                    console.log("CallState: " + JSON.stringify(res));
                    console.log("电话号码:" + res.incomingNumber);
                    if (res.callState == "ringing") {
                        console.log("来电");
                    } else if (res.callState == "offhook") { //拨打 和 接听都会回调这个
                        console.log("待机");
                        is_offhook = true;
                    } else if (res.callState == "idle") { //挂断 和 没有任何操作 都会回调这个
                        console.log("没有状态");
                        if (is_offhook == true) {
                            is_offhook = false;
                            //通话结束,执行上传录音文件操作
                            var time = new Date().Format("yyyy-MM-dd hh:mm:ss");
                            console.log("time:" + time);
                            this.getRecordFileInfo(time);
                        }
                    }
                })
            },
            isExternalStorageManager() {
                KJCallAutoRecord.isExternalStorageManager((res) => {
                    console.log("isExternalStorageManager: " + JSON.stringify(res));
                    /**
                     * 返回json说明:{"result":false}
                     * result - 是否有这个权限,andorid11以下会返回true,因为这个权限andorid11才有的
                     * */
                    if (res.result == false) {
                        uni.showModal({
                            title: '提示',
                            content: '没有所有文件访问权限,否则获取不了通话录音,是否前往设置?',
                            success: (res) => {
                                if (res.confirm) {
                                    this.openExternalStorageSetting();
                                } else if (res.cancel) {
                                    console.log('用户点击取消');
                                }
                            }
                        });
                    }
                })
            },
            openExternalStorageSetting() {
                /**
                 * 1.andorid11以下,执行这个方法,不会跳转到权限授权页面,因为这个权限andorid11才有的
                 * 2.如果之前勾选过再取消,应用会重启
                 * */
                KJCallAutoRecord.openExternalStorageSetting((res) => {
                    console.log("openExternalStorageSetting: " + JSON.stringify(res));
                })
            },
            checkAutoRecord() {
                //只测试了小米、华为、vivo、oppo手机,不保证所有手机有效
                KJCallAutoRecord.checkAutoRecord((res) => {
                    console.log("checkAutoRecord:" + JSON.stringify(res))
                });
            },
            getSettingInfo() {
                //根据某个字段判断是否开始通话录音权限,一般是带有 record auto call audio 相关字段
                KJCallAutoRecord.getSettingInfo((res) => {
                    console.log("getSettingInfo:" + JSON.stringify(res))
                    // {
                    //  "global",
                    //  [],
                    //  "secure": [],
                    //  "system": [{
                    //      "name": "button_auto_record_call" //比如小米的字段
                    //  }]
                    // }
                });
                // KJCallAutoRecord.getSystemInt({ //该方法对应的是getSettingInfo方法回调里的"system"字段
                //  "name": "button_auto_record_call" //小米的字段
                // }, (res) => {
                //  console.log("getSystemInt:" + JSON.stringify(res))
                //  if (res.result != 0) {
                //      console.log("通话录音权限已开启")
                //  }
                // });
                // KJCallAutoRecord.getGlobalInt({"name":""},(res) => {//该方法对应的是getSettingInfo方法回调里的"global"字段
                //  console.log("getGlobalInt:" + JSON.stringify(res))
                // });
                // KJCallAutoRecord.getSecureInt({"name":""},(res) => {//该方法对应的是getSettingInfo方法回调里的"secure"字段
                //  console.log("getSecureInt:" + JSON.stringify(res))
                // });
            },
            openAutoRecordSetting() {
                //只测试了小米、华为、vivo、oppo手机,不保证所有手机有效
                KJCallAutoRecord.openAutoRecordSetting();
            },
            setSearchExtensions() {
                KJCallAutoRecord.getSearchExtensions((res) => {
                    console.log("getSearchExtensions:" + JSON.stringify(res))
                })
                /**
                 * 不执行该方法,默认使用以下配置
                 */
                var arr = ["flac", "m4a", "ogg", "ape", "amr", "wma", "wav", "mp3", "aac", "aiff", "caf", "awb"];
                KJCallAutoRecord.setSearchExtensions(arr);

                KJCallAutoRecord.getSearchExtensions((res) => {
                    console.log("getSearchExtensions:" + JSON.stringify(res))
                })
            },
            getAllRecordFileInfos() {
                //只测试了小米、华为、vivo、oppo手机,如果失效,查找该手机的通话路径,然后配置addSearchDirectorys
                var dic = {
                    //"addSearchDirectorys":["MIUI/sound_recorder/call_rec"] //增加搜索通话录音的路径,如果某款手机搜索不到结果,可以在这里加
                }
                KJCallAutoRecord.getAllRecordFileInfos(dic, (res) => {
                    console.log("getAllRecordFileInfos:" + JSON.stringify(res))
                    /**
                     * 返回json字段说明:
                     * fileInfos - 录音文件信息数组
                     * absolutePath - 绝对路径
                     * lastModDate - 最近编辑时间/添加时间
                     * name - 文件名称
                     * directorys - 搜索的路径数组
                     * */
                });
            },
            getRecordFileInfo(time) {
                //只测试了小米、华为、vivo、oppo手机,如果失效,查找该手机的通话路径,然后配置addSearchDirectorys
                var dic = {
                    "time": time, //录音文件生成的大概时间,格式:yyyy-MM-dd hh:mm:ss
                    "interval": 1, //与time的间隔时间,单位:秒
                    //"addSearchDirectorys":["MIUI/sound_recorder/call_rec"] //增加搜索通话录音的路径,如果某款手机搜索不到结果,可以在这里加
                }
                KJCallAutoRecord.getRecordFileInfo(dic, (res) => {
                    console.log("getRecordFileInfo:" + JSON.stringify(res))
                    /**
                     * 返回json字段说明:
                     * fileInfo - 录音文件信息
                     * absolutePath - 绝对路径
                     * lastModDate - 最近编辑时间/添加时间
                     * name - 文件名称
                     * directorys - 搜索的路径数组
                     * */
                    uni.getFileInfo({
                        filePath: res.fileInfo.absolutePath,
                        complete: (res) => {
                            console.log(JSON.stringify(res))
                        }
                    })
                    //执行上传通话录音
                    uni.uploadFile({
                        url: 'https://www.example.com/upload', //仅为示例,非真实的接口地址
                        filePath: res.fileInfo.absolutePath,
                        name: 'file',
                        formData: {
                            'user': 'test'
                        },
                        complete: (uploadFileRes) => {
                            console.log(uploadFileRes.data);
                        }
                    });
                })
            },
            getRecordFileInfo2() {
                this.getRecordFileInfo("2022-03-29 10:56:02")
            },
            getSDAllAudioFileInfos() {
                //全盘搜索,除了Andorid目录和SD首层的录音文件
                KJCallAutoRecord.getSDAllAudioFileInfos((res) => {
                    console.log("getSDAllAudioFileInfos:" + JSON.stringify(res))
                    /**
                     * 返回json字段说明:
                     * fileInfos - 录音文件信息数组
                     * absolutePath - 绝对路径
                     * lastModDate - 最近编辑时间/添加时间
                     * name - 文件名称
                     * directorys - 搜索的路径数组
                     * */
                });
            },
            getSDAudioFileInfo() {
                //全盘搜索,除了Andorid目录和SD首层的录音文件
                var dic = {
                    "time": time, //录音文件生成的大概时间,格式:yyyy-MM-dd hh:mm:ss
                    "interval": 1 //与time的间隔时间,单位:秒
                }
                KJCallAutoRecord.getSDAudioFileInfo(dic, (res) => {
                    console.log("getSDAudioFileInfo:" + JSON.stringify(res))
                    /**
                     * 返回json字段说明:
                     * fileInfo - 录音文件信息
                     * absolutePath - 绝对路径
                     * lastModDate - 最近编辑时间/添加时间
                     * name - 文件名称
                     * directorys - 搜索的路径数组
                     * */

                });
            },
            getSDAudioFileInfo2() {
                this.getSDAudioFileInfo("2022-03-29 10:56:02")
            },
            getCallHistory() {
                var dic = {
                    //"projection": null,//[""]
                    //"selection": "date > " + new Date("2023-05-22 11:01:16").getTime(),
                    //"selection": "duration > 1 AND duration < 3", //搜索条件,捕获有通话录音的记录,类似SQL where
                    "selection": "duration > 0", //搜索条件,捕获有通话录音的记录,类似SQL where
                    //"selectionArgs": null,//[""]
                    "sortOrder": "date DESC" //排序方式
                }
                KJCallAutoRecord.getCallHistory(dic, (res) => {
                    console.log("getCallHistory:" + JSON.stringify(res))
                    /**
                     * 返回json字段说明:{"result":[{"type":1,"display_name":"ykj","name":"ykj","number":"xxxx","duration":17,"date":"2023-03-29 10:38:05"}]};
                     * type - 呼叫类型 1(来电) 2(已拨) 3(未接)
                     * display_name、name - 联系人名称
                     * number - 电话号码
                     * duration - 通话时长
                     * date - 通话记录的日期
                     * */
                    var list = res.result;
                    if (list.length > 0) {
                        this.getRecordFileInfo(list[0].date) //获取最近一条通话的录音
                    }
                });
            }
        }
    }
</script>

隐私、权限声明

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

需要:android.permission.READ_PHONE_STATE、android.permission.READ_CALL_LOG、android.permission.READ_CONTACTS

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

插件不采集任何数据

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

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问