更新记录

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:支持 ×

原生插件通用使用流程:

  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原生插件配置”->”云端插件“列表中删除该插件重新选择


来电显示悬浮窗插件 Ba-CallerID

简介

Ba-CallerID 是一款定制的来电显示悬浮窗插件,适用于来电时在屏幕上层展示客户信息、历史记录,并支持接听/拒绝操作回调。

  • 支持显示、隐藏、热更新(update
  • 支持来电监听(startListen / stopListen,内置,无需 Ba-CallListener)
  • 支持系统接听/拒接(nativePhoneAction)及手动 answerCall / rejectCall
  • 支持锁屏显示 UniApp 界面(setLockedShow,来电时可亮屏展示 App 页面)
  • 支持自定义位置(上 / 中 / 下)及窗口尺寸、偏移
  • 支持拖动(moveType:1 不可拖动 / 2 任意拖动 / 3 贴边拖动)
  • 支持多实例(tag 区分)
  • 支持申请、判断悬浮窗权限

有建议和需要,请联系 QQ:2579546054

也可关注 博客,实时更新最新插件:

uniapp 常用原生插件大全


快速开始

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=trueshow 时允许系统弹窗授权
  • 无权限时点击按钮或调用 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.vueonLaunch 中注册:

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 相同字段均可传入,仅更新传入的字段,未传字段保持不变。

支持热更新的字段:gravitywidthRatioheightRatioxRatioyRatiomoveTypenamecontentavatarcalluncallemptytotalHinttellistnativePhoneActiontag(用于指定实例)。

更新 list 后,列表区域会自动折叠为「详情记录」摘要栏,需再次点击展开。

startListen 参数

参数名 类型 默认值 说明
requestPermission Boolean true 是否自动申请 READ_PHONE_STATEREAD_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 系统接听/拒接 askPhonePermissionnativePhoneAction=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))

失败时 okfalse,常见原因:未授权 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 第二行文字颜色

注意事项

  1. 悬浮窗权限:Android 6.0+ 需「显示在其他应用上层」,用 isPermission / permission / goPermission 处理。
  2. 来电权限:监听需 READ_PHONE_STATE;建议 askPhonePermission 一次性申请电话相关权限。
  3. 接听/拒接权限:Android 8+ 需「接听和管理通话」;使用系统接听/拒接前务必授权。
  4. Android 10+ 号码限制:广播中 num 可能为空,请显示「未知号码」或走自有识别。
  5. 进程存活startListen 依赖 App 进程,被杀后失效,可配合保活方案。
  6. 重复 show:同 tag 重复 show 会先关旧窗,不会叠加多个悬浮窗。
  7. 头像清空update({ avatar: "" }) 恢复默认头像。
  8. 列表折叠updatelist 时重置为折叠状态。
  9. 平台限制:仅 Android,最低 SDK 19。

推荐测试顺序(Demo)

  1. askPhonePermission → 允许全部电话相关权限
  2. permission → 允许悬浮窗
  3. startListen → 开始监听
  4. 打开 Demo 页「系统接听/拒接」开关 → show
  5. 真机来电测试;或手动点 answerCall / rejectCall

系列插件

图片选择插件 Ba-MediaPicker文档

图片编辑插件 Ba-ImageEditor文档

文件选择插件 Ba-FilePicker文档

应用消息通知插件(多种样式,新增支持常驻通知模式) Ba-Notify文档

自定义通知(耳机电量)插件 Ba-NotifyEarphone文档

应用未读角标插件 Ba-Shortcut-Badge文档

应用开机自启插件 Ba-Autoboot文档

扫码原生插件(毫秒级、支持多码)Ba-Scanner-G文档

扫码原生插件 - 新(可任意自定义界面版本;支持连续扫码;支持设置扫码格式)Ba-Scanner文档

动态修改状态栏、导航栏背景色、字体颜色插件 Ba-AppBar文档

原生sqlite本地数据库管理 Ba-Sqlite文档

安卓保活插件(采用多种主流技术) Ba-KeepAlive文档

安卓保活套装(通用、常驻通知、电池优化、自启管理、后台运行等)文档

安卓快捷方式(桌面长按app图标) Ba-Shortcut文档

自定义图片水印(任意位置) Ba-Watermark文档

最接近微信的图片压缩插件 Ba-ImageCompressor文档

视频压缩、视频剪辑插件 Ba-VideoCompressor文档

动态切换应用图标、名称(如新年、国庆等) Ba-ChangeIcon文档

原生Toast弹窗提示(穿透所有界面、穿透原生;自定义颜色、图标 ) Ba-Toast文档

图片涂鸦、画笔 Ba-ImagePaint文档

pdf阅读(手势缩放、显示页数) Ba-Pdf文档

声音提示、震动提示、语音播报 Ba-Beep文档

websocket原生服务(自动重连、心跳检测) Ba-Websocket文档

短信监听(验证码) Ba-Sms文档

智能安装(自动升级) Ba-SmartUpgrade文档

监听系统广播、自定义广播 Ba-Broadcast文档

监听通知栏消息(支持白名单、黑名单、过滤) Ba-NotifyListener文档

全局置灰、哀悼置灰(可动态、同时支持nvue、vue) Ba-Gray文档

获取设备唯一标识(OAID、AAID、IMEI等) Ba-IdCode文档

实时定位(系统、后台运行、支持息屏)插件 Ba-Location文档

实时定位(高德、后台运行、支持息屏、坐标转换、距离计算) Ba-LocationAMap文档

窗口小工具、桌面小部件、微件 Ba-AppWidget文档

窗口小工具、桌面小部件、微件(日历、时间) Ba-AwCalendarS文档

画中画悬浮窗(视频) Ba-VideoPip文档

悬浮窗(在其他应用上层显示) Ba-FloatWindow文档

悬浮窗(应用内、无需授权) Ba-FloatWindow2文档

悬浮窗(悬浮球、动态菜单、在其他应用上层显示) Ba-FloatBall文档

添加到“用其他应用打开”中,用于文件传递、分享等 Ba-ShareReceive文档

获取地图数据(高德、地理编码、反地理编码) Ba-AMapData文档

隐私、权限声明

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

android.permission.SYSTEM_ALERT_WINDOW android.permission.READ_CALL_LOG android.permission.ANSWER_PHONE_CALLS

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

插件不采集任何数据

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