更新记录
1.0.1(2026-07-07)
p2p 传输优化
1.0.0(2026-07-03)
首次提交
平台兼容性
uni-app(4.81)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | Android插件版本 | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | 8.0 | 1.0.1 | - | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(4.82)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | - | - | - | - |
hl-xsx-glass-sdk
XSX AI Glass SDK 的 UniApp UTS 原生插件封装,提供蓝牙扫描连接、设备控制、状态监听、AI 识别、WiFi P2P 媒体传输等能力。
平台支持:仅 Android(minSdkVersion 26)
安装引入
import * as XSX from '@/uni_modules/hl-xsx-glass-sdk'
生命周期
在页面 onMounted 中初始化 SDK 并注册监听,在 onUnmounted 中移除监听并释放资源:
import { onMounted, onUnmounted } from 'vue'
onMounted(() => {
XSX.initSDK()
XSX.setConnectionListener((state) => { /* ... */ })
XSX.setBatteryListener((info) => { /* ... */ })
XSX.setStorageSpaceListener((space) => { /* ... */ })
XSX.setMediaDownloadListener((info) => { /* ... */ })
})
onUnmounted(() => {
XSX.removeConnectionListener()
XSX.removeBatteryListener()
XSX.removeStorageSpaceListener()
XSX.removeMediaDownloadListener()
XSX.releaseSDK()
})
API 参考
一、权限管理
checkPermission
检查单个 Android 权限是否已授权。
const hasPermission = XSX.checkPermission('android.permission.BLUETOOTH_SCAN')
console.log(`蓝牙扫描权限: ${hasPermission}`)
requestPermissions
批量申请权限,回调返回每个权限的授权状态。
XSX.requestPermissions(
['android.permission.BLUETOOTH_SCAN', 'android.permission.ACCESS_FINE_LOCATION'],
(result) => {
console.log(`全部授权: ${result.allGranted}`)
result.results.forEach((item) => {
console.log(`${item.permission}: ${item.granted ? '已授权' : '未授权'}`)
})
}
)
requestBluetoothPermissions
一键申请蓝牙扫描、连接、定位所需的全部权限。
XSX.requestBluetoothPermissions((granted) => {
if (granted) {
console.log('蓝牙权限已就绪,可以开始扫描')
} else {
console.log('蓝牙权限被拒绝')
}
})
requestWiFiPermissions
一键申请 WiFi P2P 相关权限。
- Android 13+(API 33+):申请
NEARBY_WIFI_DEVICES - Android 12 及以下:申请
ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION
⚠️ 这两个权限策略不能混合申请。Manifest 中
NEARBY_WIFI_DEVICES必须声明android:usesPermissionFlags="neverForLocation",否则在 Android 13+ 上会抛出IllegalArgumentException。
XSX.requestWiFiPermissions((granted) => {
if (granted) {
console.log('WiFi 权限已就绪,可以进行媒体传输')
} else {
console.log('WiFi 权限被拒绝')
}
})
requestCameraStoragePermissions
一键申请相机与存储权限。
XSX.requestCameraStoragePermissions((granted) => {
console.log(`相机存储权限: ${granted ? '已授权' : '未授权'}`)
})
requestPermissionGroup
按预定义场景分组申请权限。可选分组:'bluetooth' | 'wifi' | 'cameraStorage' | 'location' | 'recordAudio' | 'storage' | 'camera'。
XSX.requestPermissionGroup('location', (granted) => {
console.log(`定位权限: ${granted ? '已授权' : '未授权'}`)
})
Android 权限配置说明
插件已内置以下权限声明,一般无需额外配置。但如果你的宿主工程也声明了同名权限,注意避免 flags 冲突:
<!-- Android 13+ 必须加 neverForLocation -->
<uses-permission
android:name="android.permission.NEARBY_WIFI_DEVICES"
android:usesPermissionFlags="neverForLocation" />
<!-- Android 12 及以下 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 常规 WiFi / 网络权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
注意事项:
usesPermissionFlags="neverForLocation"要求 compileSdkVersion >= 33。CHANGE_WIFI_STATE/CHANGE_NETWORK_STATE/ACCESS_WIFI_STATE/ACCESS_NETWORK_STATE属于 normal 权限,无需运行时申请。- WiFi P2P 扫描/连接还依赖系统定位服务总开关(GPS 或网络定位至少开启一个),请在调用前自行检查并引导用户开启。
二、系统设置
isBluetoothEnabled
检查设备蓝牙是否开启。
if (!XSX.isBluetoothEnabled()) {
console.log('请先开启蓝牙')
}
isLocationEnabled
检查系统定位服务(GPS)是否开启。
if (!XSX.isLocationEnabled()) {
console.log('请先开启定位服务')
}
requestBluetoothEnable
调起系统蓝牙开启弹窗,引导用户打开蓝牙。
XSX.requestBluetoothEnable()
openAppSettings
跳转到当前应用的系统权限设置页面。
XSX.openAppSettings()
openLocationSettings
跳转到系统定位服务设置页面。
XSX.openLocationSettings()
三、SDK 管理
initSDK
初始化 SDK,必须在所有其他 API 调用前执行。
XSX.initSDK()
releaseSDK
释放 SDK 资源,建议在页面卸载时调用。
XSX.releaseSDK()
setLog
设置 SDK 日志输出开关。
enableLog:是否在控制台打印日志writeFile:是否将日志写入文件
// 开启控制台日志,不写文件
XSX.setLog(true, false)
// 关闭所有日志
XSX.setLog(false, false)
四、蓝牙扫描与连接
startScan
开始扫描周边蓝牙设备,每发现一个设备回调一次。
const devices = []
XSX.startScan((device) => {
console.log(`发现设备: ${device.name} (${device.address}), 信号: ${device.rssi}dBm`)
devices.push(device)
})
stopScan
停止蓝牙扫描。
XSX.stopScan()
connectDevice
连接到指定设备(通过名称和 MAC 地址)。连接结果通过 setConnectionListener 回调。
XSX.connectDevice('XSX-Glass-001', 'AA:BB:CC:DD:EE:FF')
disconnect
断开当前设备连接。
XSX.disconnect()
unbindDevice
解绑当前设备(解除绑定关系,断开连接)。
XSX.unbindDevice()
removeBtBond
移除系统蓝牙配对记录。
XSX.removeBtBond()
autoConnect
自动连接之前已绑定的设备(无需重新扫描)。
XSX.autoConnect()
isAuthenticated
检查当前是否已连接并完成认证。
if (XSX.isAuthenticated()) {
console.log('设备已连接并认证,可以进行控制操作')
}
isDeviceBound
检查当前是否已绑定设备。
if (XSX.isDeviceBound()) {
console.log('已绑定设备,可尝试自动连接')
}
getDeviceInfo
获取当前已连接设备的详细信息,未连接时返回 null。
const info = XSX.getDeviceInfo()
if (info != null) {
console.log(`当前设备: ${info.name}, MAC: ${info.address}, RSSI: ${info.rssi}`)
}
五、状态监听
setConnectionListener / removeConnectionListener
注册/移除连接状态监听。回调参数 XSXConnectionState 包含状态码、状态描述、关联设备和认证标志。
XSX.setConnectionListener((state) => {
console.log(`状态: ${state.stateName} (code=${state.state})`)
console.log(`已认证: ${state.isAuthenticated}`)
if (state.device != null) {
console.log(`设备: ${state.device.name} (${state.device.address})`)
}
})
// 页面卸载时移除
XSX.removeConnectionListener()
setBatteryListener / removeBatteryListener
注册/移除电量监听。回调参数 XSXBatteryInfo 包含左右眼电量、充电状态和低电提醒。
XSX.setBatteryListener((info) => {
console.log(`左眼: ${info.leftBattery}%, 右眼: ${info.rightBattery}%`)
console.log(`左充电: ${info.isLeftCharging}, 右充电: ${info.isRightCharging}`)
console.log(`总体: ${info.batteryLevel}%, 低电: ${info.isLowPower}`)
})
// 页面卸载时移除
XSX.removeBatteryListener()
setStorageSpaceListener / removeStorageSpaceListener
注册/移除设备存储空间变化监听。
XSX.setStorageSpaceListener((space) => {
console.log(`已用: ${space.usedStorageSpace}, 可用: ${space.unuseStorageSpace}`)
})
// 页面卸载时移除
XSX.removeStorageSpaceListener()
getBatteryInfo
主动获取当前电量信息(非监听方式),未连接时返回 null。
const info = XSX.getBatteryInfo()
if (info != null) {
console.log(`电量: 左${info.leftBattery}% 右${info.rightBattery}%`)
}
getDeviceStatus
获取设备当前运行状态(是否正在录像/录音),未连接时返回 null。
const status = XSX.getDeviceStatus()
if (status != null) {
console.log(`正在录像: ${status.isVideoRecording}`)
console.log(`正在录音: ${status.isAudioRecording}`)
}
六、设备控制
takePicture
控制设备拍照。返回 true 表示指令发送成功。
const ok = XSX.takePicture()
console.log(`拍照: ${ok ? '成功' : '失败'}`)
startRecordVideo
开始录像,可指定最长录制时长(秒)。
// 录制最长 15 秒
const ok = XSX.startRecordVideo(15)
console.log(`开始录像: ${ok ? '成功' : '失败'}`)
stopRecordVideo
手动停止录像(未到设定时长时提前结束)。
const ok = XSX.stopRecordVideo()
console.log(`停止录像: ${ok ? '成功' : '失败'}`)
startRecordAudio
开始录音,可指定最长录制时长(秒)。
// 录制最长 30 秒
const ok = XSX.startRecordAudio(30)
console.log(`开始录音: ${ok ? '成功' : '失败'}`)
stopRecordAudio
手动停止录音。
const ok = XSX.stopRecordAudio()
console.log(`停止录音: ${ok ? '成功' : '失败'}`)
shutDown
控制设备关机。
const ok = XSX.shutDown()
console.log(`关机: ${ok ? '成功' : '失败'}`)
restart
控制设备重启。
const ok = XSX.restart()
console.log(`重启: ${ok ? '成功' : '失败'}`)
restore
控制设备恢复出厂设置。
const ok = XSX.restore()
console.log(`恢复出厂: ${ok ? '成功' : '失败'}`)
syncTime
将手机当前时间同步到眼镜设备。
const ok = XSX.syncTime()
console.log(`同步时间: ${ok ? '成功' : '失败'}`)
七、设备参数
getDeviceParams
读取设备当前参数设置。
const ok = XSX.getDeviceParams()
console.log(`读取参数: ${ok ? '已发送' : '失败'}`)
setDeviceParams
设置设备参数。不修改的字段传 null 即可跳过。
XSXSetParams 字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
deviceName |
string \| null |
设备名称 |
eqModel |
number \| null |
EQ 均衡模式 |
checkWear |
boolean \| null |
佩戴检测开关 |
openPictureDateWaterMark |
boolean \| null |
照片日期水印 |
openVideoDateWaterMark |
boolean \| null |
视频日期水印 |
cameraRatio |
XSXCameraRatio \| null |
相机分辨率(含 photo/video/AI 识别三项) |
voiceAssistant |
boolean \| null |
语音助手开关 |
languageCode |
number \| null |
语言编码 |
videoDuration |
number \| null |
默认录像时长(秒) |
// 仅修改设备名称和佩戴检测,其余保持不变
XSX.setDeviceParams({
deviceName: 'My Glass',
eqModel: null,
checkWear: true,
openPictureDateWaterMark: null,
openVideoDateWaterMark: null,
cameraRatio: null,
voiceAssistant: null,
languageCode: null,
videoDuration: null
})
八、AI 能力
initAI
初始化 AI 模块,回调返回 AI 类型:'domestic'(国内)或 'oversea'(海外)。
XSX.initAI((type) => {
console.log(`AI 初始化完成,模式: ${type}`) // domestic / oversea
})
takePictureAndRecognize
拍照并使用 AI 识别图片内容,需传入识别提示词。需先调用 initAI。
const ok = XSX.takePictureAndRecognize('描述一下这张图片的内容')
console.log(`拍照识别: ${ok ? '已发送' : '失败'}`)
九、WiFi P2P 媒体传输
startDownloadMedia
开始通过 WiFi P2P 从眼镜设备下载媒体文件。
调用前必须满足以下前置条件:
- 蓝牙设备已完成认证(
isAuthenticated() === true) - 手机 WiFi 开关已开启
- 系统定位服务(GPS 或网络定位)已开启
- 已申请 WiFi P2P 相关权限(
requestWiFiPermissions) - 已设置媒体下载监听(
setMediaDownloadListener)
XSX.requestWiFiPermissions((granted) => {
if (!granted) return
XSX.setMediaDownloadListener((info) => {
// 根据 info.type 处理不同事件
})
XSX.startDownloadMedia()
})
setMediaDownloadListener / removeMediaDownloadListener
注册/移除媒体文件下载进度监听。详见下方 媒体下载回调详解。
XSX.setMediaDownloadListener((info) => {
switch (info.type) {
case 'onDownloadStart':
case 'onDownloadingMedia':
case 'onDownloadProgress':
if (info.totalBytes > 0) {
const percent = Math.round((info.downloadedBytes / info.totalBytes) * 100)
console.log(`[${info.type}] 文件 ${info.currentIndex}/${info.mediaNum} - ${percent}%`)
}
break
case 'onDownloadSuccess':
console.log(`文件已保存至: ${info.filePath}`)
break
case 'onDownloadComplete':
console.log('全部文件下载完成')
break
case 'diagnostic':
console.log(`[诊断] ${info.message}`)
break
}
})
// 页面卸载时移除
XSX.removeMediaDownloadListener()
restartP2P
重启 WiFi P2P 连接(连接异常时使用)。
const ok = XSX.restartP2P()
console.log(`重启 P2P: ${ok ? '成功' : '失败'}`)
disconnectWiFi
断开 WiFi P2P 连接。
XSX.disconnectWiFi()
getResourceInfoFilesTotal
获取眼镜设备上可导入的媒体文件总数。
const total = XSX.getResourceInfoFilesTotal()
console.log(`可导入文件数: ${total}`)
transferFileDone
通知眼镜设备当前文件传输已完成。
XSX.transferFileDone()
媒体下载回调详解
调用 setMediaDownloadListener 后,下载过程中会持续回调 XSXMediaDownloadInfo 对象。
回调字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
type |
string |
回调事件类型标识,详见 回调事件类型 |
hotspotType |
number |
热点连接类型 |
serverIp |
string \| null |
文件传输服务端 IP 地址 |
port |
number |
文件传输服务端端口号 |
mediaNum |
number |
本次传输的文件总数 |
currentIndex |
number |
当前正在下载的文件序号(从 1 开始) |
downloadedBytes |
number |
当前文件已下载的字节数 |
totalBytes |
number |
当前文件的总字节数 |
filePath |
string \| null |
文件下载完成后的本地保存路径(仅 onDownloadSuccess 时有值) |
message |
string \| null |
附加消息(如错误信息、状态提示等) |
回调事件类型
| 事件类型 | 说明 |
|---|---|
onMediaNum |
获取到可导入文件总数,mediaNum 字段有效 |
hotspotStartSuccess |
眼镜热点已启动成功,SDK 内部将自动连接手机到眼镜热点 |
onConnected |
手机已成功连接到眼镜 WiFi 热点 |
onDownloadStart |
开始下载单个文件 |
onDownloadingMedia |
正在下载媒体数据 |
onDownloadProgress |
下载进度更新 |
onDownloadSuccess |
单个文件下载成功,filePath 字段有效 |
onDownloadComplete |
全部文件下载完成 |
onDownloadFail |
下载失败 |
discoverHotspotTimeout / discoverPeersTimeout / onConnectTimeout |
热点发现 / 设备发现 / 连接超时 |
onDecodeOpus* |
音频解码相关事件 |
diagnostic |
诊断/调试日志消息,message 字段有效 |
进度计算
XSX.setMediaDownloadListener((info) => {
switch (info.type) {
case 'onMediaNum':
console.log(`可导入文件总数: ${info.mediaNum}`)
break
case 'hotspotStartSuccess':
console.log('眼镜热点已启动,等待手机连接...')
break
case 'onConnected':
console.log('已连接到眼镜 WiFi 热点')
break
case 'onDownloadStart':
case 'onDownloadingMedia':
case 'onDownloadProgress':
// 总体进度
const fileProgress = `${info.currentIndex} / ${info.mediaNum}`
// 单文件进度
const filePercent = info.totalBytes > 0
? Math.round((info.downloadedBytes / info.totalBytes) * 100)
: 0
console.log(`文件 ${fileProgress},下载 ${filePercent}%`)
break
case 'onDownloadSuccess':
console.log(`第 ${info.currentIndex} 个文件已保存: ${info.filePath}`)
break
case 'onDownloadComplete':
console.log('全部文件下载完成')
// 可选:通知设备传输完成
// XSX.transferFileDone()
break
case 'onDownloadFail':
case 'discoverHotspotTimeout':
case 'discoverPeersTimeout':
case 'onConnectTimeout':
console.log(`传输异常/超时: ${info.message}`)
break
case 'diagnostic':
console.log(`[诊断] ${info.message}`)
break
}
})
完整媒体导入流程
import * as XSX from '@/uni_modules/hl-xsx-glass-sdk'
// 前置检查
if (!XSX.isAuthenticated()) {
console.log('设备未认证,请先连接并认证蓝牙设备')
return
}
// 1. 检查系统定位服务(WiFi 扫描依赖定位开关)
// 若未开启,请引导用户跳转到系统设置页开启 GPS 或网络定位
// 2. 检查 WiFi 开关是否已开启
// 若未开启,请引导用户开启 WiFi
// 3. 申请 WiFi P2P 权限
XSX.requestWiFiPermissions((granted) => {
if (!granted) {
console.log('WiFi 权限未授权,无法传输')
return
}
// 4. 注册下载监听(必须在 startDownloadMedia 之前设置)
XSX.setMediaDownloadListener((info) => {
switch (info.type) {
case 'onMediaNum':
console.log(`可导入文件总数: ${info.mediaNum}`)
break
case 'hotspotStartSuccess':
console.log('热点启动成功')
break
case 'onConnected':
console.log('已连接眼镜热点')
break
case 'onDownloadProgress':
case 'onDownloadingMedia':
case 'onDownloadStart':
if (info.totalBytes > 0) {
const percent = Math.round((info.downloadedBytes / info.totalBytes) * 100)
console.log(`文件 ${info.currentIndex}/${info.mediaNum} - ${percent}%`)
}
break
case 'onDownloadSuccess':
console.log(`已保存: ${info.filePath}`)
break
case 'onDownloadComplete':
console.log('全部下载完成')
break
case 'onDownloadFail':
case 'discoverHotspotTimeout':
case 'discoverPeersTimeout':
case 'onConnectTimeout':
console.log(`异常: ${info.message}`)
break
case 'diagnostic':
console.log(`[诊断] ${info.message}`)
break
}
})
// 5. 查看可导入文件总数
const total = XSX.getResourceInfoFilesTotal()
console.log(`设备上有 ${total} 个媒体文件可导入`)
// 6. 开始下载
XSX.startDownloadMedia()
})
数据类型
XSXDevice — 蓝牙设备
type XSXDevice = {
name: string // 设备名称
address: string // MAC 地址
rssi: number // 信号强度(dBm)
scanRecord: string | null
}
XSXConnectionState — 连接状态
type XSXConnectionState = {
state: number // 状态码
stateName: string // 状态描述(如"已连接"、"已断开"等)
device: XSXDevice | null // 关联设备信息
isAuthenticated: boolean // 是否已完成认证
}
XSXBatteryInfo — 电量信息
type XSXBatteryInfo = {
leftBattery: number // 左眼电量 %
rightBattery: number // 右眼电量 %
isLeftCharging: boolean // 左眼是否在充电
isRightCharging: boolean // 右眼是否在充电
batteryLevel: number // 总体电量 %
isLowPower: boolean // 是否低电量警告
}
XSXDeviceStatus — 设备运行状态
type XSXDeviceStatus = {
isVideoRecording: boolean // 是否正在录像
isAudioRecording: boolean // 是否正在录音
}
XSXStorageSpace — 存储空间
type XSXStorageSpace = {
usedStorageSpace: number // 已用空间(字节)
unuseStorageSpace: number // 可用空间(字节)
}
XSXCameraRatio — 相机分辨率
type XSXCameraRatio = {
pictureRatio: number // 拍照分辨率
videoRatio: number // 录像分辨率
aiRecognizeRatio: number // AI 识别分辨率
}
XSXMediaDownloadInfo — 媒体下载信息
详见 媒体下载回调详解。
type XSXMediaDownloadInfo = {
type: string // 回调事件类型标识
hotspotType: number // 热点连接类型
serverIp: string | null // 服务端 IP
port: number // 服务端端口
mediaNum: number // 文件总数
currentIndex: number // 当前文件序号
downloadedBytes: number // 已下载字节数
totalBytes: number // 文件总字节数
filePath: string | null // 本地保存路径(onDownloadSuccess 时有值)
message: string | null // 附加消息
}
XSXPermissionResult — 权限申请结果
type XSXPermissionResult = {
permission: string // 权限常量名
granted: boolean // 是否已授权
}
type XSXPermissionRequestResult = {
allGranted: boolean // 是否全部授权
results: XSXPermissionResult[] // 每个权限的详细结果
}
注意事项
- 必须使用自定义基座运行,标准基座不包含原生 SDK
- 扫描前需确保蓝牙和定位均已开启,并申请对应权限
setDeviceParams中不修改的字段传null即可跳过- 页面退出时务必调用
removeXxxListener和releaseSDK释放资源 - WiFi P2P 媒体传输前需确保:蓝牙设备已认证、WiFi 开关已开启、系统定位服务已开启,并已申请 WiFi 相关权限
setMediaDownloadListener必须在startDownloadMedia之前调用,否则会丢失进度回调- AI 识别功能需先调用
initAI完成初始化

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 328
赞赏 0
下载 12516160
赞赏 1943
赞赏
京公网安备:11010802035340号