diff --git a/star_lock/README.md b/star_lock/README.md index 9f10dabf..1ecf099c 100644 --- a/star_lock/README.md +++ b/star_lock/README.md @@ -72,8 +72,12 @@ flutter build apk --split-per-abi --release --flavor sky -t lib/main_sky.dart 通用:build/app/outputs/apk/sky/release/app-sky-universal-release.apk 32位:build/app/outputs/apk/sky/release/app-sky-armeabi-v7a-release.apk 64位:build/app/outputs/apk/sky/release/app-sky-arm64-v8a-release.apk + +注意修改“VersionCode”为版本代码 ```bash -cp build/app/outputs/apk/sky/release/app-sky-universal-release.apk /d/Downloads/ +cp build/app/outputs/apk/sky/release/app-sky-armeabi-v7a-release.apk /d/www/SkyReleases/app-sky-32-release-VersionCode.apk +cp build/app/outputs/apk/sky/release/app-sky-arm64-v8a-release.apk /d/www/SkyReleases/app-sky-64-release-VersionCode.apk +cp build/app/outputs/apk/sky/release/app-sky-universal-release.apk /d/www/SkyReleases/app-sky-universal-release-VersionCode.apk ``` ## 获取编译包的签名 用于APP备案,国内商店上架等 @@ -102,10 +106,11 @@ java -jar android/google/pepk.jar --keystore=android/app/sky.jks --alias=upload ```bash flutter build appbundle --release --flavor sky -t lib/main_sky.dart ``` +编译后的包:`build/app/outputs/bundle/skyRelease/app-sky-release.aab` +注意修改“VersionCode”为版本代码 ```bash -cp build/app/outputs/bundle/skyRelease/app-sky-release.aab /d/Downloads/app-sky-universal-release-1.0.16+2024031302.aab +cp build/app/outputs/bundle/skyRelease/app-sky-release.aab /d/www/SkyReleases/app-sky-release-VersionCode.aab ``` - - 注意,这里的sky.jks和google_pek.zip和encryption_public_key.pem都是sky渠道的,和谷歌账号对应。如果需要使用其他谷歌账号,需要更换这两个文件。 ## 用于华为商店 diff --git a/star_lock/android/app/build.gradle b/star_lock/android/app/build.gradle index f95e017f..8dc22d6e 100644 --- a/star_lock/android/app/build.gradle +++ b/star_lock/android/app/build.gradle @@ -36,7 +36,13 @@ android { keyAlias = 'starlock' keyPassword '123456' } - // 下面的pre、sky、xhj 都是自定义变量,自身不起任何作用,而是看哪里引用了它们 + // 下面的xie、pre、sky、xhj 都是自定义变量,自身不起任何作用,而是看哪里引用了它们 + xie { + storeFile file("starlock.keystore") + storePassword '123456' + keyAlias = 'starlock' + keyPassword '123456' + } pre { storeFile file("starlock.keystore") storePassword '123456' @@ -57,10 +63,18 @@ android { keyPassword 'xhj8872' } } + // ----- BEGIN flavorDimensions (autogenerated by flutter_flavorizr) ----- flavorDimensions "flavor-type" productFlavors { + xie { + dimension "flavor-type" + applicationId "com.starlock.lock.xie" + signingConfig signingConfigs.pre + resValue "string", "app_name", "星锁-xie" + manifestPlaceholders.JPUSH_PKGNAME = "com.starlock.lock.xie" + } dev { dimension "flavor-type" applicationId "com.starlock.lock.dev" @@ -93,8 +107,7 @@ android { // ----- END flavorDimensions (autogenerated by flutter_flavorizr) ----- - - compileSdkVersion flutter.compileSdkVersion + compileSdkVersion flutter.compileSdkVersion ndkVersion flutter.ndkVersion lintOptions{ @@ -163,6 +176,7 @@ android { // 真实的解决办法 minifyEnabled false shrinkResources false + productFlavors.xie.signingConfig signingConfigs.pre productFlavors.dev.signingConfig signingConfigs.pre productFlavors.pre.signingConfig signingConfigs.pre productFlavors.sky.signingConfig signingConfigs.sky diff --git a/star_lock/android/app/src/xie/res/mipmap-hdpi/ic_launcher.png b/star_lock/android/app/src/xie/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..c4abfb2f Binary files /dev/null and b/star_lock/android/app/src/xie/res/mipmap-hdpi/ic_launcher.png differ diff --git a/star_lock/android/app/src/xie/res/mipmap-mdpi/ic_launcher.png b/star_lock/android/app/src/xie/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..6ef8ace4 Binary files /dev/null and b/star_lock/android/app/src/xie/res/mipmap-mdpi/ic_launcher.png differ diff --git a/star_lock/android/app/src/xie/res/mipmap-xhdpi/ic_launcher.png b/star_lock/android/app/src/xie/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..d17ccde3 Binary files /dev/null and b/star_lock/android/app/src/xie/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/star_lock/android/app/src/xie/res/mipmap-xxhdpi/ic_launcher.png b/star_lock/android/app/src/xie/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d496e04a Binary files /dev/null and b/star_lock/android/app/src/xie/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/star_lock/android/app/src/xie/res/mipmap-xxxhdpi/ic_launcher.png b/star_lock/android/app/src/xie/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..7af9b770 Binary files /dev/null and b/star_lock/android/app/src/xie/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/star_lock/flavorizr.yaml b/star_lock/flavorizr.yaml index 8515329a..a4e6d12e 100644 --- a/star_lock/flavorizr.yaml +++ b/star_lock/flavorizr.yaml @@ -51,6 +51,16 @@ app: flavorDimensions: "flavor-type" flavors: + xie: + app: + name: "星锁-xie" + icon: "assets/icon/dev.png" + android: + applicationId: "com.starlock.lock.xie" + customConfig: + signingConfig: signingConfigs.pre + ios: + bundleId: "com.starlock.lock.xie" dev: app: name: "星锁-dev" diff --git a/star_lock/ios/Runner/Info.plist b/star_lock/ios/Runner/Info.plist index 3251cc22..e5204edc 100644 --- a/star_lock/ios/Runner/Info.plist +++ b/star_lock/ios/Runner/Info.plist @@ -28,8 +28,16 @@ NSAppTransportSecurity - NSAllowsArbitraryLoads - + NSExceptionDomains + + jpush.cn + + NSExceptionAllowsInsecureHTTPLoads + + NSIncludesSubdomains + + + NSBluetoothAlwaysUsageDescription The app uses bluetooth to find, connect and transfer data between different devices @@ -76,8 +84,6 @@ UIViewControllerBasedStatusBarAppearance - NSUserTrackingUsageDescription - 需要访问您的隐私数据,以提供个性化的体验。 io.flutter.embedded_views_preview diff --git a/star_lock/lib/app.dart b/star_lock/lib/app.dart index 505cc1ae..8528b05f 100644 --- a/star_lock/lib/app.dart +++ b/star_lock/lib/app.dart @@ -1,17 +1,13 @@ -// import 'package:aliyun_push/aliyun_push.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:jpush_flutter/jpush_flutter.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:star_lock/flavors.dart'; import 'package:star_lock/tools/app_manager.dart'; import 'package:star_lock/tools/bindings/app_binding.dart'; -import 'package:star_lock/tools/storage.dart'; -// import 'package:star_lock/tools/storage.dart'; -// import 'package:star_lock/tools/xs_aliyunPush.dart'; +import 'package:star_lock/tools/xs_jPhush.dart'; import 'package:star_lock/translations/app_dept.dart'; import 'package:star_lock/translations/trans_lib.dart'; @@ -32,8 +28,6 @@ class MyApp extends StatefulWidget { // final RouteObserver routeObserver = RouteObserver(); class _MyAppState extends State with WidgetsBindingObserver, BaseWidget { - final JPush jpush = JPush(); - @override Widget build(BuildContext context) { return ScreenUtilInit( @@ -106,7 +100,7 @@ class _MyAppState extends State with WidgetsBindingObserver, BaseWidget { super.initState(); WidgetsBinding.instance.addObserver(this); - initJPushService(); + XSJPushProvider().initJPushService(); } @override @@ -114,43 +108,6 @@ class _MyAppState extends State with WidgetsBindingObserver, BaseWidget { WidgetsBinding.instance.removeObserver(this); super.dispose(); } - - Future initJPushService() async { - final data = await Storage.getString(saveUserLoginData); - if (data != null && data.isNotEmpty) { - jpush.setup( - appKey: "7ff37d174c1a568a89e98dad", - channel: "flutter_channel", - production: false, - debug: true, - ); - - jpush.addEventHandler( - // 接收通知回调方法。 - onReceiveNotification: (Map message) async { - print("flutter onReceiveNotification: $message"); - }, - // 点击通知回调方法。 - onOpenNotification: (Map message) async { - print("flutter onOpenNotification: $message"); - }, - // 接收自定义消息回调方法。 - onReceiveMessage: (Map message) async { - print("flutter onReceiveMessage: $message"); - }, - ); - - jpush.applyPushAuthority( - const NotificationSettingsIOS(sound: true, alert: true, badge: true)); - // jpush.setChannelAndSound( - // channel: "flutter_channel", channelID: "115700", sound: "default"); - - // Platform messages may fail, so we use a try/catch PlatformException. - jpush.getRegistrationID().then((rid) { - print("flutter get registration id : $rid"); - }); - } - } } void openBlueScan() { diff --git a/star_lock/lib/flavors.dart b/star_lock/lib/flavors.dart index b92a882c..39d9a0f2 100644 --- a/star_lock/lib/flavors.dart +++ b/star_lock/lib/flavors.dart @@ -1,4 +1,5 @@ enum Flavor { + xie, dev, pre, sky, @@ -20,6 +21,8 @@ class F { static String get title { switch (appFlavor) { + case Flavor.xie: + return '星锁-xie'; case Flavor.dev: return '星锁-dev'; case Flavor.pre: @@ -35,6 +38,8 @@ class F { static String get navTitle { switch (appFlavor) { + case Flavor.xie: + return '星锁-xie'; case Flavor.dev: return '星锁-dev'; case Flavor.pre: @@ -50,10 +55,12 @@ class F { static String get apiPrefix { switch (appFlavor) { + // case Flavor.ge: + // return 'https://ge.lock.star-lock.cn'; + case Flavor.xie: + return 'http://192.168.1.15:8022'; case Flavor.dev: return 'https://dev.lock.star-lock.cn'; - // return "http://192.168.1.15:8022"; //谢总本地 - // "https://ge.lock.star-lock.cn"; //葛工开发环境地址 case Flavor.pre: return 'https://pre.lock.star-lock.cn'; case Flavor.sky: @@ -69,6 +76,7 @@ class F { // StarLockAMapKey static StarLockAMapKey get aMapKey { switch (appFlavor) { + case Flavor.xie: case Flavor.dev: return const StarLockAMapKey( androidKey: 'b56b681ee89f4db43a5aa1879ae8cbfe', diff --git a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart index 765de6a7..00f4645d 100644 --- a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart +++ b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart @@ -7,6 +7,7 @@ import 'package:intl/intl.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart'; import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecord/keyOperationRecord_entity.dart'; +import 'package:star_lock/tools/appFirstEnterHandle.dart'; import '../../../blue/blue_manage.dart'; import '../../../blue/io_protocol/io_addUser.dart'; @@ -30,7 +31,8 @@ class LockDetailLogic extends BaseGetXController { // 监听设备返回的数据 void initReplySubscription() { - state.replySubscription = EventBusManager().eventBus!.on().listen((reply) async { + state.replySubscription = + EventBusManager().eventBus!.on().listen((reply) async { Get.log("锁详情收到了蓝牙解析消息 reply:${reply.commandType}"); // 开门 if (reply is OpenDoorReply && state.ifCurrentScreen.value == true) { @@ -48,7 +50,8 @@ class LockDetailLogic extends BaseGetXController { // } // 开完锁之后上传记录 - if (reply is SenderReferEventRecordTimeReply && state.ifCurrentScreen.value == true) { + if (reply is SenderReferEventRecordTimeReply && + state.ifCurrentScreen.value == true) { _replyReferEventRecordTime(reply); } @@ -71,7 +74,7 @@ class LockDetailLogic extends BaseGetXController { // _showFullScreenOverlay(Get.context!); state.iSClosedUnlockSuccessfulPopup.value = true; - if (state.closedUnlockSuccessfulTimer != null ) { + if (state.closedUnlockSuccessfulTimer != null) { state.closedUnlockSuccessfulTimer!.cancel(); state.closedUnlockSuccessfulTimer = null; } @@ -377,7 +380,8 @@ class LockDetailLogic extends BaseGetXController { eventBus.fire(RefreshLockDetailInfoDataEvent()); }); - BlueManage().bludSendData(state.keyInfos.value.bluetooth!.bluetoothDeviceName!, + BlueManage() + .bludSendData(state.keyInfos.value.bluetooth!.bluetoothDeviceName!, (BluetoothConnectionState deviceConnectionState) async { if (deviceConnectionState == BluetoothConnectionState.connected) { // 私钥 @@ -409,7 +413,8 @@ class LockDetailLogic extends BaseGetXController { publicKey: publicKeyDataList, privateKey: getPrivateKeyList, token: getTokenList); - } else if (deviceConnectionState == BluetoothConnectionState.disconnected) { + } else if (deviceConnectionState == + BluetoothConnectionState.disconnected) { cancelBlueConnetctToastTimer(); if (state.ifCurrentScreen.value == true) { showBlueConnetctToast(); @@ -464,7 +469,8 @@ class LockDetailLogic extends BaseGetXController { signKey: signKeyDataList, privateKey: getPrivateKeyList, ); - } else if (deviceConnectionState == BluetoothConnectionState.disconnected) { + } else if (deviceConnectionState == + BluetoothConnectionState.disconnected) { cancelBlueConnetctToastTimer(); if (state.ifCurrentScreen.value == true) { showBlueConnetctToast(); @@ -694,17 +700,22 @@ class LockDetailLogic extends BaseGetXController { /// 锁设置里面开启关闭考勤刷新锁详情 void initLockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceAction() { // 蓝牙协议通知传输跟蓝牙之外的数据传输类不一样 eventBus - state.lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent = eventBus.on().listen((event) { + state.lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent = + eventBus + .on() + .listen((event) { if (event.type == 0) { // 0考勤 state.isAttendance.value = int.parse(event.setResult); - state.keyInfos.value.lockSetting!.attendance = int.parse(event.setResult); + state.keyInfos.value.lockSetting!.attendance = + int.parse(event.setResult); } else if (event.type == 1) { // 1 开锁时是否需联网 state.isOpenLockNeedOnline.value = int.parse(event.setResult); state.keyInfos.value.lockSetting!.appUnlockOnline = int.parse(event.setResult); - Get.log("state.isOpenLockNeedOnline.value:${state.isOpenLockNeedOnline.value}"); + Get.log( + "state.isOpenLockNeedOnline.value:${state.isOpenLockNeedOnline.value}"); } else if (event.type == 2) { // 2 常开模式 state.isOpenPassageMode.value = int.parse(event.setResult); @@ -718,26 +729,28 @@ class LockDetailLogic extends BaseGetXController { state.electricQuantity.value = int.parse(event.setResult); state.keyInfos.value.electricQuantity = int.parse(event.setResult); } else if (event.type == 5) { - // 5 远程开锁 - state.keyInfos.value.lockSetting!.remoteUnlock = int.parse(event.setResult); + // 5 远程开锁 + state.keyInfos.value.lockSetting!.remoteUnlock = + int.parse(event.setResult); } eventBus.fire(RefreshLockDetailInfoDataEvent()); }); } - String getKeyStatusTextAndShow(){ + String getKeyStatusTextAndShow() { String text = ""; - if (state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusWaitIneffective || + if (state.keyInfos.value.keyStatus == + XSConstantMacro.keyStatusWaitIneffective || state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusFrozen || state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusExpired || state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusDeleted || state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusReset) { - text = "你的钥匙${XSConstantMacro.getKeyStatusStr(state.keyInfos.value.keyStatus!)}"; + text = + "你的钥匙${XSConstantMacro.getKeyStatusStr(state.keyInfos.value.keyStatus!)}"; } else { text = state.isOpenPassageMode.value == 1 ? "常开模式启动!长按闭锁" - : TranslationLoader - .lanKeys!.clickUnlockAndHoldDownClose!.tr; + : TranslationLoader.lanKeys!.clickUnlockAndHoldDownClose!.tr; } return text; } @@ -825,6 +838,20 @@ class LockDetailLogic extends BaseGetXController { return formattedTime; } + Future positionPermissionAlert() async { + //安卓平台下首次进入应用需向用户告知获取权限用途弹窗 + if (Platform.isAndroid) { + AppFirstEnterHandle() + .getAppFirstEnter(state.widgetContext, isAgreePosition); + var getFlag = await Storage.getString(isAgreePosition); + if (getFlag == isAgreePosition) { + openBlueSet(); + } + } else { + openBlueSet(); + } + } + openBlueSet() { if (!Platform.isIOS) { getMicrophonePermission().then((value) { @@ -861,10 +888,14 @@ class LockDetailLogic extends BaseGetXController { // TODO: implement onReady super.onReady(); - openBlueSet(); Get.log("LockDetailPage onReady"); // _initReplySubscription(); // _initLockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceAction(); + + // openBlueSet(); + + positionPermissionAlert(); + // _scanListDiscoveredDeviceSubscriptionAction(); } @@ -886,5 +917,4 @@ class LockDetailLogic extends BaseGetXController { // _scanListDiscoveredDeviceSubscription.cancel(); } - } diff --git a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart index 6c3b6b93..88b1b7af 100644 --- a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart +++ b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart @@ -33,7 +33,8 @@ class LockDetailPage extends StatefulWidget { State createState() => _LockDetailPageState(); } -class _LockDetailPageState extends State with TickerProviderStateMixin, RouteAware { +class _LockDetailPageState extends State + with TickerProviderStateMixin, RouteAware { // with RouteAware final logic = Get.put(LockDetailLogic()); final state = Get.find().state; @@ -61,6 +62,7 @@ class _LockDetailPageState extends State with TickerProviderStat void didChangeDependencies() { super.didChangeDependencies(); Get.log("LockDetailPage didChangeDependencies2222"); + /// 路由订阅 AppRouteObserver().routeObserver.subscribe(this, ModalRoute.of(context)!); } @@ -68,12 +70,13 @@ class _LockDetailPageState extends State with TickerProviderStat StreamSubscription? _lockRefreshLockDetailInfoDataEvent; void _initRefreshLockDetailInfoDataEventAction() { // 蓝牙协议通知传输跟蓝牙之外的数据传输类不一样 eventBus - _lockRefreshLockDetailInfoDataEvent = eventBus.on().listen((event) { + _lockRefreshLockDetailInfoDataEvent = + eventBus.on().listen((event) { setState(() {}); }); } - void loadData(){ + void loadData() { // print("widget.lockListInfoItemEntity.lockUserNo:${widget.lockListInfoItemEntity.lockUserNo}"); // print("state.lockUserNo:${state.lockUserNo}"); @@ -81,17 +84,18 @@ class _LockDetailPageState extends State with TickerProviderStat state.lockUserNo = state.keyInfos.value.lockUserNo!; if (state.lockUserNo == 0) { state.bottomBtnisEable.value = false; - }else{ + } else { state.bottomBtnisEable.value = true; } // print("state.keyInfos.value.keyStatus:${state.keyInfos.value.keyStatus}"); - if (state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusWaitIneffective || + if (state.keyInfos.value.keyStatus == + XSConstantMacro.keyStatusWaitIneffective || state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusFrozen || state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusExpired || state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusDeleted || state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusReset) { state.openDoorBtnisUneable.value = false; - }else{ + } else { state.openDoorBtnisUneable.value = true; } @@ -100,28 +104,28 @@ class _LockDetailPageState extends State with TickerProviderStat state.senderUserId = state.keyInfos.value.senderUserId!; state.isAttendance.value = state.keyInfos.value.lockSetting!.attendance!; state.isOpenLockNeedOnline.value = - state.keyInfos.value.lockSetting!.appUnlockOnline!; + state.keyInfos.value.lockSetting!.appUnlockOnline!; state.electricQuantity.value = state.keyInfos.value.electricQuantity!; state.isOpenPassageMode.value = state.keyInfos.value.passageMode!; state.lockAlias.value = state.keyInfos.value.lockAlias!; BlueManage().connectDeviceName = - state.keyInfos.value.bluetooth!.bluetoothDeviceName!; + state.keyInfos.value.bluetooth!.bluetoothDeviceName!; List publicKeyData = - state.keyInfos.value.bluetooth!.publicKey!.cast(); + state.keyInfos.value.bluetooth!.publicKey!.cast(); var saveStrList = changeIntListToStringList(publicKeyData); Storage.setStringList(saveBluePublicKey, saveStrList); // 私钥 List privateKeyData = - state.keyInfos.value.bluetooth!.privateKey!.cast(); + state.keyInfos.value.bluetooth!.privateKey!.cast(); var savePrivateKeyList = changeIntListToStringList(privateKeyData); Storage.setStringList(saveBluePrivateKey, savePrivateKeyList); // signKey List signKeyData = - state.keyInfos.value.bluetooth!.signKey!.cast(); + state.keyInfos.value.bluetooth!.signKey!.cast(); var saveSignKeyList = changeIntListToStringList(signKeyData); Storage.setStringList(saveBlueSignKey, saveSignKeyList); @@ -131,16 +135,29 @@ class _LockDetailPageState extends State with TickerProviderStat @override Widget build(BuildContext context) { + state.widgetContext = context; loadData(); return ListView( children: [ Visibility( - visible: ( - (state.keyInfos.value.keyType == XSConstantMacro.keyTypeTime || state.keyInfos.value.keyType == XSConstantMacro.keyTypeLoop) && // 限时、循环 - (DateTool().compareTimeGetDaysFromNow(state.keyInfos.value.endDate!) < 30 && DateTool().compareTimeGetDaysFromNow(state.keyInfos.value.endDate!) > 0) &&// 0到30天 - (state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusNormalUse || state.keyInfos.value.keyStatus == XSConstantMacro.keyStatusWaitReceive)// 正常使用、待接收 - ) ? true : false, + visible: + ((state.keyInfos.value.keyType == XSConstantMacro.keyTypeTime || + state.keyInfos.value.keyType == + XSConstantMacro.keyTypeLoop) && // 限时、循环 + (DateTool().compareTimeGetDaysFromNow( + state.keyInfos.value.endDate!) < + 30 && + DateTool().compareTimeGetDaysFromNow( + state.keyInfos.value.endDate!) > + 0) && // 0到30天 + (state.keyInfos.value.keyStatus == + XSConstantMacro.keyStatusNormalUse || + state.keyInfos.value.keyStatus == + XSConstantMacro.keyStatusWaitReceive) // 正常使用、待接收 + ) + ? true + : false, child: Container( // height: 30.h, color: const Color(0xFFFBEFD4), @@ -148,7 +165,8 @@ class _LockDetailPageState extends State with TickerProviderStat child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text("钥匙将在${DateTool().compareTimeGetDaysFromNow(state.keyInfos.value.endDate!)}天后失效", + Text( + "钥匙将在${DateTool().compareTimeGetDaysFromNow(state.keyInfos.value.endDate!)}天后失效", style: TextStyle( color: const Color(0xffCBA74B), fontSize: 24.sp)) ], @@ -185,21 +203,21 @@ class _LockDetailPageState extends State with TickerProviderStat ), ), Visibility( - visible: state.iSClosedUnlockSuccessfulPopup.value, - // visible: true, - child: GestureDetector( - onTap: () { - setState(() { - state.iSClosedUnlockSuccessfulPopup.value = false; - }); - }, - child: Container( - width: 1.sw, - height: 1.sh - ScreenUtil().statusBarHeight * 2, - color: Colors.black.withOpacity(0.3), - child: _unlockSuccessWidget()), - ), - ) + visible: state.iSClosedUnlockSuccessfulPopup.value, + // visible: true, + child: GestureDetector( + onTap: () { + setState(() { + state.iSClosedUnlockSuccessfulPopup.value = false; + }); + }, + child: Container( + width: 1.sw, + height: 1.sh - ScreenUtil().statusBarHeight * 2, + color: Colors.black.withOpacity(0.3), + child: _unlockSuccessWidget()), + ), + ) ]), ], ); @@ -215,73 +233,70 @@ class _LockDetailPageState extends State with TickerProviderStat SizedBox( width: 1.sw - 120.w * 2, child: Center( - child: Text( - state.lockAlias.value, - style: TextStyle( - fontSize: 22.sp, - fontWeight: FontWeight.w400, - color: state.isOpenPassageMode.value == 1 - ? AppColors.openPassageModeColor - : AppColors.darkGrayTextColor), - ))), + child: Text( + state.lockAlias.value, + style: TextStyle( + fontSize: 22.sp, + fontWeight: FontWeight.w400, + color: state.isOpenPassageMode.value == 1 + ? AppColors.openPassageModeColor + : AppColors.darkGrayTextColor), + ))), Positioned( child: Column( - children: [ - GestureDetector( - onTap: () { - // logic.getStarLockStatus(); - showDeletAlertDialog( - context, - DateTool().dateToYMDHNSString(state - .keyInfos.value.electricQuantityDate! - .toString())); - }, - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Image.asset( - showElectricIcon( - state.electricQuantity.value), - width: 30.w, - height: 24.w), - SizedBox(width: 2.w), - Text("${state.electricQuantity.value}%", - style: TextStyle( - fontSize: 18.sp, - color: AppColors.darkGrayTextColor)), - SizedBox(width: 2.w), - Icon( - Icons.info, // 使用内置的 warning 图标,它是一个叹号 - color: AppColors.mainColor, // 设置图标颜色为红色 - size: 25.w, // 设置图标大小为 30 - ), - SizedBox(width: 20.w), - ], - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Image.asset( - showElectricIcon(state.electricQuantity.value), - width: 30.w, - height: 24.w), - SizedBox(width: 2.w), - Text("--%", - style: TextStyle( - fontSize: 18.sp, - color: AppColors.darkGrayTextColor)), - SizedBox(width: 2.w), - Icon( - Icons.info, // 使用内置的 warning 图标,它是一个叹号 - color: AppColors.mainColor, // 设置图标颜色为红色 - size: 25.w, // 设置图标大小为 30 - ), - SizedBox(width: 20.w), - ], - ), - ], - )) + children: [ + GestureDetector( + onTap: () { + // logic.getStarLockStatus(); + showDeletAlertDialog( + context, + DateTool().dateToYMDHNSString(state + .keyInfos.value.electricQuantityDate! + .toString())); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Image.asset( + showElectricIcon(state.electricQuantity.value), + width: 30.w, + height: 24.w), + SizedBox(width: 2.w), + Text("${state.electricQuantity.value}%", + style: TextStyle( + fontSize: 18.sp, + color: AppColors.darkGrayTextColor)), + SizedBox(width: 2.w), + Icon( + Icons.info, // 使用内置的 warning 图标,它是一个叹号 + color: AppColors.mainColor, // 设置图标颜色为红色 + size: 25.w, // 设置图标大小为 30 + ), + SizedBox(width: 20.w), + ], + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Image.asset(showElectricIcon(state.electricQuantity.value), + width: 30.w, height: 24.w), + SizedBox(width: 2.w), + Text("--%", + style: TextStyle( + fontSize: 18.sp, + color: AppColors.darkGrayTextColor)), + SizedBox(width: 2.w), + Icon( + Icons.info, // 使用内置的 warning 图标,它是一个叹号 + color: AppColors.mainColor, // 设置图标颜色为红色 + size: 25.w, // 设置图标大小为 30 + ), + SizedBox(width: 20.w), + ], + ), + ], + )) ], ), SizedBox(height: 30.h), @@ -293,36 +308,43 @@ class _LockDetailPageState extends State with TickerProviderStat children: [ Center( child: GestureDetector( - onTap: state.openDoorBtnisUneable.value == true ? () { - // Get.log("点击开锁"); - setState(() { - startOpenLock(); - }); - } : null, - onLongPressStart: state.openDoorBtnisUneable.value == true ? (details) { - Get.log("长按闭锁"); - setState(() { - startUnLock(); - }); - // startUnLock(); - }:null, + onTap: state.openDoorBtnisUneable.value == true + ? () { + // Get.log("点击开锁"); + setState(() { + startOpenLock(); + }); + } + : null, + onLongPressStart: state.openDoorBtnisUneable.value == true + ? (details) { + Get.log("长按闭锁"); + setState(() { + startUnLock(); + }); + // startUnLock(); + } + : null, child: Stack( - children: [ - Image.asset( - state.openDoorBtnisUneable.value == false ? 'images/main/icon_main_openLockBtn_grey.png' : (state.isOpenPassageMode.value == 1 + children: [ + Image.asset( + state.openDoorBtnisUneable.value == false + ? 'images/main/icon_main_openLockBtn_grey.png' + : (state.isOpenPassageMode.value == 1 ? 'images/main/icon_main_normallyOpenMode_center.png' : 'images/main/icon_main_openLockBtn_center.png'), - width: 330.w, - height: 330.w, - ), - state.openDoorBtnisUneable.value == false ? Positioned( - child: Image.asset( - 'images/main/icon_main_openLockBtn_grey.png', - width: 330.w, - height: 330.w, - ), - ) : - state.openLockBtnState.value == 1 + width: 330.w, + height: 330.w, + ), + state.openDoorBtnisUneable.value == false + ? Positioned( + child: Image.asset( + 'images/main/icon_main_openLockBtn_grey.png', + width: 330.w, + height: 330.w, + ), + ) + : state.openLockBtnState.value == 1 ? buildRotationTransition() : Positioned( child: Image.asset( @@ -332,8 +354,8 @@ class _LockDetailPageState extends State with TickerProviderStat width: 330.w, height: 330.w, )), - ], - ), + ], + ), )), ], ), @@ -361,10 +383,10 @@ class _LockDetailPageState extends State with TickerProviderStat children: [ Text( logic.getKeyStatusTextAndShow(), - style: TextStyle( - fontSize: 22.sp, - color: AppColors.btnDisableColor, - fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 22.sp, + color: AppColors.btnDisableColor, + fontWeight: FontWeight.w500), ), ], ), @@ -543,7 +565,8 @@ class _LockDetailPageState extends State with TickerProviderStat showWidgetArr.add(bottomItem( 'images/main/icon_main_clockingIn.png', TranslationLoader.lanKeys!.checkingIn!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.checkingInListPage, arguments: state.keyInfos.value); })); @@ -552,14 +575,18 @@ class _LockDetailPageState extends State with TickerProviderStat showWidgetArr.add(bottomItem( 'images/main/icon_main_operatingRecord.png', TranslationLoader.lanKeys!.operatingRecord!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.lockOperatingRecordPage, arguments: {"keyInfo": state.keyInfos.value}); })); // 设置 - showWidgetArr.add(bottomItem('images/main/icon_main_set.png', - TranslationLoader.lanKeys!.set!.tr, state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + showWidgetArr.add(bottomItem( + 'images/main/icon_main_set.png', + TranslationLoader.lanKeys!.set!.tr, + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.lockSetPage, arguments: { "lockId": state.keyInfos.value.lockId, "isOnlyOneData": state.isOnlyOneData @@ -577,7 +604,8 @@ class _LockDetailPageState extends State with TickerProviderStat showWidgetArr.add(bottomItem( 'images/main/icon_main_clockingIn.png', TranslationLoader.lanKeys!.checkingIn!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.checkingInListPage, arguments: state.keyInfos.value); })); @@ -587,7 +615,8 @@ class _LockDetailPageState extends State with TickerProviderStat showWidgetArr.add(bottomItem( 'images/main/icon_main_electronicKey.png', TranslationLoader.lanKeys!.electronicKey!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.electronicKeyListPage, arguments: {"keyInfo": state.keyInfos.value}); })); @@ -596,7 +625,8 @@ class _LockDetailPageState extends State with TickerProviderStat showWidgetArr.add(bottomItem( 'images/main/icon_main_password.png', TranslationLoader.lanKeys!.password!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.passwordKeyListPage, arguments: {"keyInfo": state.keyInfos.value}); })); @@ -606,7 +636,8 @@ class _LockDetailPageState extends State with TickerProviderStat showWidgetArr.add(bottomItem( 'images/main/icon_main_icCard.png', TranslationLoader.lanKeys!.card!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { // logic.showToast("普通用户第一次需要在锁旁边操作哦。", something: () { // logic.showEasyLoading(); // }); @@ -621,7 +652,8 @@ class _LockDetailPageState extends State with TickerProviderStat showWidgetArr.add(bottomItem( 'images/main/icon_main_fingerprint.png', TranslationLoader.lanKeys!.fingerprint!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.fingerprintListPage, arguments: { "lockId": state.keyInfos.value.lockId, }); @@ -633,7 +665,8 @@ class _LockDetailPageState extends State with TickerProviderStat showWidgetArr.add(bottomItem( 'images/main/icon_main_remoteControl.png', TranslationLoader.lanKeys!.remoteControl!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.remoteControlListPage); })); } @@ -644,7 +677,8 @@ class _LockDetailPageState extends State with TickerProviderStat bottomItem( 'images/main/icon_face.png', TranslationLoader.lanKeys!.humanFace!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.faceList, arguments: { "lockId": state.keyInfos.value.lockId, }); // Toast.show(msg: "功能暂未开放"); @@ -658,7 +692,8 @@ class _LockDetailPageState extends State with TickerProviderStat bottomItem( 'images/main/icon_catEyes.png', TranslationLoader.lanKeys!.monitoring!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.realTimePicturePage, arguments: { "lockName": state.keyInfos.value.lockName, "isMonitoring": true @@ -672,7 +707,8 @@ class _LockDetailPageState extends State with TickerProviderStat showWidgetArr.add(bottomItem( 'images/main/icon_main_authorizedAdmin.png', TranslationLoader.lanKeys!.authorizedAdmin!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.authorizedAdminListPage, arguments: {"keyInfo": state.keyInfos.value}); })); @@ -682,53 +718,73 @@ class _LockDetailPageState extends State with TickerProviderStat // arguments: {"keyInfo": state.keyInfos.value}); // }) - var endWiddget = [ + var endWiddget = []; + endWiddget.add( // 操作记录 bottomItem( 'images/main/icon_main_operatingRecord.png', TranslationLoader.lanKeys!.operatingRecord!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { // Get.toNamed(Routers.lockOperatingRecordPage, // arguments: {"keyInfo": state.keyInfos.value}); Get.toNamed(Routers.doorLockLogPage, arguments: {"keyInfo": state.keyInfos.value}); }), - // 视频日志 - bottomItem( + ); + + if (state.keyInfos.value.lockFeature!.d3Face == 1) { + //视频日志 + endWiddget.add(bottomItem( 'images/main/icon_lockDetail_videoLog.png', TranslationLoader.lanKeys!.videoLog!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { - //视频日志 + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.videoLogPage); - }), + })); + } + endWiddget.add( // 消息提醒 bottomItem( 'images/main/icon_lockDetail_messageReminding.png', TranslationLoader.lanKeys!.messageReminding!.tr, - state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { Get.toNamed(Routers.msgNotificationPage); }), + ); + + endWiddget.add( // 设置 - bottomItem('images/main/icon_main_set.png', TranslationLoader.lanKeys!.set!.tr, state.openDoorBtnisUneable.value, state.bottomBtnisEable.value, () { + bottomItem( + 'images/main/icon_main_set.png', + TranslationLoader.lanKeys!.set!.tr, + state.openDoorBtnisUneable.value, + state.bottomBtnisEable.value, () { // logic.clickItemBtnAction(10); Get.toNamed(Routers.lockSetPage, arguments: { "lockId": state.keyInfos.value.lockId, "isOnlyOneData": state.isOnlyOneData, }); }), - ]; + ); showWidgetArr.addAll(endWiddget); return showWidgetArr; } // - Widget bottomItem(String iconUrl, String name, bool openDoorBtnisUneable, bool bottomBtnisEable, Function() onClick) { + Widget bottomItem(String iconUrl, String name, bool openDoorBtnisUneable, + bool bottomBtnisEable, Function() onClick) { var width = 42.w; var height = 42.h; return GestureDetector( - onTap:openDoorBtnisUneable ? (bottomBtnisEable ? onClick : () { - logic.showToast("请在锁旁边完成第一次开锁"); - }) : null, + onTap: openDoorBtnisUneable + ? (bottomBtnisEable + ? onClick + : () { + logic.showToast("请在锁旁边完成第一次开锁"); + }) + : null, child: Container( // height: 300.h, color: Colors.white, @@ -741,9 +797,11 @@ class _LockDetailPageState extends State with TickerProviderStat child: Image.asset(iconUrl, width: width, height: height, - color: openDoorBtnisUneable ? (bottomBtnisEable - ? AppColors.mainColor - : AppColors.lockDetailBottomBtnUneable) : AppColors.lockDetailBottomBtnUneable, + color: openDoorBtnisUneable + ? (bottomBtnisEable + ? AppColors.mainColor + : AppColors.lockDetailBottomBtnUneable) + : AppColors.lockDetailBottomBtnUneable, fit: BoxFit.fitWidth), ), SizedBox(height: 10.w), @@ -751,9 +809,11 @@ class _LockDetailPageState extends State with TickerProviderStat child: Text(name, style: TextStyle( fontSize: 20.sp, - color:openDoorBtnisUneable ? (bottomBtnisEable - ? AppColors.blackColor - : AppColors.lockDetailBottomBtnUneable) : AppColors.lockDetailBottomBtnUneable), + color: openDoorBtnisUneable + ? (bottomBtnisEable + ? AppColors.blackColor + : AppColors.lockDetailBottomBtnUneable) + : AppColors.lockDetailBottomBtnUneable), textAlign: TextAlign.center)) ], )), @@ -762,7 +822,8 @@ class _LockDetailPageState extends State with TickerProviderStat listeningAnimations() async { await Future.delayed(Duration.zero, () { - state.animationController = AnimationController(duration: const Duration(seconds: 1), vsync: this); + state.animationController = AnimationController( + duration: const Duration(seconds: 1), vsync: this); state.animationController!.repeat(); //动画开始、结束、向前移动或向后移动时会调用StatusListener state.animationController!.addStatusListener((status) { @@ -996,5 +1057,4 @@ class _LockDetailPageState extends State with TickerProviderStat // state.animationController!.stop(); // } } - } diff --git a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_state.dart b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_state.dart index be2989f4..bb13da46 100644 --- a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_state.dart +++ b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_state.dart @@ -51,6 +51,8 @@ class LockDetailState { final PageController pageController = PageController(); var currentPage = 0.obs; + late BuildContext widgetContext; + // LockDetailState() { // Map map = Get.arguments; // lockCount = map["lockCount"]; diff --git a/star_lock/lib/main/lockDetail/monitoring/monitoring/lockMonitoring_page.dart b/star_lock/lib/main/lockDetail/monitoring/monitoring/lockMonitoring_page.dart index 3992c601..cd3a7164 100644 --- a/star_lock/lib/main/lockDetail/monitoring/monitoring/lockMonitoring_page.dart +++ b/star_lock/lib/main/lockDetail/monitoring/monitoring/lockMonitoring_page.dart @@ -20,6 +20,13 @@ class _LockMonitoringPageState extends State { final logic = Get.put(LockMonitoringLogic()); final state = Get.find().state; + @override + void initState() { + super.initState(); + + requestMicrophonePermission(); + } + @override Widget build(BuildContext context) { return SizedBox( @@ -155,18 +162,9 @@ class _LockMonitoringPageState extends State { Widget bottomBottomBtnWidget() { return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ // 接听 - Obx(() => bottomBtnItemWidget(getAnswerBtnImg(), getAnswerBtnName(), Colors.white, () async { - //获取麦克风权限 - await logic.getPermissionStatus().then((value) async { - if (!value) { - return; - } - - // state.isSenderAudioData.value = false; - print("发送接听了"); - // 刚进来是接听状态,然后改为长按对讲 - logic.udpAnswerAction(); - }); + Obx(() => bottomBtnItemWidget( + getAnswerBtnImg(), getAnswerBtnName(), Colors.white, () async { + logic.udpAnswerAction(); }, longPress: () { // 开始长按 print("onLongPress"); @@ -292,6 +290,19 @@ class _LockMonitoringPageState extends State { ); } + //获取麦克风权限 + Future requestMicrophonePermission() async { + await logic.getPermissionStatus().then((value) async { + if (!value) { + return; + } + + // state.isSenderAudioData.value = false; + print("发送接听了"); + // 刚进来是接听状态,然后改为长按对讲 + }); + } + @override void dispose() { super.dispose(); diff --git a/star_lock/lib/main/lockMian/lockMain/lockMain_logic.dart b/star_lock/lib/main/lockMian/lockMain/lockMain_logic.dart index ada7765e..eb21fe05 100644 --- a/star_lock/lib/main/lockMian/lockMain/lockMain_logic.dart +++ b/star_lock/lib/main/lockMian/lockMain/lockMain_logic.dart @@ -1,4 +1,3 @@ - import 'dart:async'; import 'package:connectivity_plus/connectivity_plus.dart'; @@ -14,27 +13,27 @@ import 'lockMain_state.dart'; class LockMainLogic extends BaseGetXController { final LockMainState state = LockMainState(); - Future getStarLockInfo() async{ + Future getStarLockInfo() async { LockListInfoEntity entity = await ApiRepository.to.getStarLockListInfo( - pageNo:pageNo, - pageSize:50, + pageNo: pageNo, + pageSize: 50, ); - if(entity.errorCode!.codeIsSuccessful){ - if(entity.data!.groupList!.isEmpty){ + if (entity.errorCode!.codeIsSuccessful) { + if (entity.data!.groupList!.isEmpty) { state.dataLength.value = 0; - }else if(entity.data!.groupList!.length == 1){ + } else if (entity.data!.groupList!.length == 1) { GroupList groupList = entity.data!.groupList![0]; - if(groupList.lockList!.length > 1){ + if (groupList.lockList!.length > 1) { state.dataLength.value = 2; - }else{ + } else { state.dataLength.value = 1; } - }else{ + } else { state.dataLength.value = 2; } state.lockListInfoEntity.value = entity; // return entity.data!; - }else{ + } else { print("首页锁列表请求失败"); state.dataLength.value = 0; } @@ -70,7 +69,8 @@ class LockMainLogic extends BaseGetXController { connectListener() async { Connectivity().onConnectivityChanged.listen((ConnectivityResult result) { print("设置网络切换监听:$result"); - if(state.networkConnectionStatus.value == 0 && result != ConnectivityResult.none){ + if (state.networkConnectionStatus.value == 0 && + result != ConnectivityResult.none) { // 从无网络到有网络 state.networkConnectionStatus.value = 1; getStarLockInfo(); @@ -85,7 +85,7 @@ class LockMainLogic extends BaseGetXController { print("onReady()"); // 开启UDP - // UdpHelp().openUDP(); + UdpHelp().openUDP(); BlueManage(); } @@ -112,5 +112,4 @@ class LockMainLogic extends BaseGetXController { // _teamEvent.cancel(); // state.timer.cancel(); } - -} \ No newline at end of file +} diff --git a/star_lock/lib/main_xie.dart b/star_lock/lib/main_xie.dart new file mode 100644 index 00000000..cd62b84c --- /dev/null +++ b/star_lock/lib/main_xie.dart @@ -0,0 +1,8 @@ +import 'flavors.dart'; + +import 'main.dart' as runner; + +Future main() async { + F.appFlavor = Flavor.xie; + await runner.main(); +} diff --git a/star_lock/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_page.dart b/star_lock/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_page.dart index e08b40d6..722a94f6 100644 --- a/star_lock/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_page.dart +++ b/star_lock/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_page.dart @@ -1,6 +1,6 @@ +import 'dart:ffi'; import 'dart:io'; -import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; @@ -23,16 +23,36 @@ class MinePersonInfoPage extends StatefulWidget { State createState() => _MinePersonInfoPageState(); } -class _MinePersonInfoPageState extends State { +class _MinePersonInfoPageState extends State + with WidgetsBindingObserver { final logic = Get.put(MinePersonInfoLogic()); final state = Get.find().state; @override initState() { super.initState(); + WidgetsBinding.instance.addObserver(this); // 添加观察者 logic.getUserInfoRequest(); + _checkCameraPermission(); + _checkPhotoPermission(); } + @override + void dispose() { + WidgetsBinding.instance.removeObserver(this); // 移除观察者 + super.dispose(); + } + + // // 当应用生命周期状态变化时调用 + // @override + // void didChangeAppLifecycleState(AppLifecycleState state) { + // super.didChangeAppLifecycleState(state); + // if (state == AppLifecycleState.resumed) { + // // 当应用从后台返回前台时检查相机权限 + // checkCameraPermission(); + // } + // } + @override Widget build(BuildContext context) { return Scaffold( @@ -176,54 +196,58 @@ class _MinePersonInfoPageState extends State { )); } - Future requestCameraPermission() async { - // 检查是否已经授予相机权限 - PermissionStatus status = await Permission.camera.status; + // Future requestCameraPermission() async { + // var status = await Permission.camera.status; + // if (status.isGranted) { + // selectCamera(); + // } else { + // status = await Permission.camera.request(); + // if (status.isGranted) { + // selectCamera(); + // } else { + // showPermissionDeniedDialog(); + // } + // } + // } + Future _requestCameraPermission() async { + var status = await Permission.camera.request(); if (status.isGranted) { - // 如果权限已经被授予,执行您的相机操作 - // 这里可以调用打开相机的方法或者跳转到相机页面等 - selectCamera(); + setState(() { + state.hasCameraPermission.value = true; // 如果权限被授予,更新状态变量 + }); } else { - // 如果权限尚未被授予,请求相机权限 - // 此处会显示系统权限请求对话框 - status = await Permission.camera.request(); - - if (status.isGranted) { - // 如果用户授予了相机权限,执行您的相机操作 - selectCamera(); - } else { - // 如果用户拒绝了相机权限,您可以提供适当的提示 - // 或者引导用户手动授予权限 - showPermissionDeniedDialog(); - } + // 如果权限被拒绝,你可以选择在这里处理相应逻辑,比如显示一个提示框 + showPermissionDeniedDialog(); } } - Future requestPhotoPermission() async { - // 检查是否已经授予相机权限 - PermissionStatus status = await Permission.photos.status; - + Future _requestPhotoPermission() async { + var status = await Permission.photos.request(); if (status.isGranted) { - // 如果权限已经被授予,执行您的相机操作 - // 这里可以调用打开相机的方法或者跳转到相机页面等 - selectImage(); + setState(() { + state.hasPhotoPermission.value = true; // 如果权限被授予,更新状态变量 + }); } else { - // 如果权限尚未被授予,请求相机权限 - // 此处会显示系统权限请求对话框 - status = await Permission.photos.request(); - - if (status.isGranted) { - // 如果用户授予了相机权限,执行您的相机操作 - selectImage(); - } else { - // 如果用户拒绝了相机权限,您可以提供适当的提示 - // 或者引导用户手动授予权限 - showPermissionDeniedDialog(); - } + // 如果权限被拒绝,你可以选择在这里处理相应逻辑,比如显示一个提示框 + showPermissionDeniedDialog(); } } + // Future requestPhotoPermission() async { + // var status = await Permission.photos.status; + // if (status.isGranted) { + // selectImage(); + // } else { + // status = await Permission.photos.request(); + // if (status.isGranted) { + // selectImage(); + // } else { + // showPermissionDeniedDialog(); + // } + // } + // } + // 显示权限被永久拒绝的提示对话框 void showPermissionDeniedDialog() { showDialog( @@ -236,8 +260,8 @@ class _MinePersonInfoPageState extends State { TextButton( child: const Text('去设置'), onPressed: () { - openAppSettings(); // 打开系统设置页面 Navigator.of(context).pop(); // 关闭对话框 + openAppSettings(); // 打开系统设置页面 }, ), ], @@ -259,11 +283,13 @@ class _MinePersonInfoPageState extends State { int getSelectIndex = value; if (getSelectIndex == 0) { //拍照选项 - // selectCamera(); - requestCameraPermission(); + state.hasCameraPermission.value == true + ? selectCamera() + : _requestCameraPermission(); } else if (getSelectIndex == 1) { - // selectImage(); - requestPhotoPermission(); + state.hasPhotoPermission.value == true + ? selectImage() + : _requestPhotoPermission(); } }, ); @@ -300,23 +326,29 @@ class _MinePersonInfoPageState extends State { } } - // child: state.mineInfoData.value.headUrl != null - // ? CachedNetworkImage( - // imageUrl: Uri.encodeFull( - // state.mineInfoData.value.headUrl!), - // width: 72.w, - // height: 72.w, - // fit: BoxFit.fill, - // placeholder: (context, url) => Image.asset( - // 'images/controls_user.png', - // width: 72.w, - // height: 72.w, - // fit: BoxFit.fill, - // )) - // : Image.asset( - // 'images/controls_user.png', - // width: 72.w, - // height: 72.w, - // fit: BoxFit.fill, - // ), + Future _checkCameraPermission() async { + var status = await Permission.camera.status; + if (status.isGranted) { + setState(() { + state.hasCameraPermission.value = true; // 如果权限已经被授予,更新状态变量 + }); + } else { + setState(() { + state.hasCameraPermission.value = false; // 如果权限未被授予,更新状态变量 + }); + } + } + + Future _checkPhotoPermission() async { + var status = await Permission.photos.status; + if (status.isGranted) { + setState(() { + state.hasPhotoPermission.value = true; // 如果权限已经被授予,更新状态变量 + }); + } else { + setState(() { + state.hasPhotoPermission.value = false; // 如果权限未被授予,更新状态变量 + }); + } + } } diff --git a/star_lock/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_state.dart b/star_lock/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_state.dart index 4f4ac5b1..ac5e2f75 100644 --- a/star_lock/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_state.dart +++ b/star_lock/lib/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_state.dart @@ -12,4 +12,7 @@ class MinePersonInfoState { List? imageList; // 使用ImagePicker前必须先实例化 final ImagePicker imagePicker = ImagePicker(); + + var hasPhotoPermission = false.obs; //是否有相册权限 + var hasCameraPermission = false.obs; //是否有相机权限 } diff --git a/star_lock/lib/talk/udp/udp_talkClass.dart b/star_lock/lib/talk/udp/udp_talkClass.dart index 8740a9e3..8113bf71 100644 --- a/star_lock/lib/talk/udp/udp_talkClass.dart +++ b/star_lock/lib/talk/udp/udp_talkClass.dart @@ -2,6 +2,8 @@ import 'dart:async'; import 'package:audioplayers/audioplayers.dart'; import 'package:fast_gbk/fast_gbk.dart'; import 'package:get/get.dart'; +import 'package:star_lock/main/lockDetail/monitoring/monitoring/lockMonitoring_logic.dart'; +import 'package:star_lock/talk/call/callTalk.dart'; import '../../appRouters.dart'; import '../../tools/storage.dart'; import 'udp_manage.dart'; @@ -68,6 +70,10 @@ class UDPTalkClass { Get.toNamed(Routers.lockMonitoringPage, arguments: {"lockId": "111"}); } + Timer(const Duration(minutes: 1), () { + stopLocalAudio(); + callNoAnswer(); + }); playLocalAudio(); } else { @@ -127,4 +133,13 @@ class UDPTalkClass { audioPlayer.setReleaseMode(ReleaseMode.loop); await audioPlayer.stop(); } + + //呼叫有响铃无应答处理 + void callNoAnswer() { + CallTalk().stopPcmSound(); + // 挂断 + LockMonitoringLogic().udpHangUpAction(); + // 关闭当前界面 + Get.back(); + } } diff --git a/star_lock/lib/tools/xs_aliyunPush.dart b/star_lock/lib/tools/xs_aliyunPush.dart deleted file mode 100644 index 4a922ebb..00000000 --- a/star_lock/lib/tools/xs_aliyunPush.dart +++ /dev/null @@ -1,137 +0,0 @@ -/* -import 'dart:io'; - -import 'package:aliyun_push/aliyun_push.dart'; -import 'package:star_lock/flavors.dart'; -import 'package:star_lock/network/api_repository.dart'; -import 'package:star_lock/tools/baseGetXController.dart'; - -class XSAliyunPushProvider { - late AliyunPush _aliyunPush = AliyunPush(); - - Future init(AliyunPush aliyunPush) async { - _aliyunPush = aliyunPush; - if (Platform.isAndroid) { - _aliyunPush.createAndroidChannel('1', '测试通道A', 3, '测试创建通知通道'); - _aliyunPush.setAndroidLogLevel(kAliyunPushLogLevelError); - } - _addPushCallback(); - } - - Future _onNotification(Map message) async { - // print('onNotification: $message'); - } - - Future _onAndroidNotificationReceivedInApp( - Map message) async { - // print('onAndroidNotificationReceivedInApp: $message'); - } - - Future _onMessage(Map message) async { - // print('onMessage: $message'); - } - - Future _onNotificationOpened(Map message) async { - // print('onNotificationOpened: $message'); - } - - Future _onNotificationRemoved(Map message) async { - // print('onNotificationRemoved: $message'); - } - - Future _onAndroidNotificationClickedWithNoAction( - Map message) async { - // print('onAndroidNotificationClickedWithNoAction: $message'); - } - - Future _onIOSChannelOpened(Map message) async {} - - Future _onIOSRegisterDeviceTokenSuccess( - Map message) async { - // Toast.show(msg: 'APNs注册成功, $message'); - } - - Future _onIOSRegisterDeviceTokenFailed( - Map message) async { - // Toast.show(msg: '注册APNs失败, errorMsg: $message'); - } - - _addPushCallback() { - _aliyunPush.addMessageReceiver( - onNotification: _onNotification, - onNotificationOpened: _onNotificationOpened, - onNotificationRemoved: _onNotificationRemoved, - onMessage: _onMessage, - onAndroidNotificationReceivedInApp: _onAndroidNotificationReceivedInApp, - onAndroidNotificationClickedWithNoAction: - _onAndroidNotificationClickedWithNoAction, - onIOSChannelOpened: _onIOSChannelOpened, - onIOSRegisterDeviceTokenSuccess: _onIOSRegisterDeviceTokenSuccess, - onIOSRegisterDeviceTokenFailed: _onIOSRegisterDeviceTokenFailed); - } - - Future initAliyunPush() async { - String appKey; - String appSecret; - - if (Platform.isIOS) { - if (F.appFlavor == Flavor.sky) { - appKey = "334068745"; - appSecret = "bee9c200835e4951a85dc8709c319560"; - } else { - appKey = "333904046"; - appSecret = "3eead09a7fc7416cb4082319aa6f48c6"; - } - } else { - if (F.appFlavor == Flavor.sky) { - appKey = "334068743"; - appSecret = "64de537f14984159a66ada10e54c6b63"; - } else { - appKey = "333904040"; - appSecret = "c316965fe0a74fc9a481a5c44a535dc2"; - } - } - - _aliyunPush - .initPush(appKey: appKey, appSecret: appSecret) - .then((initResult) { - var code = initResult['code']; - if (code == kAliyunPushSuccessCode) { - // Toast.show(msg: "初始化推送成功"); - } else { - String errorMsg = initResult['errorMsg']; - // print('初始化推送失败,原因为:$errorMsg'); - // Toast.show(msg: '初始化推送失败, errorMsg: $errorMsg.}'); - } - }); - - // If the widget was removed from the tree while the asynchronous platform - // message was in flight, we want to discard the reply rather than calling - // setState to update our non-existent appearance. - } - - Future initAliyunThirdPush() async { - // Platform messages may fail, so we use a try/catch PlatformException. - // We also handle the message potentially returning null. - _aliyunPush.initAndroidThirdPush().then((initResult) { - var code = initResult['code']; - if (code == kAliyunPushSuccessCode) { - // Toast.show(msg: "初始化辅助通道成功"); - } else { - String errorMsg = initResult['errorMsg']; - // Toast.show(msg: '初始化辅助通道成功, errorMsg: $errorMsg'); - // print("初始化辅助通道失败,原因为:$errorMsg"); - } - }); - - // If the widget was removed from the tree while the asynchronous platform - // message was in flight, we want to discard the reply rather than calling - // setState to update our non-existent appearance. - } - - void pushBindDeviceID(String deviceID, int deviceType) async { - var entity = await ApiRepository.to.pushBindAppId(deviceID, deviceType); - if (entity.errorCode!.codeIsSuccessful) {} - } -} -*/ \ No newline at end of file diff --git a/star_lock/lib/tools/xs_jPhush.dart b/star_lock/lib/tools/xs_jPhush.dart new file mode 100644 index 00000000..edd217dc --- /dev/null +++ b/star_lock/lib/tools/xs_jPhush.dart @@ -0,0 +1,53 @@ +import 'dart:io'; + +import 'package:jpush_flutter/jpush_flutter.dart'; +import 'package:star_lock/network/api_repository.dart'; +import 'package:star_lock/tools/baseGetXController.dart'; +import 'package:star_lock/tools/storage.dart'; + +class XSJPushProvider { + final JPush jpush = JPush(); + + Future initJPushService() async { + final data = await Storage.getString(saveUserLoginData); + if (data != null && data.isNotEmpty) { + jpush.setup( + appKey: "7ff37d174c1a568a89e98dad", + channel: "flutter_channel", + production: false, + debug: true, + ); + + jpush.addEventHandler( + // 接收通知回调方法。 + onReceiveNotification: (Map message) async { + print("flutter onReceiveNotification: $message"); + }, + // 点击通知回调方法。 + onOpenNotification: (Map message) async { + print("flutter onOpenNotification: $message"); + }, + // 接收自定义消息回调方法。 + onReceiveMessage: (Map message) async { + print("flutter onReceiveMessage: $message"); + }, + ); + + jpush.applyPushAuthority( + const NotificationSettingsIOS(sound: true, alert: true, badge: true)); + // jpush.setChannelAndSound( + // channel: "flutter_channel", channelID: "115700", sound: "default"); + + // Platform messages may fail, so we use a try/catch PlatformException. + jpush.getRegistrationID().then((rid) { + print("flutter get registration id : $rid"); + pushBindDeviceID(rid, Platform.isAndroid ? 10 : 20); + }); + } + } + + void pushBindDeviceID(String deviceID, int deviceType) async { + var entity = await ApiRepository.to.pushBindAppId(deviceID, deviceType); + if (entity.errorCode!.codeIsSuccessful) {} + } +} diff --git a/star_lock/lib/versionUndate/versionUndateTool.dart b/star_lock/lib/versionUndate/versionUndateTool.dart index 9eafd463..5db662de 100644 --- a/star_lock/lib/versionUndate/versionUndateTool.dart +++ b/star_lock/lib/versionUndate/versionUndateTool.dart @@ -101,8 +101,8 @@ class VersionUndateTool { child: Text("下次再说"), onPressed: () { Navigator.pop(context); - Storage.setString( - isShowUpdateVersion, isShowUpdateVersion); + // Storage.setString( + // isShowUpdateVersion, isShowUpdateVersion); }, ), CupertinoDialogAction( diff --git a/star_lock/pubspec.yaml b/star_lock/pubspec.yaml index 71a10589..6c027ca9 100644 --- a/star_lock/pubspec.yaml +++ b/star_lock/pubspec.yaml @@ -18,8 +18,11 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. # 版本说明: -# 1.0.18+20240321:打包给欧阳测试 -version: 1.0.19+20240321 +# 1.0.18+2024032001:修复同意隐私政策前获取SN +# 1.0.18+2024032002:修复注册页布局错乱;修复第二次才可以删除锁的问题;修改申请权限字符串 +# 1.0.18+20240321(2024032101):打包给欧阳测试 +# 1.0.20+2024032102:修复Apple Store App Tracking Transparency权限问题 +version: 1.0.20+2024032102 environment: sdk: '>=2.12.0 <3.0.0'