鸿蒙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秒宽限期,避免误判

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

相关推荐
奋斗的小青年!!11 小时前
Flutter适配OpenHarmony:打造无缝国际化用户体验的实战指南
flutter·harmonyos·鸿蒙
奋斗的小青年!!11 小时前
Flutter跨平台数据筛选器:深度适配OpenHarmony实战指南
flutter·harmonyos·鸿蒙
哈__11 小时前
React Native 鸿蒙跨平台开发:Animated 实现鸿蒙端组件的上下滑动入场动画
react native·react.js·harmonyos
奋斗的小青年!!12 小时前
Flutter与OpenHarmony深度协同:SnackBar组件的跨平台适配实战
flutter·harmonyos·鸿蒙
行者9612 小时前
OpenHarmony Flutter跨平台开发:树形视图组件的实践与性能优化
flutter·性能优化·harmonyos·鸿蒙
wszy180921 小时前
新文章标签:让用户一眼发现最新内容
java·python·harmonyos
wszy180921 小时前
顶部标题栏的设计与实现:让用户知道自己在哪
java·python·react native·harmonyos
Van_Moonlight1 天前
RN for OpenHarmony 实战 TodoList 项目:空状态占位图
javascript·开源·harmonyos
anyup1 天前
2026第一站:分享我在高德大赛现场学到的技术、产品与心得
前端·架构·harmonyos
anyup1 天前
从赛场到产品:分享我在高德大赛现场学到的技术、产品与心得
前端·harmonyos·产品