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 { Future<bool> verifyDeviceCanPair(String macAddress) async {
try { 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:app_settings/app_settings.dart';
import 'package:deep_voice/data/models/user_Info.dart'; import 'package:deep_voice/data/models/user_Info.dart';
import 'package:deep_voice/data/services/network/api.dart'; import 'package:deep_voice/data/services/network/api.dart';
@ -418,41 +421,32 @@ class PairingController extends GetxController {
// TODO: 实现API验证逻辑 // TODO: 实现API验证逻辑
// 暂时模拟验证通过 // 暂时模拟验证通过
// await Future.delayed(const Duration(seconds: 2));; // await Future.delayed(const Duration(seconds: 2));;
if (await authbindingDevice()) { if (await authbindingDevice(device)) {
// 检查设备名称是否包含 DeepSound 或 DeapSound Logger.i(_tag, '设备验证通过');
final deviceName = device.name ?? ''; _verifiedDeviceAddress = device.address;
if (deviceName.contains('DeepSound') || // 检查是否已有BLE关联
deviceName.contains('DeapSound')) { final pairedMacAddress = await _bleManager.getPairedMacAddress();
Logger.i(_tag, '设备验证通过'); Logger.i(_tag, '已关联的MAC地址: $pairedMacAddress');
_verifiedDeviceAddress = device.address;
if (pairedMacAddress != null &&
// 检查是否已有BLE关联 pairedMacAddress.toUpperCase() == device.address.toUpperCase()) {
final pairedMacAddress = await _bleManager.getPairedMacAddress(); // 已有关联,检查BLE连接状态
Logger.i(_tag, '已关联的MAC地址: $pairedMacAddress'); Logger.i(_tag, '设备已关联,检查BLE连接状态');
final currentBleState = await _bleManager.getConnectionState();
if (pairedMacAddress != null && Logger.i(_tag, '验证时BLE状态: $currentBleState');
pairedMacAddress.toUpperCase() == device.address.toUpperCase()) {
// 已有关联,检查BLE连接状态 if (currentBleState == 2) {
Logger.i(_tag, '设备已关联,检查BLE连接状态'); // BleConnectionState.connected
final currentBleState = await _bleManager.getConnectionState(); Logger.i(_tag, 'BLE已连接,直接完成配对');
Logger.i(_tag, '验证时BLE状态: $currentBleState'); _transition(PairingState.completed);
if (currentBleState == 2) {
// BleConnectionState.connected
Logger.i(_tag, 'BLE已连接,直接完成配对');
_transition(PairingState.completed);
} else {
Logger.i(_tag, 'BLE未连接,等待BLE连接');
_transition(PairingState.waitingBle);
}
} else { } else {
// 没有关联或关联的是其他设备,需要进行关联 Logger.i(_tag, 'BLE未连接,等待BLE连接');
Logger.i(_tag, '需要进行BLE设备关联'); _transition(PairingState.waitingBle);
_transition(PairingState.associating);
} }
} else { } else {
// _setError(ErrorType.deviceNotMatch, '请连接 DeepSound 设备'); // 没有关联或关联的是其他设备,需要进行关联
_transition(PairingState.completed); Logger.i(_tag, '需要进行BLE设备关联');
_transition(PairingState.associating);
} }
} else { } else {
//验证失败 进入手动授权 //验证失败 进入手动授权
@ -531,27 +525,76 @@ class PairingController extends GetxController {
} }
//自动绑定设备 //自动绑定设备
Future<bool> authbindingDevice() async { Future<bool> authbindingDevice(BluetoothDevice device) async {
if (User.instance.earphonemac == currentDevice?.address) { if (User.instance.earphonemac == device.address) {
// 已经绑定 // 已经绑定
return true; return true;
} }
// 调用BLE管理器的自动绑定方法 // 检查设备名称是否包含 DeepSound 或 DeapSound
final response = await Api.bindearphone({ final deviceName = device.name ?? '';
"earphonemac": currentDevice?.address, print('获取到 deviceName: $deviceName');
}); if (deviceName.contains('DeepSound') || deviceName.contains('DeapSound')) {
Logger.i(_tag, '手动授权结果 ${response}'); await _bleManager.startScan();
if (response != null) { // 尝试最多读取 3 次设备信息,每次间隔 1 秒
Logger.i(_tag, '设备自动绑定成功'); Map<String, String>? deviceinfo;
User.instance.earphonemac = currentDevice?.address ?? ''; for (int i = 0; i < 3; i++) {
return true; 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 { } else {
Logger.e(_tag, '手动绑定失败!');
return false; 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 { void onAutoCodeInputTap() async {
// 调用BLE管理器的自动绑定方法 // 调用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 * 打印设备信息和服务UUID
*/ */
private fun printDeviceInfo(result: ScanResult) { private fun printDeviceInfo(result: ScanResult):Map<String,Any>?{
val device = result.device val device = result.device
val scanRecord = result.scanRecord val scanRecord = result.scanRecord
val serviceUuids = val serviceUuids =
scanRecord?.serviceUuids?.joinToString(", ") { it.uuid.toString() } ?: "无" scanRecord?.serviceUuids?.joinToString(", ") { it.uuid.toString() } ?: "无"
Log.d( Log.d(
TAG, "扫描到设备: 名称=${device.name ?: "未知"}, 地址=${device.address}, " + TAG, "liwei--------- 扫描到设备: 名称=${device.name ?: "未知"}, 地址=${device.address}, " +
"RSSI=${result.rssi}, 服务UUID=[$serviceUuids]" "RSSI=${result.rssi}, 服务UUID=[$serviceUuids]"
) )
val info = mutableMapOf(
"name" to (device.name ?: "未知"),
"address" to device.address
)
// 打印广播数据的详细信息 // 打印广播数据的详细信息
val scanData = scanRecord?.bytes val scanData = scanRecord?.bytes
if (scanData != null) { if (scanData != null) {
val hexString = scanData.joinToString("") { String.format("%02X", it) } 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) -> scanRecord.serviceData?.forEach { (uuid, data) ->
val dataHex = data.joinToString("") { String.format("%02X", it) } val dataHex = data.joinToString("") { String.format("%02X", it) }
Log.d(TAG, "服务数据: UUID=${uuid.uuid}, 数据=$dataHex") 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) 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 -> { else -> {
result.notImplemented() 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后台扫描 /// 注册BLE后台扫描
/// ///
/// 注册后,即使应用被杀死,系统也会在检测到设备广播时唤醒应用 /// 注册后,即使应用被杀死,系统也会在检测到设备广播时唤醒应用

Loading…
Cancel
Save