fix:修复 开锁会有时候一直执行动画的问题

This commit is contained in:
anfe 2024-05-23 18:10:34 +08:00
parent ffd709a1ae
commit a097f882e2
5 changed files with 170 additions and 75 deletions

View File

@ -144,12 +144,11 @@ class BlueManage {
if (isAvailable) { if (isAvailable) {
if (_adapterState == BluetoothAdapterState.on) { if (_adapterState == BluetoothAdapterState.on) {
try { try {
//android 8 //android 3
final int divisor = Platform.isAndroid ? 3 : 1; final int divisor = Platform.isAndroid ? 3 : 1;
FlutterBluePlus.startScan( FlutterBluePlus.startScan(
continuousDivisor: divisor, continuousDivisor: divisor,
continuousUpdates: true, continuousUpdates: true,
// withServiceData:[ServiceDataFilter()],
withKeywords: <String>[deviceName], withKeywords: <String>[deviceName],
timeout: Duration(seconds: timeout)); timeout: Duration(seconds: timeout));
final Completer<dynamic> completer = Completer<dynamic>(); final Completer<dynamic> completer = Completer<dynamic>();
@ -317,7 +316,7 @@ class BlueManage {
if (isAddEquipment == false && isExistDevice == false) { if (isAddEquipment == false && isExistDevice == false) {
//使 //使
startScanSingle(deviceName, 10, (List<ScanResult> scanDevices) { startScanSingle(deviceName, 15, (List<ScanResult> scanDevices) {
_connectDevice(scanDevices, deviceName, connectStateCallBack, _connectDevice(scanDevices, deviceName, connectStateCallBack,
isAddEquipment: isAddEquipment); isAddEquipment: isAddEquipment);
}); });

View File

@ -8,6 +8,7 @@ import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart'; import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart';
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart'; import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockTime/getServerDatetime_entity.dart'; import 'package:star_lock/main/lockDetail/lockSet/lockTime/getServerDatetime_entity.dart';
import 'package:star_lock/tools/throttler.dart';
import 'package:star_lock/widget/permission/permission_dialog.dart'; import 'package:star_lock/widget/permission/permission_dialog.dart';
@ -33,6 +34,10 @@ import 'lockNetToken_entity.dart';
class LockDetailLogic extends BaseGetXController { class LockDetailLogic extends BaseGetXController {
final LockDetailState state = LockDetailState(); final LockDetailState state = LockDetailState();
//
FunctionBlocker functionBlocker =
FunctionBlocker(duration: const Duration(seconds: 2));
// //
void initReplySubscription() { void initReplySubscription() {
state.replySubscription = state.replySubscription =
@ -114,10 +119,19 @@ class LockDetailLogic extends BaseGetXController {
break; break;
case 0x16: case 0x16:
// ... // ...
final int isOpen = reply.data[8];
String? msg;
if (isOpen == 0) {
msg = '正在开锁中...'.tr;
} else if (isOpen == 32) {
msg = '正在闭锁中...'.tr;
}
resetOpenDoorState(); resetOpenDoorState();
showToast('正在开锁中...'.tr, something: () { if (msg != null) {
cancelBlueConnetctToastTimer(); showToast(msg, something: () {
}); cancelBlueConnetctToastTimer();
});
}
break; break;
case 0x0d: case 0x0d:
// //
@ -161,14 +175,13 @@ class LockDetailLogic extends BaseGetXController {
void openDoorError() { void openDoorError() {
resetOpenDoorState(); resetOpenDoorState();
state.animationController!.stop(); state.animationController!.stop();
cancelBlueConnetctToastTimer(); blueManageDisconnect();
BlueManage().disconnect();
} }
// //
void closeLuckStatus() { void closeLuckStatus() {
state.openLockBtnState.value = 0; state.openLockBtnState.value = 0;
state.openDoorBtnisUneable.value = false; state.openDoorBtnisUneable.value = true;
state.animationController!.stop(canceled: true); state.animationController!.stop(canceled: true);
cancelBlueConnetctToastTimer(); cancelBlueConnetctToastTimer();
} }
@ -225,29 +238,28 @@ class LockDetailLogic extends BaseGetXController {
if (dataLength == state.logCountPage) { if (dataLength == state.logCountPage) {
senderReferEventRecordTime(); senderReferEventRecordTime();
} else { } else {
await BlueManage().disconnect(); await blueManageDisconnect();
} }
} }
break; break;
case 0x06: case 0x06:
// //
BlueManage().disconnect(); blueManageDisconnect();
cancelBlueConnetctToastTimer();
break; break;
default: default:
BlueManage().disconnect(); blueManageDisconnect();
cancelBlueConnetctToastTimer();
break; break;
} }
} }
// //
Future<void> openDoorAction() async { Future<void> openDoorAction() async {
showBlueConnetctToastTimer(action: () { showBlueConnetctToastTimer(
resetOpenDoorState(); outTimer: 20,
closeLuckStatus(); action: () {
BlueManage().disconnect(); resetOpenDoorState();
}); blueManageDisconnect();
});
final List<String>? privateKey = final List<String>? privateKey =
await Storage.getStringList(saveBluePrivateKey); await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!); final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
@ -285,13 +297,20 @@ class LockDetailLogic extends BaseGetXController {
}); });
} }
//
Future<void> blueManageDisconnect() async {
//便
closeLuckStatus();
cancelBlueConnetctToastTimer();
await BlueManage().disconnect();
}
// () // ()
void senderReferEventRecordTime() { void senderReferEventRecordTime() {
showBlueConnetctToastTimer( showBlueConnetctToastTimer(
isShowBlueConnetctToast: false, isShowBlueConnetctToast: false,
action: () { action: () {
closeLuckStatus(); blueManageDisconnect();
BlueManage().disconnect();
}); });
BlueManage().blueSendData(BlueManage().connectDeviceName, BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState connectionState) async { (BluetoothConnectionState connectionState) async {
@ -325,7 +344,7 @@ class LockDetailLogic extends BaseGetXController {
} }
// //
void getServerDatetime() async { Future<void> getServerDatetime() async {
final GetServerDatetimeEntity entity = final GetServerDatetimeEntity entity =
await ApiRepository.to.getServerDatetimeData(); await ApiRepository.to.getServerDatetimeData();
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
@ -341,7 +360,7 @@ class LockDetailLogic extends BaseGetXController {
} }
// token // token
void getLockNetToken() async { Future<void> getLockNetToken() async {
final LockNetTokenEntity entity = await ApiRepository.to final LockNetTokenEntity entity = await ApiRepository.to
.getLockNetToken(lockId: state.keyInfos.value.lockId.toString()); .getLockNetToken(lockId: state.keyInfos.value.lockId.toString());
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
@ -375,7 +394,7 @@ class LockDetailLogic extends BaseGetXController {
} }
// //
void getLockRecordLastUploadDataTime() async { Future<void> getLockRecordLastUploadDataTime() async {
final LockOperatingRecordGetLastRecordTimeEntity entity = final LockOperatingRecordGetLastRecordTimeEntity entity =
await ApiRepository.to.getLockRecordLastUploadDataTime( await ApiRepository.to.getLockRecordLastUploadDataTime(
lockId: state.keyInfos.value.lockId.toString()); lockId: state.keyInfos.value.lockId.toString());
@ -402,7 +421,7 @@ class LockDetailLogic extends BaseGetXController {
} }
// //
void deletKeyData() async { Future<void> deletKeyData() async {
final ElectronicKeyListEntity entity = await ApiRepository.to final ElectronicKeyListEntity entity = await ApiRepository.to
.deleteElectronicKey( .deleteElectronicKey(
keyId: state.keyInfos.value.keyId.toString(), includeUnderlings: 0); keyId: state.keyInfos.value.keyId.toString(), includeUnderlings: 0);
@ -497,13 +516,6 @@ class LockDetailLogic extends BaseGetXController {
await PermissionDialog.request(Permission.location); await PermissionDialog.request(Permission.location);
await PermissionDialog.requestBluetooth(); await PermissionDialog.requestBluetooth();
final String connectDeviceName =
state.keyInfos.value.bluetooth!.bluetoothDeviceName!;
if (!BlueManage().isExistScanDevices(connectDeviceName)) {
BlueManage().startScanSingle(
connectDeviceName, 15, (List<ScanResult> p0) => null);
}
} }
@override @override

View File

@ -254,14 +254,20 @@ class _LockDetailPageState extends State<LockDetailPage>
children: <Widget>[ children: <Widget>[
const Spacer(), const Spacer(),
GestureDetector( GestureDetector(
onTap: state.openDoorBtnisUneable.value == true onTap: () {
? isNeedRealNameAuthThenOpenLock if (state.openDoorBtnisUneable.value == true) {
: null, logic.functionBlocker.block(isNeedRealNameAuthThenOpenLock);
onLongPressStart: state.openDoorBtnisUneable.value == true }
? (LongPressStartDetails details) { },
setState(startUnLock); onLongPressStart: (LongPressStartDetails details) {
} if (state.openDoorBtnisUneable.value == true) {
: null, void callback() {
setState(startUnLock);
}
logic.functionBlocker.block(callback);
}
},
child: Container( child: Container(
width: 100.r, width: 100.r,
height: 100.r, height: 100.r,
@ -583,14 +589,20 @@ class _LockDetailPageState extends State<LockDetailPage>
children: <Widget>[ children: <Widget>[
Center( Center(
child: GestureDetector( child: GestureDetector(
onTap: state.openDoorBtnisUneable.value == true onTap: () {
? isNeedRealNameAuthThenOpenLock if (state.openDoorBtnisUneable.value == true) {
: null, logic.functionBlocker.block(isNeedRealNameAuthThenOpenLock);
onLongPressStart: state.openDoorBtnisUneable.value == true }
? (LongPressStartDetails details) { },
setState(startUnLock); onLongPressStart: (LongPressStartDetails details) {
} if (state.openDoorBtnisUneable.value == true) {
: null, void callback() {
setState(startUnLock);
}
logic.functionBlocker.block(callback);
}
},
child: Stack( child: Stack(
children: <Widget>[ children: <Widget>[
FlavorsImg( FlavorsImg(
@ -1347,7 +1359,7 @@ class _LockDetailPageState extends State<LockDetailPage>
state.iSOpenLock.value = false; state.iSOpenLock.value = false;
state.openLockBtnState.value = 1; state.openLockBtnState.value = 1;
state.animationController!.forward(); state.animationController!.forward();
EasyLoading.showToast('正在尝试闭锁……'.tr, duration: 2000.milliseconds); EasyLoading.showToast('正在尝试闭锁……'.tr, duration: 1000.milliseconds);
AppLog.log('长按闭锁'); AppLog.log('长按闭锁');
if (state.isOpenLockNeedOnline.value == 0) { if (state.isOpenLockNeedOnline.value == 0) {
// //

View File

@ -48,16 +48,16 @@ class LockEscalationLogic extends BaseGetXController {
// //
Future<void> otaUpdate() async { Future<void> otaUpdate() async {
var status = await PermissionDialog.requestStorage(); final bool status = await PermissionDialog.requestStorage();
if (status != true) { if (status != true) {
return; return;
} }
FilePickerResult? result = await FilePicker.platform.pickFiles(); final FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result == null || result.files.single.path is! String) { if (result == null || result.files.single.path is! String) {
return; return;
} }
File file = File(result.files.single.path!); final File file = File(result.files.single.path!);
Uint8List data = await file.readAsBytes(); final Uint8List data = await file.readAsBytes();
headJson = await getHeadFile(data); headJson = await getHeadFile(data);
if (headJson is! Map) { if (headJson is! Map) {
return; return;
@ -66,15 +66,13 @@ class LockEscalationLogic extends BaseGetXController {
if (otaBin == null) { if (otaBin == null) {
return; return;
} }
String md5Str = md5.convert(otaBin!).toString(); final String md5Str = md5.convert(otaBin!).toString();
headJson!['fwMd5'] = md5Str; headJson!['fwMd5'] = md5Str;
ShowTipView().showIosTipWithContentDialog("未避免异常情况,请在门打开时升级".tr, () async { ShowTipView().showIosTipWithContentDialog('未避免异常情况,请在门打开时升级'.tr, () async {
blueOTAUpgrade(headJson!, [0, 0, 0, 0]); blueOTAUpgrade(headJson!, [0, 0, 0, 0]);
EasyLoading.show( EasyLoading.show(
status: '设备连接中...'.tr, maskType: EasyLoadingMaskType.black); status: '设备连接中...'.tr, maskType: EasyLoadingMaskType.black);
Future.delayed(const Duration(seconds: 4), () { Future.delayed(const Duration(seconds: 4), EasyLoading.dismiss);
EasyLoading.dismiss();
});
}); });
} }
@ -83,11 +81,11 @@ class LockEscalationLogic extends BaseGetXController {
BlueManage().blueSendData(BlueManage().connectDeviceName, BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState deviceConnectionState) async { (BluetoothConnectionState deviceConnectionState) async {
if (deviceConnectionState == BluetoothConnectionState.connected) { if (deviceConnectionState == BluetoothConnectionState.connected) {
var privateKey = await Storage.getStringList(saveBluePrivateKey); final privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!); final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
var signKey = await Storage.getStringList(saveBlueSignKey); final signKey = await Storage.getStringList(saveBlueSignKey);
List<int> signKeyDataList = changeStringListToIntList(signKey!); final List<int> signKeyDataList = changeStringListToIntList(signKey!);
String uid = await Storage.getUid() ?? ''; final String uid = await Storage.getUid() ?? '';
BlueManage().writeCharacteristicWithResponse(OTAUpgradeCommand( BlueManage().writeCharacteristicWithResponse(OTAUpgradeCommand(
lockID: BlueManage().connectDeviceName, lockID: BlueManage().connectDeviceName,
userID: uid, userID: uid,
@ -113,30 +111,30 @@ class LockEscalationLogic extends BaseGetXController {
if (!state.otaUpdateIng.value) { if (!state.otaUpdateIng.value) {
return; return;
} }
int length = otaBin?.length ?? 0; final int length = otaBin?.length ?? 0;
if (otaCount == 0) { if (otaCount == 0) {
// //
int difference = length % 240; final int difference = length % 240;
otaCount = length ~/ 240 + (difference > 0 ? 1 : 0); otaCount = length ~/ 240 + (difference > 0 ? 1 : 0);
startSecond = DateTime.now().millisecondsSinceEpoch ~/ 1000; startSecond = DateTime.now().millisecondsSinceEpoch ~/ 1000;
startOTAData(); startOTAData();
} }
if (otaCount <= otaIndex) { if (otaCount <= otaIndex) {
int now = DateTime.now().millisecondsSinceEpoch ~/ 1000; final int now = DateTime.now().millisecondsSinceEpoch ~/ 1000;
String msg = final String msg =
'传输完成 时间:${now - startSecond}秒 otaCount:$otaCount otaIndex:$otaIndex '; '传输完成 时间:${now - startSecond}秒 otaCount:$otaCount otaIndex:$otaIndex ';
closeOTADAta(); closeOTADAta();
AppLog.log(msg); AppLog.log(msg);
// showToast(msg); // showToast(msg);
return; return;
} }
int star = otaIndex * 240; final int star = otaIndex * 240;
int end = (otaIndex + 1) * 240; int end = (otaIndex + 1) * 240;
if (end > length) { if (end > length) {
end = length; end = length;
} }
int size = end - star; final int size = end - star;
List<int> data = otaBin!.sublist(star, end); final List<int> data = otaBin!.sublist(star, end);
state.otaProgress.value = otaIndex / otaCount; state.otaProgress.value = otaIndex / otaCount;
await BlueManage().writeCharacteristicWithResponse( await BlueManage().writeCharacteristicWithResponse(
ProcessOtaUpgradeCommand(index: otaIndex, size: size, data: data) ProcessOtaUpgradeCommand(index: otaIndex, size: size, data: data)
@ -176,7 +174,8 @@ class LockEscalationLogic extends BaseGetXController {
// //
String header; String header;
try { try {
header = utf8.decode(data.sublist(0, 12)); final Uint8List list = data.sublist(0, 12);
header = utf8.decode(list);
} catch (e) { } catch (e) {
showToast('非SYD固件请选择正确的文件'.tr); showToast('非SYD固件请选择正确的文件'.tr);
return null; return null;
@ -210,7 +209,7 @@ class LockEscalationLogic extends BaseGetXController {
return null; return null;
} }
AppLog.log(metaStr); AppLog.log(metaStr);
var meta = jsonDecode(metaStr); final meta = jsonDecode(metaStr);
if (meta is! Map) { if (meta is! Map) {
showToast('解析元数据失败,请选择正确的文件'.tr); showToast('解析元数据失败,请选择正确的文件'.tr);
return null; return null;
@ -220,11 +219,11 @@ class LockEscalationLogic extends BaseGetXController {
// bin // bin
Future<Uint8List?> checkFile(Uint8List data, Map meta) async { Future<Uint8List?> checkFile(Uint8List data, Map meta) async {
num binOffset = 16 + (meta['metaLen'] ?? 0); final num binOffset = 16 + (meta['metaLen'] ?? 0);
// //
Uint8List bin = data.sublist(binOffset.toInt(), data.length); final Uint8List bin = data.sublist(binOffset.toInt(), data.length);
//md5 //md5
String md5Str = md5.convert(bin).toString().toUpperCase(); final String md5Str = md5.convert(bin).toString().toUpperCase();
AppLog.log('固件 md5 检验md5$md5Str 固件信息 md5${meta['fwMd5']}'); AppLog.log('固件 md5 检验md5$md5Str 固件信息 md5${meta['fwMd5']}');
if (md5Str != meta['fwMd5']) { if (md5Str != meta['fwMd5']) {
showToast('文件校验失败 0x02'.tr); showToast('文件校验失败 0x02'.tr);

73
lib/tools/throttler.dart Normal file
View File

@ -0,0 +1,73 @@
import 'dart:async';
import 'package:star_lock/app_settings/app_settings.dart';
///
///
// 1
// Throttler throttler = Throttler(Duration(seconds: 1));
//
// //
// void myFunction() {
// print("函数被调用");
// }
//
// // 1
// throttler.throttle(myFunction);
//
// //
// Throttler customThrottler = Throttler(Duration(milliseconds: 500)); // 500
// customThrottler.throttle(myFunction); // 500
//
// //
// customThrottler.cancel(); //
class Throttler {
Throttler(this._delay);
final Duration _delay;
Timer? _timer;
late Function _callback;
void throttle(Function callback) {
if (_timer == null || !_timer!.isActive) {
_callback = callback;
_timer = Timer(_delay, () {
_callback();
_timer?.cancel();
});
}
}
void cancel() {
_timer?.cancel();
}
}
///
///
///
class FunctionBlocker {
FunctionBlocker({required this.duration});
bool _blocked = false;
Duration duration;
void block(Function function) {
if (!_blocked) {
_blocked = true;
function();
Timer(duration, () {
_blocked = false;
});
}
}
//
void countdownProhibited({required Duration duration}) {
_blocked = true;
Timer(duration, () {
_blocked = false;
});
}
}