Browse Source

上传设备授权码自动绑定流程代码

newdev_shunjiawei
liwei1dao 1 year ago
parent
commit
dd9e6ddf04
  1. 19
      lib/data/services/ble_manager.dart
  2. 131
      lib/modules/pairing/controllers/pairing_controller.dart
  3. 26
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt
  4. 10
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleServicePlugin.kt
  5. 32
      local_plugins/ble_service/lib/ble_service.dart

19
lib/data/services/ble_manager.dart

@ -767,6 +767,25 @@ class BleManager extends GetxService {
}
}
/// 验证设备是否可以配对
Future<void> startScan() async {
try {
await _bleService.startScan();
} catch (e) {
Logger.error('开始扫描设备: ${e.toString()}');
}
}
Future<Map<String, String>?> getDeviceInfo(String address) async {
try {
final result = _bleService.getDeviceInfo(address);
return result;
} catch (e) {
Logger.error('获取设备信息: ${e.toString()}');
return null;
}
}
/// 验证设备是否可以配对
Future<bool> verifyDeviceCanPair(String macAddress) async {
try {

131
lib/modules/pairing/controllers/pairing_controller.dart

@ -1,3 +1,6 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:app_settings/app_settings.dart';
import 'package:deep_voice/data/models/user_Info.dart';
import 'package:deep_voice/data/services/network/api.dart';
@ -418,41 +421,32 @@ class PairingController extends GetxController {
// TODO: 实现API验证逻辑
// 暂时模拟验证通过
// await Future.delayed(const Duration(seconds: 2));;
if (await authbindingDevice()) {
// 检查设备名称是否包含 DeepSound 或 DeapSound
final deviceName = device.name ?? '';
if (deviceName.contains('DeepSound') ||
deviceName.contains('DeapSound')) {
Logger.i(_tag, '设备验证通过');
_verifiedDeviceAddress = device.address;
// 检查是否已有BLE关联
final pairedMacAddress = await _bleManager.getPairedMacAddress();
Logger.i(_tag, '已关联的MAC地址: $pairedMacAddress');
if (pairedMacAddress != null &&
pairedMacAddress.toUpperCase() == device.address.toUpperCase()) {
// 已有关联,检查BLE连接状态
Logger.i(_tag, '设备已关联,检查BLE连接状态');
final currentBleState = await _bleManager.getConnectionState();
Logger.i(_tag, '验证时BLE状态: $currentBleState');
if (currentBleState == 2) {
// BleConnectionState.connected
Logger.i(_tag, 'BLE已连接,直接完成配对');
_transition(PairingState.completed);
} else {
Logger.i(_tag, 'BLE未连接,等待BLE连接');
_transition(PairingState.waitingBle);
}
if (await authbindingDevice(device)) {
Logger.i(_tag, '设备验证通过');
_verifiedDeviceAddress = device.address;
// 检查是否已有BLE关联
final pairedMacAddress = await _bleManager.getPairedMacAddress();
Logger.i(_tag, '已关联的MAC地址: $pairedMacAddress');
if (pairedMacAddress != null &&
pairedMacAddress.toUpperCase() == device.address.toUpperCase()) {
// 已有关联,检查BLE连接状态
Logger.i(_tag, '设备已关联,检查BLE连接状态');
final currentBleState = await _bleManager.getConnectionState();
Logger.i(_tag, '验证时BLE状态: $currentBleState');
if (currentBleState == 2) {
// BleConnectionState.connected
Logger.i(_tag, 'BLE已连接,直接完成配对');
_transition(PairingState.completed);
} else {
// 没有关联或关联的是其他设备,需要进行关联
Logger.i(_tag, '需要进行BLE设备关联');
_transition(PairingState.associating);
Logger.i(_tag, 'BLE未连接,等待BLE连接');
_transition(PairingState.waitingBle);
}
} else {
// _setError(ErrorType.deviceNotMatch, '请连接 DeepSound 设备');
_transition(PairingState.completed);
// 没有关联或关联的是其他设备,需要进行关联
Logger.i(_tag, '需要进行BLE设备关联');
_transition(PairingState.associating);
}
} else {
//验证失败 进入手动授权
@ -531,27 +525,76 @@ class PairingController extends GetxController {
}
//自动绑定设备
Future<bool> authbindingDevice() async {
if (User.instance.earphonemac == currentDevice?.address) {
Future<bool> authbindingDevice(BluetoothDevice device) async {
if (User.instance.earphonemac == device.address) {
// 已经绑定
return true;
}
// 调用BLE管理器的自动绑定方法
final response = await Api.bindearphone({
"earphonemac": currentDevice?.address,
});
Logger.i(_tag, '手动授权结果 ${response}');
if (response != null) {
Logger.i(_tag, '设备自动绑定成功');
User.instance.earphonemac = currentDevice?.address ?? '';
return true;
// 检查设备名称是否包含 DeepSound 或 DeapSound
final deviceName = device.name ?? '';
print('获取到 deviceName: $deviceName');
if (deviceName.contains('DeepSound') || deviceName.contains('DeapSound')) {
await _bleManager.startScan();
// 尝试最多读取 3 次设备信息,每次间隔 1 秒
Map<String, String>? deviceinfo;
for (int i = 0; i < 3; i++) {
deviceinfo = await _bleManager.getDeviceInfo(device.address);
print('获取到 deviceinfo: $deviceinfo');
if (deviceinfo != null) {
break;
}
await Future.delayed(Duration(seconds: 1));
}
print('获取到 deviceinfo: $deviceinfo');
if (deviceinfo != null) {
// final code = processHex(deviceinfo["hex"]!, 15, 25);
String code = extractAndReverseBytes(deviceinfo["hex"]!, 15, 24);
print('获取到 code: $code');
// 安全检查长度
if (code != "") {
final response = await Api.bindearphone({
"code": code,
"earphonemac": device.address,
});
Logger.i(_tag, '手动授权结果 ${response}');
if (response != null) {
Logger.i(_tag, '设备自动绑定成功');
User.instance.earphonemac = device.address ?? '';
return true;
} else {
Logger.e(_tag, '手动绑定失败!');
return false;
}
} else {
return false;
}
}
return false;
// 调用BLE管理器的自动绑定方法
} else {
Logger.e(_tag, '手动绑定失败!');
return false;
}
}
int reverseBits(int byte) {
// 这里是 nibble swap 还是 bit 反转?看你需求,先保持 nibble swap
return ((byte & 0x0F) << 4) | ((byte & 0xF0) >> 4);
}
String extractAndReverseBytes(String hex, int start, int end) {
List<int> bytes = [];
for (int i = 0; i < hex.length; i += 2) {
bytes.add(int.parse(hex.substring(i, i + 2), radix: 16));
}
List<int> slice = bytes.sublist(start, end + 1);
List<int> reversed = slice.reversed.toList();
return reversed
.map((b) => b.toRadixString(16).padLeft(2, '0'))
.join()
.toUpperCase();
}
/// 用户点击授权码输入框
void onAutoCodeInputTap() async {
// 调用BLE管理器的自动绑定方法

26
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt

@ -298,32 +298,48 @@ object BleService {
}
}
fun getDeviceInfo(address: String): Map<String,Any>? {
// 更新缓存
val idx = scanResults.indexOfFirst { it.device.address == address }
Log.d(TAG, "获取设备信息:${address} idx:$idx")
if (idx >= 0){
val result = scanResults[idx];
return printDeviceInfo(result)
}
return null;
}
/**
* 打印设备信息和服务UUID
*/
private fun printDeviceInfo(result: ScanResult) {
private fun printDeviceInfo(result: ScanResult):Map<String,Any>?{
val device = result.device
val scanRecord = result.scanRecord
val serviceUuids =
scanRecord?.serviceUuids?.joinToString(", ") { it.uuid.toString() } ?: "无"
Log.d(
TAG, "扫描到设备: 名称=${device.name ?: "未知"}, 地址=${device.address}, " +
TAG, "liwei--------- 扫描到设备: 名称=${device.name ?: "未知"}, 地址=${device.address}, " +
"RSSI=${result.rssi}, 服务UUID=[$serviceUuids]"
)
val info = mutableMapOf(
"name" to (device.name ?: "未知"),
"address" to device.address
)
// 打印广播数据的详细信息
val scanData = scanRecord?.bytes
if (scanData != null) {
val hexString = scanData.joinToString("") { String.format("%02X", it) }
Log.d(TAG, "广播数据: $hexString")
Log.d(TAG, "liwei------------ 广播数据: $hexString")
info["hex"] = hexString
// 解析服务数据
scanRecord.serviceData?.forEach { (uuid, data) ->
val dataHex = data.joinToString("") { String.format("%02X", it) }
Log.d(TAG, "服务数据: UUID=${uuid.uuid}, 数据=$dataHex")
}
}
return info
}
// ======================================================================================================

10
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleServicePlugin.kt

@ -294,6 +294,16 @@ class BleServicePlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
result.error("UNSUPPORTED", "设备不支持Companion Device Manager", null)
}
}
"startScan" -> {
val connected = BleService.startScan()
result.success(connected)
}
"getDeviceInfo" -> {
val address = call.argument<String>("address")?:""
val info = BleService.getDeviceInfo(address);
Log.d(TAG, "getDeviceInfo $info")
result.success(info)
}
else -> {
result.notImplemented()
}

32
local_plugins/ble_service/lib/ble_service.dart

@ -281,6 +281,38 @@ class BleService {
}
}
/// 断开连接
Future<bool> startScan() async {
try {
final result = await _methodChannel.invokeMethod<bool>('startScan');
return result ?? false;
} catch (e) {
print('开启扫描ble设备失败: $e');
return false;
}
}
/// 断开连接
Future<Map<String, String>?> getDeviceInfo(String address) async {
try {
final result = await _methodChannel
.invokeMethod<Map>('getDeviceInfo', {'address': address});
print('获取设备信息!: $result');
if (result != null) {
return {
'name': result['name'] ?? "未知",
'address': result['address'] ?? "",
'hex': result['hex'] ?? "",
};
} else {
return null;
}
} catch (e) {
print('获取设备信息失败!: $e');
return null;
}
}
/// 注册BLE后台扫描
///
/// 注册后,即使应用被杀死,系统也会在检测到设备广播时唤醒应用

Loading…
Cancel
Save