801 lines
15 KiB
Markdown
801 lines
15 KiB
Markdown
# 小屏幕WiFi+蓝牙配网功能设计
|
||
|
||
## 1. 概述
|
||
|
||
本设计针对504×410分辨率的小屏幕设备,实现蓝牙配网功能。用户通过长按屏幕左上角进入配网模式,使用蓝牙与移动端配网APP建立连接,完成WiFi网络配置。
|
||
|
||
### 核心特性
|
||
- **小屏幕优化**: 专为504×410分辨率设计的触摸友好界面
|
||
- **蓝牙配网**: 通过蓝牙连接进行网络配置
|
||
- **手势触发**: 长按左上角触发配网模式
|
||
- **状态反馈**: 实时显示配网进度和连接状态
|
||
- **自动重试**: 配网失败时自动重试连接
|
||
|
||
## 2. 技术架构
|
||
|
||
### 2.1 系统架构图
|
||
|
||
``mermaid
|
||
graph TD
|
||
A[用户长按触发] --> B[配网模式检测器]
|
||
B --> C[蓝牙配网管理器]
|
||
|
||
C --> D[蓝牙配网服务]
|
||
|
||
D --> F[蓝牙广播服务]
|
||
D --> G[配网数据接收器]
|
||
|
||
F --> J[移动端配网APP]
|
||
|
||
G --> L[网络连接器]
|
||
|
||
L --> M[连接状态管理器]
|
||
M --> N[配网结果反馈]
|
||
```
|
||
|
||
### 2.2 核心组件
|
||
|
||
#### BluetoothConfigManager (蓝牙配网管理器)
|
||
``mermaid
|
||
classDiagram
|
||
class BluetoothConfigManager {
|
||
-BluetoothConfigService bluetoothService
|
||
-ConnectionStatusManager statusManager
|
||
+startConfigMode()
|
||
+stopConfigMode()
|
||
+switchConfigMode()
|
||
+onConfigResult()
|
||
}
|
||
|
||
class BluetoothConfigService {
|
||
-BluetoothAdapter adapter
|
||
-ConfigDataReceiver receiver
|
||
+startAdvertising()
|
||
+stopAdvertising()
|
||
+onDataReceived()
|
||
}
|
||
|
||
class WiFiHotspotConfigService {
|
||
-WifiManager wifiManager
|
||
-HTTPConfigServer server
|
||
+createHotspot()
|
||
+startConfigServer()
|
||
+onConfigReceived()
|
||
}
|
||
```
|
||
|
||
## 3. 功能模块设计
|
||
|
||
### 3.1 触发机制
|
||
|
||
#### 长按检测器 (LongPressDetector)
|
||
``mermaid
|
||
sequenceDiagram
|
||
participant U as 用户
|
||
participant D as LongPressDetector
|
||
participant M as ConfigNetworkManager
|
||
participant UI as ConfigModeUI
|
||
|
||
U->>D: 长按左上角区域
|
||
D->>D: 检测按压时长(3秒)
|
||
D->>M: triggerConfigMode()
|
||
M->>UI: showConfigModeDialog()
|
||
UI->>U: 显示配网选择界面
|
||
```
|
||
|
||
#### 触摸区域定义
|
||
- **触发区域**: 左上角50×50dp区域
|
||
- **长按时长**: 3秒钟
|
||
- **视觉反馈**: 渐进式圆形进度指示器
|
||
|
||
### 3.2 BLE配网模式
|
||
|
||
#### BLE服务端架构
|
||
```mermaid
|
||
flowchart TD
|
||
A[小程序客户端] --> B[连接设备iB86]
|
||
B --> C[BLE GATT服务器]
|
||
|
||
C --> D[Service 0xFA00]
|
||
D --> E[Characteristic 0xEA01<br/>状态通知]
|
||
D --> F[Characteristic 0xEA03<br/>扫描指令]
|
||
D --> G[Characteristic 0xEA05<br/>SSID配置]
|
||
D --> H[Characteristic 0xEA06<br/>密码配置]
|
||
|
||
F --> I[WiFi扫描器]
|
||
I --> J[扫描结果]
|
||
J --> E
|
||
|
||
G --> K[配网管理器]
|
||
H --> K
|
||
K --> L[WiFi连接器]
|
||
L --> M[连接状态]
|
||
M --> E
|
||
```
|
||
|
||
#### BLE协议规范
|
||
|
||
**设备信息**
|
||
- **设备名称**: iB86
|
||
- **Service UUID**: 0xFA00
|
||
- **角色**: BLE服务端(GATT Server)
|
||
|
||
**Characteristic定义**
|
||
|
||
| UUID | 权限 | 功能描述 |
|
||
|------|------|----------|
|
||
| 0xEA01 | Notify | 状态通知和扫描结果回传 |
|
||
| 0xEA03 | Write | 接收扫描指令 |
|
||
| 0xEA05 | Write | 接收WiFi SSID |
|
||
| 0xEA06 | Write | 接收WiFi密码 |
|
||
|
||
#### AT命令协议
|
||
|
||
**状态码定义**
|
||
```
|
||
AT+STATE=0 # 当前无操作
|
||
AT+STATE=1 # 收到扫描指令,开始扫描网络
|
||
AT+STATE=2 # 收到SSID和密码,开始连接网络
|
||
AT+STATE=3 # 已连接WiFi并获取IP
|
||
AT+STATE=6 # 密码错误
|
||
AT+STATE=7 # 没有找到该WiFi
|
||
```
|
||
|
||
**指令格式**
|
||
```
|
||
# 扫描指令
|
||
AT+SSID # 或 AT+SCAN
|
||
|
||
# 扫描结果回传格式
|
||
AT+SSID=<数量>,<SSID1>,<SSID2>,...,<SSIDn>
|
||
# 示例: AT+SSID=1603,iLock,TP-LINK15DA,HUAWEI-AB8D
|
||
```
|
||
|
||
#### 配网流程
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant MP as 小程序
|
||
participant BLE as BLE服务器
|
||
participant WIFI as WiFi扫描器
|
||
participant NET as 网络连接器
|
||
|
||
MP->>BLE: 连接设备iB86
|
||
MP->>BLE: 写入0xEA03 "AT+SSID"
|
||
BLE->>BLE: 更新状态AT+STATE=1
|
||
BLE->>WIFI: 开始WiFi扫描
|
||
WIFI->>BLE: 返回扫描结果
|
||
BLE->>MP: 通过0xEA01回传扫描结果
|
||
|
||
MP->>BLE: 写入0xEA05 目标SSID
|
||
MP->>BLE: 写入0xEA06 WiFi密码
|
||
BLE->>BLE: 更新状态AT+STATE=2
|
||
BLE->>NET: 尝试连接WiFi
|
||
|
||
alt 连接成功
|
||
NET->>BLE: 连接成功并获取IP
|
||
BLE->>BLE: 更新状态AT+STATE=3
|
||
BLE->>MP: 通过0xEA01通知成功
|
||
else 密码错误
|
||
NET->>BLE: 认证失败
|
||
BLE->>BLE: 更新状态AT+STATE=6
|
||
BLE->>MP: 通过0xEA01通知密码错误
|
||
else 网络未找到
|
||
NET->>BLE: 网络不存在
|
||
BLE->>BLE: 更新状态AT+STATE=7
|
||
BLE->>MP: 通过0xEA01通知网络未找到
|
||
end
|
||
```
|
||
|
||
## 4. 用户界面设计
|
||
|
||
### 4.1 小屏幕适配规范
|
||
|
||
#### 布局约束
|
||
``xml
|
||
<!-- 小屏幕配网界面约束 -->
|
||
<constraints>
|
||
<screen_size>504x410dp</screen_size>
|
||
<touch_target_min>48dp</touch_target_min>
|
||
<text_size_min>16sp</text_size_min>
|
||
<margin_horizontal>16dp</margin_horizontal>
|
||
<margin_vertical>12dp</margin_vertical>
|
||
</constraints>
|
||
```
|
||
|
||
#### 界面层级结构
|
||
```mermaid
|
||
graph TD
|
||
A[长按触发] --> B[BLE配网页面]
|
||
|
||
B --> C[BLE服务器启动]
|
||
B --> D[等待小程序连接]
|
||
B --> E[WiFi扫描状态]
|
||
B --> F[配网进度显示]
|
||
B --> G[连接结果页面]
|
||
|
||
G --> H[返回主界面]
|
||
```
|
||
|
||
### 4.2 状态指示器设计
|
||
|
||
#### 配网状态机
|
||
```mermaid
|
||
stateDiagram-v2
|
||
[*] --> 待机模式
|
||
待机模式 --> 配网触发检测 : 长按左上角
|
||
配网触发检测 --> BLE服务启动 : 触发成功
|
||
|
||
BLE服务启动 --> 等待连接 : AT+STATE=0
|
||
等待连接 --> WiFi扫描 : 收到AT+SSID指令
|
||
WiFi扫描 --> 扫描中 : AT+STATE=1
|
||
扫描中 --> 等待配置 : 回传扫描结果
|
||
|
||
等待配置 --> 连接WiFi : 收到SSID和密码
|
||
连接WiFi --> 连接中 : AT+STATE=2
|
||
|
||
连接中 --> 连接成功 : AT+STATE=3
|
||
连接中 --> 密码错误 : AT+STATE=6
|
||
连接中 --> 网络未找到 : AT+STATE=7
|
||
|
||
连接成功 --> [*]
|
||
密码错误 --> 等待配置 : 重新配置
|
||
网络未找到 --> 等待配置 : 重新配置
|
||
```
|
||
|
||
## 5. 数据模型
|
||
|
||
### 5.1 配网配置模型
|
||
|
||
#### WiFiConfigData
|
||
```java
|
||
public class WiFiConfigData {
|
||
private String ssid; // WiFi名称
|
||
private String password; // WiFi密码
|
||
private SecurityType security; // 加密类型
|
||
private boolean isHidden; // 是否隐藏网络
|
||
private String ipConfig; // IP配置类型
|
||
private String proxyConfig; // 代理配置
|
||
}
|
||
```
|
||
|
||
#### BluetoothConfigStatus
|
||
```java
|
||
public class BluetoothConfigStatus {
|
||
private ConfigState state; // 配网状态
|
||
private String message; // 状态消息
|
||
private int progress; // 进度百分比
|
||
private long timestamp; // 时间戳
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.2 枚举定义
|
||
|
||
```java
|
||
public enum ConfigState {
|
||
IDLE("待机"), // AT+STATE=0
|
||
DETECTING("检测触发"),
|
||
BLE_SERVER_STARTING("BLE服务启动"),
|
||
WAITING_CONNECTION("等待连接"),
|
||
WIFI_SCANNING("WiFi扫描中"), // AT+STATE=1
|
||
WAITING_CONFIG("等待配置"),
|
||
CONNECTING_WIFI("连接WiFi中"), // AT+STATE=2
|
||
SUCCESS("连接成功"), // AT+STATE=3
|
||
PASSWORD_ERROR("密码错误"), // AT+STATE=6
|
||
NETWORK_NOT_FOUND("网络未找到"); // AT+STATE=7
|
||
}
|
||
```
|
||
|
||
## 6. 核心服务实现
|
||
|
||
### 6.1 配网触发服务
|
||
|
||
#### LongPressGestureDetector
|
||
```java
|
||
public class LongPressGestureDetector {
|
||
private static final long LONG_PRESS_DURATION = 3000; // 3秒
|
||
private static final int TRIGGER_AREA_SIZE = 50; // 50dp
|
||
|
||
public boolean isInTriggerArea(float x, float y) {
|
||
return x <= dpToPx(TRIGGER_AREA_SIZE) &&
|
||
y <= dpToPx(TRIGGER_AREA_SIZE);
|
||
}
|
||
|
||
public void handleTouchEvent(MotionEvent event) {
|
||
// 处理触摸事件逻辑
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6.2 BLE配网服务
|
||
|
||
#### BleConfigGattServer
|
||
```java
|
||
public class BleConfigGattServer {
|
||
// UUID定义
|
||
private static final UUID SERVICE_UUID = UUID.fromString("0000fa00-0000-1000-8000-00805f9b34fb");
|
||
private static final UUID STATUS_CHAR_UUID = UUID.fromString("0000ea01-0000-1000-8000-00805f9b34fb");
|
||
private static final UUID SCAN_CHAR_UUID = UUID.fromString("0000ea03-0000-1000-8000-00805f9b34fb");
|
||
private static final UUID SSID_CHAR_UUID = UUID.fromString("0000ea05-0000-1000-8000-00805f9b34fb");
|
||
private static final UUID PASSWORD_CHAR_UUID = UUID.fromString("0000ea06-0000-1000-8000-00805f9b34fb");
|
||
|
||
private BluetoothGattServer gattServer;
|
||
private ATCommandProcessor atProcessor;
|
||
|
||
public void startGattServer() {
|
||
BluetoothGattService service = new BluetoothGattService(
|
||
SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY);
|
||
|
||
// 0xEA01 - 状态通知Characteristic
|
||
BluetoothGattCharacteristic statusChar = new BluetoothGattCharacteristic(
|
||
STATUS_CHAR_UUID,
|
||
BluetoothGattCharacteristic.PROPERTY_NOTIFY,
|
||
BluetoothGattCharacteristic.PERMISSION_READ);
|
||
|
||
// 0xEA03 - 扫描指令Characteristic
|
||
BluetoothGattCharacteristic scanChar = new BluetoothGattCharacteristic(
|
||
SCAN_CHAR_UUID,
|
||
BluetoothGattCharacteristic.PROPERTY_WRITE,
|
||
BluetoothGattCharacteristic.PERMISSION_WRITE);
|
||
|
||
// 0xEA05 - SSID配置Characteristic
|
||
BluetoothGattCharacteristic ssidChar = new BluetoothGattCharacteristic(
|
||
SSID_CHAR_UUID,
|
||
BluetoothGattCharacteristic.PROPERTY_WRITE,
|
||
BluetoothGattCharacteristic.PERMISSION_WRITE);
|
||
|
||
// 0xEA06 - 密码配置Characteristic
|
||
BluetoothGattCharacteristic passwordChar = new BluetoothGattCharacteristic(
|
||
PASSWORD_CHAR_UUID,
|
||
BluetoothGattCharacteristic.PROPERTY_WRITE,
|
||
BluetoothGattCharacteristic.PERMISSION_WRITE);
|
||
|
||
service.addCharacteristic(statusChar);
|
||
service.addCharacteristic(scanChar);
|
||
service.addCharacteristic(ssidChar);
|
||
service.addCharacteristic(passwordChar);
|
||
|
||
gattServer.addService(service);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### ATCommandProcessor
|
||
```java
|
||
public class ATCommandProcessor {
|
||
private WiFiScanManager wifiScanner;
|
||
private WiFiConnectionManager wifiConnector;
|
||
private BleConfigGattServer gattServer;
|
||
|
||
public void processCommand(String command, UUID characteristicUuid) {
|
||
if (SCAN_CHAR_UUID.equals(characteristicUuid)) {
|
||
if ("AT+SSID".equals(command) || "AT+SCAN".equals(command)) {
|
||
handleWiFiScan();
|
||
}
|
||
} else if (SSID_CHAR_UUID.equals(characteristicUuid)) {
|
||
handleSSIDConfig(command);
|
||
} else if (PASSWORD_CHAR_UUID.equals(characteristicUuid)) {
|
||
handlePasswordConfig(command);
|
||
}
|
||
}
|
||
|
||
private void handleWiFiScan() {
|
||
notifyState(1); // AT+STATE=1
|
||
wifiScanner.startScan(new WiFiScanCallback() {
|
||
@Override
|
||
public void onScanCompleted(List<String> ssidList) {
|
||
String result = formatScanResult(ssidList);
|
||
gattServer.notifyCharacteristic(STATUS_CHAR_UUID, result.getBytes());
|
||
}
|
||
});
|
||
}
|
||
|
||
private String formatScanResult(List<String> ssidList) {
|
||
StringBuilder sb = new StringBuilder();
|
||
sb.append("AT+SSID=").append(ssidList.size());
|
||
for (String ssid : ssidList) {
|
||
sb.append(",").append(ssid);
|
||
}
|
||
return sb.toString();
|
||
}
|
||
|
||
private void handleSSIDConfig(String ssid) {
|
||
this.targetSSID = ssid;
|
||
checkAndConnect();
|
||
}
|
||
|
||
private void handlePasswordConfig(String password) {
|
||
this.targetPassword = password;
|
||
checkAndConnect();
|
||
}
|
||
|
||
private void checkAndConnect() {
|
||
if (targetSSID != null && targetPassword != null) {
|
||
notifyState(2); // AT+STATE=2
|
||
wifiConnector.connect(targetSSID, targetPassword, new WiFiConnectionCallback() {
|
||
@Override
|
||
public void onConnected(String ipAddress) {
|
||
notifyState(3); // AT+STATE=3
|
||
}
|
||
|
||
@Override
|
||
public void onPasswordError() {
|
||
notifyState(6); // AT+STATE=6
|
||
}
|
||
|
||
@Override
|
||
public void onNetworkNotFound() {
|
||
notifyState(7); // AT+STATE=7
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
private void notifyState(int state) {
|
||
String stateMsg = "AT+STATE=" + state;
|
||
gattServer.notifyCharacteristic(STATUS_CHAR_UUID, stateMsg.getBytes());
|
||
}
|
||
}
|
||
```
|
||
|
||
## 7. 安全性设计
|
||
|
||
### 7.1 数据传输安全
|
||
|
||
#### 蓝牙配网安全
|
||
- **配对验证**: 使用PIN码配对验证
|
||
- **数据加密**: AES-128加密WiFi凭证
|
||
- **超时机制**: 配网会话5分钟超时
|
||
- **设备认证**: 验证设备MAC地址白名单
|
||
|
||
### 7.2 权限管理
|
||
|
||
#### 必需权限清单
|
||
``xml
|
||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||
<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.INTERNET" />
|
||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||
```
|
||
|
||
## 8. 测试策略
|
||
|
||
### 8.1 功能测试
|
||
|
||
#### 测试用例矩阵
|
||
| 测试场景 | 蓝牙配网 | 预期结果 |
|
||
|---------|---------|----------|
|
||
| 正常配网流程 | ✓ | 配网成功 |
|
||
| 错误WiFi凭证 | ✓ | 显示错误信息 |
|
||
| 网络连接超时 | ✓ | 自动重试 |
|
||
| 长按触发 | - | 正确进入配网 |
|
||
| 小屏幕适配 | ✓ | 界面正常显示 |
|
||
|
||
### 8.2 性能测试
|
||
|
||
#### 关键指标
|
||
- **触发响应时间**: < 500ms
|
||
- **蓝牙广播启动**: < 2s
|
||
- **配网完成时间**: < 30s
|
||
- **内存占用**: < 50MB
|
||
- **CPU占用**: < 20%
|
||
|
||
### 8.3 兼容性测试
|
||
|
||
#### 测试环境
|
||
- **Android版本**: API 26-34
|
||
- **蓝牙版本**: 4.0+
|
||
- **WiFi标准**: 802.11 b/g/n
|
||
- **屏幕分辨率**: 504×410dp
|
||
- **设备类型**: 嵌入式Android设备
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|