starwork_flutter/lib/views/device/searchDevice/search_device_controller.dart

288 lines
10 KiB
Dart

import 'dart:math';
import 'package:get/get.dart';
import 'package:starwork_flutter/base/app_logger.dart';
import 'package:starwork_flutter/base/app_permission.dart';
import 'package:starwork_flutter/base/base_controller.dart';
import 'package:starwork_flutter/ble/ble_service.dart';
import 'package:starwork_flutter/ble/command/base/base_ble_response_parser.dart';
import 'package:starwork_flutter/ble/command/request/ble_cmd_add_admin.dart';
import 'package:starwork_flutter/ble/command/request/ble_cmd_get_private_key.dart';
import 'package:starwork_flutter/ble/command/request/ble_cmd_get_public_key.dart';
import 'package:starwork_flutter/ble/command/request/ble_cmd_read_lock_status.dart';
import 'package:starwork_flutter/ble/command/response/ble_cmd_get_private_key_parser.dart';
import 'package:starwork_flutter/ble/command/response/ble_cmd_get_public_key_parser.dart';
import 'package:starwork_flutter/ble/command/response/ble_cmd_read_lock_status_parser.dart';
import 'package:starwork_flutter/ble/command/response/model/ble_add_admin_response.dart';
import 'package:starwork_flutter/ble/model/scan_device_info.dart';
import 'package:starwork_flutter/common/constant/app_toast_messages.dart';
import 'package:starwork_flutter/common/constant/cache_keys.dart';
import 'package:starwork_flutter/common/utils/shared_preferences_utils.dart';
class SearchDeviceController extends BaseController {
// 搜索状态管理
final RxBool isSearching = false.obs;
// 设备列表管理
final RxList<ScanDeviceInfo> deviceList = <ScanDeviceInfo>[].obs;
// 权限状态标识
final RxBool permissionsGranted = false.obs;
@override
void onInit() async {
super.onInit();
// 异步初始化权限
_initializePermissions();
}
@override
void onClose() {
// 停止搜索
BleService().stopBluetoothSearch();
super.onClose();
}
/// 初始化权限
Future<void> _initializePermissions() async {
try {
AppLogger.highlight('🔐 开始检查权限...');
// 使用 BleService 中的统一权限申请方法
bool hasPermissions = await _checkAndRequestBlePermission();
if (!hasPermissions) {
AppLogger.error('❌ 蓝牙相关权限被拒绝');
showToast('蓝牙功能需要相关权限,请在设置中开启');
return;
}
AppLogger.highlight('✅ 所有权限已获得');
// 所有权限都获得了,标记为可以开始搜索
permissionsGranted.value = true;
AppLogger.highlight('🎉 所有权限已就绪,准备开始搜索');
// 开始搜索
await _startBluetoothSearch();
} catch (e, stackTrace) {
AppLogger.error('权限初始化失败', error: e, stackTrace: stackTrace);
showToast('权限初始化失败,请重试');
}
}
/// 启动蓝牙搜索
Future<void> _startBluetoothSearch() async {
if (!permissionsGranted.value) {
AppLogger.warn('⚠️ 权限未就绪,无法开始搜索');
return;
}
try {
AppLogger.highlight('🔍 开始启动蓝牙搜索...');
// 清空设备列表
deviceList.clear();
// 更新搜索状态
isSearching.value = true;
// 启动搜索
BleService().enableBluetoothSearch(onDeviceFound: _onDeviceFound);
// 定期更新搜索状态
_updateSearchingStatus();
} catch (e, stackTrace) {
AppLogger.error('启动蓝牙搜索失败', error: e, stackTrace: stackTrace);
isSearching.value = false;
showToast('启动搜索失败,请刷新并重试');
}
}
/// 定期更新搜索状态
void _updateSearchingStatus() {
// 每秒检查一次搜索状态
Future.delayed(const Duration(seconds: 1), () {
if (isSearching.value) {
bool actuallyScanning = BleService().isScanningNow;
if (isSearching.value != actuallyScanning) {
isSearching.value = actuallyScanning;
if (!actuallyScanning) {
AppLogger.highlight('🔍 搜索已停止');
isSearching.value = false;
}
}
// 如果还在搜索,继续检查
if (actuallyScanning) {
_updateSearchingStatus();
}
}
});
}
/// 搜索结果回调
void _onDeviceFound(ScanDeviceInfo device) {
AppLogger.highlight('📲 发现新设备: ${device.advName}');
// 检查是否已存在相同设备(避免重复添加)
bool exists = deviceList.any((existingDevice) => existingDevice.rawDeviceInfo.device.remoteId == device.rawDeviceInfo.device.remoteId);
if (!exists) {
deviceList.add(device);
deviceList.refresh();
AppLogger.debug('✅ 设备已添加到列表,当前设备数量: ${deviceList.length},设备信息:${deviceList.toString()}');
} else {
AppLogger.debug('⚠️ 设备已存在,跳过添加');
}
}
// 刷新设备数据
Future<void> refreshDevices() async {
AppLogger.highlight('🔄 开始刷新设备列表');
if (!permissionsGranted.value) {
AppLogger.warn('⚠️ 权限未就绪,无法刷新');
showToast('请先授权必要的权限');
return;
}
try {
// 停止当前搜索
BleService().stopBluetoothSearch();
isSearching.value = false;
// 清空设备列表
deviceList.clear();
// 模拟网络请求延迟
await Future.delayed(const Duration(seconds: 1));
// 重新开始搜索
await _startBluetoothSearch();
AppLogger.highlight('✅ 设备列表刷新完成');
} catch (e, stackTrace) {
AppLogger.error('刷新设备列表失败', error: e, stackTrace: stackTrace);
showToast('刷新失败,请重试');
}
}
/// 连接设备
/// 1.获取锁公钥
/// 2.获取锁私钥
/// 3.注册管理员密码
void connectingDevices(ScanDeviceInfo device) async {
try {
showLoading();
// 停止搜索
BleService().stopBluetoothSearch();
isSearching.value = false;
// 创建命令
BleCmdGetPublicKey getPublicKeyCmd = BleCmdGetPublicKey(lockId: device.advName);
// 发送命令,允许自动连接和搜索设备
GetPublicKeyResponse? publicKeyResponse = await BleService().sendCommand<GetPublicKeyResponse>(
command: getPublicKeyCmd,
targetDeviceName: device.advName,
// 通过名称搜索设备
autoConnectIfNeeded: true,
);
if (publicKeyResponse != null && publicKeyResponse.isSuccess) {
AppLogger.info('🎯 获取公钥成功: ${publicKeyResponse.publicKeyHex}');
await SharedPreferencesUtils.saveIntList(CacheKeys.lockPublicKey, publicKeyResponse.publicKey);
BleCmdGetPrivateKey getPrivateKeyCmd = BleCmdGetPrivateKey(
lockId: device.advName,
keyId: '1',
authUserID: '1',
nowTime: DateTime.now().millisecondsSinceEpoch ~/ 1000,
publicKey: publicKeyResponse.publicKey,
);
// 发送命令,允许自动连接和搜索设备
GetPrivateKeyResponse? privateKeyResponse = await BleService().sendCommand<GetPrivateKeyResponse>(
command: getPrivateKeyCmd,
targetDeviceName: device.advName,
// 通过名称搜索设备
autoConnectIfNeeded: true,
);
if (privateKeyResponse != null && privateKeyResponse.isSuccess) {
await SharedPreferencesUtils.saveIntList(CacheKeys.lockCommKey, privateKeyResponse.commKey);
await SharedPreferencesUtils.saveIntList(CacheKeys.lockSignKey, privateKeyResponse.signKey);
AppLogger.info('🎯 获取私钥成功: ${privateKeyResponse.toString()}');
// 更新缓存的私钥,以便在解密时使用
BleService.setCachedPrivateKey(privateKeyResponse.commKey);
//读取锁状态
BleCmdReadLockStatus readLockStatusCmd = BleCmdReadLockStatus(
lockId: device.advName,
userId: '1',
timeStamp: DateTime.now().millisecondsSinceEpoch ~/ 1000,
localUnix: 0,
privateKey: privateKeyResponse.commKey,
);
// 发送命令,允许自动连接和搜索设备
ReadLockStatusResponse? readLockStatusResponse = await BleService().sendCommand<ReadLockStatusResponse>(
command: readLockStatusCmd,
targetDeviceName: device.advName,
// 通过名称搜索设备
autoConnectIfNeeded: true,
);
if (readLockStatusResponse != null && readLockStatusResponse.isSuccess) {
AppLogger.highlight('readLockStatusResponse:${readLockStatusResponse}');
final Random rng = Random();
// 生成 100000 到 999999 之间的随机整数
final int number = rng.nextInt(900000) + 100000;
//读取锁状态
BleCmdAddAdmin addAdminCmd = BleCmdAddAdmin(
lockId: device.advName,
userId: '13655',
privateKey: privateKeyResponse.commKey,
authUserId: '13655',
keyId: '1',
startDate: DateTime.now().millisecondsSinceEpoch,
expireDate: 0x11223344,
password: number.toString(),
token: [0, 0, 0, 0],
publicKey: publicKeyResponse.publicKey,
);
// 发送命令,允许自动连接和搜索设备
BleAddAdminResponse? addAdminResponse = await BleService().sendCommand<BleAddAdminResponse>(
command: addAdminCmd,
targetDeviceName: device.advName,
// 通过名称搜索设备
autoConnectIfNeeded: true,
);
AppLogger.highlight('addAdminResponse:${addAdminResponse}');
}
}
} else {
AppLogger.warn('⚠️ 命令发送完成,但未收到有效响应');
}
} catch (e, stackTrace) {
AppLogger.error('连接设备失败', error: e, stackTrace: stackTrace);
showToast('连接失败,请重试');
} finally {
hideLoading();
}
}
/// 检查并申请权限
Future<bool> _checkAndRequestBlePermission() async {
var locationPermission = await AppPermission.requestLocationPermission();
if (!locationPermission) {
showToast(AppToastMessages.notLocationPermission);
return false;
}
var bluetoothPermissions = await AppPermission.requestBluetoothPermissions();
if (!bluetoothPermissions) {
showToast(AppToastMessages.notBluetoothPermissions);
return false;
}
return true;
}
}