更新记录
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 - 14.0 | armeabi-v7a:支持,arm64-v8a:支持,x86:支持 | × |
原生插件通用使用流程:
- 购买插件,选择该插件绑定的项目。
- 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
- 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
- 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
- 开发完毕后正式云打包
付费原生插件目前不支持离线打包。
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>