Files
OpticalSystem/developer-front/public/docs/venus-sdk-1.0.md
一休哥哥6666 e186d45bec Initial commit
2026-06-14 14:39:51 +08:00

1876 lines
52 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

VenusSDK接入与开发指南AndroidvX.X.X
=====================================
<br>
# 1. 文档概述
本文介绍在 Android 平台上集成 VenusSDK 的方法,实现应用与 VenusOS 智能眼镜的连接与交互,包括设备连接、设备信息获取、设备状态同步、系统设置、固件升级、以及各项功能(实时语音转文字服务、导航、提词)的信息同步。
<br>
# 2. 支持平台与版本
- Android 7.0 及以上
- minSdk 24 及以上
- 支持 Classic Bluetooth 连接
<br>
# 3. 快速开始
<br>
## 3.1 集成SDK
1.`VenusSDK_vx.x.x_release.aar` 复制到 Application Module/libs 文件夹
2. 在 app 的 build.gradle.kts 中添加依赖:
```gradle
dependencies {
implementation(files("libs/VenusSDK_vx.x.x_release.aar"))
}
```
<br>
## 3.2 声明权限
根据场景需要,在 `/app/src/main/AndroidManifest.xml` 文件中申请获取相应的设备权限:
```xml
<!-- 访问网络权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 用于 SDK 获取网络状态变化 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 麦克风权限,用于语音消息时录制语音,不使用录制语音可以移除 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 获取运营商信息,用于获取网络状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!-- 读取存储权限,用于附件等的获取 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- 访问 GPS 定位,用于定位消息,如果不用定位相关可以移除 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- 允许程序在手机屏幕关闭后后台进程仍然运行 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
```
<br>
## 3.3 混淆配置
`app/proguard-rules.pro` 文件中添加:
```proguard
-keep class com.jueyuantech.venussdk.** { *; }
-dontwarn com.jueyuantech.venussdk.**
```
<br>
## 3.4 SDK初始化
VenusSDK 主要提供:`VNSDK``VNCommon``VNOTA` 接口:
- `VNSDK` 负责 SDK 初始化、自定义参数、获取版本构建信息等;
- `VNCommon` 负责处理与设备相关的常用功能,如设备连接管理、系统配置、状态监听和功能调用等;
- `VNOTA` 负责固件升级相关功能。
<br>
在 Application 类中初始化 SDK
```java
VNSDK.init(this, new VNOptions());
```
<br>
> 📝 **注意:** 调用 `VNSDK.init` 后SDK 内部同时会对 VNCommon 和 VNOTA 进行初始化,开发者无需手动初始化,可直接调用其功能。
<br>
## 3.5 获取SDK构建信息
获取SDK的版本构建信息
```java
VNVersionInfo versionInfo = VNSDK.getVersionInfo();
```
返回的 `VNVersionInfo` 对象包含以下信息:
- buildType构建类型
- code版本号
- name版本名称
- commit构建提交号
- date构建日期
<br>
# 4. 设备连接和配置
<br>
## 4.1 设备扫描
SDK 中不提供扫描设备的接口,开发者需自行扫描附近 **Classic Bluetooth** 蓝牙设备,将获取到的 `BluetoothDevice` 对象传递给 SDK 进行初始化和连接。
<br>
## 4.2 设备连接管理
> **提示:** 设备连接是指 APP 与眼镜设备的**业务通路**连接。如有用到**音频通路**连接A2DP、HFP开发者需通过Android标准API自行维护。
<br>
1. 初始化设备:
```java
VNCommon.initDevice(bluetoothDevice);
```
<br>
2. 设置连接状态监听:
```java
VNCommon.setDeviceServiceListener(new VNDeviceServiceListener() {
@Override
public void onStateChanged(int state) {
// 根据state判断连接状态
switch (state) {
case VNConstant.ServiceState.CONNECT_SUCCESS:
// 连接成功
break;
case VNConstant.ServiceState.CONNECT_ERROR:
// 连接失败
break;
}
}
});
```
<br>
3. 连接设备:
```java
VNCommon.connect(bluetoothDevice);
```
<br>
4. 获取当前连接状态:
```java
boolean connected = VNCommon.isConnected();
```
<br>
5. 断开连接:
```java
VNCommon.disconnect();
```
<br>
## 4.3 设备信息获取
通过`getDeviceInfo`方法获取设备的基本信息包括设备名称、MAC地址、固件版本等信息
```java
VNCommon.getDeviceInfo(new VNDeviceInfoCallBack() {
@Override
public void onSuccess(VNDeviceInfo deviceInfo) {
// 获取设备信息成功
// 厂商
String manufacturer = deviceInfo.getManufacturer();
// 型号
String model = deviceInfo.getModel();
// 发行版
String edition = deviceInfo.getEdition();
// 蓝牙MAC地址
String mac = deviceInfo.getMac();
// 设备序列号
String sn = deviceInfo.getSn();
// 固件版本
String firmware = deviceInfo.getFirmware();
// 协议栈版本
String bth = deviceInfo.getBth();
}
@Override
public void onTimeOut() {
// 获取设备信息超时
}
@Override
public void onFailed() {
// 获取设备信息失败
}
});
```
<br>
## 4.4 系统配置获取
通过`getSystemConfig`方法获取当前系统的各项配置信息,包括亮度、自动亮度调节、字体大小、系统语言、佩戴检测、触控板等状态:
```java
VNCommon.getSystemConfig(new VNSystemConfigCallBack() {
@Override
public void onSuccess(VNSystemConfig systemConfig) {
// 获取系统配置成功
// 屏幕亮度值0 - 255
Integer brightness = systemConfig.getBrightness();
// 自动亮度调节状态0 - 关闭1 - 开启)
Integer autoBrightness = systemConfig.getAutoBrightnessEnabled();
// 系统语言
String language = systemConfig.getLanguage();
// 触控板状态0 - 关闭1 - 开启)
Integer touchpadEnabled = systemConfig.getTouchpadEnabled();
// ......
}
@Override
public void onTimeOut() {
// 获取系统配置超时
}
@Override
public void onFailed() {
// 获取系统配置失败
}
});
```
<br>
## 4.5 时间设置
> **提示:** 设备系统时间由 SDK 在设备连接成功时自动设置,正常情况下无需开发者进行设置。
在检测到应用终端时间发生改变的情况下,需开发者主动调用以同步时间:
```java
/**
* @param timeConfig 时间配置:时间、格式等
*/
void setTimeConfig(TimeConfig timeConfig, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:
TimeConfig timeConfig = new TimeConfig();
timeConfig.setTime(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()));
VNCommon.setTimeConfig(timeConfig, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
> 📝 **注意:** 若APP时间与眼镜设备系统时间不一致以下功能会受影响
> - [显示通知](#CUSTOM_54_1)
<br>
历史固件版本设置时间方法:
```java
/**
* @param time 时间戳,单位:秒
* @deprecated prefer setTimeConfig
*/
void setTime(long time, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:
VNCommon.setTime(System.currentTimeMillis() / 1000, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 4.6 亮度设置
手动设置亮度:
```java
/**
* @param brightness 0 - 255
*/
void setBrightness(int brightness, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:设置亮度值为 128
VNCommon.setBrightness(128, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
自动亮度调节开关:
```java
/**
* @param enabled
* VNConstant.EnableState.ENABLED - 开启
* VNConstant.EnableState.DISABLED - 关闭
*/
void setAutoBrightnessEnabled(int enabled, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:开启自动亮度功能
VNCommon.setAutoBrightnessEnabled(VNConstant.EnableState.ENABLED, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
> 📝 **注意:**
>- 亮度建议值 80 - 180 之间,结合实际场景调优。
>- 自动亮度功能需设备硬件支持。当自动亮度开启时,手动设置亮度值会被覆盖。
<br>
## 4.7 音量设置
眼镜设备音量跟随系统音量设置。
<br>
## 4.8 显示模式设置
支持显示模式设置,如全屏显示、半屏显示:
```java
/**
* @param displayConfig 显示配置:显示模式、显示区域等配置。
*/
void setDisplayConfig(DisplayConfig displayConfig, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:
DisplayConfig config = new DisplayConfig();
config.setMode(1); // 显示模式1 - 全屏0 - 半屏
VNCommon.setDisplayConfig(config, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 4.9 系统语言设置
系统界面语言设置:
```java
/**
* @param language BCP 47 语言代码
*/
void setLanguage(String language, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:设置系统语言为中文
VNCommon.setLanguage("zh-CN", new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
支持语言列表如下:
|语言 |标识符 |
|--------------------|------------|
| 中文(简体) | zh-CN |
| 中文(繁体) | zh-TW |
| English | en-US |
| 日本語 | ja |
| 한국어 | ko |
| Deutsch | de |
| Français | fr-FR |
| Русский | ru |
| Italiano | it |
| Português (Brasil) | pt-BR |
| Español (Spain) | es-ES |
| Tiếng Việt | vi |
| ภาษาไทย | th |
> 📝 **注意:** 支持的语言列表,根据设备固件版本的字库调整。
<br>
## 4.10 通知功能设置
设备支持在界面显示通知信息,当功能开启后,用户可以通过 [5.4 通知](#54-通知) 或 ANCS苹果通知中心服务向设备发送通知信息。
设置通知功能的开关状态:
```java
/**
* @param enabled
* VNConstant.EnableState.ENABLED - 开启
* VNConstant.EnableState.DISABLED - 关闭
*/
void setNotificationEnabled(int enabled, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:开启通知功能
VNCommon.setNotificationEnabled(VNConstant.EnableState.ENABLED, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
> 📝 **注意:** [5.4 通知](#54-通知) 中的**系统通知**不受该设置影响。
<br>
## 4.11 触控板设置
用户可以通过眼镜设备的触控区域进行单击、双击、长按、滑动等手势与设备交互。
设置触控板功能的开关状态:
```java
/**
* @param enabled
* VNConstant.EnableState.ENABLED - 开启
* VNConstant.EnableState.DISABLED - 关闭
*/
void setTouchpadEnabled(int enabled, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:开启触控板
VNCommon.setTouchpadEnabled(VNConstant.EnableState.ENABLED, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
**使用场景:**
- 菜单导航:快速浏览和切换不同功能界面
- 内容控制:确认选择、返回上级等操作
- 特殊场景:在不方便使用语音控制时提供替代操作方式
> 📝 **注意:** 此功能需设备硬件支持。
<br>
## 4.12 静置状态自动熄屏设置
通过设备的静置传感器检测设备是否处于静置状态(如放置在桌面)。当检测到设备静置超过 10 秒时,系统自动熄屏。
设置静置熄屏功能的开关状态:
```java
/**
* @param enabled
* VNConstant.EnableState.ENABLED - 开启
* VNConstant.EnableState.DISABLED - 关闭
*/
void setIdleDetectionEnabled(int enabled, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:开启功能
VNCommon.setIdleDetectionEnabled(VNConstant.EnableState.ENABLED, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
**使用场景:**
- 自动熄屏:用户将设备放置不动时自动进入熄屏模式
- 节能管理:通过自动熄屏机制延长设备使用时间
> 📝 **注意:**
> - 此功能需设备硬件支持。
> - 在任意功能界面进入熄屏后30 秒会收到 [系统状态监听](#CUSTOM_51_1) 的`onViewChanged(int vnAppId)`退回`HOME`主界面的消息。
<br>
## 4.13 非活跃状态自动熄屏设置
非活跃状态监听是指设备监听超过一段时间timeout无新消息抵达设备与设备无消息交互则设备自动熄屏。
```java
/**
* @param timeout 单位0 表示关闭
*/
void setInactivityTimeout(int timeout, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:设置无交互 1 分钟后自动熄屏
VNCommon.setInactivityTimeout(60, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
> 📝 **注意:**
> - 在任意功能界面进入熄屏后30 秒会收到 [系统状态监听](#CUSTOM_51_1) 的`onViewChanged(int vnAppId)`退回`HOME`主界面的消息。
> - 在特殊场景(如提词)需要保持亮屏时,可周期性(间隔低于 timeout调用 `VNCommon.sendKeepAlive()` 发送保活信号。
<br>
## 4.14 熄屏状态自动关机设置
设备支持熄屏一段时间timeout后自动关机设置
```java
/**
* @param timeout 单位0 表示关闭
*/
void setPoweroffTimeout(int timeout, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:设置熄屏 5 分钟后自动关机
VNCommon.setPoweroffTimeout(300, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 4.15 佩戴检测设置
开启佩戴检测后,当用户戴上设备时自动亮屏,摘下设备时自动熄屏:
```java
/**
* @param enabled
* VNConstant.EnableState.ENABLED - 开启
* VNConstant.EnableState.DISABLED - 关闭
*/
void setWearDetectionEnabled(int enabled, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:
VNCommon.setWearDetectionEnabled(VNConstant.EnableState.ENABLED, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
> 📝 **注意:** 此功能需设备硬件支持。
<br>
# 5 系统状态和操控
用户可以实时获取系统当前的各种状态、事件,结合业务场景来设计实现各项交互:
- `运行状态`:熄屏、亮屏
- `充电状态`:正在充电、未在充电
- `电池电量`
- `应用的进入和退出`
- `触控事件`:长按、双击、前滑、后滑
- `系统主动上报消息`:语音业务请求等
<br>
## 5.1 获取、监听、设置系统状态
<a id="CUSTOM_51_1"></a>
1. 系统状态监听
通过`setDeviceStatusListener`方法设置设备状态监听器,可以监听设备的系统状态、充电状态、电池电量、应用切换等变化,以及触控板按键事件:
```java
// 设置设备状态监听
VNCommon.setDeviceStatusListener(new VNDeviceStatusListener() {
@Override
public void onSysStateChanged(int sysState) {
// 系统状态变化回调
switch (sysState) {
case VNConstant.SysState.SCREEN_OFF:
// 熄屏状态
break;
case VNConstant.SysState.SCREEN_ON:
// 亮屏状态
break;
}
}
@Override
public void onChargeStateChanged(int chargeState) {
// 充电状态变化回调
switch (chargeState) {
case VNConstant.ChargeState.NOT_CHARGING:
// 未充电
break;
case VNConstant.ChargeState.CHARGING:
// 充电中
break;
}
}
@Override
public void onBatteryChanged(int battery) {
// 电池电量变化回调0-100
}
@Override
public void onViewChanged(int vnAppId) {
// 视图状态变化回调
switch (vnAppId) {
case VNConstant.View.HOME:
// 主页
break;
case VNConstant.View.TRANSCRIBE:
// 转写页
break;
case VNConstant.View.TRANSLATE:
// 翻译页
break;
case VNConstant.View.MAP:
// 地图页
break;
case VNConstant.View.PROMPTER:
// 提词器页
break;
case VNConstant.View.READER:
// 阅读页
break;
}
}
@Override
public void onTouchEvent(int event) {
// 设备触控板事件回调,在设备端未消费的事件
switch (event) {
case VNConstant.TouchEvent.SINGLE_TAP:
// 单击
break;
case VNConstant.TouchEvent.DOUBLE_TAP:
// 双击
break;
case VNConstant.TouchEvent.LONG_PRESS:
// 长按
break;
case VNConstant.TouchEvent.SLIP_LEFT:
// 前滑
break;
case VNConstant.TouchEvent.SLIP_RIGHT:
// 后滑
break;
default:
}
}
});
```
<br>
2. 通过`getSystemStatus`方法**主动获取**设备当时的运行状态,包括系统状态、充电状态、电池电量等:
```java
VNCommon.getSystemStatus(new VNSystemStatusCallBack() {
@Override
public void onSuccess(int sysState, int chargeState, int battery) {
// 获取设备状态成功
// sysState: 系统状态,参考 VNConstant.SysState
// chargeState: 充电状态,参考 VNConstant.ChargeState
// battery: 电池电量0-100
}
@Override
public void onFail(int code, String msg) {
// 获取设备状态失败
}
});
```
<br>
3. 在特殊场景下,开发者可**主动设置**系统运行状态:
```java
/**
* @param sysState
* VNConstant.SysState.SCREEN_ON - 亮屏状态
* VNConstant.SysState.SCREEN_OFF - 熄屏状态
*/
void setSysState(int sysState, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:将设备熄屏
VNCommon.setSysState(VNConstant.SysState.SCREEN_OFF, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
// 示例:将设备亮屏
VNCommon.setSysState(VNConstant.SysState.SCREEN_ON, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 5.2 触控板
开发者可通过 [系统状态监听](#CUSTOM_51_1) 中的 `onTouchEvent(int event)` 回调方法监听到未被设备消费的触摸事件。
在特殊场景下,支持开发者主动发送触摸事件:
```java
/**
* @param event
* VNConstant.TouchEvent.SINGLE_TAP: 单击事件
* VNConstant.TouchEvent.DOUBLE_TAP: 双击事件
* VNConstant.TouchEvent.LONG_PRESS: 长按事件
* VNConstant.TouchEvent.SLIP_LEFT: 向左滑动事件
* VNConstant.TouchEvent.SLIP_RIGHT: 向右滑动事件
*/
void sendTouchEvent(int event)
```
```java
// 示例:发送长按事件
VNCommon.sendTouchEvent(VNConstant.TouchEvent.LONG_PRESS);
```
<br>
## 5.3 应用的进入和退出
当系统被触控板或其他途径操控进入和退出应用时,开发者通过 [系统状态监听](#CUSTOM_51_1) 中的 `onViewChanged(int vnAppId)` 回调方法监听到相应的请求。
也可以主动进行应用跳转:
```java
/**
* @param vnAppId
* VNConstant.View.HOME - 主页
* VNConstant.View.TRANSCRIBE - 语音转写
* VNConstant.View.TRANSLATE - 翻译
* VNConstant.View.MAP - 导航
* VNConstant.View.PROMPTER - 题词
* VNConstant.View.GALLERY - 图库
* VNConstant.View.AI - AI会话
*/
void setView(int vnAppId, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:进入翻译应用界面
VNCommon.setView(VNConstant.View.TRANSLATE, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
// 示例:返回主页
VNCommon.setView(VNConstant.View.HOME, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
获取设备当前所在应用:
```java
void getView(VNViewCallBack vnViewCallBack)
```
```java
// 示例:获取设备当前所在应用
VNCommon.getView(new VNViewCallBack() {
@Override
public void onSuccess(int vnAppId) {
// vnAppId 参考 VNConstant.View
}
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 5.4 通知
系统支持在界面上方与用户进行通知交互:
<a id="CUSTOM_54_1"></a>
1. 显示通知:
```java
/**
* @param vnNotificationInfo
* 必选id - 区分通知用于更新、移除
* 必选title - 标题
* 必选msg - 内容
* 必选type - 通知类型0-用户1-系统
* 必选duration - 持续时间单位0 - 常驻等待关闭n - 时间到自动关闭
* 必选timeConfig - 通知时间
*/
void addNotification(VNNotificationInfo vnNotificationInfo, VNCommonCallBack vnCommonCallBack)
```
参数说明:
- 类型 `type`
- `0 - 用户`:当 [4.10 通知功能设置](#410-通知功能设置) 关闭时,用户通知将被过滤不显示;
- `1 - 系统`:不受 [4.10 通知功能设置](#410-通知功能设置) 状态影响
- 持续时间 `duration`
- `0 - 常驻等待关闭`:显示后需调用 [移除通知](#CUSTOM_54_2) 关闭,或通过双击触控板关闭
- `n - 时间到自动关闭`n 秒时间到后自动关闭
```java
// 示例:显示通知:
VNNotificationInfo notificationInfo = new VNNotificationInfo();
notificationInfo.setId(1000);
notificationInfo.setTitle("通知标题");
notificationInfo.setMsg("通知内容");
notificationInfo.setType(0);
notificationInfo.setDuration(3);
TimeConfig timeConfig = new TimeConfig();
timeConfig.setTime(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()));
notificationInfo.setTimeConfig(timeConfig);
Bitmap appIcon = ...; // (可选)通知图标
String iconBmpData = VNCommon.getVenusBmpRawData(appIcon, 32, 32, true);
notificationInfo.setIconBitmap(iconBmpData);
VNCommon.addNotification(notificationInfo, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
<a id="CUSTOM_54_2"></a>
2. 更新通知:
```java
/**
* @param vnNotificationInfo
* 必选id - 区分通知用于更新、移除
* 可选msg - 内容
*/
void updateNotification(VNNotificationInfo vnNotificationInfo, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:更新已有通知的内容
notificationInfo.setId(1000);
notificationInfo.setMsg("更新后的通知内容");
VNCommon.updateNotification(notificationInfo, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
<a id="CUSTOM_54_3"></a>
3. 移除通知:
```java
/**
* @param vnNotificationInfo
* 必选id - 区分通知用于更新、移除
*/
void removeNotification(VNNotificationInfo vnNotificationInfo, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例移除指定ID的通知
notificationInfo.setId(1000);
VNCommon.removeNotification(notificationInfo, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 5.5 文件系统
系统支持用户在 [提词信息同步](#65-提词信息同步)、 [图库](#66-图库)等应用场景下,对设备文件进行管理。如查看设备上当前已上传的提词文件列表、上传新文件等等操作。
<br>
<a id="CUSTOM_55_1"></a>
1. 文件描述
`VNFile`用于描述设备中的文件信息,包括文件名,文件/文件夹,大小等描述。
部分 API 接收 `VNFile` 参数时,开发者可通过接口将 `File` 转为 `VNFile`
```java
/**
* @param file 原文件
* @param vnFileType 应用场景
* VNConstant.VNFile.Type.PROMPTER - 题词
* VNConstant.VNFile.Type.GALLERY - 图库
* @return VNFile 设备文件描述
*/
VNFile initVNFile(File file, int vnFileType)
```
```java
// 示例:将本地文件转为题词文件描述
File file = new File("/xxx/xxx.txt");
VNFile vnFile = initVNFile(file, VNConstant.VNFile.Type.GALLERY);
```
<br>
<a id="CUSTOM_55_2"></a>
2. 文件列表
```java
/**
* @param vnFileType 应用场景
* VNConstant.VNFile.Type.PROMPTER - 题词
* VNConstant.VNFile.Type.GALLERY - 图库
*/
void getFileList(int vnFileType, VNFileListCallBack vnFileListCallBack)
```
```java
// 示例:获取设备端题词场景文件列表
VNCommon.getFileList(VNConstant.VNFile.Type.PROMPTER, new VNFileListCallBack() {
@Override public void onSuccess(List<VNFile> files) { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
<a id="CUSTOM_55_3"></a>
3. 上传文件
上传本地文件至设备指定应用场景中:
```java
// 示例上传本地txt文件至设备题词场景中
IVNFileUploadTask vnFileUploadTask = VNCommon.createFileTransferTask();
// 将要上传的本地文件
File file = new File("/xxx/xxx.txt");
// 初始化上传任务,并注册上传回调
vnFileUploadTask.init(file, VNConstant.VNFile.Type.PROMPTER, new VNFileUploadListener() {
@Override
public void onError(int code, String msg) {
// 发生错误可以通过retry重试并续传
}
@Override
public void onComplete() {
// 上传完成
}
@Override
public void onProgress(int cur, int total) {
// 上传进度
}
});
// 开始上传
vnFileUploadTask.start();
// 重试上传发生错误时通过retry重试并续传
vnFileUploadTask.retry();
// 取消当前正在进行中的任务
vnFileUploadTask.cancel();
```
<br>
4. 删除文件
```java
/**
* @param vnFile 设备文件描述
* @param vnCommonCallBack 执行结果回调
*/
VNCommon.removeFile(VNFile vnFile, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例删除由getFileList获取到的设备文件列表中的某文件
VNCommon.removeFile(vnFile, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
5. 清空目录
```java
/**
* @param vnFileType 应用场景
* VNConstant.VNFile.Type.PROMPTER - 题词
* VNConstant.VNFile.Type.GALLERY - 图库
* @param vnCommonCallBack 执行结果回调
*/
void clearFolder(int vnFileType, VNCommonCallBack vnCommonCallBack)
```
```java
// 示例:清空题词文件目录
VNCommon.clearFolder(VNConstant.VNFile.Type.PROMPTER, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
6. 检查本地文件是否在设备存在
通常情况下,如果本地目标文件在设备端已经存在,则不需要重新上传。判断是否存在:
```java
/**
* @param file 原文件
* @param vnFileType 应用场景
* VNConstant.VNFile.Type.PROMPTER - 题词
* VNConstant.VNFile.Type.GALLERY - 图库
* @param vnCommonCallBack 执行结果回调
*/
void isFileExist(File file, int vnFileType, VNCommonCallBack vnCommonCallBack)
```
```java
VNCommon.isFileExist(file, VNConstant.VNFile.Type.GALLERY, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 5.6 查看存储空间
```java
/**
* @param vnRomUsageCallBack 查询结果回调
*/
void getRomUsage(VNRomUsageCallBack vnRomUsageCallBack)
```
```java
// 示例:查询设备存储空间情况
VNCommon.getRomUsage(new VNRomUsageCallBack() {
@Override
public void onSuccess(VNRomUsage usage) {
long remaining = usage.getRemaining(); // 单位KB
long total = usage.getTotal(); // 单位KB
}
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 5.7 监听设备主动消息
监听由眼镜设备主动上报的请求,如唤醒、助手等业务:
```java
// 示例:设置设备主动上报监听
VNCommon.setDeviceUnsolicitedListener(new VNDeviceUnsolicitedListener() {
@Override
public void onSttRequest() {
// 设备发出 STT 请求,至于是需要进入 `TRANSCRIBE` 或 `TRANSLATE` 由 APP 决策
}
});
```
<br>
## 5.8 重启
```java
VNCommon.reboot(new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 5.9 恢复出厂设置
```java
VNCommon.factoryReset(new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 5.10 解绑设备
```java
VNCommon.unbind(new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
# 6. 应用
系统支持常用的应用场景界面,如实时翻译、题词、导航等,并支持开发者把上位机获取到的实时业务信息发送到设备端呈现。
<br>
## 6.1 实时翻译(语音转文字显示)信息同步
<br>
系统提供将`实时翻译结果`传输到设备端进行显示的方法,以下是使用步骤:
**步骤一:进入翻译应用**
```java
// 示例:
VNCommon.setView(VNConstant.View.TRANSLATE, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
**步骤二:配置界面偏好**
<a id="CUSTOM_61_STEP2_setTextMode"></a>
- **设置文本显示模式** 语音业务时界面`仅当前``含历史`
```java
/**
* @param vnAppId 应用,与 setView() 对应。
* @param mode 模式:
* VNConstant.SttConfig.TextMode.CURRENT_ONLY - 仅显示当前转写文本
* VNConstant.SttConfig.TextMode.CURRENT_AND_HISTORICAL - 同时显示当前和历史转写文本
* @param vnCommonCallBack 执行结果回调可为null
*/
void setTextMode(int vnAppId, int mode, VNCommonCallBack vnCommonCallBack)
```
<br>
<a id="CUSTOM_61_STEP2_setTransMode"></a>
- **设置译文显示模式** 语音翻译业务时界面`仅显示译文`或`译文和原文都显示`
```java
/**
* @param vnAppId 应用与setView()对应。
* @param mode 模式:
* VNConstant.SttConfig.TransMode.TRANSLATION_ONLY - 仅显示翻译文本
* VNConstant.SttConfig.TransMode.ORIGINAL_AND_TRANSLATION - 同时显示翻译文本和原文
* @param vnCommonCallBack 执行结果回调可为null。
*/
void setTransMode(int vnAppId, int mode, VNCommonCallBack vnCommonCallBack)
```
<br>
<a id="CUSTOM_61_STEP2_setFontConfig"></a>
- **设置字号**
```java
// 字号配置
FontConfig fontConfig = new FontConfig();
fontConfig.setWeight(30); // 字体大小,整数类型,建议 30
fontConfig.setWordSpace(1); // 字间距,整数类型,控制字符之间的间距
fontConfig.setRowSpace(8); // 行间距,整数类型,控制行与行之间的间距
/**
* @param vnAppId 应用,与 setView() 对应。
* @param fontConfig 字号配置。
* @param vnCommonCallBack 执行结果回调,可为 null。
*/
void setFontConfig(int vnAppId, FontConfig fontConfig, VNCommonCallBack vnCommonCallBack);
```
<br>
<a id="CUSTOM_61_STEP2_setLanguageHint"></a>
- **设置当前语种信息提示**
```java
// 语种信息提示配置
LanguageHint languageHint = new LanguageHint();
languageHint.setMode(1); // 0 - 仅显示源语言1 - 源语言与目标语言双向显示
languageHint.setSource("中文");
languageHint.setTarget("English");
/**
* @param vnAppId 应用,与 setView() 对应。
* @param languageHint 语种信息提示配置
* @param vnCommonCallBack 执行结果回调,可为 null。
*/
void setLanguageHint(int vnAppId, LanguageHint languageHint, VNCommonCallBack vnCommonCallBack)
```
<br>
<a id="CUSTOM_61_STEP2_setAudioSourceIndicator"></a>
- **设置当前拾音指示** 指示当前是`手机拾音`或是`眼镜设备拾音`
```java
/**
* @param vnAppId 应用与setView()对应。
* @param audioSource 音源:
* VNConstant.SttConfig.AudioSource.PHONE - 使用手机麦克风作为音频输入源
* VNConstant.SttConfig.AudioSource.GLASSES - 使用眼镜设备麦克风作为音频输入源
* @param vnCommonCallBack 执行结果回调可为null。
*/
void setAudioSourceIndicator(int vnAppId, int audioSource, VNCommonCallBack vnCommonCallBack)
```
> 📝 **注意:** 仅图标指示。实际音源切换通过 Android 平台标准 API 实现。
<br>
<a id="CUSTOM_61_STEP2_setMicDirectional"></a>
- **设置麦克风拾音方向** 当眼镜设备拾音时,拾音方向为`前向`或`全向`
```java
/**
* @param vnAppId 应用与setView()对应。
* @param micDirectional 拾音方向:
* VNConstant.SttConfig.MicDirectional.OMNI - 全向收音,接收来自各个方向的声音
* VNConstant.SttConfig.MicDirectional.FRONT - 定向收音,主要接收正前方向的声音
*/
void setMicDirectional(int vnAppId, int micDirectional, VNCommonCallBack vnCommonCallBack)
```
> 📝 **注意:** 仅当前为**眼镜设备拾音**时生效。
<br>
**步骤三:发送语音转文字内容**
开发者可以通过`VNSttInfo`描述实时转写的内容和状态包括消息ID、类型、内容、显示区域等。支持根据**消息ID**进行新增、更新更正、移除对应消息:
- `msgId`消息ID整数类型用于多消息同步更新的会话场景相同msgId的消息会被关联处理。
- `transcribeStr`:转写文本内容,字符串类型
- `translateStr`:翻译文本内容,字符串类型
- `msgType`:消息类型
- `VNConstant.SttInfo.MsgType.STT` 转写内容消息
- `VNConstant.SttInfo.MsgType.HINT` 提示消息,如“正在听...”“网络波动”等提示HINT类型消息不会进入历史显示。
- `area`:显示区域,对话场景
- `VNConstant.SttInfo.Area.LEFT` 居左
- `VNConstant.SttInfo.Area.RIGHT` 居右
- `VNConstant.SttInfo.Area.CENTER` 居中
- `actionType`:动作类型,用于指定是新建还是更新消息
- `VNConstant.SttInfo.ActionType.NEW` 新建一个语句
- `VNConstant.SttInfo.ActionType.UPDATE` 更新更正语音转文字内容,用于实时场景
- `VNConstant.SttInfo.ActionType.REMOVE` 移除语句
- `isFinal`:最终更正结果标志,如果界面停在 isFinal 条目,则支持划动触控板向前浏览
<br>
场景一:顺序推送实时转写结果,不会出现更新历史句、移除某句的场景时,可以不指定`msgId`,而是通过`actionType`来控制句子更新,`NEW`新增一句、`UPDATE`更新更正上一次推送:
```java
// 示例:新建一句
VNSttInfo sttInfo = new VNSttInfo();
sttInfo.setTranscribe(transcribeStr);
sttInfo.setTranslate(translateStr);
sttInfo.setMsgType(VNConstant.SttInfo.MsgType.STT);
sttInfo.setActionType(VNConstant.SttInfo.ActionType.NEW);
VNCommon.updateSttInfo(vnAppId, sttInfo, null);
// 示例:更新上一次推送
VNSttInfo sttInfo = new VNSttInfo();
sttInfo.setTranscribe(transcribeStr);
sttInfo.setTranslate(translateStr);
sttInfo.setMsgType(VNConstant.SttInfo.MsgType.STT);
sttInfo.setActionType(VNConstant.SttInfo.ActionType.UPDATE);
VNCommon.updateSttInfo(vnAppId, sttInfo, null);
```
<br>
场景二:当 [文本显示模式](#CUSTOM_61_STEP2_setTextMode) 切换为`含历史`时,可能更新历史句,或可能删除某句的业务场景时,需要指定 `msgId` 来实现:
```java
// 示例更新更正msgId句
VNSttInfo sttInfo = new VNSttInfo();
sttInfo.setMsgId(msgId);
sttInfo.setTranscribe(transcribeStr);
sttInfo.setTranslate(translateStr);
sttInfo.setMsgType(VNConstant.SttInfo.MsgType.STT);
sttInfo.setActionType(VNConstant.SttInfo.ActionType.UPDATE);
VNCommon.updateSttInfo(vnAppId, sttInfo, null);
// 示例移除某msgId句
VNSttInfo sttInfo = new VNSttInfo();
sttInfo.setMsgId(msgId);
sttInfo.setActionType(VNConstant.SttInfo.ActionType.REMOVE);
VNCommon.updateSttInfo(vnAppId, sttInfo, null);
```
<br>
**步骤四:退出转写应用**
```java
// 返回主页
VNCommon.setView(VNConstant.View.HOME, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 6.2 实时转写(语音转文字显示)信息同步
使用步骤同 [6.1 实时翻译(语音转文字显示)信息同步](#61-实时翻译语音转文字显示信息同步),调整:
- 将所有vnAppId参数换为VNConstant.View.TRANSCRIBE
- 移除sttInfo.setTranscribe(transcribeStr);
<br>
## 6.3 对话信息同步
用于语音助手等问答场景,界面支持区分左右条目:
使用步骤同 [6.1 实时翻译(语音转文字显示)信息同步](#61-实时翻译语音转文字显示信息同步),调整:
- 将所有vnAppId参数换为 `VNConstant.View.AI`
- 通过sttInfo.setArea()设置该句的显示区域;
<br>
## 6.4 导航信息同步
将`实时导航信息`同步至设备端显示的步骤如下:
<br>
**步骤一:进入导航应用**
```java
// 切换到导航应用界面
VNCommon.setView(VNConstant.View.MAP, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
**步骤二:发送导航信息**
```java
// 创建导航信息对象
VNNavInfo navInfo = new VNNavInfo();
// 设置导航信息参数
navInfo.setCurStepRetainDistance("500米"); // 当前导航段剩余距离
navInfo.setNextRoadName("前方道路名称"); // 下一条道路名称
navInfo.setSpeed("60km/h"); // 当前行驶速度
navInfo.setRemainDistance("17.2公里"); // 剩余里程
navInfo.setRemainTime("22分钟"); // 剩余时间
navInfo.setNavMode(1); // 导航模式 1-驾驶
Bitmap customIcon = ...; // 自定义图标位图
String iconBmpData = VNCommon.getVenusBmpRawData(customIcon, width, height, true);
navInfo.setIconBitmap(iconBmpData);
// 发送导航信息到设备
VNCommon.updateNav(navInfo, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
- 图标尺寸建议48x48使用 `VNCommon.getVenusBmpRawDataNav(bitmap, 48, 48)`
<br>
**步骤三:退出导航应用**
```java
// 返回主页
VNCommon.setView(VNConstant.View.HOME, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 6.5 提词信息同步
本功能支持将`txt`格式的文件同步至设备端显示。
**步骤一:进入提词应用**
```java
// 切换到提词应用界面
VNCommon.setView(VNConstant.View.PROMPTER, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
**步骤二(可选):设置界面偏好**
- **设置是否显示上下文** 界面显示上一页的末行和下一页的首行
```java
// 设置是否显示上下文0 - 不显示1 - 显示
VNCommon.setPrompterContextLine(1, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
- **设置字号**
```java
// 字号配置
FontConfig fontConfig = new FontConfig();
fontConfig.setWeight(30); // 字体大小,整数类型,建议 30
fontConfig.setWordSpace(1); // 字间距,整数类型,控制字符之间的间距
fontConfig.setRowSpace(8); // 行间距,整数类型,控制行与行之间的间距
/**
* @param vnAppId 应用与setView()对应。
* @param fontConfig 字号配置。
* @param vnCommonCallBack 执行结果回调可为null。
*/
void setFontConfig(int vnAppId, FontConfig fontConfig, VNCommonCallBack vnCommonCallBack);
```
> ⚠️ 重要:不支持提词过程中设置字号,须在设置文件之前完成字号设置
<br>
**步骤三:监听提词动态** 获取眼镜设备端实时显示内容和进度
```java
VNCommon.setPrompterListener(new VNPrompterListener() {
@Override
public void onPageChanged(VNPrompterPage p) {
// 进度
int curPage = p.getCurrent();
int totalPage = p.getTotal();
// 当前显示的正文
String curContent = p.getCurText().getContent(); // 文本内容
int curStart = p.getCurText().getStart(); // 在原文档的起始位置(字节)
int curEnd = p.getCurText().getEnd(); // 在原文档的结束位置(字节)
// 当前显示的上下文
String preContent = p.getPreText().getContent();
int preStart = p.getPreText().getStart();
int preEnd = p.getPreText().getEnd();
String nextContent = p.getNextText().getContent();
int nextStart = p.getNextText().getStart();
int nextEnd = p.getNextText().getEnd();
}
@Override
public void onLoadStart() {
// 文档加载开始。根据文档大小,加载时间不同,加载过程中须提示用户
}
@Override
public void onLoadEnd() {
// 文档加载完成。完成后可以设置目标页面。
}
});
```
<br>
**步骤四:设置提词文档**
将当前App可访问的`txt`文件通过setPrompterFile接口通知设备端进行加载
onSuccess():加载成功,进行下一步,参考 [显示目标页面](#CUSTOM_65_STEP5) 的说明;
onFailed():加载失败,需通过 [上传文件](#CUSTOM_55_3) 后重试。
```java
// 示例将file设置为题词文件
VNCommon.setPrompterFile(file, new VNCommonCallBack() {
@Override
public void onSuccess() {
// 设备端检查文件通过,进行下一步,设置页面显示
}
@Override
public void onTimeOut() {
// 检查超时,提示用户或重试
}
@Override
public void onFailed() {
// 设备端检查文件未通过需上传file文件后再试
}
});
```
> ⚠️ **重要:** 仅支持utf-8编码的txt格式文档
> 📝 **注意:** 建议文件大小不超过 30 KB
<br>
<a id="CUSTOM_65_STEP5"></a>
**步骤五:显示目标页面**
当文档设置成功后,通过此接口显示目标页面:
```java
// 示例:显示首页
VNPrompterPage vnPrompterPage = new VNPrompterPage();
vnPrompterPage.setCurrent(1);
VNCommon.setPrompterPage(vnPrompterPage, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
**步骤六:翻页**
可通过设备触控区域前后滑动翻页也可通过调用API发送翻页指令
```java
// 示例:前一页
VNCommon.setPrompterPageUp(new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
// 示例:后一页
VNCommon.setPrompterPageDown(new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
**步骤七:退出题词**
```java
// 示例:返回主页
VNCommon.setView(VNConstant.View.HOME, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
## 6.6 图库
**步骤一:进入图库应用**
```java
VNCommon.setView(VNConstant.View.GALLERY, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
**步骤二:显示图片**
- **显示已在眼镜设备上存在的图片**
通过 [文件列表](#CUSTOM_55_2) 获取Gallery类型的VNFile列表选择列表中文件显示
```java
// 示例:或通过设备端文件对象
VNCommon.setGalleryFile(vnFile, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
- **上传 APP 端图片到眼镜设备并显示**
通过 [上传文件](#CUSTOM_55_3) 上传Gallery类型的file文件上传成功后显示
```java
// 示例:
File file = new File("/xxx/xxx.jpg");
VNCommon.setGalleryFile(file, new VNCommonCallBack() {
@Override
public void onSuccess() {
// 设备端检查文件通过,显示图片
}
@Override
public void onTimeOut() {
// 检查超时,提示用户或重试
}
@Override
public void onFailed() {
// 设备端检查文件未通过需上传file文件后再试
}
});
```
> **⚠️ 重要:** 图片文件需由 APP 端预处理:
> - 分辨率:根据设备型号查询
> - 文件大小:建议不超过 200 KB
> - 图像:灰度图
<br>
**步骤三:退出图库**
```java
// 示例:返回主页
VNCommon.setView(VNConstant.View.HOME, new VNCommonCallBack() {
@Override public void onSuccess() { }
@Override public void onTimeOut() { }
@Override public void onFailed() { }
});
```
<br>
# 7. 应用定制
联系我们
<br>
# 8. 固件升级
固件升级服务通过专用数据通路VNOTA工作在进行固件升级之前需要先断开与设备的消息服务通路VNCommon
<br>
```
+-------------+ +------------+ +-----------+
| Application | | VNCommon | | VNOTA |
+-------------+ +------------+ +-----------+
| | |
| 检查VNCommon连接状态 | |
|---------------------->| |
| | |
| 如果已连接断开VNCommon |
|---------------------->| |
| | |
| 等待VNCommon完全断开 | |
| | |
| 初始化VNOTA | |
|--------------------------------------------->|
| | |
| 连接VNOTA | |
|--------------------------------------------->|
| | |
| | onConnected |
|<---------------------------------------------|
| | |
| | onStateChanged(2305) |
|<---------------------------------------------|
| | |
| 开始OTA升级 | |
|--------------------------------------------->|
| | |
| | onProgressChanged |
|<---------------------------------------------|
| | |
| | onSuccess/onError|
|<---------------------------------------------|
| | |
| 断开VNOTA连接 | |
|--------------------------------------------->|
| | |
| | onDisconnected |
|<---------------------------------------------|
| | |
| 重新连接VNCommon | |
|---------------------->| |
| | |
```
<br>
1. **准备阶段**
- 检查设备电量是否满足升级要求,建议电量在 40% 以上;
- 检查OTA文件是否有效且本地存储路径可访问。
<br>
2. **断开VNCommon连接**
- 如有自动重连机制,请停止;
- 断开VNCommon连接: `VNCommon.disconnect()`
- 等待并确认VNCommon已断开。
```java
// 断开消息服务通路
VNCommon.disconnect();
// 检查连接状态,如通过轮询
new Runnable() {
@Override
public void run() {
if (retryCount < maxRetries) {
if (VNCommon.isConnected()) {
retryCount++;
handler.postDelayed(this, 1000);
} else {
// TODO 已断开连接,可以进行固件升级操作
}
}
}
};
// 确认断开连接后再进行固件升级操作
```
<br>
3. **设置OTA状态监听**
```java
VNOTA.setOtaServiceListener(new VNOtaServiceListener() {
@Override
public void onConnected() {
// 服务已连接
}
@Override
public void onDisconnected() {
// 服务已断开
}
@Override
public void onStateChanged(int state, String msg) {
// 升级过程中阶段变化提示
if (state == 2305) {
VNOTA.startOta();
}
}
@Override
public void onProgressChanged(String progress) {
// 升级进度变更
}
@Override
public void onSuccess() {
// OTA升级成功
// TODO VNCommon.connect()
}
@Override
public void onError(int code, String msg) {
// OTA升级失败
// code: 错误码,具体定义参考 VNConstant.Ota.ErrorCode
// msg: 错误信息
}
});
```
<br>
4. **初始化并连接VNOTA**
```java
BluetoothDevice device = null; // 蓝牙设备实例
String otaFilePath = ""; // 升级文件路径
int otaUser = VNConstant.Ota.User.FIRMWARE; // FIRMWARE表示固件升级
VNOTA.initOta(device, otaFilePath, otaUser);
//连接设备的OTA服务链路
VNOTA.connect(device)
```
<br>
5. **执行OTA升级**
- 在VNOTA连接成功后SDK内部会开始协商请等待`onStateChanged`
- ⚠️ 重要:当`onStateChanged`收到 `state == 2305` 时开始OTA: `VNOTA.startOta()`
- 通过监听器接收升级进度: `onProgressChanged()`
```java
...
@Override
public void onStateChanged(int state, String msg) {
if (state == 2305) {
VNOTA.startOta();
}
}
...
```
<br>
5. **OTA完成处理**
- 升级成功: `onSuccess()`
- 断开VNOTA连接: `VNOTA.disconnect()`
- 如有,清除本地设备信息,待重新连接后获取升级后的设备信息;
- 建立VNCommon连接`VNCommon.disconnect()`。
- 升级失败: `onError()`
- 断开VNOTA连接: `VNOTA.disconnect()`
- 显示错误对话框,重试或退出。
<br>
> 📝 **注意:**
> 1. 在进行 OTA 升级时,需要确保设备电量充足(至少 40%
> 2. OTA 升级过程中不应中断,可能导致设备固件损坏;
> 3. 在 OTA 升级完成后,正常情况下设备会自动重启,启动时间比正常开机用时长 1 - 2 分钟。
<br>
# 9. 常见问题
<br>
## 9.1 设备无法扫描到
- 检查设备是否开机并停留在蓝牙配对界面
- 检查设备是否已与其他终端配对并连接
<br>
## 9.2 设备没有声音
- 检查系统蓝牙连接状态,需要 A2DP、HFP 连接正常
<br>
# 10. 更新历史
<br>