diff --git a/assets/html/h264.html b/assets/html/h264.html index 97143565..63303e3c 100644 --- a/assets/html/h264.html +++ b/assets/html/h264.html @@ -56,7 +56,7 @@ }, flushingTime: 0, // 禁用自动刷新 clearBuffer: false, // 保留解码缓存 - maxBufferLength: 2, + fps:20, onReady: () => { console.log('播放器初始化完成'); // 通知Flutter端准备就绪 diff --git a/lib/main/lockDetail/lockDetail/lockDetail_state.dart b/lib/main/lockDetail/lockDetail/lockDetail_state.dart index 5e168524..760f1289 100755 --- a/lib/main/lockDetail/lockDetail/lockDetail_state.dart +++ b/lib/main/lockDetail/lockDetail/lockDetail_state.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart'; import '../../../blue/io_reply.dart'; import '../../lockMian/entity/lockListInfo_entity.dart'; @@ -9,7 +10,7 @@ import '../../lockMian/entity/lockListInfo_entity.dart'; class LockDetailState { Rx keyInfos = LockListInfoItemEntity().obs; - + final Rx lockSetInfoData = LockSetInfoData().obs; late StreamSubscription replySubscription; StreamSubscription? lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent; StreamSubscription? LockSetChangeSetRefreshLockDetailWithTypeSubscription; diff --git a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_logic.dart b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_logic.dart index 763d25ca..c350b336 100755 --- a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_logic.dart +++ b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_logic.dart @@ -8,6 +8,7 @@ import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:get/get.dart'; import 'package:network_info_plus/network_info_plus.dart'; import 'package:permission_handler/permission_handler.dart'; +import 'package:star_lock/appRouters.dart'; import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/blue/io_gateway/io_gateway_configuringWifi.dart'; import 'package:star_lock/blue/io_gateway/io_gateway_getStatus.dart'; @@ -68,7 +69,12 @@ class ConfiguringWifiLogic extends BaseGetXController { secretKey: secretKey, peerId: peerId, ); - Get.close(2); + + if (state.pageName.value == 'lockSet') { + Get.close(2); + } else { + Get.offAllNamed(Routers.starLockMain); + } }); } } diff --git a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_page.dart b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_page.dart index 55a6a02c..89ea1ee1 100755 --- a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_page.dart +++ b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_page.dart @@ -47,7 +47,8 @@ class _ConfiguringWifiPageState extends State SubmitBtn( btnName: '确定'.tr, onClick: () { - logic.senderConfiguringWifiAction(); + FocusScope.of(context).requestFocus(FocusNode()); + logic.senderConfiguringWifiAction(); }, ), ], diff --git a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_state.dart b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_state.dart index 33707851..062ebf51 100755 --- a/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_state.dart +++ b/lib/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifi_state.dart @@ -9,6 +9,7 @@ class ConfiguringWifiState{ ConfiguringWifiState() { var map = Get.arguments; lockSetInfoData.value = map['lockSetInfoData']; + pageName.value = map['pageName']; lockBasicInfo.value = lockSetInfoData.value.lockBasicInfo!; if (map['wifiName'] != null) { wifiName.value = map['wifiName']; @@ -20,6 +21,7 @@ class ConfiguringWifiState{ Rx lockBasicInfo = LockBasicInfo().obs; RxString wifiName = ''.obs; + RxString pageName = ''.obs; RxBool ifCurrentScreen = true.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示 RxInt sureBtnState = 0.obs;// 0普通状态(可用) 1连接中(不可用) diff --git a/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_page.dart b/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_page.dart index 937c2e8a..bd976e9d 100755 --- a/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_page.dart +++ b/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_page.dart @@ -24,11 +24,18 @@ class _WifiListPageState extends State { @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.white, - appBar: TitleAppBar( + return WillPopScope( + onWillPop: () async { + if (state.pageName.value == 'lockSet') { + return true; + } + return false; + }, + child: Scaffold( + backgroundColor: Colors.white, + appBar: TitleAppBar( barTitle: 'WIFI列表'.tr, - haveBack: true, + haveBack: state.pageName.value == 'lockSet', actionsList: [ TextButton( child: Text( @@ -38,45 +45,50 @@ class _WifiListPageState extends State { onPressed: logic.senderGetWifiListWifiAction, ), ], - backgroundColor: AppColors.mainColor), - body: Column( - children: [ - Expanded( - child: Obx(() => state.wifiNameDataList.value.isNotEmpty - ? ListView.builder( - itemCount: state.wifiNameDataList.value.length, - itemBuilder: (BuildContext c, int index) { - Map wifiNameStr = state.wifiNameDataList.value[index]; - return _messageListItem( - wifiNameStr['wifiName'], wifiNameStr['rssi'], () { - Get.toNamed(Routers.configuringWifiPage, arguments: { - 'lockSetInfoData': state.lockSetInfoData.value, - 'wifiName': wifiNameStr['wifiName'], + backgroundColor: AppColors.mainColor, + ), + body: Column( + children: [ + Expanded( + child: Obx(() => state.wifiNameDataList.value.isNotEmpty + ? ListView.builder( + itemCount: state.wifiNameDataList.value.length, + itemBuilder: (BuildContext c, int index) { + Map wifiNameStr = state.wifiNameDataList.value[index]; + return _messageListItem( + wifiNameStr['wifiName'], wifiNameStr['rssi'], () { + Get.toNamed(Routers.configuringWifiPage, + arguments: { + 'lockSetInfoData': + state.lockSetInfoData.value, + 'wifiName': wifiNameStr['wifiName'], + 'pageName': state.pageName.value, + }); }); + }) + : NoData( + noDataHeight: 1.sh - + ScreenUtil().statusBarHeight - + ScreenUtil().bottomBarHeight - + 64.h)), + ), + SubmitBtn( + btnName: '手动配网'.tr, + fontSize: 28.sp, + borderRadius: 20.w, + padding: EdgeInsets.only(top: 25.w, bottom: 25.w), + onClick: () { + Get.toNamed(Routers.configuringWifiPage, + arguments: { + 'lockSetInfoData': state.lockSetInfoData.value }); - }) - : NoData( - noDataHeight: 1.sh - - ScreenUtil().statusBarHeight - - ScreenUtil().bottomBarHeight - - 64.h)), - ), - SubmitBtn( - btnName: '手动配网'.tr, - fontSize: 28.sp, - borderRadius: 20.w, - padding: EdgeInsets.only(top: 25.w, bottom: 25.w), - onClick: () { - Get.toNamed(Routers.configuringWifiPage, - arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); - }), - SizedBox( - height: 64.h, - ) - ], - )); + }), + SizedBox( + height: 64.h, + ) + ], + )), + ); } Widget _messageListItem(String wifiName, String rssi, Function() action) { diff --git a/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_state.dart b/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_state.dart index ca058136..d640b496 100755 --- a/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_state.dart +++ b/lib/main/lockDetail/lockSet/configuringWifi/wifiList/wifiList_state.dart @@ -1,18 +1,22 @@ - import 'package:get/get.dart'; import '../../lockSet/lockSetInfo_entity.dart'; -class WifiListState{// 0普通状态(可用) 1连接中(不可用) +class WifiListState { + // 0普通状态(可用) 1连接中(不可用) WifiListState() { final map = Get.arguments; lockSetInfoData.value = map['lockSetInfoData']; + pageName.value = map['pageName']; lockBasicInfo.value = lockSetInfoData.value.lockBasicInfo!; } - final RxList> wifiNameDataList = >[].obs; + + final RxList> wifiNameDataList = + >[].obs; Rx lockSetInfoData = LockSetInfoData().obs; Rx lockBasicInfo = LockBasicInfo().obs; RxBool ifCurrentScreen = true.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示 RxInt sureBtnState = 0.obs; -} \ No newline at end of file + RxString pageName = ''.obs; +} diff --git a/lib/main/lockDetail/lockSet/lockSet/lockSet_page.dart b/lib/main/lockDetail/lockSet/lockSet/lockSet_page.dart index dbea2c40..a0011308 100755 --- a/lib/main/lockDetail/lockSet/lockSet/lockSet_page.dart +++ b/lib/main/lockDetail/lockSet/lockSet/lockSet_page.dart @@ -595,10 +595,10 @@ class _LockSetPageState extends State isHaveLine: true, isHaveDirection: true, action: () { - Get.toNamed(Routers.wifiListPage, - arguments: { - 'lockSetInfoData': state.lockSetInfoData.value - }); + Get.toNamed(Routers.wifiListPage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value, + 'pageName': 'lockSet' + }); // Get.toNamed(Routers.configuringWifiPage, arguments: { // 'lockSetInfoData': state.lockSetInfoData.value // }); diff --git a/lib/main/lockDetail/videoLog/videoLogDetail/videoLogDetail_page.dart b/lib/main/lockDetail/videoLog/videoLogDetail/videoLogDetail_page.dart index 619d0539..ca1259cb 100755 --- a/lib/main/lockDetail/videoLog/videoLogDetail/videoLogDetail_page.dart +++ b/lib/main/lockDetail/videoLog/videoLogDetail/videoLogDetail_page.dart @@ -170,7 +170,7 @@ class _VideoLogDetailPageState extends State { _buildImageItem(RecordListData recordData) { return RotatedBox( - quarterTurns: 1, + quarterTurns: -1, child: Image.network( recordData.imagesUrl!, fit: BoxFit.cover, diff --git a/lib/main/lockMian/entity/lockListInfo_entity.dart b/lib/main/lockMian/entity/lockListInfo_entity.dart index b3b46464..81838ba6 100755 --- a/lib/main/lockMian/entity/lockListInfo_entity.dart +++ b/lib/main/lockMian/entity/lockListInfo_entity.dart @@ -345,6 +345,8 @@ class LockFeature { this.isSupportCatEye, this.isSupportBackupBattery, this.isNoSupportedBlueBroadcast, + this.wifiLockType, + this.wifi, }); LockFeature.fromJson(Map json) { @@ -360,6 +362,8 @@ class LockFeature { isSupportCatEye = json['isSupportCatEye']; isSupportBackupBattery = json['isSupportBackupBattery']; isNoSupportedBlueBroadcast = json['isNoSupportedBlueBroadcast']; + wifiLockType = json['wifiLockType']; + wifi = json['wifi']; } int? password; @@ -374,6 +378,8 @@ class LockFeature { int? isSupportCatEye; int? isSupportBackupBattery; int? isNoSupportedBlueBroadcast; + int? wifiLockType; + int? wifi; Map toJson() { final Map data = {}; @@ -389,6 +395,8 @@ class LockFeature { data['isSupportCatEye'] = isSupportCatEye; data['isSupportBackupBattery'] = isSupportBackupBattery; data['isNoSupportedBlueBroadcast'] = isNoSupportedBlueBroadcast; + data['wifiLockType'] = wifiLockType; + data['wifi'] = wifi; return data; } } diff --git a/lib/mine/addLock/saveLock/saveLock_logic.dart b/lib/mine/addLock/saveLock/saveLock_logic.dart index 7e8ae377..ce1cc799 100755 --- a/lib/mine/addLock/saveLock/saveLock_logic.dart +++ b/lib/mine/addLock/saveLock/saveLock_logic.dart @@ -1,11 +1,12 @@ - import 'dart:async'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:get/get.dart'; import 'package:star_lock/apm/apm_helper.dart'; +import 'package:star_lock/appRouters.dart'; import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_logic.dart'; +import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart'; import 'package:star_lock/mine/addLock/saveLock/entity/SaveLockEntity.dart'; import '../../../app_settings/app_settings.dart'; @@ -408,10 +409,11 @@ class SaveLockLogic extends BaseGetXController { final String getMobile = (await Storage.getMobile())!; ApmHelper.instance.trackEvent('save_lock_result', { - 'lock_name':BlueManage().connectDeviceName, - 'account':getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, - 'date':DateTool().getNowDateWithType(1), - 'save_lock_result':'成功', + 'lock_name': BlueManage().connectDeviceName, + 'account': + getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, + 'date': DateTool().getNowDateWithType(1), + 'save_lock_result': '成功', }); backAction(); // await senderCustomPasswords(); @@ -424,10 +426,11 @@ class SaveLockLogic extends BaseGetXController { final String getMobile = (await Storage.getMobile())!; ApmHelper.instance.trackEvent('save_lock_result', { - 'lock_name':BlueManage().connectDeviceName, - 'account':getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, - 'date':DateTool().getNowDateWithType(1), - 'save_lock_result':'${entity.errorCode}--${entity.errorMsg}', + 'lock_name': BlueManage().connectDeviceName, + 'account': + getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, + 'date': DateTool().getNowDateWithType(1), + 'save_lock_result': '${entity.errorCode}--${entity.errorMsg}', }); } } @@ -482,20 +485,52 @@ class SaveLockLogic extends BaseGetXController { // ); // } - void backAction() { + void backAction() async { eventBus.fire(RefreshLockListInfoDataEvent(clearScanDevices: true)); BlueManage().disconnect(); - Future.delayed(const Duration(seconds: 1), () { - Get.close(state.isFromMap == 1 ? (CommonDataManage().seletLockType == 0 ? 4 : 5) : (CommonDataManage().seletLockType == 0 ? 5 : 6)); - }); - //刚刚配对完,需要对开锁页锁死 2 秒 - Future.delayed(const Duration(milliseconds: 200), () { - if (Get.isRegistered()) { - Get.find() - .functionBlocker - .countdownProhibited(duration: const Duration(seconds: 2)); + + // 查询锁设置信息 + final LockSetInfoEntity entity = + await ApiRepository.to.getLockSettingInfoDataIsNotLoadingIcon( + lockId: state.lockId.toString(), + ); + if (entity.errorCode!.codeIsSuccessful) { + state.lockSetInfoData.value = entity.data!; + if (state.lockSetInfoData.value.lockFeature?.wifi == 1) { + // await Future.delayed(const Duration(seconds: 1), () {c + // Get.close(state.isFromMap == 1 + // ? (CommonDataManage().seletLockType == 0 ? 4 : 5) + // : (CommonDataManage().seletLockType == 0 ? 5 : 6)); + // }); + // //刚刚配对完,需要对开锁页锁死 2 秒 + // await Future.delayed(const Duration(milliseconds: 200), () { + // if (Get.isRegistered()) { + // Get.find() + // .functionBlocker + // .countdownProhibited(duration: const Duration(seconds: 2)); + // } + // }); + // 如果是wifi锁,需要配置WIFI + Get.toNamed(Routers.wifiListPage, arguments: { + 'lockSetInfoData': state.lockSetInfoData.value, + 'pageName': 'saveLock' + }); + } else { + Future.delayed(const Duration(seconds: 1), () { + Get.close(state.isFromMap == 1 + ? (CommonDataManage().seletLockType == 0 ? 4 : 5) + : (CommonDataManage().seletLockType == 0 ? 5 : 6)); + }); + //刚刚配对完,需要对开锁页锁死 2 秒 + Future.delayed(const Duration(milliseconds: 200), () { + if (Get.isRegistered()) { + Get.find() + .functionBlocker + .countdownProhibited(duration: const Duration(seconds: 2)); + } + }); } - }); + } } @override diff --git a/lib/mine/addLock/saveLock/saveLock_state.dart b/lib/mine/addLock/saveLock/saveLock_state.dart index 564fe3d3..1a14896c 100755 --- a/lib/mine/addLock/saveLock/saveLock_state.dart +++ b/lib/mine/addLock/saveLock/saveLock_state.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart'; import '../../../blue/blue_manage.dart'; @@ -25,7 +26,7 @@ class SaveLockState { RxString aliName = ''.obs; RxInt pwdTimestamp = 0.obs; RxMap addressInfo = {}.obs; - + final Rx lockSetInfoData = LockSetInfoData().obs; TextEditingController aliNameController = TextEditingController(); FocusNode focusNode = FocusNode(); diff --git a/lib/mine/mine/starLockMine_logic.dart b/lib/mine/mine/starLockMine_logic.dart index 9e69a978..9380e65d 100755 --- a/lib/mine/mine/starLockMine_logic.dart +++ b/lib/mine/mine/starLockMine_logic.dart @@ -24,7 +24,7 @@ class StarLockMineLogic extends BaseGetXController { //删除账号请求 Future userLogoutRequest() async { - final LoginEntity entity = await ApiRepository.to.userLogout(deviceld: ''); + final LoginEntity entity = await ApiRepository.to.userLogout(storageNonce: ''); if (entity.errorCode!.codeIsSuccessful) {} } diff --git a/lib/mine/mineSet/mineSet/mineSet_logic.dart b/lib/mine/mineSet/mineSet/mineSet_logic.dart index 33b0f61a..8778dfc0 100755 --- a/lib/mine/mineSet/mineSet/mineSet_logic.dart +++ b/lib/mine/mineSet/mineSet/mineSet_logic.dart @@ -130,7 +130,7 @@ class MineSetLogic extends BaseGetXController { } }); final LoginEntity entity = - await ApiRepository.to.userLogout(deviceld: getPushDeviceID); + await ApiRepository.to.userLogout(storageNonce: getPushDeviceID); final String getMobile = (await Storage.getMobile())!; if (entity.errorCode!.codeIsSuccessful) { ApmHelper.instance.logout(); @@ -169,6 +169,8 @@ class MineSetLogic extends BaseGetXController { ///退出登录 void logOut() async { + final XSJPushProvider jpushProvider = XSJPushProvider(); + await jpushProvider.resetJPushService(); Storage.clearAll(); } diff --git a/lib/mine/mineSet/mineSet/mineSet_page.dart b/lib/mine/mineSet/mineSet/mineSet_page.dart index cf62b035..7f639d2b 100755 --- a/lib/mine/mineSet/mineSet/mineSet_page.dart +++ b/lib/mine/mineSet/mineSet/mineSet_page.dart @@ -292,21 +292,20 @@ class _MineSetPageState extends State SizedBox( height: 10.h, ), - Obx(() { - // AppLog.log('state.currentLanguageName: ${state.currentLanguageName} state.currentLanguage.value: ${state.currentLanguage.value}'); - return CommonItem( - leftTitel: '多语言'.tr, - rightTitle: state.currentLanguageName, - isHaveLine: true, - isHaveDirection: true, - action: () async { - // Get.toNamed(Routers.mineMultiLanguagePage); - await Get.toNamed(Routers.mineMultiLanguagePage)!.then((value) { - state.currentLanguage.value = value['currentLanguage']; - setState(() {}); - }); + + // AppLog.log('state.currentLanguageName: ${state.currentLanguageName} state.currentLanguage.value: ${state.currentLanguage.value}'); + CommonItem( + leftTitel: '多语言'.tr, + rightTitle: state.currentLanguageName, + isHaveLine: true, + isHaveDirection: true, + action: () async { + // Get.toNamed(Routers.mineMultiLanguagePage); + await Get.toNamed(Routers.mineMultiLanguagePage)!.then((value) { + state.currentLanguage.value = value['currentLanguage']; + setState(() {}); }); - }), + }), /* 2024-01-12 会议确定去掉“锁屏” by DaisyWu Obx(() => CommonItem( leftTitel: TranslationLoader.lanKeys!.lockScreen!.tr, diff --git a/lib/network/api.dart b/lib/network/api.dart index c51b05f6..8a04dc74 100755 --- a/lib/network/api.dart +++ b/lib/network/api.dart @@ -67,8 +67,7 @@ abstract class Api { final String getWifiServiceIpURL = '/wifiLock/getWifiServiceIp'; // 获取Wifi锁服务器 final String updateLockSettingUrl = '/v2/lockSetting/updateLockSetting'; // 锁设置里面所有的设置 - final String deviceNetworkConfiguration = - '/deviceNetwork/setting'; // 设备网络配置 + final String deviceNetworkConfiguration = '/deviceNetwork/setting'; // 设备网络配置 final String getDeviceNetworkConfiguration = '/deviceNetwork/getNetworkInfo'; // 设备网络配置 final String roomQueryDateUrl = '/room/queryDate'; // 获取网关时间 @@ -195,6 +194,7 @@ abstract class Api { final String setAppUnlockMustOnlineURL = '/room/setAppUnlockMustOnline'; //APP开锁时需手机联网的锁 final String userLogoutURL = '/v2/user/logout'; //退出登录 + final String userLogout3URL = '/v3/user/logout'; //退出登录 final String deleteAccountURL = '/user/delete'; //删除账号 final String getUserInfoURL = '/user/getUserInfo'; //获取个人信息 final String sendValidationCodeAuthURL = @@ -214,6 +214,7 @@ abstract class Api { final String unbindPhoneTokenURL = '/user/unbindPhoneToken'; //获取解绑手机号Token final String unbindEmailTokenURL = '/user/unbindEmailToken'; //获取解绑邮箱Token final String pushBindAppIdURL = '/user/bindAppId'; //推送绑定APP设备 + final String bindPushTokenURL = '/user/bindPushToken'; //推送绑定APP设备 final String messageListURL = '/notifications/list'; //消息列表 final String readMessageURL = '/notifications/markAsRead'; //读取消息 diff --git a/lib/network/api_provider.dart b/lib/network/api_provider.dart index a758294c..2139c1af 100755 --- a/lib/network/api_provider.dart +++ b/lib/network/api_provider.dart @@ -423,6 +423,15 @@ class ApiProvider extends BaseProvider { 'lockId': lockId, })); + // 获取所有锁设置信息 + Future getLockSettingInfoDataIsNotLoadingIcon(String lockId) => + post( + getLockSettingURL.toUrl, + jsonEncode({ + 'lockId': lockId, + }), + isUnShowLoading: true); + // 删除锁 Future deletLockInfo(int lockId) => post( deletLockURL.toUrl, @@ -1950,8 +1959,8 @@ class ApiProvider extends BaseProvider { })); //退出登录 - Future userLogout(String deviceld) => - post(userLogoutURL.toUrl, jsonEncode({'deviceld': deviceld})); + Future userLogout(String storageNonce) => + post(userLogout3URL.toUrl, jsonEncode({'storageNonce': storageNonce})); //删除账号 Future deleteAccount( @@ -2115,6 +2124,12 @@ class ApiProvider extends BaseProvider { pushBindAppIdURL.toUrl, jsonEncode({'deviceId': deviceId, 'deviceType': deviceType})); + //推送channel绑定 + Future pushBindChannels( + String storageNonce, List> channels) => + post(bindPushTokenURL.toUrl, + jsonEncode({'storageNonce': storageNonce, 'channels': channels})); + // 消息列表 Future messageListLoadData(String pageNo, String pageSize) => post( messageListURL.toUrl, diff --git a/lib/network/api_repository.dart b/lib/network/api_repository.dart index 7c97ae82..6ef31dcd 100755 --- a/lib/network/api_repository.dart +++ b/lib/network/api_repository.dart @@ -486,6 +486,12 @@ class ApiRepository { final res = await apiProvider.getLockSettingInfoData(lockId); return LockSetInfoEntity.fromJson(res.body); } + // 获取所有锁设置信息(不显示加载框) + Future getLockSettingInfoDataIsNotLoadingIcon( + {required String lockId}) async { + final res = await apiProvider.getLockSettingInfoDataIsNotLoadingIcon(lockId); + return LockSetInfoEntity.fromJson(res.body); + } // 删除锁 Future deletOwnerLockData({required int lockId}) async { @@ -1871,8 +1877,8 @@ class ApiRepository { } // 退出登录 - Future userLogout({required String deviceld}) async { - final res = await apiProvider.userLogout(deviceld); + Future userLogout({required String storageNonce}) async { + final res = await apiProvider.userLogout(storageNonce); return LoginEntity.fromJson(res.body); } @@ -2170,6 +2176,13 @@ class ApiRepository { return MineUnbindPhoneOrEmailEntity.fromJson(res.body); } + //推送channel绑定 + Future pushBindChannels( + String storageNonce, List> channels) async { + final res = await apiProvider.pushBindChannels(storageNonce, channels); + return MineUnbindPhoneOrEmailEntity.fromJson(res.body); + } + // 消息列表 Future messageListLoadData( {required String pageNo, required String pageSize}) async { @@ -2731,7 +2744,4 @@ class ApiRepository { ); return DeviceNetwork.fromJson(res.body); } - - - } diff --git a/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart b/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart index a95b1c78..cb00a0d3 100644 --- a/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart +++ b/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart @@ -160,6 +160,8 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle final TalkDataH264Frame talkDataH264Frame = TalkDataH264Frame(); talkDataH264Frame.mergeFromBuffer(talkData.content); frameHandler.handleFrame(talkDataH264Frame); + AppLog.log( + "帧:${talkDataH264Frame.frameType},帧序号:${talkDataH264Frame.frameSeq},对应I帧序号:${talkDataH264Frame.frameSeqI}"); } /// 处理图片数据 diff --git a/lib/talk/starChart/handle/other/h264_frame_handler.dart b/lib/talk/starChart/handle/other/h264_frame_handler.dart index 5eaa27df..2b4ea1ee 100644 --- a/lib/talk/starChart/handle/other/h264_frame_handler.dart +++ b/lib/talk/starChart/handle/other/h264_frame_handler.dart @@ -1,52 +1,51 @@ +import 'dart:collection'; +import 'dart:typed_data'; + import 'package:star_lock/app_settings/app_settings.dart'; import '../../proto/talk_data_h264_frame.pb.dart'; class H264FrameHandler { - final Map _frameBuffer = {}; + final LinkedHashMap _frameBuffer = LinkedHashMap(); final void Function(List frameData) onCompleteFrame; - int _lastProcessedSeq = -1; + + final LinkedHashMap _frameTypeIndex = LinkedHashMap(); H264FrameHandler({required this.onCompleteFrame}); void handleFrame(TalkDataH264Frame frame) { // 存储帧 _frameBuffer[frame.frameSeq] = frame; + _frameTypeIndex[frame.frameSeq] = frame.frameType; // 检查是否可以组装完整的 GOP (Group of Pictures) _tryAssembleFrames(frame.frameSeq); } void _tryAssembleFrames(int currentSeq) { - // 找到连续的帧序列 - final List sortedSeqs = _frameBuffer.keys.toList()..sort(); final List framesToProcess = []; + int? startFrameSeq; // 从当前帧开始向前找到最近的 I 帧或 P 帧 - int? startFrameSeq; - for (var seq in sortedSeqs.reversed) { - final frame = _frameBuffer[seq]; - if (frame?.frameType == TalkDataH264Frame_FrameTypeE.I) { + for (int seq = currentSeq; seq >= 0; seq--) { + final frameType = _frameTypeIndex[seq]; + if (frameType == null) continue; + if (frameType == TalkDataH264Frame_FrameTypeE.I) { startFrameSeq = seq; break; - } else if (frame?.frameType == TalkDataH264Frame_FrameTypeE.P) { - // 检查 P 帧是否有对应的 I 帧 - if (_frameBuffer.containsKey(frame?.frameSeqI)) { + } else if (frameType == TalkDataH264Frame_FrameTypeE.P) { + if (_frameBuffer.containsKey(_frameBuffer[seq]!.frameSeqI)) { startFrameSeq = seq; break; } else { - // 丢弃没有对应 I 帧的 P 帧 _frameBuffer.remove(seq); + _frameTypeIndex.remove(seq); } } } if (startFrameSeq != null) { - // 收集从 I 帧或 P 帧开始的连续帧 - int expectedSeq = startFrameSeq; - for (var seq in sortedSeqs.where((s) => s >= startFrameSeq!)) { - if (seq != expectedSeq) break; + for (int seq = startFrameSeq; _frameBuffer.containsKey(seq); seq++) { framesToProcess.add(seq); - expectedSeq++; } if (framesToProcess.isNotEmpty) { @@ -57,28 +56,50 @@ class H264FrameHandler { } } - void _clearOldFrames(int currentSeq) { - // 清理比当前帧序列旧的帧 - _frameBuffer.removeWhere((seq, frame) => seq < currentSeq - 200); // 调整阈值 - } - void _processFrames(List frameSeqs) { // 按顺序组装帧数据 - final List assembledData = []; + // final List assembledData = []; + // + // for (var seq in frameSeqs) { + // final frame = _frameBuffer[seq]!; + // assembledData.addAll(frame.frameData); + // + // // 处理完后从缓冲区移除 + // _frameBuffer.remove(seq); + // } + // + // // 回调完整的帧数据 + // onCompleteFrame(assembledData); + // Calculate the total length of the assembled data + int totalLength = frameSeqs.fold( + 0, (sum, seq) => sum + _frameBuffer[seq]!.frameData.length); + + // Allocate a buffer for the assembled data + final assembledData = Uint8List(totalLength); + int offset = 0; for (var seq in frameSeqs) { final frame = _frameBuffer[seq]!; - assembledData.addAll(frame.frameData); + assembledData.setRange( + offset, offset + frame.frameData.length, frame.frameData); + offset += frame.frameData.length; - // 处理完后从缓冲区移除 + // Remove the frame from the buffer after processing _frameBuffer.remove(seq); + _frameTypeIndex.remove(seq); } - // 回调完整的帧数据 + // Callback with the complete frame data onCompleteFrame(assembledData); } void clear() { _frameBuffer.clear(); } + + void _clearOldFrames(int currentSeq) { + // 清理比当前帧序列旧的帧 + _frameBuffer.removeWhere((seq, frame) => seq < currentSeq - 200); // 调整阈值 + _frameTypeIndex.removeWhere((seq, frameType) => seq < currentSeq - 200); + } } diff --git a/lib/tools/push/xs_jPhush.dart b/lib/tools/push/xs_jPhush.dart index 3ce9adf3..11b16951 100755 --- a/lib/tools/push/xs_jPhush.dart +++ b/lib/tools/push/xs_jPhush.dart @@ -1,3 +1,5 @@ +import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; @@ -13,11 +15,37 @@ import 'package:star_lock/tools/storage.dart'; import '../../app_settings/app_settings.dart'; class XSJPushProvider { + static const Map channelTypeMapping = { + 1: 'xiaomi', + 2: 'huawei', + 3: 'meizu', + 4: 'oppo', + 5: 'vivo', + 6: 'honor', + 7: 'apns', + 8: 'fcm', + 9: 'jiguang' + }; final JPush jpush = JPush(); + late Completer> _jpushRegistrationIdCompleter; + late Completer> _vendorTokenCompleter; + + Future resetJPushService() async { + debugPrint("resetJPushService start"); + jpush.setup( + appKey: '', + channel: 'flutter_channel', + production: F.isProductionEnv, + debug: !F.isProductionEnv, + ); + } // appKey: 251fc8074820d122b6de58d2--鑫泓佳AppKey // appKey: 7ff37d174c1a568a89e98dad--sky Future initJPushService() async { + debugPrint("initJPushService start"); + _jpushRegistrationIdCompleter = Completer>(); + _vendorTokenCompleter = Completer>(); final String? data = await Storage.getString(saveUserLoginData); if (data == null || data.isEmpty) { AppLog.log('No user data found.'); @@ -34,25 +62,49 @@ class XSJPushProvider { production: F.isProductionEnv, debug: !F.isProductionEnv, ); - jpush.applyPushAuthority( const NotificationSettingsIOS(sound: true, alert: true, badge: false), ); addJPushEventHandler(); AppLog.log('JPush initialized.'); - - final String rid = await jpush.getRegistrationID(); - AppLog.log('flutter get registration id : $rid'); - pushBindDeviceID(rid); + debugPrint("initJPushService end"); } + static const int CMD_GET_REGISTRATION_ID = 2005; //getRegistrationID 异步回调 + static const int CMD_GET_TOKEN = 10000; //厂商 token 注册回调 + //极光推送事件处理方法 void addJPushEventHandler() { jpush.addEventHandler( - onCommandResult: (Map message) async { - AppLog.log('onCommandResult: $message'); - debugPrint("addJPushEventHandler onCommandResult:$message"); + onCommandResult: (Map data) async { + AppLog.log('onCommandResult: $data'); + debugPrint("addJPushEventHandler onCommandResult:$data"); + final int cmdCode = data['cmd']; + switch (cmdCode) { + case CMD_GET_REGISTRATION_ID: + await Storage.setString(pushDeviceID, data['message']); + AppLog.log('flutter get registration id : ${data['message']}'); + _jpushRegistrationIdCompleter.complete({ + 'channel': 'jiguang', + 'channelToken': data['message'] + }); + // final String? channel2TokenStr = + // await Storage.getString(vendorPushChannelInfo); + // if (Platform.isAndroid && channel2TokenStr != null) { + // _vendorTokenCompleter.complete(jsonDecode(channel2TokenStr)); + // } + break; + case CMD_GET_TOKEN: + final Map channel2Token = { + 'channel': channelTypeMapping[data['platform']], + 'channelToken': data['token'] + }; + await Storage.setString( + vendorPushChannelInfo, jsonEncode(channel2Token)); + _vendorTokenCompleter.complete(channel2Token); + break; + } }, onReceiveNotification: (Map message) async { AppLog.log('onReceiveNotification: $message'); @@ -79,32 +131,22 @@ class XSJPushProvider { debugPrint("addJPushEventHandler onInAppMessageShow:$message"); }, onConnected: (Map message) async { - //绑定设备id - final String rid = await jpush.getRegistrationID(); - AppLog.log('onConnected registration id : $rid'); - debugPrint("addJPushEventHandler onConnected:$message"); - await Storage.setString(pushDeviceID, rid); - await pushBindDeviceID(rid); - return Future.value(); }, ); - - // Remove the incorrect addEventHandler call + bindPushChannels(); } - Future pushBindDeviceID(String deviceID) async { + // jpush 统一推送通道设备绑定 + Future bindPushChannels() async { try { - if (deviceID.isEmpty) { - AppLog.log('Device ID is empty.'); - //绑定设备id - final String rid = await jpush.getRegistrationID(); - AppLog.log('onConnected registration id : $rid'); - deviceID = rid; - } - await Storage.setString(pushDeviceID, deviceID); - final MineUnbindPhoneOrEmailEntity entity = await ApiRepository.to - .pushBindAppId(deviceID, Platform.isAndroid ? 10 : 20); + debugPrint("await PushChannels start"); + var channels = await Future.wait( + [_jpushRegistrationIdCompleter.future, _vendorTokenCompleter.future]); + final String? registrationId = await Storage.getString(pushDeviceID); + debugPrint("await PushChannels end"); + final MineUnbindPhoneOrEmailEntity entity = + await ApiRepository.to.pushBindChannels(registrationId!, channels); if (entity.errorCode!.codeIsSuccessful) { AppLog.log('绑定成功'); } else { diff --git a/lib/tools/storage.dart b/lib/tools/storage.dart index cf4e9666..eb251a53 100755 --- a/lib/tools/storage.dart +++ b/lib/tools/storage.dart @@ -25,6 +25,7 @@ const String isAgreeCamera = 'isAgreeCamera'; //是否同意获取相机/相册 const String isShowUpdateVersion = 'isShowUpdateVersion'; //是否更新弹窗 const String saveLockAlias = 'saveLockAlias'; //锁别名 const String pushDeviceID = 'pushDeviceID'; //推送设备ID +const String vendorPushChannelInfo = 'pushChannelInfo'; //推送设备ID const String saveIsVip = 'saveIsVip'; //是否是VIP const String saveUserLoginData = 'userLoginData'; @@ -37,6 +38,7 @@ const String relayInfo = 'relayInfo'; //星图中继服务器信息 const String lockNetWorkInfo = 'lockNetWorkInfo'; //锁板配网信息 const String appVersionHistoryUrl = 'appVersionHistoryUrl'; //是否同意隐私协议弹窗 + class Storage { factory Storage() => _instance; diff --git a/pubspec.lock b/pubspec.lock index 40584305..dd6aba4d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -992,8 +992,8 @@ packages: dependency: "direct main" description: path: "." - ref: "807ddb8e396c2dce16919df84efe795072404dde" - resolved-ref: "807ddb8e396c2dce16919df84efe795072404dde" + ref: ed2bd31147ccc929d9b9cf47205c2b8142a6d3f2 + resolved-ref: ed2bd31147ccc929d9b9cf47205c2b8142a6d3f2 url: "git@code-internal.star-lock.cn:StarlockTeam/jpush_flutter.git" source: git version: "2.5.8" diff --git a/pubspec.yaml b/pubspec.yaml index 885185dc..7d0cc89b 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -214,7 +214,7 @@ dependencies: jpush_flutter: git: url: git@code-internal.star-lock.cn:StarlockTeam/jpush_flutter.git - ref: 807ddb8e396c2dce16919df84efe795072404dde + ref: ed2bd31147ccc929d9b9cf47205c2b8142a6d3f2 #视频播放器 video_player: ^2.9.2