更新记录

1.0.0(2026-04-16)

1.0.0

  • 首次发布 Android 语音后台保活 UTS API 插件。
  • 支持 uni-app 和 uni-app x 通过统一 UTS API 调用。
  • 支持启动/停止 Android 前台保活服务。
  • 支持麦克风状态维护、音频焦点保持、后台健康检查和异常恢复。
  • 支持蓝牙耳机、有线耳机、扬声器、听筒等音频路由监听。
  • 支持 App 前后台状态通知、手动刷新采集、状态查询和事件回调。
  • 提供 RTC 语音房验收 Demo,便于验证锁屏和后台语音链路。

平台兼容性

YY语音后台保活

yy-voicekeepalive 是一个 Android RTC 语音通话后台保活 UTS API 插件,适用于语音房、实时通话、会议、对讲等需要在锁屏或切后台后继续保持麦克风语音链路的场景。

插件负责 Android 本地音频保活,不包含 RTC 入会、推流、订阅等 RTC SDK 能力。业务侧需要先接入自己的 RTC SDK,并在入会成功后调用本插件启动保活。

功能特性

  • 启动 Android 前台服务,降低后台通话被系统回收的概率
  • 维护麦克风状态,支持开麦/静音状态同步
  • 保持语音通话音频模式和音频焦点
  • 监听扬声器、听筒、有线耳机、蓝牙耳机等音频路由变化
  • 支持 App 前后台状态同步
  • 支持锁屏、后台、音频焦点丢失后的健康检查和恢复
  • 支持手动刷新采集
  • 支持状态查询和事件回调

兼容说明

  • 插件类型:UTS API 插件
  • 支持框架:uni-app、uni-app x
  • 支持平台:App Android
  • 最低 Android:Android 5.0 / API 21
  • 建议 HBuilderX:3.9.1+
  • 不支持:iOS、H5、小程序

使用流程

推荐接入顺序:

检查权限 -> 初始化并加入 RTC 频道 -> RTC 入会成功 -> 启动语音保活 -> 同步开麦/静音和前后台状态 -> 离会时停止保活

关键点:

  • startVoiceKeepAlive 建议在 RTC onJoinChannelSuccess 或同等入会成功回调之后调用。
  • stopVoiceKeepAlive 必须在 RTC 离会或通话结束时调用。
  • 业务侧执行 RTC 开麦/静音后,需要同步调用 setExpectedMicEnabled
  • App 进入后台、回到前台时,建议同步调用 setAppVisibility

示例工程

示例工程用于验证完整链路:

Android App 加入 RTC 频道 -> 启动语音保活 -> 切后台/锁屏 -> Web 对端继续听音 -> 离会清理

示例工程中,Android App 是保活端,Web 端只是 RTC 测试对端,不启动原生保活。这样只有一台 Android 手机时,也可以用浏览器作为另一端来验证后台语音是否持续。

示例工程准备

  1. 用 HBuilderX 打开 YY-voicekeepalive-uts-demo
  2. 在 demo 根目录执行插件同步:
npm run sync:plugin
  1. 打开 demo 的 config.js,填写 RTC 配置:
const rtcDemoConfig = {
    appId: 'your-rtc-app-id',
    channelId: '1',
    userId: '1001',
    webUserId: '1002',
    token: '',
    appToken: '',
    webToken: '',
    rtcNativePluginName: 'AR-RtcModule',
    rtcDebug: true,
    mobileJoinDebugOnly: false,
    webPublishMicrophone: false
}

export default rtcDemoConfig
  1. 确认 demo 工程已包含 RTC 原生插件 AR-RtcModule,并在 HBuilderX 中制作 Android 自定义运行基座。
  2. 在 Android App 端加入语音房。
  3. 在 Web 端打开同一 demo,使用相同频道 ID、不同用户 ID 加入频道。
  4. App 切后台或锁屏,观察 Web 端是否还能听到 App 端声音。

如果 RTC 项目未启用 App Certificate,tokenappTokenwebToken 可以留空。如果已启用,需要分别填写 App 端和 Web 端对应用户的 token。

示例页面功能

示例页面位于:

YY-voicekeepalive-uts-demo/pages/index/index.vue

页面提供以下操作:

  • 检查权限
  • 初始化 RTC
  • 加入语音房
  • 开麦/静音
  • 查询保活状态
  • 刷新采集
  • 模拟切后台
  • 模拟回前台
  • 离开频道
  • 查看 RTC 和保活日志

安装使用

将插件目录放入项目:

your-project/uni_modules/yy-voicekeepalive

在业务代码中导入:

// #ifdef APP-PLUS
import { startVoiceKeepAlive, stopVoiceKeepAlive, setExpectedMicEnabled, setAppVisibility, refreshCapture, onKeepAliveEvent, offKeepAliveEvent, getStatus } from '@/uni_modules/yy-voicekeepalive'
// #endif

基础用法

启动保活

通常在 RTC 入会成功,并且本端需要保持麦克风语音链路时调用:

startVoiceKeepAlive(
    {
        channelId: 'room-1001',
        uid: '1001',
        expectMicEnabled: true,
        visible: true,
        preferSpeaker: true,
        enableBluetoothWatch: true,
        reason: 'join_success'
    },
    res => {
        console.log('startVoiceKeepAlive', res)
    }
)

通知开麦或静音

当业务侧执行 RTC 开麦/静音后,同步通知保活插件:

setExpectedMicEnabled(
    {
        enabled: true
    },
    res => {
        console.log('setExpectedMicEnabled', res)
    }
)

通知前后台状态

建议在页面或应用生命周期中同步调用:

setAppVisibility(
    {
        visible: false
    },
    res => {
        console.log('setAppVisibility', res)
    }
)

手动刷新采集

当业务检测到后台回前台、音频中断、RTC 采集异常时,可以触发一次刷新:

refreshCapture(
    {
        reason: 'manual_refresh'
    },
    res => {
        console.log('refreshCapture', res)
    }
)

监听事件

const handleKeepAliveEvent = event => {
    console.log('keepalive event', event)
}

onKeepAliveEvent({}, handleKeepAliveEvent)

取消监听:

offKeepAliveEvent({}, handleKeepAliveEvent)

查询状态

getStatus({}, res => {
    console.log('keepalive status', res)
})

停止保活

通常在 RTC 离会或通话结束时调用:

stopVoiceKeepAlive(
    {
        reason: 'leave_channel'
    },
    res => {
        console.log('stopVoiceKeepAlive', res)
    }
)

API 说明

startVoiceKeepAlive(options, callback)

启动 Android 前台保活服务。

options 支持字段:

  • channelId:频道 ID,用于状态和通知展示。
  • uid:当前用户 ID,用于状态展示。
  • expectMicEnabled:是否期望麦克风保持开启,默认 true
  • visible:App 当前是否前台可见,默认 true
  • preferSpeaker:无耳机时是否优先扬声器,默认 true
  • enableBluetoothWatch:是否监听蓝牙耳机路由,默认 true
  • reason:调用原因,便于日志排查。

stopVoiceKeepAlive(options, callback)

停止保活服务,并释放音频焦点、WakeLock、系统监听和前台通知。

setExpectedMicEnabled(options, callback)

同步业务侧麦克风预期状态。开麦时插件会尽量维持音频焦点、通话音频模式和麦克风非静音;静音时插件会放松部分保活行为。

options.enabledtrue 表示期望开麦,为 false 表示期望静音。

setAppVisibility(options, callback)

同步 App 前后台状态。后台状态下插件会使用更积极的健康检查和恢复策略。

options.visibletrue 表示前台,为 false 表示后台。

refreshCapture(options, callback)

手动触发一次保活刷新,适合配合 RTC 侧重新启用本地音频、回前台恢复、音频焦点丢失后重试等流程。

onKeepAliveEvent(options, callback)

监听保活事件。当前事件包括:

  • service_started
  • service_stopped
  • route_changed
  • audio_focus_gained
  • audio_focus_lost
  • interruption_begin
  • interruption_end
  • recover_triggered
  • capture_refreshed
  • recover_succeeded
  • recover_failed
  • diagnostic

offKeepAliveEvent(options, callback)

取消事件监听。传入指定 callback 时移除该监听,不传 callback 时移除全部监听。

getStatus(options, callback)

查询保活状态。

常见返回字段:

  • code0 表示调用成功。
  • msg:调用结果描述。
  • running:保活服务是否运行。
  • platform:当前平台,Android 返回 android
  • inChannel:保活侧是否处于通话链路状态。
  • appStateforegroundbackground
  • audioFocusgrantedlost
  • audioRoutespeakerearpiecewiredbluetoothunknown
  • micMuted:系统麦克风是否静音。
  • recoverCount:恢复次数。
  • channelId:当前频道 ID。
  • uid:当前用户 ID。
  • expectMicEnabled:是否期望开麦。
  • preferSpeaker:是否优先扬声器。
  • enableBluetoothWatch:是否启用蓝牙监听。
  • bluetoothScoOn:蓝牙 SCO 是否开启。
  • reason:最近一次状态原因。
  • timestamp:状态时间戳。

Android 权限

插件声明的主要权限:

android.permission.RECORD_AUDIO
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.WAKE_LOCK
android.permission.FOREGROUND_SERVICE
android.permission.FOREGROUND_SERVICE_MICROPHONE
android.permission.POST_NOTIFICATIONS
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BLUETOOTH_CONNECT

运行时至少需要麦克风权限。Android 13+ 建议申请通知权限,Android 12+ 使用蓝牙耳机时建议申请蓝牙连接权限。

最佳实践

  • 在 RTC 入会成功后再调用 startVoiceKeepAlive,不要在未入会时提前启动。
  • 开麦时调用 setExpectedMicEnabled({ enabled: true }),静音时调用 setExpectedMicEnabled({ enabled: false })
  • App 进入后台时调用 setAppVisibility({ visible: false }),回到前台时调用 setAppVisibility({ visible: true })
  • 后台回前台、音频焦点丢失、RTC 采集异常时,可以调用 refreshCapture 做一次保活刷新。
  • 离开频道、挂断通话、退出语音房时必须调用 stopVoiceKeepAlive
  • 建议把 getStatusonKeepAliveEvent 接入业务日志,方便排查不同机型上的后台策略差异。

常见问题

这个插件是否包含 RTC SDK?

不包含。插件只负责 Android 本地语音保活,RTC 入会、推流、订阅、频道管理仍由你的 RTC SDK 完成。

Web、iOS、小程序能使用吗?

不能。当前插件只支持 App Android。Web、iOS、小程序不会启动原生保活。

为什么启动后状态里 audioFocuslost

可能是系统或其他应用暂时占用了音频焦点,也可能是当前未期望开麦。建议确认麦克风权限、RTC 是否已入会、是否调用了 setExpectedMicEnabled({ enabled: true }),必要时调用 refreshCapture

为什么蓝牙耳机没有走蓝牙路由?

请确认 Android 12+ 已授予蓝牙连接权限,并确认耳机支持通话蓝牙 SCO。部分设备或耳机只支持媒体播放蓝牙,不支持通话采集。

为什么锁屏后仍然可能被系统限制?

不同厂商的后台策略不同。插件已使用前台服务、WakeLock、音频焦点和健康检查来提升稳定性,但个别系统仍可能需要用户在系统设置中允许后台运行、通知显示或关闭电池优化。

注意事项

  • 插件会显示 Android 前台服务通知,这是后台使用麦克风类能力的正常系统要求。
  • 免费插件默认 MIT 协议;如你的项目有额外协议要求,请自行确认。
  • 本插件不采集、不上传用户数据,仅在应用本地维持音频保活并向 JS 层返回状态。

隐私、权限声明

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

android.permission.RECORD_AUDIO 麦克风权限。语音通话和后台保活的核心权限,运行时必须授权。 android.permission.MODIFY_AUDIO_SETTINGS 修改音频设置。用于设置通话音频模式、扬声器、蓝牙 SCO、麦克风静音状态等。 android.permission.WAKE_LOCK 唤醒锁。用于降低锁屏后音频保活逻辑被系统挂起的概率。 android.permission.FOREGROUND_SERVICE 前台服务权限。用于启动 Android 前台服务。 android.permission.FOREGROUND_SERVICE_MICROPHONE 麦克风类型前台服务权限。Android 10+ / 高版本系统中,后台使用麦克风相关前台服务需要声明。 android.permission.POST_NOTIFICATIONS 通知权限。Android 13+ 建议申请,否则前台服务通知可能无法正常显示。 android.permission.BLUETOOTH 蓝牙基础权限。用于兼容旧 Android 版本的蓝牙耳机状态处理。 android.permission.BLUETOOTH_ADMIN 蓝牙管理权限。用于兼容旧 Android 版本的蓝牙耳机路由处理。 android.permission.BLUETOOTH_CONNECT 蓝牙连接权限。Android 12+ 使用蓝牙耳机通话路由时建议申请。

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

插件使用的 RTC SDK会采集数据,详细可参考https://www.anyrtc.io/products/voice_call

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

暂无用户评论。