Merge branch 'develop_sky' into 'canary_release_sky'

Develop sky

See merge request StarlockTeam/app-starlock!274
This commit is contained in:
李仪 2025-09-04 09:19:35 +00:00
commit 472a6f20d3
6 changed files with 103 additions and 82 deletions

View File

@ -144,7 +144,7 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
break;
case AppLifecycleState.paused:
// AppLog.log('App--->进入后台');
BlueManage().disconnect();
BlueManage.instance.disconnect();
break;
case AppLifecycleState.resumed:
// AppLog.log('App--->进入前台');

View File

@ -85,6 +85,12 @@ class BlueManage {
return _manager;
}
// 访
static BlueManage get instance {
_manager ??= BlueManage._init();
return _manager!;
}
BlueManage? get manager => shareManager();
void _initBlue() {
@ -94,9 +100,13 @@ class BlueManage {
}
void _initGetMtuSubscription() {
_mtuSubscription ??= bluetoothConnectDevice!.mtu.listen((int value) {
//
_mtuSubscription?.cancel();
_mtuSubscription = null;
_mtuSubscription = bluetoothConnectDevice!.mtu.listen((int value) {
_mtuSize = value - 3;
AppLog.log('_mtuSizeValue:$value mtuSize:$_mtuSize');
AppLog.log('设备MTU变化 - 原始值:$value 计算后MTU:$_mtuSize 设备:${bluetoothConnectDevice?.remoteId.str}');
});
}
@ -954,6 +964,12 @@ class BlueManage {
Future<void> disconnect() async {
try {
connectDeviceMacAddress = '';
// MTU监听
_mtuSubscription?.cancel();
_mtuSubscription = null;
_mtuSize = 20; // MTU为默认值
if (bluetoothConnectionState == BluetoothConnectionState.connected) {
//
await bluetoothConnectDevice!.disconnect(timeout: 3);
@ -975,10 +991,29 @@ class BlueManage {
}
}
// MTU信息
String getMtuDebugInfo() {
return 'MTU Debug Info:\n'
'- Current MTU Size: $_mtuSize\n'
'- Connected Device: ${bluetoothConnectDevice?.remoteId.str ?? "None"}\n'
'- Device Name: $connectDeviceName\n'
'- Connection State: $bluetoothConnectionState\n'
'- MTU Subscription Active: ${_mtuSubscription != null}';
}
void disposed() {
_sendStreamSubscription?.cancel();
_mtuSubscription!.cancel();
_adapterStateStateSubscription!.cancel();
_connectionStateSubscription!.cancel();
_mtuSubscription?.cancel();
_adapterStateStateSubscription?.cancel();
_connectionStateSubscription?.cancel();
//
_mtuSize = 20;
connectDeviceName = '';
connectDeviceMacAddress = '';
bluetoothConnectDevice = null;
scanDevices.clear();
allData.clear();
lastTimeData.clear();
}
}

View File

@ -439,9 +439,24 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
_handlerVoicePackageConfigureConfirmation(
VoicePackageConfigureConfirmationReply reply,
) async {
final int status = reply.data[2];
switch (status) {
case 0x00:
showEasyLoading();
showBlueConnetctToastTimer(action: () {
dismissEasyLoading();
});
final LoginEntity entity = await ApiRepository.to.settingCurrentVoiceTimbre(
data: {
'lang': state.tempLangStr.value,
'timbre': state.tempTimbreStr.value,
},
lockId: state.lockSetInfoData.value.lockId!,
);
if (entity.errorCode!.codeIsSuccessful) {
showSuccess('设置成功'.tr, something: () async {
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.lang =
state.tempLangStr.value;
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre
?.timbre = state.tempTimbreStr.value;
await BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState deviceConnectionState) async {
if (deviceConnectionState == BluetoothConnectionState.connected) {
@ -458,10 +473,8 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
showBlueConnetctToast();
}
});
break;
default:
showToast('设置'.tr + '失败'.tr);
break;
await Future.delayed(Duration(seconds: 1));
});
}
}
@ -470,24 +483,6 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
switch (status) {
case 0x00:
cancelBlueConnetctToastTimer();
final LoginEntity entity =
await ApiRepository.to.settingCurrentVoiceTimbre(
data: {
'lang': state.tempLangStr.value,
'timbre': state.tempTimbreStr.value,
},
lockId: state.lockSetInfoData.value.lockId!,
);
if (entity.errorCode!.codeIsSuccessful) {
showSuccess('设置成功'.tr, something: () {
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre
?.lang = state.tempLangStr.value;
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre
?.timbre = state.tempTimbreStr.value;
eventBus.fire(
PassCurrentLockInformationEvent(state.lockSetInfoData.value));
});
}
dismissEasyLoading();
break;
default:
@ -522,7 +517,6 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
languageCode =
languageCode.replaceAll('\u0000', ''); // (null bytes)
if (languageCode != null && languageCode != '') {
final indexWhere = state.languages
.indexWhere((element) => element.lang == languageCode);

View File

@ -64,7 +64,7 @@ class _SpeechLanguageSettingsPageState
return CommonItem(
leftTitel: soundType,
leftTitleStyle: TextStyle(
fontSize: 22.sp,
fontSize: 20.sp,
fontWeight: state.selectSoundTypeIndex.value == index
? FontWeight.bold
: null,
@ -111,7 +111,7 @@ class _SpeechLanguageSettingsPageState
return CommonItem(
leftTitel: item.langText,
leftTitleStyle: TextStyle(
fontSize: 22.sp,
fontSize: 20.sp,
fontWeight: state.selectPassthroughListIndex.value == index
? FontWeight.bold
: null,

View File

@ -84,22 +84,42 @@ class LockVoiceSettingLogic extends BaseGetXController {
showBlueConnetctToastTimer(action: () {
dismissEasyLoading();
});
await BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState deviceConnectionState) async {
if (deviceConnectionState == BluetoothConnectionState.connected) {
await BlueManage().writeCharacteristicWithResponse(
SetVoicePackageFinalResult(
lockID: BlueManage().connectDeviceName,
languageCode: state.tempLangStr.value,
).packageData(),
);
} else if (deviceConnectionState ==
BluetoothConnectionState.disconnected) {
dismissEasyLoading();
cancelBlueConnetctToastTimer();
showBlueConnetctToast();
}
});
final LoginEntity entity = await ApiRepository.to.settingCurrentVoiceTimbre(
data: {
'lang': state.tempLangStr.value,
'timbre': state.tempTimbreStr.value,
},
lockId: state.lockSetInfoData.value.lockId!,
);
if (entity.errorCode!.codeIsSuccessful) {
showSuccess('设置成功'.tr, something: () async {
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.lang =
state.tempLangStr.value;
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre
?.timbre = state.tempTimbreStr.value;
await BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState deviceConnectionState) async {
if (deviceConnectionState == BluetoothConnectionState.connected) {
await BlueManage().writeCharacteristicWithResponse(
SetVoicePackageFinalResult(
lockID: BlueManage().connectDeviceName,
languageCode: state.tempLangStr.value,
).packageData(),
);
} else if (deviceConnectionState ==
BluetoothConnectionState.disconnected) {
dismissEasyLoading();
cancelBlueConnetctToastTimer();
showBlueConnetctToast();
}
});
await Future.delayed(Duration(seconds: 1));
eventBus
.fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value));
Get.offAllNamed(Routers.starLockMain);
});
}
}
void handleSetResult(SetVoicePackageFinalResultReply reply) async {
@ -107,26 +127,6 @@ class LockVoiceSettingLogic extends BaseGetXController {
switch (status) {
case 0x00:
cancelBlueConnetctToastTimer();
final LoginEntity entity =
await ApiRepository.to.settingCurrentVoiceTimbre(
data: {
'lang': state.tempLangStr.value,
'timbre': state.tempTimbreStr.value,
},
lockId: state.lockSetInfoData.value.lockId!,
);
if (entity.errorCode!.codeIsSuccessful) {
showSuccess('设置成功'.tr, something: () {
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre
?.lang = state.tempLangStr.value;
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre
?.timbre = state.tempTimbreStr.value;
eventBus.fire(
PassCurrentLockInformationEvent(state.lockSetInfoData.value));
Get.offAllNamed(Routers.starLockMain);
});
}
dismissEasyLoading();
break;
default:
@ -473,33 +473,25 @@ class LockVoiceSettingLogic extends BaseGetXController {
//
cancelBlueConnetctToastTimer();
// 1. LanguageCode
// CmdID (2 bytes) + Status (1 byte) = 3 bytes -> LanguageCode 3
const int languageCodeStartIndex = 3;
const int languageCodeLength = 20;
const int languageCodeEndIndex =
languageCodeStartIndex + languageCodeLength; // 23
// 2.
if (reply.data.length < languageCodeEndIndex) {
throw Exception(
'Reply data is too short to contain LanguageCode. Expected at least $languageCodeEndIndex bytes, got ${reply.data.length}');
}
// 3. LanguageCode
List<int> languageCodeBytes =
reply.data.sublist(languageCodeStartIndex, languageCodeEndIndex);
// 4.
// UTF-8 ASCII
String languageCode = String.fromCharCodes(languageCodeBytes);
// 5. () '\0'
// 20 '\0'
languageCode = languageCode.trim(); //
languageCode =
languageCode.replaceAll('\u0000', ''); // (null bytes)
// 6. 使 languageCode
print('LanguageCode: $languageCode'); // : zh_CN, en_US
if (languageCode != null && languageCode != '') {

View File

@ -96,7 +96,7 @@ class _LockVoiceSettingState extends State<LockVoiceSetting> {
return CommonItem(
leftTitel: soundType,
leftTitleStyle: TextStyle(
fontSize: 22.sp,
fontSize: 20.sp,
fontWeight: state.selectSoundTypeIndex.value == index
? FontWeight.bold
: null,
@ -142,7 +142,7 @@ class _LockVoiceSettingState extends State<LockVoiceSetting> {
return CommonItem(
leftTitel: item.langText,
leftTitleStyle: TextStyle(
fontSize: 22.sp,
fontSize: 20.sp,
fontWeight:
state.selectPassthroughListIndex.value == index
? FontWeight.bold
@ -152,7 +152,7 @@ class _LockVoiceSettingState extends State<LockVoiceSetting> {
isHaveLine: true,
isHaveDirection: false,
isHaveRightWidget: true,
leftTitleMaxWidth: 0.9.sw,
leftTitleMaxWidth: 0.85.sw,
rightWidget:
state.selectPassthroughListIndex.value == index
? Image(