鸿蒙ArkTS开发:微信/系统来电通话监听功能实现

本文将介绍如何在鸿蒙应用中使用ArkTS实现通话监听和录音功能,利用harmony-utils工具库简化开发流程。

工具库地址

一、功能概述

本实现包含以下核心功能:

  1. 通话状态监听:检测来电、去电和通话中状态

  2. 音频流监控:通过麦克风使用情况判断是否在通话

  3. 权限管理:动态申请麦克风和通话记录权限

  4. 状态管理:15秒宽限期后执行锁定操作

二、完整实现代码

TypeScript 复制代码
import { PermissionUtil, ToastUtil } from "@pura/harmony-utils";
import { audio } from "@kit.AudioKit";
import { call, observer } from "@kit.TelephonyKit";

@Entry
@Component
struct CallMonitorPage {
  private stillTalking: boolean = false; // 是否在通话中

  aboutToDisappear() {
    // 释放资源
    let am = audio.getAudioManager();
    let audioStreamManager = am.getStreamManager();
    audioStreamManager.off('audioCapturerChange');
    observer.off('callStateChange')
  }

  // 检测到通话后的处理
  private hearPhone() {
    if (this.stillTalking) return;
    
    ToastUtil.showToast('检测到通话中,15秒后将锁定页面~');
    this.stillTalking = true;
    
    setTimeout(() => {
      if (this.stillTalking) {
        // 这里可以添加锁定页面的逻辑
        ToastUtil.showToast('页面已锁定,请结束通话后继续');
      }
    }, 15000);
  }

  // 申请录音监听权限
  async useAudioStreamManager() {
    // 1. 检查麦克风权限
    PermissionUtil.checkRequestPermissions("ohos.permission.MICROPHONE").then((res) => {
      if (!res) {
        // 2. 如果没有权限则申请
        PermissionUtil.requestPermissionOnSetting("ohos.permission.MICROPHONE").then((res) => {
          if (!res) {
            ToastUtil.showToast('请给予录音权限~');
          }
          this.onHear();
        });
      } else {
        this.onHear();
      }
    });
    
    // 3. 检查通话记录权限
    PermissionUtil.checkRequestPermissions("ohos.permission.READ_CALL_LOG").then(() => {
      // 4. 检查当前是否有通话
      if (call.getCallStateSync()) {
        this.hearPhone();
      }
      
      // 5. 监听主卡槽通话状态变化
      observer.on('callStateChange', { slotId: 0 }, (data) => {
        this.handleCallStateChange(data);
      });
      
      // 6. 监听副卡槽通话状态变化
      observer.on('callStateChange', { slotId: 1 }, (data) => {
        this.handleCallStateChange(data);
      });
    });
  }

  // 处理通话状态变化
  private handleCallStateChange(data) {
    // 来电状态
    if (data.state === 0) {
      this.stillTalking = false;
      return;
    }
    // 通话中状态(包括保持状态)
    if ([3].includes(data.state)) {
      this.hearPhone();
    }
  }

  // 监听音频流变化
  private onHear() {
    let am = audio.getAudioManager();
    let audioStreamManager = am.getStreamManager();
    
    // 检查当前是否有音频活动
    if (audioStreamManager.isActiveSync(0)) {
      this.hearPhone();
    }
    
    // 监听音频捕获变化
    audioStreamManager.on('audioCapturerChange', () => {
      setTimeout(() => {
        if (audioStreamManager.isActiveSync(0)) {
          // 通话中
          this.hearPhone();
        } else {
          this.stillTalking = false;
        }
      }, 500);
    });
  }

  build() {
    Column() {
      Button('开始监听通话')
        .onClick(() => {
          this.useAudioStreamManager();
        })
        .margin(20)
        .width('80%')
    }
    .width('100%')
    .height('100%')
  }
}
其中系统来电采用observer.on('callStateChange')监听,而微信来电使用audioStreamManager.on('audioCapturerChange')有没有在录音来监听,理论其他APP也是可以监听到的

三、权限配置

module.json5中添加以下权限声明:

json

javascript 复制代码
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.MICROPHONE",
        "reason": "需要录音权限"
      }
    ]
  }
}

四、核心API说明

API 说明
call.getCallStateSync() 获取当前通话状态
observer.on('callStateChange') 监听通话状态变化
audioStreamManager.isActiveSync(0) 检测音频流是否活跃
PermissionUtil.checkRequestPermissions() 检查并申请权限
PermissionUtil.requestPermissionOnSetting() 二次申请权限

五、通话状态值说明

-1 无效状态,当获取呼叫状态失败时返回。
0 表示没有正在进行的呼叫。
1 表示来电正在振铃或等待。
2 表示至少有一个呼叫处于拨号、通话中或呼叫保持状态,并且没有新的来电振铃或等待。
3 表示来电已经接听。

六、实现原理

  1. 双重检测机制

    • 通过系统通话状态API直接检测

    • 通过音频流变化间接检测

  2. 权限管理

    • 使用harmony-utils简化权限申请流程

    • 优雅处理权限拒绝情况

  3. 状态管理

    • 设置15秒宽限期,避免误判

    • 使用标志位防止重复处理

相关推荐
zhanshuo6 小时前
构建可扩展的状态系统:基于 ArkTS 的模块化状态管理设计与实现
harmonyos
zhanshuo6 小时前
ArkTS 模块通信全解析:用事件总线实现页面消息联动
harmonyos
codefish79811 小时前
鸿蒙开发学习之路:从入门到实践的全面指南
harmonyos
yrjw17 小时前
一款基于react-native harmonyOS 封装的【文档】文件预览查看开源库(基于Harmony 原生文件预览服务进行封装)
harmonyos
小徐不徐说1 天前
每日一算:华为-批萨分配问题
数据结构·c++·算法·leetcode·华为·动态规划·后端开发
搜狐技术产品小编20231 天前
搜狐新闻直播间适配HarmonyOs实现点赞动画
华为·harmonyos
zhanshuo2 天前
ArkUI 玩转水平滑动视图:超全实战教程与项目应用解析
harmonyos·arkui
zhanshuo2 天前
ArkUI Canvas 实战:快速绘制柱状图图表组件
harmonyos·arkui
zhanshuo2 天前
手把手教你用 ArkUI 写出高性能分页列表:List + onScroll 实战解析
harmonyos
zhanshuo2 天前
深入解析 ArkUI 触摸事件机制:从点击到滑动的开发全流程
harmonyos