解决bug
This commit is contained in:
parent
d44c7ee20e
commit
bc74511fd5
@ -397,32 +397,19 @@ class LockDetailLogic extends BaseGetXController {
|
||||
indexMap['type'] = indexList[0].toString();
|
||||
|
||||
final int userNo = (indexList[1] * 256) + indexList[2];
|
||||
indexMap['user'] = userNo.toString();
|
||||
// AppLog.log('userNouserNouserNouserNo:$userNo');
|
||||
if (userNo == 0xFFFF) {
|
||||
// 离线密码情况:16进制格式,去除结束符F(0x1F)及其之后的内容
|
||||
final List<int> passwordData = indexList.sublist(7, 17); // 取10个字节
|
||||
// 找到结束符F(0x1F)的位置
|
||||
int endIndex = passwordData.indexOf(0x1F);
|
||||
if (endIndex == -1) {
|
||||
// 如果没有结束符,取全部数据
|
||||
endIndex = passwordData.length;
|
||||
}
|
||||
// 只取结束符前的部分(不包括结束符)
|
||||
final List<int> actualPasswordData = passwordData.sublist(0, endIndex);
|
||||
// 转换为十六进制字符串
|
||||
String passwordHex = actualPasswordData.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join();
|
||||
// 过滤掉字母部分
|
||||
passwordHex = passwordHex.replaceAll(RegExp(r'[^0-9]'), '');
|
||||
|
||||
indexMap['password'] = passwordHex;
|
||||
// indexMap['password'] = passwordHex; // 存储十六进制字符串表示
|
||||
AppLog.log('离线密码开锁:$passwordHex');
|
||||
final List<int> passwordData = indexList.sublist(7, 17);
|
||||
final String password;
|
||||
if(userNo == 65535){
|
||||
//离线密码
|
||||
password = passwordData
|
||||
.map((byte) => byte.toRadixString(16).padLeft(2, '0'))
|
||||
.join('')
|
||||
.replaceAll(RegExp(r'f*$'), '');
|
||||
} else {
|
||||
final List<int> passwordData = indexList.sublist(7, 17);
|
||||
final String password = utf8String(passwordData);
|
||||
indexMap['password'] = password.toString();
|
||||
indexMap['user'] = userNo.toString();
|
||||
password = utf8String(passwordData);
|
||||
}
|
||||
indexMap['password'] = password.toString();
|
||||
|
||||
// AppLog.log('passwordpasswordpassword:$password');
|
||||
|
||||
@ -481,42 +468,7 @@ class LockDetailLogic extends BaseGetXController {
|
||||
final List<String>? token = await Storage.getStringList(saveBlueToken);
|
||||
final List<int> getTokenList = changeStringListToIntList(token!);
|
||||
|
||||
final String command = OpenLockCommand(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
openMode: state.openDoorModel,
|
||||
openTime: getUTCNetTime(),
|
||||
onlineToken: state.lockNetToken,
|
||||
token: getTokenList,
|
||||
needAuthor: 1,
|
||||
signKey: signKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
).toString();
|
||||
AppLog.log('command:${command}');
|
||||
|
||||
showBlueConnetctToastTimer(
|
||||
outTimer: 20,
|
||||
action: () async {
|
||||
final String getMobile = (await Storage.getMobile())!;
|
||||
ApmHelper.instance.trackEvent('open_lock', {
|
||||
'lock_name': state.keyInfos.value.lockName!,
|
||||
'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
|
||||
'date': DateTool().getNowDateWithType(1),
|
||||
'open_lock_result': '超时',
|
||||
});
|
||||
|
||||
resetOpenDoorState();
|
||||
blueManageDisconnect();
|
||||
BuglyTool.uploadException(
|
||||
message: '开门超时处理-开锁失败', detail: '开门超时,断开连接,开锁失败--OpenLockCommand:$command', upload: true);
|
||||
},
|
||||
);
|
||||
|
||||
BlueManage().blueSendData(state.keyInfos.value.bluetooth!.bluetoothDeviceName!,
|
||||
(BluetoothConnectionState deviceConnectionState) async {
|
||||
if (deviceConnectionState == BluetoothConnectionState.connected) {
|
||||
BuglyTool.uploadException(message: '蓝牙连接成功', detail: '蓝牙连接成功,发送开锁指令--OpenLockCommand:$command', upload: false);
|
||||
// FlutterBuglyPlugin.reportException(exceptionName: '蓝牙连接成功', reason: '蓝牙连接成功,发送开锁指令');
|
||||
BlueManage().blueSendData(state.keyInfos.value.bluetooth!.bluetoothDeviceName!, (BluetoothConnectionState deviceConnectionState) async {
|
||||
IoSenderManage.senderOpenLock(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
@ -528,23 +480,6 @@ class LockDetailLogic extends BaseGetXController {
|
||||
signKey: signKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
} else if (deviceConnectionState == BluetoothConnectionState.disconnected) {
|
||||
cancelBlueConnetctToastTimer();
|
||||
BuglyTool.uploadException(
|
||||
message: '蓝牙连接失败-开锁失败', detail: '蓝牙连接失败,断开连接, 开锁失败--OpenLockCommand:$command', upload: true);
|
||||
final String getMobile = (await Storage.getMobile())!;
|
||||
ApmHelper.instance.trackEvent('open_lock', {
|
||||
'lock_name': state.keyInfos.value.lockName!,
|
||||
'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
|
||||
'date': DateTool().getNowDateWithType(1),
|
||||
'open_lock_result': '断开连接',
|
||||
});
|
||||
|
||||
// if (state.ifCurrentScreen.value == true) {
|
||||
// showBlueConnetctToast();
|
||||
// }
|
||||
resetOpenDoorState();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -689,224 +624,62 @@ class LockDetailLogic extends BaseGetXController {
|
||||
|
||||
// 远程开锁
|
||||
Future<void> remoteOpenLock() async {
|
||||
final LockListInfoItemEntity currentKeyInfo = CommonDataManage().currentKeyInfo;
|
||||
|
||||
var lockId = currentKeyInfo.lockId ?? 0;
|
||||
var remoteUnlock = currentKeyInfo.lockSetting?.remoteUnlock ?? 0;
|
||||
|
||||
final lockPeerId = StartChartManage().lockPeerId;
|
||||
final LockListInfoGroupEntity? lockListInfoGroupEntity = await Storage.getLockMainListData();
|
||||
|
||||
//检查蓝牙连接状态
|
||||
final connectedDevices = await FlutterBluePlus.connectedDevices;
|
||||
final isDeviceConnected = connectedDevices.any((device) =>
|
||||
device.remoteId.str == BlueManage().connectDeviceName);
|
||||
|
||||
if (!isDeviceConnected) {
|
||||
AppLog.log('蓝牙已断开,尝试重新连接');
|
||||
// 蓝牙断开,需要重新连接并获取新的token
|
||||
await _reconnectAndRefreshToken();
|
||||
final catEyeConfig = state.keyInfos.value.lockSetting?.catEyeConfig ?? [];
|
||||
// 支持猫眼功能时,才需要判断是否是省电模式
|
||||
if (state.keyInfos.value.lockFeature?.isSupportCatEye == 1 && catEyeConfig[0].catEyeMode == 0) {
|
||||
showToast('猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式'.tr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lockListInfoGroupEntity != null) {
|
||||
lockListInfoGroupEntity!.groupList?.forEach((element) {
|
||||
final lockList = element.lockList;
|
||||
if (lockList != null && lockList.length != 0) {
|
||||
for (var lockInfo in lockList) {
|
||||
final peerId = lockInfo.network?.peerId;
|
||||
if (peerId != null && peerId != '') {
|
||||
if (peerId == lockPeerId) {
|
||||
lockId = lockInfo.lockId ?? 0;
|
||||
remoteUnlock = lockInfo.lockSetting?.remoteUnlock ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (remoteUnlock == 1) {
|
||||
// 发送蓝牙透传开锁
|
||||
await _sendUnlockViaBluetooth();
|
||||
// 发送远程开锁api
|
||||
final LoginEntity entity = await ApiRepository.to.remoteOpenLock(lockId: lockId.toString(), timeOut: 60);
|
||||
if(state.keyInfos.value.network?.peerId != null){
|
||||
// wifi锁
|
||||
final LoginEntity entity = await ApiRepository.to.remoteOpenLock(
|
||||
lockId: state.keyInfos.value.lockId.toString(),
|
||||
timeOut: 60,
|
||||
);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
showToast('已开锁'.tr);
|
||||
StartChartManage().lockListPeerId = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增方法:通过蓝牙透传发送开锁命令
|
||||
Future<void> _sendUnlockViaBluetooth() async {
|
||||
try {
|
||||
// 获取必要的密钥信息
|
||||
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> privateKeyList = changeStringListToIntList(privateKey!);
|
||||
} else {
|
||||
// 网关锁
|
||||
// 使用存储的新token进行远程开锁
|
||||
final List<String>? privateKey = await Storage.getStringList(
|
||||
saveBluePrivateKey);
|
||||
final List<int> getPrivateKeyList = changeStringListToIntList(
|
||||
privateKey!);
|
||||
|
||||
final List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
|
||||
final List<int> signKeyList = changeStringListToIntList(signKey!);
|
||||
final List<String>? signKey = await Storage.getStringList(
|
||||
saveBlueSignKey);
|
||||
final List<int> signKeyDataList = changeStringListToIntList(signKey!);
|
||||
|
||||
final List<String>? token = await Storage.getStringList(saveBlueToken);
|
||||
final List<int> tokenList = changeStringListToIntList(token!);
|
||||
final List<String>? storedToken = await Storage.getStringList(
|
||||
saveBlueToken);
|
||||
final List<int> tokenToUse = storedToken != null
|
||||
? changeStringListToIntList(storedToken)
|
||||
: <int>[0, 0, 0, 0];
|
||||
|
||||
// 构建开锁命令
|
||||
final OpenLockCommand openLockCommand = OpenLockCommand(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
openMode: state.openDoorModel,
|
||||
openTime: getUTCNetTime(),
|
||||
onlineToken: state.lockNetToken,
|
||||
token: tokenList,
|
||||
needAuthor: 1,
|
||||
signKey: signKeyList,
|
||||
privateKey: privateKeyList,
|
||||
);
|
||||
|
||||
// 包装命令数据
|
||||
final List<int> messageDetail = openLockCommand.packageData();
|
||||
final OpenLockCommand openLockCommand = OpenLockCommand(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
openMode: state.openDoorModel,
|
||||
openTime: getUTCNetTime(),
|
||||
onlineToken: state.lockNetToken,
|
||||
token: tokenToUse,
|
||||
// 使用新获取的token
|
||||
needAuthor: 1,
|
||||
signKey: signKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
|
||||
// 通过蓝牙透传发送开锁命令
|
||||
StartChartManage().sendRemoteUnLockMessage(
|
||||
bluetoothDeviceName: BlueManage().connectDeviceName,
|
||||
openLockCommand: messageDetail,
|
||||
);
|
||||
final messageDetail = openLockCommand.packageData();
|
||||
|
||||
AppLog.log('通过蓝牙透传发送远程开锁命令');
|
||||
|
||||
// 监听开锁结果,处理token不一致的情况
|
||||
_listenForOpenLockReply(tokenList);
|
||||
} catch (e) {
|
||||
AppLog.log('蓝牙透传开锁异常: $e');
|
||||
showToast('蓝牙透传开锁失败'.tr);
|
||||
}
|
||||
}
|
||||
|
||||
// 监听开锁回复,处理token验证
|
||||
void _listenForOpenLockReply(List<int> originalToken) {
|
||||
StreamSubscription<Reply>? subscription;
|
||||
// 设置监听器处理开锁回复
|
||||
subscription = EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
|
||||
if (reply is OpenDoorReply) {
|
||||
final int status = reply.data[6];
|
||||
|
||||
// 如果是token不一致的情况(状态码0x06)
|
||||
if (status == 0x06) {
|
||||
AppLog.log('token不一致,使用新token重新开锁');
|
||||
|
||||
// 提取新的token
|
||||
final List<int> newToken = reply.data.sublist(2, 6);
|
||||
|
||||
// 保存新token到存储
|
||||
final List<String> saveStrList = changeIntListToStringList(newToken);
|
||||
Storage.setStringList(saveBlueToken, saveStrList);
|
||||
|
||||
// 使用新token重新发送开锁命令
|
||||
await _reSendUnlockWithNewToken(newToken);
|
||||
}
|
||||
|
||||
// 取消监听
|
||||
subscription?.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
// 设置超时机制,避免监听器一直存在
|
||||
Timer(const Duration(seconds: 10), () {
|
||||
subscription?.cancel();
|
||||
});
|
||||
}
|
||||
|
||||
// 使用新token重新发送开锁命令
|
||||
Future<void> _reSendUnlockWithNewToken(List<int> newToken) async {
|
||||
try {
|
||||
// 获取必要的密钥信息
|
||||
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> privateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
final List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
|
||||
final List<int> signKeyList = changeStringListToIntList(signKey!);
|
||||
|
||||
// 构建新的开锁命令
|
||||
final OpenLockCommand openLockCommand = OpenLockCommand(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
openMode: state.openDoorModel,
|
||||
openTime: getUTCNetTime(),
|
||||
onlineToken: state.lockNetToken,
|
||||
token: newToken,
|
||||
needAuthor: 1,
|
||||
signKey: signKeyList,
|
||||
privateKey: privateKeyList,
|
||||
);
|
||||
|
||||
// 包装命令数据
|
||||
final List<int> messageDetail = openLockCommand.packageData();
|
||||
|
||||
// 通过蓝牙透传发送开锁命令
|
||||
StartChartManage().sendRemoteUnLockMessage(
|
||||
bluetoothDeviceName: BlueManage().connectDeviceName,
|
||||
openLockCommand: messageDetail,
|
||||
);
|
||||
|
||||
AppLog.log('使用新token重新发送开锁命令');
|
||||
} catch (e) {
|
||||
AppLog.log('使用新token重新开锁异常: $e');
|
||||
showToast('重新开锁失败'.tr);
|
||||
}
|
||||
}
|
||||
|
||||
// 新增方法:重新连接蓝牙并刷新token
|
||||
Future<void> _reconnectAndRefreshToken() async {
|
||||
try {
|
||||
// 重新连接蓝牙
|
||||
await BlueManage().blueSendData(
|
||||
state.keyInfos.value.bluetooth!.bluetoothDeviceName!,
|
||||
(BluetoothConnectionState deviceConnectionState) async {
|
||||
if (deviceConnectionState == BluetoothConnectionState.connected) {
|
||||
AppLog.log('蓝牙重新连接成功');
|
||||
// 获取新的token
|
||||
await _refreshLockToken();
|
||||
} else if (deviceConnectionState == BluetoothConnectionState.disconnected) {
|
||||
AppLog.log('蓝牙重新连接失败');
|
||||
showToast('蓝牙连接失败,请重试'.tr);
|
||||
}
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
AppLog.log('蓝牙重连异常: $e');
|
||||
showToast('蓝牙连接异常,请重试'.tr);
|
||||
}
|
||||
}
|
||||
|
||||
// 新增方法:刷新锁token
|
||||
Future<void> _refreshLockToken() async {
|
||||
try {
|
||||
final List<String>? token = await Storage.getStringList(saveBlueToken);
|
||||
final List<int> tokenList = changeStringListToIntList(token!);
|
||||
|
||||
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> privateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
final List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
|
||||
final List<int> signKeyList = changeStringListToIntList(signKey!);
|
||||
|
||||
// 发送获取新token的命令
|
||||
IoSenderManage.senderOpenLock(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
openMode: state.openDoorModel,
|
||||
openTime: getUTCNetTime(),
|
||||
onlineToken: state.lockNetToken,
|
||||
token: tokenList,
|
||||
needAuthor: 1,
|
||||
signKey: signKeyList,
|
||||
privateKey: privateKeyList,
|
||||
);
|
||||
|
||||
// 等待一段时间让token更新完成
|
||||
await Future.delayed(Duration(milliseconds: 500));
|
||||
} catch (e) {
|
||||
AppLog.log('刷新token异常: $e');
|
||||
// 发送远程开门消息
|
||||
StartChartManage().sendRemoteUnLockMessage(
|
||||
bluetoothDeviceName: BlueManage().connectDeviceName,
|
||||
openLockCommand: messageDetail,
|
||||
);
|
||||
AppLog.log('使用新token重新发送开锁命令');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -66,14 +66,12 @@ class AppLifecycleObserver extends WidgetsBindingObserver {
|
||||
final status = StartChartManage().talkStatus.status;
|
||||
if ((status == TalkStatus.passiveCallWaitingAnswer ||
|
||||
status == TalkStatus.proactivelyCallWaitingAnswer ||
|
||||
status == TalkStatus.answeredSuccessfully) &&
|
||||
status == TalkStatus.answeredSuccessfully ||
|
||||
status == TalkStatus.uninitialized) &&
|
||||
Get.currentRoute != '/StarLockRegisterPage') { // 避免在注册页返回
|
||||
Get.back();
|
||||
}
|
||||
// 避免在无通话状态时销毁对讲资源
|
||||
if (status != TalkStatus.uninitialized) {
|
||||
StartChartManage().destruction();
|
||||
}
|
||||
StartChartManage().destruction();
|
||||
_readMessageRefreshUIEvent?.cancel();
|
||||
}
|
||||
|
||||
|
||||
@ -1301,13 +1301,8 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
state.currentQuality.value = quality;
|
||||
TalkExpectReq talkExpectReq = StartChartManage().getDefaultTalkExpect();
|
||||
final audioType = talkExpectReq.audioType;
|
||||
|
||||
// 立即显示loading状态
|
||||
state.isLoading.value = true;
|
||||
|
||||
int width = 864;
|
||||
int height = 480;
|
||||
|
||||
switch (quality) {
|
||||
case '高清':
|
||||
talkExpectReq = TalkExpectReq(
|
||||
@ -1327,23 +1322,15 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
break;
|
||||
}
|
||||
|
||||
// 立即预设解码器尺寸
|
||||
/// 修改发送预期数据
|
||||
StartChartManage().changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer(talkExpect: talkExpectReq);
|
||||
|
||||
// 不立即loading,继续解码旧流帧,等待frameSeq回绕检测
|
||||
// 仅重置frameSeq回绕检测标志
|
||||
_pendingStreamReset = false;
|
||||
_pendingResetWidth = width;
|
||||
_pendingResetHeight = height;
|
||||
|
||||
try {
|
||||
// 并行执行两个操作以提高效率,设置更短的总超时时间
|
||||
await Future.wait([
|
||||
// 立即重置解码器
|
||||
_resetDecoderForNewStream(width, height),
|
||||
// 修改发送预期数据
|
||||
Future.microtask(() =>
|
||||
StartChartManage().changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer(talkExpect: talkExpectReq))
|
||||
]).timeout(const Duration(milliseconds: 1500)); // 设置总超时时间
|
||||
} catch (e) {
|
||||
AppLog.log('切换清晰度超时或失败: $e');
|
||||
state.isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
void _initHdOptions() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user