更新记录

1.0.0(2026-04-09)

  • 基于 VtnTest Android demo 抽出 hans-v-wake-up uni-app x 插件。
  • 提供 setupstartListeningstopListeningdestroygetStateonWakeuponAuth 等基础 API。
  • 集成 VTN.jar、Android soassets/res 运行资源与录音权限声明。
  • 支持自定义唤醒词资源生成、动态加载与移除。
  • 提供 iOS / Harmony 的 not supported 占位实现。
  • 修正 destroy() 后再次 setup/startListening 无法继续收到事件的问题。

平台兼容性

uni-app(4.87)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - - - - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(4.87)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - - - -

hans-v-wake-up

基于讯飞 VTN Android SDK 的语音唤醒插件,提供页面内监听、前台服务监听、唤醒事件回调和动态唤醒词资源管理能力。

支持平台

  • 支持:uni-app / uni-app xApp-Android
  • 不支持:H5、各类小程序、App-iOSHarmony

接入要求

  • HBuilderX >= 4.87.0
  • uni-app >= 4.87uni-app x >= 4.87
  • Android minSdkVersion >= 24
  • 需使用 Android 自定义基座或正式打包产物验证,标准基座下原生依赖和资源不会生效
  • 建议使用真机调试,语音唤醒不适合作为模拟器验收场景

使用前准备

  • 页面统一从 @/uni_modules/hans-v-wake-up 导入,不要直接引用 utssdk/*
  • 业务侧需要准备可用的 appIdsn
  • resIdentifier 必须和插件内资源目录一致,例如 assets/res/ivw_3.17.12/gwgw/
  • 当前 solutionType 仅支持 MIC1_STD_31712
  • 运行时仍需申请 RECORD_AUDIO
  • 如果使用前台服务模式,Android 13+ 还需要确保通知权限已授予

导入

import {
  checkPermission,
  requestPermission,
  setup,
  startListening,
  stopListening,
  startForegroundListening,
  stopForegroundListening,
  destroy,
  getState,
  onWakeup,
  offWakeup,
  onAuth,
  offAuth,
  generateWakeWords,
  addWakeWords,
  removeWakeWords,
  setLogEnabled,
  isLogEnabled
} from '@/uni_modules/hans-v-wake-up'

快速开始

页面模式

适合页面停留期间做语音唤醒,页面离开后手动停止。

import {
  checkPermission,
  requestPermission,
  setup,
  startListening,
  stopListening,
  destroy,
  onWakeup,
  offWakeup,
  onAuth,
  offAuth
} from '@/uni_modules/hans-v-wake-up'

let wakeupListenerId: number | null = null
let authListenerId: number | null = null

async function startPageWakeup() {
  const granted = checkPermission() || await requestPermission()
  if (!granted) {
    throw new Error('录音权限未授予')
  }

  await setup({
    appId: '你的 appId',
    sn: '设备唯一 sn',
    resIdentifier: 'gwgw',
    solutionType: 'MIC1_STD_31712',
    workDirName: 'iflytek',
    enableLog: true,
  })

  wakeupListenerId = onWakeup((event) => {
    console.log('wakeup', JSON.stringify(event))
  })

  authListenerId = onAuth((event) => {
    console.log('auth', JSON.stringify(event))
  })

  await startListening()
}

async function stopPageWakeup() {
  try {
    await stopListening()
  } finally {
    if (wakeupListenerId != null) {
      offWakeup(wakeupListenerId)
      wakeupListenerId = null
    }
    if (authListenerId != null) {
      offAuth(authListenerId)
      authListenerId = null
    }
    destroy()
  }
}

推荐顺序:

  1. checkPermission() / requestPermission()
  2. setup()
  3. onWakeup() / onAuth()
  4. startListening()
  5. stopListening()
  6. destroy()

前台服务模式

适合应用切到后台后继续保持唤醒监听。前台服务模式和页面模式互斥,切换前先停掉另一种模式。

import {
  checkPermission,
  requestPermission,
  setup,
  startForegroundListening,
  stopForegroundListening,
  getState,
  onWakeup,
  offWakeup
} from '@/uni_modules/hans-v-wake-up'

let wakeupListenerId: number | null = null

async function startServiceWakeup() {
  const granted = checkPermission() || await requestPermission()
  if (!granted) {
    throw new Error('录音权限未授予')
  }

  await setup({
    appId: '你的 appId',
    sn: '设备唯一 sn',
    resIdentifier: 'gwgw',
    solutionType: 'MIC1_STD_31712',
    workDirName: 'iflytek',
  })

  wakeupListenerId = onWakeup((event) => {
    console.log('wakeup', JSON.stringify(event))
  })

  await startForegroundListening({
    serviceTitle: '语音唤醒服务',
    serviceText: '正在后台监听语音唤醒',
  })

  console.log('state', JSON.stringify(getState()))
}

async function stopServiceWakeup() {
  await stopForegroundListening()
  if (wakeupListenerId != null) {
    offWakeup(wakeupListenerId)
    wakeupListenerId = null
  }
}

说明:

  • startForegroundListening() 前仍然需要先 setup(),服务会读取最近一次保存的初始化参数
  • stopForegroundListening() 只停止前台服务模式,不会清理页面上注册的事件监听
  • 如果前台服务仍在运行时调用 destroy(),插件会把前台服务一并停止

状态与事件

getState()

可读取当前插件运行状态,常用字段:

  • initialized: 是否已完成 setup()
  • listening: 当前是否正在采集音频
  • runMode: page | foreground-service
  • serviceRunning: 前台服务是否仍在运行
  • notificationReady: 前台服务通知是否已就绪
  • lastError: 最近一次错误信息
  • workDirsolutionTyperesIdentifier
  • micCountrefCountframeBytes

onWakeup(callback)

唤醒事件常用字段:

  • raw: 原始回调字符串
  • timestamp: 事件时间戳
  • keyword: 命中的唤醒词
  • keywordType
  • startMs / endMs
  • beam / physical
  • score / threshold
  • power / angle / snr

onAuth(callback)

鉴权事件常用字段:

  • raw
  • timestamp
  • result
  • authType

监听移除

  • offWakeup(listenerId) / offAuth(listenerId):移除指定监听器
  • offWakeup() / offAuth():不传参数时清空当前类型的全部监听器

动态唤醒词

动态唤醒词相关 API 需要在 setup() 成功之后调用。

import {
  setup,
  generateWakeWords,
  addWakeWords,
  removeWakeWords
} from '@/uni_modules/hans-v-wake-up'

let resourceId: number | null = null

async function updateWakeWords() {
  await setup({
    appId: '你的 appId',
    sn: '设备唯一 sn',
    resIdentifier: 'gwgw',
  })

  const generated = await generateWakeWords({
    keywords: '小飞小飞|你好小飞',
  })

  const added = await addWakeWords({
    resourcePath: generated.outputPath,
  })

  resourceId = added.resourceId
}

async function clearWakeWords() {
  if (resourceId == null) {
    return
  }
  await removeWakeWords({ resourceId })
  resourceId = null
}

说明:

  • generateWakeWords({ keywords }) 中的 keywords 为唤醒词文本,多个词可按你的业务格式拼接后传入
  • 未传 outputPath 时,插件会把生成结果写到工作目录下的 userKeywordResource/generated_wakeup_words.bin
  • addWakeWords() 返回的 resourceId 需要自行保存,后续通过 removeWakeWords({ resourceId }) 卸载

日志

  • setLogEnabled(true):打开插件日志
  • isLogEnabled():读取当前日志开关

建议在联调阶段主动开启日志,发布前再按业务需要决定默认值。

使用建议

  • setup()sn 应该是设备唯一值,不要对所有设备写死同一个值
  • 页面模式和前台服务模式不要并行启动,同一时刻只保留一种模式
  • 前台服务模式请重点验证通知权限、锁屏、后台切换和重复启停场景
  • 如果只是切换页面但希望后台继续监听,不要误调 destroy()
  • 如果需要彻底释放插件,包括停止前台服务,再调用 destroy()

隐私、权限声明

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

Android 需要 RECORD_AUDIO、INTERNET、ACCESS_NETWORK_STATE、ACCESS_WIFI_STATE、CHANGE_NETWORK_STATE、MODIFY_AUDIO_SETTINGS;接入前需由业务侧自行提供合法的 appId、sn 和 VTN 资源配置。

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

插件仅在本地进行录音、鉴权与唤醒词检测,不包含额外的数据采集逻辑。

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

无广告

暂无用户评论。