Merge branch 'develop_sky_liyi' into 'develop_sky'

fix:增加和读取锁板上的语音包设置

See merge request StarlockTeam/app-starlock!268
This commit is contained in:
李仪 2025-09-01 06:31:07 +00:00
commit 2347ba871f
6 changed files with 223 additions and 120 deletions

View File

@ -48,7 +48,7 @@ class ReadLockCurrentVoicePacketReply extends Reply {
CommandType commandType, List<int> dataDetail) CommandType commandType, List<int> dataDetail)
: super.parseData(commandType, dataDetail) { : super.parseData(commandType, dataDetail) {
data = dataDetail; data = dataDetail;
status = data[6]; status = data[2];
errorWithStstus(status); errorWithStstus(status);
} }
} }

View File

@ -55,7 +55,7 @@ class SetVoicePackageFinalResultReply extends Reply {
CommandType commandType, List<int> dataDetail) CommandType commandType, List<int> dataDetail)
: super.parseData(commandType, dataDetail) { : super.parseData(commandType, dataDetail) {
data = dataDetail; data = dataDetail;
status = data[6]; status = data[2];
errorWithStstus(status); errorWithStstus(status);
} }
} }

View File

@ -18,9 +18,11 @@ import 'package:star_lock/blue/io_protocol/io_processOtaUpgrade.dart';
import 'package:star_lock/blue/io_protocol/io_readAdminPassword.dart'; import 'package:star_lock/blue/io_protocol/io_readAdminPassword.dart';
import 'package:star_lock/blue/io_protocol/io_readSupportFunctionsNoParameters.dart'; import 'package:star_lock/blue/io_protocol/io_readSupportFunctionsNoParameters.dart';
import 'package:star_lock/blue/io_protocol/io_readSupportFunctionsWithParameters.dart'; import 'package:star_lock/blue/io_protocol/io_readSupportFunctionsWithParameters.dart';
import 'package:star_lock/blue/io_protocol/io_readVoicePackageFinalResult.dart';
import 'package:star_lock/blue/io_protocol/io_referEventRecordTime.dart'; import 'package:star_lock/blue/io_protocol/io_referEventRecordTime.dart';
import 'package:star_lock/blue/io_protocol/io_setSupportFunctionsNoParameters.dart'; import 'package:star_lock/blue/io_protocol/io_setSupportFunctionsNoParameters.dart';
import 'package:star_lock/blue/io_protocol/io_setSupportFunctionsWithParameters.dart'; import 'package:star_lock/blue/io_protocol/io_setSupportFunctionsWithParameters.dart';
import 'package:star_lock/blue/io_protocol/io_setVoicePackageFinalResult.dart';
import 'package:star_lock/blue/io_protocol/io_timing.dart'; import 'package:star_lock/blue/io_protocol/io_timing.dart';
import 'package:star_lock/blue/io_protocol/io_voicePackageConfigure.dart'; import 'package:star_lock/blue/io_protocol/io_voicePackageConfigure.dart';
import 'package:star_lock/blue/io_protocol/io_voicePackageConfigureProcess.dart'; import 'package:star_lock/blue/io_protocol/io_voicePackageConfigureProcess.dart';
@ -317,6 +319,18 @@ class CommandReciverManager {
commandType, data); commandType, data);
} }
break; break;
case CommandType.readLockCurrentVoicePacket:
{
reply =
ReadLockCurrentVoicePacketReply.parseData(commandType, data);
}
break;
case CommandType.setLockCurrentVoicePacket:
{
reply =
SetVoicePackageFinalResultReply.parseData(commandType, data);
}
break;
case CommandType.generalExtendedCommond: case CommandType.generalExtendedCommond:
{ {
// //

View File

@ -12,6 +12,7 @@ import 'package:star_lock/blue/blue_manage.dart';
import 'package:star_lock/blue/io_protocol/io_getDeviceModel.dart'; import 'package:star_lock/blue/io_protocol/io_getDeviceModel.dart';
import 'package:star_lock/blue/io_protocol/io_otaUpgrade.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_protocol/io_processOtaUpgrade.dart';
import 'package:star_lock/blue/io_protocol/io_readVoicePackageFinalResult.dart';
import 'package:star_lock/blue/io_protocol/io_setVoicePackageFinalResult.dart'; import 'package:star_lock/blue/io_protocol/io_setVoicePackageFinalResult.dart';
import 'package:star_lock/blue/io_protocol/io_voicePackageConfigure.dart'; import 'package:star_lock/blue/io_protocol/io_voicePackageConfigure.dart';
import 'package:star_lock/blue/io_protocol/io_voicePackageConfigureProcess.dart'; import 'package:star_lock/blue/io_protocol/io_voicePackageConfigureProcess.dart';
@ -55,9 +56,12 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
handleVoiceConfigureThrottled(reply); handleVoiceConfigureThrottled(reply);
} else if (reply is SetVoicePackageFinalResultReply) { } else if (reply is SetVoicePackageFinalResultReply) {
handleSetResult(reply); handleSetResult(reply);
} else if (reply is ReadLockCurrentVoicePacketReply) {
handleLockCurrentVoicePacketResult(reply);
} }
}); });
await initList(); await initList();
readLockLanguage();
} }
/// ///
@ -438,42 +442,22 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
final int status = reply.data[2]; final int status = reply.data[2];
switch (status) { switch (status) {
case 0x00: case 0x00:
// await BlueManage().blueSendData(BlueManage().connectDeviceName, await BlueManage().blueSendData(BlueManage().connectDeviceName,
// (BluetoothConnectionState deviceConnectionState) async { (BluetoothConnectionState deviceConnectionState) async {
// if (deviceConnectionState == BluetoothConnectionState.connected) { if (deviceConnectionState == BluetoothConnectionState.connected) {
// await BlueManage().writeCharacteristicWithResponse( await BlueManage().writeCharacteristicWithResponse(
// SetVoicePackageFinalResult( SetVoicePackageFinalResult(
// lockID: BlueManage().connectDeviceName, lockID: BlueManage().connectDeviceName,
// languageCode: state.tempLangStr.value, languageCode: state.tempLangStr.value,
// ).packageData(), ).packageData(),
// ); );
// } else if (deviceConnectionState == } else if (deviceConnectionState ==
// BluetoothConnectionState.disconnected) { BluetoothConnectionState.disconnected) {
// dismissEasyLoading(); dismissEasyLoading();
// cancelBlueConnetctToastTimer(); cancelBlueConnetctToastTimer();
// showBlueConnetctToast(); showBlueConnetctToast();
// } }
// }); });
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; break;
default: default:
showToast('设置'.tr + '失败'.tr); showToast('设置'.tr + '失败'.tr);
@ -511,4 +495,75 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
break; break;
} }
} }
void handleLockCurrentVoicePacketResult(
ReadLockCurrentVoicePacketReply reply) {
final int status = reply.data[2];
switch (status) {
case 0x00:
//
cancelBlueConnetctToastTimer();
const int languageCodeStartIndex = 3;
const int languageCodeLength = 20;
const int languageCodeEndIndex =
languageCodeStartIndex + languageCodeLength; // 23
if (reply.data.length < languageCodeEndIndex) {
throw Exception(
'Reply data is too short to contain LanguageCode. Expected at least $languageCodeEndIndex bytes, got ${reply.data.length}');
}
List<int> languageCodeBytes =
reply.data.sublist(languageCodeStartIndex, languageCodeEndIndex);
String languageCode = String.fromCharCodes(languageCodeBytes);
languageCode = languageCode.trim(); //
languageCode =
languageCode.replaceAll('\u0000', ''); // (null bytes)
if (languageCode != null && languageCode != '') {
final indexWhere = state.languages
.indexWhere((element) => element.lang == languageCode);
if (indexWhere != -1) {
print('锁板上的语言是:$languageCode,下标是:$indexWhere');
state.selectPassthroughListIndex.value = indexWhere;
}
}
dismissEasyLoading();
break;
case 0x06:
//
final List<int> token = reply.data.sublist(2, 6);
if (state.data != null) {
sendFileToDevice(state.data!, token);
}
break;
default:
break;
}
}
void readLockLanguage() async {
showEasyLoading();
showBlueConnetctToastTimer(action: () {
dismissEasyLoading();
});
await BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState deviceConnectionState) async {
if (deviceConnectionState == BluetoothConnectionState.connected) {
await BlueManage().writeCharacteristicWithResponse(
ReadLockCurrentVoicePacket(
lockID: BlueManage().connectDeviceName,
).packageData(),
);
} else if (deviceConnectionState ==
BluetoothConnectionState.disconnected) {
dismissEasyLoading();
cancelBlueConnetctToastTimer();
showBlueConnetctToast();
}
});
}
} }

View File

@ -63,6 +63,12 @@ class _SpeechLanguageSettingsPageState
final soundType = state.soundTypeList.value[index]; final soundType = state.soundTypeList.value[index];
return CommonItem( return CommonItem(
leftTitel: soundType, leftTitel: soundType,
leftTitleStyle: TextStyle(
fontSize: 22.sp,
fontWeight: state.selectSoundTypeIndex.value == index
? FontWeight.bold
: null,
),
rightTitle: '', rightTitle: '',
isHaveLine: !isLastItem, isHaveLine: !isLastItem,
isHaveDirection: false, isHaveDirection: false,
@ -94,35 +100,44 @@ class _SpeechLanguageSettingsPageState
height: 8.h, height: 8.h,
), ),
// //
Container( Obx(
color: Colors.transparent, () => Container(
child: Column( color: Colors.transparent,
children: List.generate( child: Column(
state.languages.length, children: List.generate(
(index) { state.languages.length,
final item = state.languages[index]; (index) {
return CommonItem( final item = state.languages[index];
leftTitel: item.langText, return CommonItem(
rightTitle: '', leftTitel: item.langText,
isHaveLine: true, leftTitleStyle: TextStyle(
isHaveDirection: false, fontSize: 22.sp,
isHaveRightWidget: true, fontWeight: state.selectPassthroughListIndex.value == index
leftTitleMaxWidth: 0.9.sw, // ? FontWeight.bold
rightWidget: : null,
state.selectPassthroughListIndex.value == index ),
? Image( rightTitle: '',
image: const AssetImage( isHaveLine: true,
'images/icon_item_checked.png'), isHaveDirection: false,
width: 30.w, isHaveRightWidget: true,
height: 30.w, leftTitleMaxWidth: 0.9.sw,
fit: BoxFit.contain, //
) rightWidget:
: Container(), state.selectPassthroughListIndex.value == index
action: () { ? Image(
state.selectPassthroughListIndex.value = index; image: const AssetImage(
}, 'images/icon_item_checked.png'),
); width: 30.w,
}, height: 30.w,
fit: BoxFit.contain,
)
: Container(),
action: () {
state.selectPassthroughListIndex.value = index;
},
);
},
),
), ),
), ),
), ),
@ -133,16 +148,6 @@ class _SpeechLanguageSettingsPageState
} }
List<Widget> _buildList() {
final appLocalLanguages = state.languages;
return List.generate(
appLocalLanguages.length,
(index) => _buildItem(
appLocalLanguages[index],
index,
),
);
}
@override @override
void dispose() { void dispose() {
@ -152,24 +157,4 @@ class _SpeechLanguageSettingsPageState
} }
} }
_buildItem(PassthroughItem item, index) {
return CommonItem(
leftTitel: item.langText,
rightTitle: '',
isHaveLine: true,
isHaveDirection: false,
isHaveRightWidget: true,
rightWidget: state.selectPassthroughListIndex.value == index
? Image(
image: const AssetImage('images/icon_item_checked.png'),
width: 30.w,
height: 30.w,
fit: BoxFit.contain,
)
: Container(),
action: () {
state.selectPassthroughListIndex.value = index;
},
);
}
} }

View File

@ -12,6 +12,7 @@ import 'package:star_lock/app_settings/app_colors.dart';
import 'package:star_lock/blue/blue_manage.dart'; import 'package:star_lock/blue/blue_manage.dart';
import 'package:star_lock/blue/io_protocol/io_getDeviceModel.dart'; import 'package:star_lock/blue/io_protocol/io_getDeviceModel.dart';
import 'package:star_lock/blue/io_protocol/io_readVoicePackageFinalResult.dart'; import 'package:star_lock/blue/io_protocol/io_readVoicePackageFinalResult.dart';
import 'package:star_lock/blue/io_protocol/io_setVoicePackageFinalResult.dart';
import 'package:star_lock/blue/io_protocol/io_voicePackageConfigure.dart'; import 'package:star_lock/blue/io_protocol/io_voicePackageConfigure.dart';
import 'package:star_lock/blue/io_protocol/io_voicePackageConfigureProcess.dart'; import 'package:star_lock/blue/io_protocol/io_voicePackageConfigureProcess.dart';
import 'package:star_lock/blue/io_reply.dart'; import 'package:star_lock/blue/io_reply.dart';
@ -53,6 +54,8 @@ class LockVoiceSettingLogic extends BaseGetXController {
handleVoiceConfigureThrottled(reply); handleVoiceConfigureThrottled(reply);
} else if (reply is ReadLockCurrentVoicePacketReply) { } else if (reply is ReadLockCurrentVoicePacketReply) {
handleLockCurrentVoicePacketResult(reply); handleLockCurrentVoicePacketResult(reply);
} else if (reply is SetVoicePackageFinalResultReply) {
handleSetResult(reply);
} }
}); });
initList(); initList();
@ -77,26 +80,59 @@ class LockVoiceSettingLogic extends BaseGetXController {
Future<void> _executeLogic( Future<void> _executeLogic(
VoicePackageConfigureConfirmationReply reply) async { VoicePackageConfigureConfirmationReply reply) async {
final LoginEntity entity = await ApiRepository.to.settingCurrentVoiceTimbre( showEasyLoading();
data: { showBlueConnetctToastTimer(action: () {
'lang': state.tempLangStr.value, dismissEasyLoading();
'timbre': state.tempTimbreStr.value, });
}, await BlueManage().blueSendData(BlueManage().connectDeviceName,
lockId: state.lockSetInfoData.value.lockId!, (BluetoothConnectionState deviceConnectionState) async {
); if (deviceConnectionState == BluetoothConnectionState.connected) {
if (entity.errorCode!.codeIsSuccessful) { await BlueManage().writeCharacteristicWithResponse(
showSuccess('设置成功'.tr, something: () { SetVoicePackageFinalResult(
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.lang = lockID: BlueManage().connectDeviceName,
state.tempLangStr.value; languageCode: state.tempLangStr.value,
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre ).packageData(),
?.timbre = state.tempTimbreStr.value; );
} else if (deviceConnectionState ==
BluetoothConnectionState.disconnected) {
dismissEasyLoading();
cancelBlueConnetctToastTimer();
showBlueConnetctToast();
}
});
}
eventBus void handleSetResult(SetVoicePackageFinalResultReply reply) async {
.fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value)); final int status = reply.data[2];
Get.offAllNamed(Routers.starLockMain); 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:
showToast('设置'.tr + '失败'.tr);
break;
} }
dismissEasyLoading();
} }
void saveSpeechLanguageSettings() async { void saveSpeechLanguageSettings() async {
@ -201,14 +237,12 @@ class LockVoiceSettingLogic extends BaseGetXController {
// //
void _handlerStartVoicePackageConfigure( void _handlerStartVoicePackageConfigure(
VoicePackageConfigureReply reply) async { VoicePackageConfigureReply reply) async {
final int status = reply.data[3]; final int status = reply.data[6];
switch (status) { switch (status) {
case 0x00: case 0x00:
// //
cancelBlueConnetctToastTimer(); cancelBlueConnetctToastTimer();
_startSendLanguageFile(); _startSendLanguageFile();
break; break;
case 0x06: case 0x06:
// //
@ -218,7 +252,8 @@ class LockVoiceSettingLogic extends BaseGetXController {
} }
break; break;
default: default:
showToast('获取设备型号失败'.tr); dismissEasyLoading();
cancelBlueConnetctToastTimer();
break; break;
} }
} }
@ -409,6 +444,10 @@ class LockVoiceSettingLogic extends BaseGetXController {
} }
void readLockLanguage() async { void readLockLanguage() async {
showEasyLoading();
showBlueConnetctToastTimer(action: () {
dismissEasyLoading();
});
await BlueManage().blueSendData(BlueManage().connectDeviceName, await BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState deviceConnectionState) async { (BluetoothConnectionState deviceConnectionState) async {
if (deviceConnectionState == BluetoothConnectionState.connected) { if (deviceConnectionState == BluetoothConnectionState.connected) {
@ -428,7 +467,7 @@ class LockVoiceSettingLogic extends BaseGetXController {
void handleLockCurrentVoicePacketResult( void handleLockCurrentVoicePacketResult(
ReadLockCurrentVoicePacketReply reply) { ReadLockCurrentVoicePacketReply reply) {
final int status = reply.data[6]; final int status = reply.data[2];
switch (status) { switch (status) {
case 0x00: case 0x00:
// //
@ -462,6 +501,16 @@ class LockVoiceSettingLogic extends BaseGetXController {
// 6. 使 languageCode // 6. 使 languageCode
print('LanguageCode: $languageCode'); // : zh_CN, en_US print('LanguageCode: $languageCode'); // : zh_CN, en_US
if (languageCode != null && languageCode != '') {
final indexWhere = state.languages
.indexWhere((element) => element.lang == languageCode);
if (indexWhere != -1) {
print('锁板上的语言是:$languageCode,下标是:$indexWhere');
state.selectPassthroughListIndex.value = indexWhere;
}
}
dismissEasyLoading();
break; break;
case 0x06: case 0x06:
// //