app-starlock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart

740 lines
26 KiB
Dart
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

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.

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:date_format/date_format.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/blue/io_protocol/io_getPrivateKey.dart';
import 'package:star_lock/blue/io_protocol/io_getPublicKey.dart';
import 'package:star_lock/blue/io_protocol/io_otaUpgrade.dart';
import 'package:star_lock/blue/io_protocol/io_processOtaUpgrade.dart';
import 'package:star_lock/blue/io_type.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockTime/getServerDatetime_entity.dart';
import 'package:star_lock/mine/addLock/nearbyLock/nearbyLock_page.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/widget/permission/permission_dialog.dart';
import '../../../appRouters.dart';
import '../../../app_settings/app_settings.dart';
import '../../../blue/blue_manage.dart';
import '../../../blue/io_protocol/io_getStarLockStatusInfo.dart';
import '../../../blue/io_reply.dart';
import '../../../blue/io_tool/io_tool.dart';
import '../../../blue/io_tool/manager_event_bus.dart';
import '../../../blue/sender_manage.dart';
import '../../../network/api_repository.dart';
import '../../../tools/storage.dart';
import 'nearbyLock_state.dart';
class NearbyLockLogic extends BaseGetXController {
final NearbyLockState state = NearbyLockState();
int otaCount = 0;
int otaIndex = 0;
Uint8List? otaBin;
int startSecond = 0;
Map? headJson;
String? deviceName;
StreamSubscription<Reply>? _replySubscription;
// 点击连接设备
void connect(String deviceName) {
showTitleEasyLoading('${'获取锁信息'.tr} 1/3');
showBlueConnetctToastTimer(action: () {
dismissEasyLoading();
});
BlueManage().blueSendData(deviceName,
(BluetoothConnectionState state) async {
AppLog.log('点击要添加的设备了');
if (state == BluetoothConnectionState.connected) {
AppLog.log('开始获取公钥');
IoSenderManage.getPublicKey(lockId: deviceName);
} else if (state == BluetoothConnectionState.disconnected) {
dismissEasyLoading();
}
}, isAddEquipment: true);
}
void _initReplySubscription() {
_replySubscription =
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) {
if (reply is GetPublicKeyReply) {
_replyGetPublicKey(reply);
}
if (reply is GetPrivateKeyReply) {
_replyGetPrivateKeyKey(reply);
}
// 获取锁状态信息
if (reply is GetStarLockStatuInfoReply && state.ifCurrentScreen.value) {
_replyGetStarLockStatusInfo(reply);
}
if (reply is OTAUpgradeReply) {
if (reply.status == 0x00) {
//验证通过,开始发送数据包
dismissEasyLoading();
startOTAData();
processOtaUpgrade();
} else if (reply.status == 0x06) {
blueOTAUpgrade(headJson!, reply.token);
}
} else if (reply is ProcessOtaUpgradeReply && reply.status == 0x00) {
otaIndex++;
processOtaUpgrade();
} else if (reply is ConfirmationOTAUpgradeReply && reply.status == 0x00) {
showToast('固件升级完成'.tr);
closeOTADAta();
}
});
}
Future<void> _replyGetPublicKey(Reply reply) async {
// 获取公钥
switch (reply.status) {
case 0x00:
//成功
// AppLog.log('获取公钥成功');
// 储存公钥
final List<int> publicKey = reply.data.sublist(3);
final List<String> saveStrList = changeIntListToStringList(publicKey);
Storage.setStringList(saveBluePublicKey, saveStrList);
// 获取私钥
// AppLog.log('开始获取私钥');
showTitleEasyLoading('${'获取锁信息'.tr} 2/3');
IoSenderManage.getPrivateKey(
lockId: BlueManage().connectDeviceName,
keyID: '1',
authUserID: await Storage.getUid(),
nowTime: state.serverTime,
publicKeyData: publicKey,
needAuthor: 1);
break;
default:
AppLog.log('获取公钥失败');
break;
}
}
Future<void> _replyGetPrivateKeyKey(Reply reply) async {
switch (reply.status) {
case 0x00:
// AppLog.log('获取私钥成功');
//成功
reply.data.removeAt(0);
// 私钥
final List<int> privateKey = reply.data.sublist(0, 16);
final List<String> savePrivateKeyList =
changeIntListToStringList(privateKey);
await Storage.setStringList(saveBluePrivateKey, savePrivateKeyList);
// signKey
final List<int> signKey = reply.data.sublist(16, 32);
final List<String> saveSignKeyList = changeIntListToStringList(signKey);
await Storage.setStringList(saveBlueSignKey, saveSignKeyList);
// 时间戳
final List<int> timestamp = reply.data.sublist(32, 36);
state.timestampValue = (0xff & timestamp[0]) << 24 |
(0xff & timestamp[1]) << 16 |
(0xff & timestamp[2]) << 8 |
(0xFF & timestamp[3]);
showTitleEasyLoading('${'获取锁信息'.tr} 3/3');
_getStarLockStatus();
break;
default:
break;
}
}
// 获取星锁状态
Future<void> _replyGetStarLockStatusInfo(Reply reply) async {
final int status = reply.data[2];
dismissEasyLoading();
switch (status) {
case 0x00:
//成功
// AppLog.log('获取锁状态成功');
// 厂商名称
int index = 3;
final List<int> vendor = reply.data.sublist(index, index + 20);
final String vendorStr = utf8String(vendor);
state.lockInfo['vendor'] = vendorStr;
// state.lockInfo["vendor"] = "XL";
index = index + 20;
// AppLog.log('厂商名称 vendorStr:$vendorStr');
// 锁设备类型
final int product = reply.data[index];
state.lockInfo['product'] = product;
index = index + 1;
// AppLog.log('锁设备类型 product:$product');
// 产品名称
final List<int> model = reply.data.sublist(index, index + 20);
final String modelStr = utf8String(model);
state.lockInfo['model'] = modelStr;
// state.lockInfo["model"] = "JL-BLE-01";
index = index + 20;
// AppLog.log('产品名称 mmodelStr:$modelStr');
// 软件版本
final List<int> fwVersion = reply.data.sublist(index, index + 20);
final String fwVersionStr = utf8String(fwVersion);
state.lockInfo['fwVersion'] = fwVersionStr;
index = index + 20;
// AppLog.log('软件版本 fwVersionStr:$fwVersionStr');
// 硬件版本
final List<int> hwVersion = reply.data.sublist(index, index + 20);
final String hwVersionStr = utf8String(hwVersion);
state.lockInfo['hwVersion'] = hwVersionStr;
index = index + 20;
// AppLog.log('硬件版本 hwVersionStr:$hwVersionStr');
// 厂商序列号
final List<int> serialNum0 = reply.data.sublist(index, index + 16);
final String serialNum0Str = utf8String(serialNum0);
state.lockInfo['serialNum0'] = serialNum0Str;
// state.lockInfo["serialNum0"] = "${DateTime.now().millisecondsSinceEpoch ~/ 10}";
index = index + 16;
AppLog.log('厂商序列号 serialNum0Str:$serialNum0Str');
// 成品商序列号
final List<int> serialNum1 = reply.data.sublist(index, index + 16);
final String serialNum1Str = utf8String(serialNum1);
state.lockInfo['serialNum1'] = serialNum1Str;
index = index + 16;
// AppLog.log('成品商序列号 serialNum1Str:$serialNum1Str');
// 蓝牙名称
final List<int> btDeviceName = reply.data.sublist(index, index + 16);
final String btDeviceNameStr = utf8String(btDeviceName);
state.lockInfo['btDeviceName'] = btDeviceNameStr;
index = index + 16;
// AppLog.log('蓝牙名称 btDeviceNameStr:$btDeviceNameStr');
// 电池剩余电量
final int battRemCap = reply.data[index];
state.lockInfo['electricQuantity'] = battRemCap;
index = index + 1;
// AppLog.log('电池剩余电量 battRemCap:$battRemCap');
// 备用电池剩余电量
final int battRemCapStandby = reply.data[index];
state.lockInfo['electricQuantityStandby'] = battRemCapStandby;
index = index + 1;
// AppLog.log('电池剩余电量 battRemCap:$battRemCap');
// 重置次数
final List<int> restoreCounter = reply.data.sublist(index, index + 2);
state.lockInfo['restoreCount'] =
restoreCounter[0] * 256 + restoreCounter[1];
index = index + 2;
// AppLog.log('重置次数 restoreCounter:${restoreCounter[0] * 256 + restoreCounter[1]}');
// 重置时间
final List<int> restoreDate = reply.data.sublist(index, index + 4);
final int restoreDateValue = (0xff & restoreDate[0]) << 24 |
(0xff & restoreDate[1]) << 16 |
(0xff & restoreDate[2]) << 8 |
(0xFF & restoreDate[3]);
// String restoreDateStr = DateTool().dateToYMDHNSString(restoreDateValue.toString());
state.lockInfo['restoreDate'] = restoreDateValue * 1000;
index = index + 4;
// AppLog.log('重置时间 restoreDateValue:$restoreDateValue');
// 主控芯片型号
final List<int> icPartNo = reply.data.sublist(index, index + 10);
final String icPartNoStr = utf8String(icPartNo);
state.lockInfo['icPartNo'] = icPartNoStr;
index = index + 10;
// AppLog.log('主控芯片型号 icPartNoStr:$icPartNoStr');
// 有效时间
final List<int> indate = reply.data.sublist(index, index + 4);
final int indateValue = (0xff & indate[0]) << 24 |
(0xff & indate[1]) << 16 |
(0xff & indate[2]) << 8 |
(0xFF & indate[3]);
// String indateStr = DateTool().dateToYMDHNSString("$indateValue");
state.lockInfo['indate'] = indateValue * 1000;
index = index + 4;
// AppLog.log('有效时间 indateValue:$indateValue');
// mac地址
final List<int> macAddress = reply.data.sublist(index, index + 20);
final String macAddressStr = utf8String(macAddress);
state.lockInfo['mac'] = macAddressStr;
index = index + 20;
// AppLog.log('mac地址 macAddressStr:$macAddressStr');
//时区偏移
state.lockInfo['timezoneOffset'] =
DateTime.now().timeZoneOffset.inSeconds;
// 锁特征值字符串长度
final int featureValueLength = reply.data[index];
index = index + 1;
AppLog.log('锁特征值字符串长度 featureValueLength:$featureValueLength');
// 锁特征值说明(本机能支持的功能)
// 获取到锁给的字符数组
final int featureNetxLength = index + featureValueLength;
if (reply.data.length < featureNetxLength) {
showToast('锁数据异常,请重试'.tr);
return;
}
final List<int> featureValue =
reply.data.sublist(index, index + featureValueLength);
final String featureValueStr = asciiString(featureValue);
state.featureValue = featureValueStr;
// List allFeatureValueTwoList = charListChangeIntList(featureValue);
// AppLog.log("featureValueLength:$featureValueLength featureValue:$featureValue \n featureValueStr:$featureValueStr");
index = index + featureValueLength;
AppLog.log('锁特征值字符串 featureValueStr:$featureValueStr');
// 使能特征值字符串长度
final int featureEnValLength = reply.data[index];
index = index + 1;
AppLog.log('使能特征值字符串长度 featureEnValLength:$featureEnValLength');
// 使能锁特征值说明(本机启用的功能)
final int featureEnNextLength = index + featureEnValLength;
if (reply.data.length < featureEnNextLength) {
showToast('锁数据异常,请重试'.tr);
return;
}
final List<int> featureEnVal =
reply.data.sublist(index, index + featureEnValLength);
final String featureEnValStr = asciiString(featureEnVal);
state.featureSettingValue = featureEnValStr;
// List allFeatureEnValTwoList = charListChangeIntList(featureEnVal);
// AppLog.log("featureEnValLength:$featureEnValLength featureEnVal:$featureEnVal \n featureEnValStr:$featureEnValStr");
index = index + featureEnValLength;
AppLog.log('使能锁特征值说明 featureEnValStr:$featureEnValStr');
// 支持的带参数特征值的总条目数
// var featureParaTotal = reply.data[index];
final List<int> featureParaTotalList = reply.data.sublist(index);
state.featureSettingParams = featureParaTotalList;
AppLog.log('featureParaTotalList:$featureParaTotalList');
// Get.toNamed(Routers.lockAddressGaoDePage, arguments: <String, Object>{
// 'pwdTimestamp': state.timestampValue * 1000,
// 'lockInfo': state.lockInfo,
// 'featureValue': state.featureValue,
// 'featureSettingValue': state.featureSettingValue,
// 'featureSettingParams': state.featureSettingParams,
// });
Get.toNamed(Routers.saveLockPage, arguments: <String, Object?>{
'addressInfo': {},
'pwdTimestamp': state.timestampValue * 1000,
'lockInfo': state.lockInfo,
'featureValue': state.featureValue,
'featureSettingValue': state.featureSettingValue,
'featureSettingParams': state.featureSettingParams,
'isFromMap': 0,
});
break;
case 0x06:
//无权限
final List<String>? privateKey =
await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList =
changeStringListToIntList(privateKey!);
IoSenderManage.senderGetStarLockStatuInfo(
lockID: BlueManage().connectDeviceName,
userID: await Storage.getUid(),
utcTimeStamp: state.serverTime,
unixTimeStamp: getLocalTime(),
isBeforeAddUser: true,
privateKey: getPrivateKeyList,
);
break;
default:
//失败
break;
}
}
// 获取锁状态
Future<void> _getStarLockStatus() async {
// 进来之后首先连接
// BlueManage().bludSendData(BlueManage().connectDeviceName, (BluetoothConnectionState state) async {
// if (state == BluetoothConnectionState.connected) {
// dismissEasyLoading();
// AppLog.log('开始获取锁状态');
final List<String>? privateKey =
await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
final String getUTCDate = formatDate(
DateTime.fromMillisecondsSinceEpoch(state.serverTime * 1000),
<String>[yyyy, '-', mm, '-', dd, ' ', HH, ':', nn, ':', ss]);
final String getLocalDate = formatDate(
DateTime.fromMillisecondsSinceEpoch(getLocalTime() * 1000),
<String>[yyyy, '-', mm, '-', dd, ' ', HH, ':', nn, ':', ss]);
// AppLog.log('state.serverTime:${state.serverTime} getUTCDate:$getUTCDate '
// 'getLocalTime:${getLocalTime()} getLocalDate:$getLocalDate '
// '差值:${getLocalTime() - state.serverTime}');
IoSenderManage.senderGetStarLockStatuInfo(
lockID: BlueManage().connectDeviceName,
userID: await Storage.getUid(),
utcTimeStamp: state.serverTime,
unixTimeStamp: getLocalTime(),
isBeforeAddUser: true,
privateKey: getPrivateKeyList,
);
}
void startScanBlueList() {
BlueManage().startScan(2000, DeviceType.blue, (List<ScanResult> list) {
state.devices.clear();
for (final device in list) {
final String? serviceUuid =
device.advertisementData.serviceUuids.isNotEmpty
? device.advertisementData.serviceUuids[0].toString()
: null;
if (serviceUuid != null && !isPaired(serviceUuid)) {
state.devices.add(device);
}
}
});
}
/// 判断是否已配对(支持 128-bit 和 32-bit
bool isPaired(String serviceUuid) {
if (serviceUuid.length < 6) return false; // 最短需要 6 个字符才能判断
try {
if (serviceUuid.length >= 32) {
// 128-bit UUID检查第 31 和 32 位
String status = serviceUuid.substring(30, 32);
return status == '01'; // '01' 表示已配对
} else if (serviceUuid.length >= 5) {
// 32-bit UUID检查第 4 和 5 位
String status = serviceUuid.substring(4, 6);
return status == '01'; // '01' 表示已配对
}
return false; // 如果长度不足,则返回 false
} catch (e) {
return false; // 如果索引越界或其他错误,返回 false
}
}
/// 判断是否休眠(支持 128-bit 和 32-bit
bool isSleeping(String serviceUuid) {
if (serviceUuid.length < 8) return false; // 最短需要 8 个字符才能判断
try {
if (serviceUuid.length >= 34) {
// 128-bit UUID检查第 33 和 34 位
String status = serviceUuid.substring(32, 34);
return status == '00'; // '00' 表示休眠
} else if (serviceUuid.length >= 7) {
// 32-bit UUID检查第 6 和 7 位
String status = serviceUuid.substring(6, 8);
return status == '00'; // '00' 表示休眠
}
return false; // 如果长度不足,则返回 false
} catch (e) {
return false; // 如果索引越界或其他错误,返回 false
}
}
void stopScanBlueList() {
BlueManage().disconnect();
BlueManage().stopScan();
}
// 点击连接设备,升级 ota 固件
void oTAUpgrade(String deviceName) {
showTitleEasyLoading('连接设备中...'.tr);
this.deviceName = deviceName;
BlueManage().blueSendData(deviceName,
(BluetoothConnectionState state) async {
// AppLog.log('连接设备');
if (state == BluetoothConnectionState.connected) {
// AppLog.log('连接成功');
dismissEasyLoading();
otaUpdate();
} else if (state == BluetoothConnectionState.disconnected) {
// AppLog.log('连接失败');
dismissEasyLoading();
}
}, isAddEquipment: true);
}
//手动升级
Future<void> otaUpdate() async {
final bool status = await PermissionDialog.requestStorage();
if (status != true) {
return;
}
final FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result == null || result.files.single.path is! String) {
return;
}
final File file = File(result.files.single.path!);
final Uint8List data = await file.readAsBytes();
headJson = await getHeadFile(data);
if (headJson is! Map) {
return;
}
otaBin = await checkFile(data, headJson!);
if (otaBin == null) {
return;
}
final String md5Str = md5.convert(otaBin!).toString();
headJson!['fwMd5'] = md5Str;
blueOTAUpgrade(headJson!, <int>[0, 0, 0, 0]);
}
//蓝牙操作 ota 升级
void blueOTAUpgrade(Map data, List<int> token) {
if (deviceName == null) {
AppLog.log('blueOTAUpgrade:设备名字为 null');
return;
}
BlueManage().blueSendData(deviceName!,
(BluetoothConnectionState deviceConnectionState) async {
if (deviceConnectionState == BluetoothConnectionState.connected) {
final String uid = await Storage.getUid() ?? '';
BlueManage().writeCharacteristicWithResponse(OTAUpgradeCommand(
lockID: deviceName,
userID: uid,
keyID: deviceName,
platform: int.tryParse(data['platform']) ?? 0,
product: int.tryParse(data['product']) ?? 0,
hwVersion: data['hwVersion'],
fwVersion: data['fwVersion'],
fwSize: data['fwSize'],
fwMD5: data['fwMd5'],
needAuthor: 1,
token: token,
encrypt: false,
).packageData());
} else if (deviceConnectionState ==
BluetoothConnectionState.disconnected) {}
}, isAddEquipment: true);
}
//循环传输升级固件包
Future<void> processOtaUpgrade() async {
if (!state.otaUpdateIng.value) {
return;
}
final int length = otaBin?.length ?? 0;
if (otaCount == 0) {
//首次
final int difference = length % 240;
otaCount = length ~/ 240 + (difference > 0 ? 1 : 0);
startSecond = DateTime.now().millisecondsSinceEpoch;
}
if (otaCount <= otaIndex) {
final int now = DateTime.now().millisecondsSinceEpoch;
// final String msg = '传输完成 时间:${now - startSecond}秒 otaCount:$otaCount otaIndex:$otaIndex ';
closeOTADAta();
AppLog.log(
'传输完成 时间:${now - startSecond}秒 otaCount:$otaCount otaIndex:$otaIndex ');
// showToast(msg);
return;
}
final int star = otaIndex * 240;
int end = (otaIndex + 1) * 240;
if (end > length) {
end = length;
}
final int size = end - star;
final List<int> data = otaBin!.sublist(star, end);
state.otaProgress.value = otaIndex / otaCount;
await BlueManage().writeCharacteristicWithResponse(
ProcessOtaUpgradeCommand(index: otaIndex, size: size, data: data)
.packageData());
}
//开始 ota升级
void startOTAData() {
state.otaUpdateIng.value = true;
state.oTAProgressDialog = true;
Get.dialog(
OTAProgressDialog(
logic: this,
),
barrierDismissible: false)
.then((dynamic value) => state.oTAProgressDialog = false);
}
//清楚 ata 安装文件
void closeOTADAta() {
if (state.oTAProgressDialog) {
Get.back();
}
state.otaUpdateIng.value = false;
state.otaProgress.value = 0;
otaIndex = 0;
otaCount = 0;
startSecond = 0;
otaBin = null;
}
// 拦截返回事件
void getBack() {
if (state.otaUpdateIng.value) {
closeOTADAta();
} else {
Get.back();
}
}
// 检查文件头
Future<Map?> getHeadFile(Uint8List data) async {
if (data.length <= 16) {
showToast('错误固件,请选择正确的文件'.tr);
return null;
}
// 检查文件头
String header;
try {
header = utf8.decode(data.sublist(0, 12));
} catch (e) {
showToast('非SYD固件请选择正确的文件'.tr);
return null;
}
if (header != 'SYD-BIN-DATA') {
showToast('非SYD固件请选择正确的文件'.tr);
return null;
}
// 解析元数据长度
Uint8List metaLenList;
int metaLen;
try {
metaLenList = data.sublist(12, 16);
metaLen = ByteData.sublistView(metaLenList).getUint32(0);
} catch (e) {
showToast('文件校验失败 0x01'.tr);
return null;
}
if (metaLen < 2 || metaLen > 10240) {
showToast('文件校验失败 0x01'.tr);
return null;
}
// 读取和解析元数据
Uint8List metaStrList;
String metaStr;
try {
metaStrList = data.sublist(16, 16 + metaLen);
metaStr = utf8.decode(metaStrList);
} catch (e) {
showToast('解析元数据失败,请选择正确的文件'.tr);
return null;
}
AppLog.log(metaStr);
final meta = jsonDecode(metaStr);
if (meta is! Map) {
showToast('解析元数据失败,请选择正确的文件'.tr);
return null;
}
return meta..['metaLen'] = metaLen;
}
//检测升级文件并读取 bin
Future<Uint8List?> checkFile(Uint8List data, Map meta) async {
final num binOffset = 16 + (meta['metaLen'] ?? 0);
// 获取固件数据部分
final Uint8List bin = data.sublist(binOffset.toInt(), data.length);
//md5 校验有问题,暂时不解析
final String md5Str = md5.convert(bin).toString().toUpperCase();
// AppLog.log('---> $md5Str ${meta['fwMd5']}');
if (md5Str != meta['fwMd5']) {
showToast('文件校验失败 0x02'.tr);
return null;
}
if (bin.length != meta['fwSize']) {
showToast('文件校验失败 0x03'.tr);
return null;
}
return bin;
}
// 从服务器获取锁的时间 开锁时传入
Future<void> getServerDatetime() async {
final GetServerDatetimeEntity entity =
await ApiRepository.to.getServerDatetimeData(isUnShowLoading: false);
if (entity.errorCode!.codeIsSuccessful) {
state.serverTime = entity.data!.date! ~/ 1000;
if (state.otaState.value) {
oTAUpgrade(state.selectLockName.value);
} else {
connect(state.selectLockName.value);
}
}
}
int getLocalTime() {
final DateTime now = DateTime.now();
final Duration timeZoneOffset = now.timeZoneOffset;
AppLog.log('timeZoneOffset.inSeconds:$timeZoneOffset.inSeconds');
return state.serverTime + timeZoneOffset.inSeconds;
}
@override
void onReady() {
super.onReady();
getNearByLimits();
}
@override
void onInit() {
super.onInit();
}
@override
void onClose() {
_replySubscription?.cancel();
super.onClose();
}
Future<void> getNearByLimits() async {
if (!Platform.isIOS) {
// bool bluetoothRequest = false;
// try {
// bluetoothRequest = await PermissionDialog.requestBluetooth();
// AppLog.log('bluetoothRequest:$bluetoothRequest');
// if (!bluetoothRequest) {
// return;
// }
// } catch (e) {
// AppLog.log('bluetoothRequest:$e');
// }
final bool bluetoothRequest = await PermissionDialog.requestBluetooth();
final bool locationRequest =
await PermissionDialog.request(Permission.location);
AppLog.log('locationRequest:$locationRequest');
if (!bluetoothRequest || !locationRequest) {
return;
}
}
_initReplySubscription();
state.ifCurrentScreen.value = true;
startScanBlueList();
}
}