更新记录

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 绑定当前回调。

隐私、权限声明

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

READ_PHONE_STATE、READ_CALL_LOG、READ_CONTACTS、WRITE_CONTACTS、CALL_PHONE、FOREGROUND_SERVICE、FOREGROUND_SERVICE_SPECIAL_USE、POST_NOTIFICATIONS、RECEIVE_BOOT_COMPLETED

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

插件不主动采集数据,仅监听电话状态变化事件

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

无

暂无用户评论。