更新记录
1.2(2026-06-26)
关闭方法优化(hide)
1.1(2026-06-22)
- 支持监听来电事件
- 支持接听和挂断来电
- 支持监听关闭事件
1.0(2023-04-23)
init,来电显示悬浮窗
查看更多平台兼容性
| 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原生插件配置”->”云端插件“列表中删除该插件重新选择
来电显示悬浮窗插件 Ba-CallerID
简介
Ba-CallerID 是一款定制的来电显示悬浮窗插件,适用于来电时在屏幕上层展示客户信息、历史记录,并支持接听/拒绝操作回调。
- 支持显示、隐藏、热更新(
update) - 支持来电监听(
startListen/stopListen,内置,无需 Ba-CallListener) - 支持系统接听/拒接(
nativePhoneAction)及手动answerCall/rejectCall - 支持锁屏显示 UniApp 界面(
setLockedShow,来电时可亮屏展示 App 页面) - 支持自定义位置(上 / 中 / 下)及窗口尺寸、偏移
- 支持拖动(
moveType:1 不可拖动 / 2 任意拖动 / 3 贴边拖动) - 支持多实例(
tag区分) - 支持申请、判断悬浮窗权限
有建议和需要,请联系 QQ:2579546054
也可关注 博客,实时更新最新插件:
快速开始
在 script 中引入插件:
const callerID = uni.requireNativePlugin('Ba-CallerID')
显示悬浮窗:
callerID.show({
gravity: 0, // 0 中间 1 上 2 下
name: "三杯五岳",
content: "VIP 客户 · 到期日 D-29",
tel: "010-0100-7530",
avatar: "https://example.com/avatar.jpg",
totalHint: "详情记录(2)",
list: [{
iconText: "张",
title1: "张三",
title2: "河北某宝公司",
date: "2023-4-19",
time: "22:10:21",
iconColor: "#A71F21",
title1Color: "#6B646B",
title2Color: "#333333",
}]
}, (res) => {
console.log(res) // { ok: true, msg: "success" }
})
隐藏悬浮窗:
callerID.hide({}, (res) => {
console.log(res)
})
典型场景:来电监听 + 悬浮窗
来电显示推荐流程:startListen 监听 → 查业务数据 → show/update 悬浮窗 → 挂断 hide。
// App.vue onLaunch
const callerID = uni.requireNativePlugin('Ba-CallerID')
const globalEvent = uni.requireNativePlugin('globalEvent')
// 1. 允许 UniApp 界面在锁屏上显示 + 开始监听来电
callerID.setLockedShow({ show: true })
callerID.startListen({
requestPermission: true, // 自动申请 READ_PHONE_STATE 等权限
autoShow: false, // true 则来电时原生自动 show(可配 showOptions)
autoHide: false, // true 则挂断时原生自动 hide
})
// 2. 监听来电事件
globalEvent.addEventListener('baCallerIdPhoneEvent', (e) => {
const { state, num } = e
// state: RINGING 响铃 / OFFHOOK 接听 / IDLE 挂断
if (state === 'RINGING') {
callerID.show({
name: num || '未知号码',
tel: num,
totalHint: '查询中...',
list: []
})
queryCustomer(num).then(data => {
callerID.update({
name: data.name,
content: data.remark,
avatar: data.avatar,
totalHint: `详情记录(${data.list.length})`,
list: data.list
})
})
} else if (state === 'IDLE') {
callerID.hide({})
}
})
// 3. 监听悬浮窗按钮点击
globalEvent.addEventListener('baCallerIdEvent', (e) => {
if (e.tag === 'call') {
// 方式 A:show 时 nativePhoneAction: true,原生自动接听
// 方式 B:手动调用
// callerID.answerCall()
}
if (e.tag === 'uncall') {
// callerID.rejectCall()
}
if (e.tag === 'close') { callerID.hide({}) }
})
一键自动模式(原生侧自动 show/hide,JS 只负责 update enrich):
callerID.startListen({
autoShow: true,
autoHide: true,
showOptions: {
gravity: 1,
nativePhoneAction: true, // 可选:自动弹窗时启用系统接听/拒接
call: '接听',
uncall: '拒绝',
empty: '无记录',
list: []
}
})
// 来电后自动弹出,可用 update 补充 CRM 数据
globalEvent.addEventListener('baCallerIdPhoneEvent', (e) => {
if (e.state === 'RINGING' && e.num) {
queryCustomer(e.num).then(data => callerID.update({ ...data }))
}
})
兼容旧事件名
baCallListenerEvent,参数相同{ state, num }。Android 10+ 部分机型广播中无法获取来电号码(
num可能为空),需结合业务号码识别方案。监听依赖 App 进程存活,后台被杀后需配合保活插件或引导用户加白名单。
update必须在show成功显示后调用;仅更新传入的字段,未传字段保持原值。
系统接听/拒接(nativePhoneAction)
悬浮窗上的「接听」「拒绝」按钮,默认只上报 baCallerIdEvent,不会操作系统电话。开启 nativePhoneAction 后,点击按钮会额外调用系统 API 接听/拒接。
| 模式 | 配置 | 行为 |
|---|---|---|
| 仅事件回调 | nativePhoneAction: false(默认) |
点击按钮 → 触发 baCallerIdEvent,由 JS 自行处理 |
| 系统接听/拒接 | nativePhoneAction: true |
点击按钮 → 触发事件 + 调用 TelecomManager 接听/拒接 |
| 手动 API | 事件中调用 | answerCall() / rejectCall(),不依赖按钮参数 |
// 方式一:show 时开启
callerID.show({
nativePhoneAction: true,
name: '张三',
tel: '13800138000',
list: []
})
// 方式二:悬浮窗已显示时动态切换
callerID.update({ nativePhoneAction: true })
// 方式三:仅事件回调,手动接听/拒接
globalEvent.addEventListener('baCallerIdEvent', (e) => {
if (e.tag === 'call') callerID.answerCall()
if (e.tag === 'uncall') callerID.rejectCall()
})
权限说明:
- Android 8+ 需要
**ANSWER_PHONE_CALLS**(「接听和管理通话」)运行时权限 - 请先调用
**askPhonePermission**,或在nativePhoneAction=true的show时允许系统弹窗授权 - 无权限时点击按钮或调用 API 会先弹出授权,授权后需再次点击
- 部分厂商 ROM / 非默认拨号器场景可能仍无法接听拒接,请以真机为准
完整示例
const callerID = uni.requireNativePlugin('Ba-CallerID')
export default {
data() {
return {
nativePhoneAction: false // 统一控制是否系统接听/拒接
}
},
methods: {
// 显示
showFW(gravity) {
callerID.show({
gravity: gravity,
nativePhoneAction: this.nativePhoneAction,
// tag: 'main',
// widthRatio: 1,
// heightRatio: 0.6,
// moveType: 1,
// isPermission: true,
name: '三杯五岳',
content: '生活的梦,永远不止如此!',
call: '接听电话',
uncall: '拒绝电话',
empty: '无记录',
avatar: 'https://example.com/avatar.jpg',
totalHint: '详情记录(6)',
tel: '010-0100-7530',
list: [/* 见 list 参数表 */]
}, (res) => console.log(res))
},
// 动态切换系统接听/拒接(弹窗已显示时立即生效)
toggleNativePhoneAction(enabled) {
this.nativePhoneAction = enabled
callerID.update({ nativePhoneAction: enabled }, (res) => console.log(res))
},
// 热更新
updateFW() {
callerID.update({
nativePhoneAction: this.nativePhoneAction,
name: '三杯五岳(已更新)',
content: '热更新内容',
totalHint: '详情记录(2)',
tel: '010-0100-9999',
list: [/* ... */]
}, (res) => console.log(res))
},
hideFW() {
callerID.hide({}, (res) => console.log(res))
},
// 系统接听 / 拒接(也可在 baCallerIdEvent 中调用)
answerCallFW() {
callerID.answerCall((res) => console.log(res))
},
rejectCallFW() {
callerID.rejectCall((res) => console.log(res))
},
setLockedShow(show) {
callerID.setLockedShow({ show }, (res) => console.log(res))
},
permissionFW() {
callerID.permission((res) => console.log(res))
},
goPermissionFW() {
callerID.goPermission((res) => console.log(res))
},
isPermissionFW() {
callerID.isPermission((res) => console.log(res.data))
},
startListenFW() {
callerID.startListen({
requestPermission: true,
autoShow: false,
autoHide: false,
}, (res) => console.log(res))
},
stopListenFW() {
callerID.stopListen((res) => console.log(res))
},
askPhonePermissionFW() {
callerID.askPhonePermission((res) => console.log(res))
},
isPhonePermissionFW() {
callerID.isPhonePermission((res) => console.log(res.data))
},
}
}
点击事件监听
悬浮窗按钮事件 baCallerIdEvent
在 App.vue 的 onLaunch 中注册:
onLaunch() {
const globalEvent = uni.requireNativePlugin('globalEvent')
globalEvent.addEventListener('baCallerIdEvent', (e) => {
console.log('baCallerIdEvent:' + JSON.stringify(e))
switch (e.tag) {
case 'call': // 点击接听
break
case 'uncall': // 点击拒绝
break
case 'close': // 点击关闭
break
}
})
}
| 属性名 | 说明 |
|---|---|
| action | 事件类型,固定为 onClick |
| tag | 按钮标识:call 接听 / uncall 拒绝 / close 关闭 |
无论
nativePhoneAction是否为true,按钮点击都会触发此事件。nativePhoneAction=true时在事件之外还会调用系统接听/拒接。
来电状态事件 baCallerIdPhoneEvent
调用 startListen 后,来电状态变化时触发(兼容旧名 baCallListenerEvent):
globalEvent.addEventListener('baCallerIdPhoneEvent', (e) => {
console.log(e.state, e.num)
})
| 属性名 | 说明 |
|---|---|
| state | RINGING 响铃 / OFFHOOK 接听 / IDLE 挂断 |
| num | 来电号码,Android 10+ 部分机型可能为空字符串 |
示例:
{"state":"RINGING","num":"13800138000"}
{"state":"OFFHOOK","num":"13800138000"}
{"state":"IDLE","num":""}
API 列表
| 方法名 | 说明 |
|---|---|
| show | 显示来电悬浮窗 |
| update | 热更新已显示的悬浮窗数据 |
| hide | 隐藏悬浮窗 |
| answerCall | 接听当前响铃来电 |
| rejectCall | 拒接响铃或结束当前通话 |
| startListen | 开始监听来电 |
| stopListen | 停止监听来电 |
| askPhonePermission | 申请来电相关权限 |
| isPhonePermission | 查询来电相关权限 |
| setLockedShow | 设置 UniApp Activity 是否可在锁屏上显示 |
| permission | 申请悬浮窗权限 |
| goPermission | 跳转系统悬浮窗权限设置页 |
| isPermission | 查询是否已有悬浮窗权限 |
统一回调格式
所有 API 回调均返回:
{ "ok": true, "msg": "success" }
失败时:
{ "ok": false, "msg": "show error" }
isPermission 额外返回 data:
{ "ok": true, "msg": "success", "data": { "isPermission": true } }
update 在悬浮窗未显示时:
{ "ok": false, "msg": "update error: caller id not shown" }
show 参数
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| tag | String | — | 实例标识,多实例时使用 |
| gravity | Number | 0 | 显示位置:0 中间 / 1 上 / 2 下 |
| widthRatio | Number | 1 | 窗口宽度占屏幕比例 |
| heightRatio | Number | 0.6 | 窗口高度占屏幕比例 |
| xRatio | Number | 0 | 水平偏移占屏幕宽度比例 |
| yRatio | Number | — | 垂直偏移占屏幕高度比例(设置 gravity 时被覆盖) |
| moveType | Number | 1 | 1 不可拖动 / 2 任意拖动 / 3 贴边拖动 |
| isPermission | Boolean | true | 是否先申请悬浮窗权限再显示 |
| name | String | — | 来电姓名/标题 |
| content | String | — | 副标题/描述 |
| avatar | String | — | 头像 URL |
| call | String | 接听电话 | 接听按钮文字 |
| uncall | String | 拒绝电话 | 拒绝按钮文字 |
| empty | String | 无记录 | 无历史记录时的提示文字 |
| totalHint | String | — | 详情记录栏标题,如 详情记录(6) |
| tel | String | — | 电话号码 |
| list | Array | [] | 历史记录列表,见下表 |
| nativePhoneAction | Boolean | false | 为 true 时,点击接听/拒绝会调用系统接听/拒接(需 ANSWER_PHONE_CALLS) |
nativePhoneAction=true时:show会在悬浮窗权限通过后尝试申请ANSWER_PHONE_CALLS;仍可通过update({ nativePhoneAction: false })关闭。也可保持
nativePhoneAction=false,在baCallerIdEvent中手动调用answerCall()/rejectCall()。
update 参数
与 show 相同字段均可传入,仅更新传入的字段,未传字段保持不变。
支持热更新的字段:gravity、widthRatio、heightRatio、xRatio、yRatio、moveType、name、content、avatar、call、uncall、empty、totalHint、tel、list、nativePhoneAction、tag(用于指定实例)。
更新
list后,列表区域会自动折叠为「详情记录」摘要栏,需再次点击展开。
startListen 参数
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| requestPermission | Boolean | true | 是否自动申请 READ_PHONE_STATE、READ_CALL_LOG |
| autoShow | Boolean | false | 响铃时是否自动调用 show |
| autoHide | Boolean | false | 挂断(IDLE)时是否自动调用 hide |
| showOptions | Object | — | autoShow=true 时的 show 参数模板,name/tel 默认填充为来电号码 |
askPhonePermission / isPhonePermission
申请或查询以下权限:
| 权限 | 用途 | 申请方式 |
|---|---|---|
| READ_PHONE_STATE | 监听电话状态 | askPhonePermission / startListen |
| READ_CALL_LOG | Android 9 及以下辅助获取来电号码 | 同上 |
| ANSWER_PHONE_CALLS | 系统接听/拒接 | askPhonePermission 或 nativePhoneAction=true 的 show |
isPhonePermission 返回:
{
"ok": true,
"data": {
"phoneState": true,
"callLog": true,
"answerPhone": true,
"answerPhoneRequired": true,
"allGranted": true
}
}
| 字段 | 说明 |
|---|---|
| phoneState | 是否已有 READ_PHONE_STATE |
| callLog | 是否已有 READ_CALL_LOG |
| answerPhone | 是否满足接听/拒接权限(Android 8 以下设备恒为 true) |
| answerPhoneRequired | 当前设备是否需要 ANSWER_PHONE_CALLS(Android 8+ 为 true) |
| allGranted | 以上权限是否均已满足 |
answerCall / rejectCall
手动接听或拒接,不依赖 nativePhoneAction。无权限时会先弹出 ANSWER_PHONE_CALLS 授权。
| 方法 | 系统要求 | 说明 |
|---|---|---|
| answerCall | Android 8+ | 接听当前响铃 |
| rejectCall | Android 9+ | 拒接响铃或结束通话 |
callerID.answerCall((res) => console.log(res.ok, res.msg))
callerID.rejectCall((res) => console.log(res.ok, res.msg))
失败时 ok 为 false,常见原因:未授权 ANSWER_PHONE_CALLS、当前无响铃来电、厂商限制。
hide 参数
| 参数名 | 类型 | 说明 |
|---|---|---|
| tag | String | 可选,指定要隐藏的实例;不传则隐藏默认实例 |
调用时必须传入第一个参数对象(可为空 {}),再传回调,例如 callerID.hide({}, callback)。不可只传 callback,否则 Weex 桥接会类型转换失败。
setLockedShow 参数
控制 UniApp 主界面(Activity) 在设备锁屏状态下是否可见,对应系统 API Activity.setShowWhenLocked()。
| 参数名 | 类型 | 说明 |
|---|---|---|
| show | Boolean | true 锁屏时仍可显示 UniApp 界面 / false 恢复默认(锁屏不显示) |
与悬浮窗无关:来电悬浮窗(
show)已单独配置锁屏相关 Window Flag,即使不调用setLockedShow也可能在锁屏上弹出。
若来电时需要 点亮屏幕并展示 UniApp 页面(例如全屏来电页),请在 App 启动时调用setLockedShow({ show: true })。
list 列表项参数
| 参数名 | 类型 | 说明 |
|---|---|---|
| iconText | String | 图标内文字(通常为姓氏) |
| title1 | String | 第一行标题 |
| title2 | String | 第二行标题(加粗) |
| date | String | 日期 |
| time | String | 时间 |
| type | Number | 0 圆形图标(默认)/ 1 方形边框 |
| iconColor | String | 图标背景色,如 #A71F21 |
| iconTextColor | String | 图标文字颜色 |
| title1Color | String | 第一行文字颜色 |
| title2Color | String | 第二行文字颜色 |
注意事项
- 悬浮窗权限:Android 6.0+ 需「显示在其他应用上层」,用
isPermission/permission/goPermission处理。 - 来电权限:监听需
READ_PHONE_STATE;建议askPhonePermission一次性申请电话相关权限。 - 接听/拒接权限:Android 8+ 需「接听和管理通话」;使用系统接听/拒接前务必授权。
- Android 10+ 号码限制:广播中
num可能为空,请显示「未知号码」或走自有识别。 - 进程存活:
startListen依赖 App 进程,被杀后失效,可配合保活方案。 - 重复 show:同
tag重复 show 会先关旧窗,不会叠加多个悬浮窗。 - 头像清空:
update({ avatar: "" })恢复默认头像。 - 列表折叠:
update含list时重置为折叠状态。 - 平台限制:仅 Android,最低 SDK 19。
推荐测试顺序(Demo)
askPhonePermission→ 允许全部电话相关权限permission→ 允许悬浮窗startListen→ 开始监听- 打开 Demo 页「系统接听/拒接」开关 →
show - 真机来电测试;或手动点
answerCall/rejectCall
系列插件
应用消息通知插件(多种样式,新增支持常驻通知模式) Ba-Notify(文档)
自定义通知(耳机电量)插件 Ba-NotifyEarphone(文档)
应用未读角标插件 Ba-Shortcut-Badge (文档)
扫码原生插件(毫秒级、支持多码)Ba-Scanner-G(文档)
扫码原生插件 - 新(可任意自定义界面版本;支持连续扫码;支持设置扫码格式)Ba-Scanner(文档)
动态修改状态栏、导航栏背景色、字体颜色插件 Ba-AppBar(文档)
安卓保活插件(采用多种主流技术) Ba-KeepAlive(文档)
安卓保活套装(通用、常驻通知、电池优化、自启管理、后台运行等)(文档)
安卓快捷方式(桌面长按app图标) Ba-Shortcut(文档)
自定义图片水印(任意位置) Ba-Watermark(文档)
最接近微信的图片压缩插件 Ba-ImageCompressor(文档)
视频压缩、视频剪辑插件 Ba-VideoCompressor(文档)
动态切换应用图标、名称(如新年、国庆等) Ba-ChangeIcon(文档)
原生Toast弹窗提示(穿透所有界面、穿透原生;自定义颜色、图标 ) Ba-Toast(文档)
websocket原生服务(自动重连、心跳检测) Ba-Websocket(文档)
智能安装(自动升级) Ba-SmartUpgrade(文档)
监听通知栏消息(支持白名单、黑名单、过滤) Ba-NotifyListener(文档)
全局置灰、哀悼置灰(可动态、同时支持nvue、vue) Ba-Gray(文档)
获取设备唯一标识(OAID、AAID、IMEI等) Ba-IdCode(文档)
实时定位(系统、后台运行、支持息屏)插件 Ba-Location(文档)
实时定位(高德、后台运行、支持息屏、坐标转换、距离计算) Ba-LocationAMap(文档)
窗口小工具、桌面小部件、微件 Ba-AppWidget(文档)
窗口小工具、桌面小部件、微件(日历、时间) Ba-AwCalendarS(文档)
悬浮窗(在其他应用上层显示) Ba-FloatWindow(文档)
悬浮窗(应用内、无需授权) Ba-FloatWindow2(文档)
悬浮窗(悬浮球、动态菜单、在其他应用上层显示) Ba-FloatBall(文档)

收藏人数:
购买(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 14456
赞赏 6
下载 13387
赞赏 1
赞赏
京公网安备:11010802035340号