更新记录
1.3.2(2026-10-15)
1、修改ios平台打包报错的问题
1.3.1(2026-10-13)
1、修改了ios平台打基座可能报错的问题
1.3.0(2026-10-12)
1、优化应用后台驻留时的体验
查看更多平台兼容性
uni-app(3.97)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | × | × | √ | √ | 5.0 | √ | 12 |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(3.97)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | 5.0 | √ | 12 | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| × | × | × | √ |
ZG-PhoneCallMonitor
ZG-PhoneCallMonitor 是一个 uni-app UTS 电话能力插件,提供通话事件监听、联系人读写、直接拨号和短信能力。
当前插件包版本:1.3.0
平台支持
| 能力 | Android | HarmonyOS NEXT | iOS |
|---|---|---|---|
| 来电、去电和通话状态监听 | 支持 | 支持 | 不支持 |
| 后台前台服务与开机恢复 | 支持 | 不支持 | 不支持 |
| 无 JS 回调时暂存来电事件 | 支持 | 不支持 | 不支持 |
| 读取、新增联系人 | 支持 | 支持 | 支持 |
| 直接拨号 | 支持 | 不支持 | 支持 |
| 打开短信编辑器 | 支持 | 支持 | 支持 |
| 后台直接发送短信 | 支持 | 支持 | 不支持 |
Android 最低版本为 API 21;HarmonyOS NEXT 最低版本为 API 12。
iOS 系统不允许第三方应用监听系统通话,因此
onPhoneCallEvent和setCallMonitorConfig在 iOS 上不会启动通话监听。联系人、拨号和短信接口仍可使用。
引入插件
import {
requestPermissions,
hasPermissions,
setCallMonitorConfig,
onPhoneCallEvent,
stopMonitoring,
getStatus,
consumePendingPhoneEvents,
openBatteryOptimizationSettings,
openAppDetailsSettings,
getAllContacts,
addContact,
makeCall,
sendSMS
} from '@/uni_modules/ZG-PhoneCallMonitor'
// Vue 3 和后台服务场景推荐使用 PhoneCallMonitor 保活入口。
// #ifdef APP-PLUS
import { PhoneCallMonitor } from '@/uni_modules/ZG-PhoneCallMonitor'
// #endif
修改 Android 原生源码、权限或前台服务后,需要重新制作自定义调试基座或正式包;仅在标准基座中运行,修改后的原生代码不会生效。
Android 权限
插件会自动合并以下 Manifest 权限:
| 权限 | 用途 |
|---|---|
READ_PHONE_STATE |
监听通话状态,必选 |
READ_CALL_LOG |
Android 9+ 获取来电和去电号码,必选 |
READ_CONTACTS |
根据号码解析联系人姓名,可选 |
WRITE_CONTACTS |
将号码写入系统通讯录,可选 |
CALL_PHONE |
使用 makeCall 直接拨号,可选 |
SEND_SMS |
使用 sendSMS({ directSend: true }) 后台发送,可选 |
FOREGROUND_SERVICE |
Android 8.0+ 前台服务,可选 |
FOREGROUND_SERVICE_SPECIAL_USE |
Android 14+ specialUse 前台服务,可选 |
POST_NOTIFICATIONS |
Android 13+ 显示前台服务通知,可选 |
RECEIVE_BOOT_COMPLETED |
开机和应用升级后恢复监听,可选 |
requestPermissions 会请求核心电话权限以及联系人、直接拨号和通知权限。SEND_SMS 属于敏感权限,不在该方法的自动请求列表中;使用后台直接发送短信前,需要由宿主应用单独申请。
Android 的电话权限请求为系统异步流程:
requestPermissions的回调只表示请求已经发起,allGranted不保证是用户最终选择。- 用户完成授权后,应再次调用
hasPermissions()。 hasPermissions()只会检查通话监听最核心的READ_PHONE_STATE和READ_CALL_LOG。
建议在启动页或 App.vue 的 onShow 中重新检查权限,再绑定监听。
快速开始
下面的示例适用于 Android 和 HarmonyOS。通话监听必须在真实设备上测试。
Android 在页面或进程重建后需要重新调用监听入口,以更新当前 JS 回调。HarmonyOS 在同一进程内重复调用 onPhoneCallEvent 会返回“监听已启动”,可先通过 getStatus().isListening 判断。
import { onShow } from '@dcloudio/uni-app'
import {
requestPermissions,
hasPermissions,
setCallMonitorConfig,
onPhoneCallEvent,
stopMonitoring,
consumePendingPhoneEvents
} from '@/uni_modules/ZG-PhoneCallMonitor'
// #ifdef APP-PLUS
import { PhoneCallMonitor } from '@/uni_modules/ZG-PhoneCallMonitor'
// #endif
const MONITOR_CONFIG = {
// Android 推荐开启,应用进入后台或进程被回收后仍可监听。
enableForegroundService: true,
notificationTitle: '来电监听服务',
notificationContent: '正在后台监听电话事件',
resolveContactName: true,
outgoingRetryCount: 3
}
function handlePhoneCallEvent(event) {
console.log('电话事件', event)
switch (event.type) {
case 'ringing':
console.log('来电响铃', event.phoneNumber, event.contactName)
break
case 'dialing':
console.log('去电拨号', event.phoneNumber, event.contactName)
break
case 'answered':
console.log('通话接通', event.phoneNumber, event.direction)
break
case 'hangup':
console.log('通话结束', event.phoneNumber, event.duration)
break
case 'missed':
console.log('未接来电', event.phoneNumber)
break
case 'error':
console.error('监听异常', event.message)
break
}
}
function startPhoneMonitor() {
if (!hasPermissions()) {
console.warn('缺少 READ_PHONE_STATE 或 READ_CALL_LOG 权限')
return { success: false, message: '缺少电话监听权限' }
}
setCallMonitorConfig(MONITOR_CONFIG)
// PhoneCallMonitor 使用 @UTSJS.keepAlive 保存回调,Vue 3 中推荐使用。
// #ifdef APP-PLUS
const result = PhoneCallMonitor.onPhoneCallEvent(handlePhoneCallEvent)
// #endif
// #ifndef APP-PLUS
const result = onPhoneCallEvent(handlePhoneCallEvent)
// #endif
console.log('启动监听结果', result)
return result
}
function requestPhoneMonitorPermission() {
if (hasPermissions()) {
return startPhoneMonitor()
}
requestPermissions((result) => {
console.log('权限请求结果', result)
// HarmonyOS/iOS 会在用户操作完成后回调;
// Android 需要稍后再次调用 hasPermissions() 确认真实结果。
if (result.allGranted || hasPermissions()) {
startPhoneMonitor()
}
})
}
function recoverPendingEvents() {
const raw = consumePendingPhoneEvents()
let events = []
try {
events = JSON.parse(raw || '[]')
} catch (error) {
console.error('待处理电话事件解析失败', error)
return
}
for (const event of events) {
handlePhoneCallEvent(event)
}
}
onShow(() => {
// 页面或进程重建后,需要重新绑定当前 JS 实例的回调。
if (hasPermissions()) {
startPhoneMonitor()
recoverPendingEvents()
}
})
// 用户关闭监听时调用。
function disablePhoneMonitor() {
return stopMonitoring()
}
监听配置
在调用 onPhoneCallEvent 或 PhoneCallMonitor.onPhoneCallEvent 之前调用 setCallMonitorConfig。
setCallMonitorConfig({
enableForegroundService: true,
notificationTitle: '来电监听服务',
notificationContent: '正在后台监听电话事件',
resolveContactName: true,
outgoingRetryCount: 3
})
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enableForegroundService |
boolean |
false |
Android 是否启动前台服务。生产环境建议开启 |
notificationTitle |
string |
电话监听服务 |
Android 前台服务通知标题 |
notificationContent |
string |
正在后台监听电话事件 |
Android 前台服务通知内容 |
resolveContactName |
boolean |
true |
是否根据号码解析联系人姓名 |
outgoingRetryCount |
number |
3 |
获取去电号码失败时的重试次数 |
传入 null 可以恢复默认配置。
电话事件
type PhoneCallEvent = {
type: 'ringing' | 'dialing' | 'answered' | 'hangup' | 'missed' | 'error'
phoneNumber: string
contactName: string | null
direction: 'incoming' | 'outgoing' | ''
duration: number
timestamp: number
message: string | null
}
| 事件 | 触发时机 | 说明 |
|---|---|---|
ringing |
来电响铃 | 方向为 incoming |
dialing |
去电拨号 | 方向为 outgoing |
answered |
来电接听或去电接通 | 方向与当前通话一致 |
hangup |
已接通通话结束 | duration 为通话秒数 |
missed |
来电未接 | 方向为 incoming |
error |
监听启动或运行异常 | message 包含错误信息 |
contactName 仅在获得联系人读取权限并匹配成功时返回;timestamp 使用毫秒时间戳。
API 说明
权限
requestPermissions(callback: (result: PermResult) => void): void
请求当前平台所需权限。Android 请求电话、联系人、直接拨号和通知权限;HarmonyOS 当前仅请求通讯录写入权限;iOS 请求通讯录权限。Android 回调不是最终授权结果,请在授权流程结束后再次调用 hasPermissions()。
type PermResult = {
allGranted: boolean
grantedPermissions: string[]
deniedPermissions: string[]
message: string
}
hasPermissions(): boolean
检查核心权限。Android 检查 READ_PHONE_STATE 和 READ_CALL_LOG;iOS 检查通讯录权限。
监听控制
setCallMonitorConfig(config: CallMonitorConfig | null): void
设置监听配置,应在绑定事件回调之前调用。
onPhoneCallEvent(callback: (event: PhoneCallEvent) => void): OpResult
启动监听或替换当前事件回调。Android 未启用前台服务时,仅在当前页面进程内监听。
PhoneCallMonitor.onPhoneCallEvent(
callback: (event: PhoneCallEvent) => void
): OpResult
PhoneCallMonitor 是推荐的 APP 端入口,内部保留跨 JS 实例回调,可避免 Vue 3 页面重建后旧回调失效。重复调用会更新当前回调,不会重复启动 Android 前台服务。
stopMonitoring(): OpResult
停止监听、停止 Android 前台服务,并清除回调。
type OpResult = {
success: boolean
message: string
}
getStatus(): CallMonitorStatus
获取监听状态。
type CallMonitorStatus = {
isListening: boolean
hasPermissions: boolean
isForegroundServiceRunning: boolean
currentCallState: 'IDLE' | 'RINGING' | 'OFFHOOK' | 'DIALING'
version: string
}
进程恢复与系统设置
consumePendingPhoneEvents(): string
读取并清空 Android 原生服务暂存的电话事件,返回 JSON 数组字符串。
- 只在 JS 回调尚未恢复时暂存事件。
- 当前主要暂存
ringing来电事件,最多保留 50 条。 - 建议在 App 恢复监听后调用。
const events = JSON.parse(consumePendingPhoneEvents() || '[]')
openBatteryOptimizationSettings(): boolean
打开 Android 电池优化设置,仅 Android 有效。
openAppDetailsSettings(): boolean
打开当前应用详情页,便于用户检查自启动、通知和权限设置。
当前仅 Android 有效,HarmonyOS 和 iOS 返回 false。
联系人
getAllContacts(callback: (result: ContactsResult) => void): void
读取系统联系人。Android 需要 READ_CONTACTS,HarmonyOS/iOS 需要通讯录权限。
type ContactInfo = {
id: string
name: string
phones: string
}
type ContactsResult = {
success: boolean
message: string
contacts: ContactInfo[]
total: number
}
多个电话号码在 phones 中以英文逗号分隔。
getAllContacts((result) => {
if (!result.success) {
console.error(result.message)
return
}
console.log(result.contacts)
})
addContact(
name: string,
phoneNumber: string,
callback: (result: OpResult) => void
): void
新增联系人。Android 需要 WRITE_CONTACTS,HarmonyOS/iOS 需要通讯录写入权限。
addContact('张三', '***', (result) => {
console.log(result.success, result.message)
})
拨号
makeCall(phoneNumber: string): OpResult
Android 使用系统原生 ACTION_CALL 直接拨号,需要 CALL_PHONE 权限;iOS 使用 tel: URL;HarmonyOS 暂不支持此接口。
const result = makeCall('***')
if (!result.success) {
uni.makePhoneCall({
phoneNumber: '***'
})
}
短信
sendSMS(options: SmsOptions): SmsResult
type SmsOptions = {
phoneNumber?: string
phoneNumbers?: string[]
content?: string
directSend?: boolean
}
type SmsResult = {
success: boolean
message: string
sent?: boolean
}
推荐使用 phoneNumbers 传入多个收件人;单个 phoneNumber 仍兼容。
// 默认打开系统短信编辑器。
sendSMS({
phoneNumbers: ['***', '***'],
content: '会议通知'
})
// Android/HarmonyOS 后台直接发送。
const result = sendSMS({
phoneNumbers: ['***'],
content: '会议通知',
directSend: true
})
后台直接发送需要 Android 的 SEND_SMS 或 HarmonyOS 的 SEND_MESSAGES 权限。iOS 不支持静默发送,始终打开系统短信编辑器,并且系统可能不允许预填短信内容。
HarmonyOS 配置
HarmonyOS NEXT 使用通话状态观察器和 CallerInfoQueryExtensionAbility 获取来去电号码。宿主应用的 module.json5 需要注册扩展能力:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.WRITE_CONTACTS",
"reason": "$string:contacts_write_permission_reason"
}
],
"extensionAbilities": [
{
"name": "CallerInfoExtension",
"srcEntry": "./ets/CallerInfoExtension.ets",
"type": "callerInfoQuery",
"metadata": [
{
"name": "ohos.extension.callerInfoQuery",
"value": "caller_info_query"
}
]
}
]
}
}
同时需要在 resources/base/element/string.json 中提供 contacts_write_permission_reason:
{
"string": [
{
"name": "contacts_write_permission_reason",
"value": "用于将来电号码存入通讯录"
}
]
}
HarmonyOS 实现暂不支持 Android 风格的前台服务、待处理事件恢复和原生直接拨号。
注意事项
- 必须使用真机测试通话事件,模拟器无法产生真实电话状态。
- Android 厂商系统可能限制后台运行,建议引导用户关闭省电限制并允许自启动。
- Android 13+ 如果没有通知权限,前台服务通知可能不可见,但仍应按系统行为申请
POST_NOTIFICATIONS。 READ_CALL_LOG和SEND_SMS属于敏感权限,上架应用市场前需要确认符合平台政策。- 监听功能建议由用户明确开启,并在关闭时调用
stopMonitoring。 - 每次进程或页面实例重建后,应重新调用
PhoneCallMonitor.onPhoneCallEvent绑定当前回调。

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 15
赞赏 0
下载 12694450
赞赏 1956
赞赏
京公网安备:11010802035340号