添加高德地图、调试蓝牙协议、添加添加锁逻辑
This commit is contained in:
parent
1a659b5579
commit
10c8357fba
@ -5,11 +5,15 @@
|
|||||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />
|
||||||
<!-- <uses-permission android:name="android.permission.BLUETOOTH_SCAN"-->
|
|
||||||
<!-- tools:remove="android:usesPermissionFlags"-->
|
|
||||||
<!-- tools:targetApi="s" />-->
|
|
||||||
|
|
||||||
<application
|
<!--允许访问网络,必选权限-->
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<!--允许获取精确位置,精准定位必选-->
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<!--允许获取粗略位置,粗略定位必选-->
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
|
|
||||||
|
<application
|
||||||
android:label="star_lock"
|
android:label="star_lock"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
@ -40,5 +44,9 @@
|
|||||||
<meta-data
|
<meta-data
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
|
|
||||||
|
<!-- 配置定位Service -->
|
||||||
|
<service android:name="com.amap.api.location.APSService"/>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@ -191,6 +191,7 @@
|
|||||||
"lanChinese":"Chinese",
|
"lanChinese":"Chinese",
|
||||||
"multilingual":"Multilingual",
|
"multilingual":"Multilingual",
|
||||||
"addLock":"Add Lock",
|
"addLock":"Add Lock",
|
||||||
|
"lockAddress":"Lock Address",
|
||||||
"selectLockType":"Select lock type",
|
"selectLockType":"Select lock type",
|
||||||
"videoIntercomDoorLock":"Video intercom door lock",
|
"videoIntercomDoorLock":"Video intercom door lock",
|
||||||
"NFCPassiveLock":"NFC Passive Lock",
|
"NFCPassiveLock":"NFC Passive Lock",
|
||||||
|
|||||||
@ -191,6 +191,7 @@
|
|||||||
"lanChinese":"lanChinese",
|
"lanChinese":"lanChinese",
|
||||||
"multilingual":"multilingual",
|
"multilingual":"multilingual",
|
||||||
"addLock":"addLock",
|
"addLock":"addLock",
|
||||||
|
"lockAddress":"lockAddress",
|
||||||
"selectLockType":"selectLockType",
|
"selectLockType":"selectLockType",
|
||||||
"videoIntercomDoorLock":"videoIntercomDoorLock",
|
"videoIntercomDoorLock":"videoIntercomDoorLock",
|
||||||
"NFCPassiveLock":"NFCPassiveLock",
|
"NFCPassiveLock":"NFCPassiveLock",
|
||||||
|
|||||||
@ -191,6 +191,7 @@
|
|||||||
"lanChinese":"中文",
|
"lanChinese":"中文",
|
||||||
"multilingual":"多语言",
|
"multilingual":"多语言",
|
||||||
"addLock":"添加锁",
|
"addLock":"添加锁",
|
||||||
|
"lockAddress":"锁地址",
|
||||||
"selectLockType":"选择锁类型",
|
"selectLockType":"选择锁类型",
|
||||||
"videoIntercomDoorLock":"可视对讲门锁",
|
"videoIntercomDoorLock":"可视对讲门锁",
|
||||||
"NFCPassiveLock":"NFC无源锁",
|
"NFCPassiveLock":"NFC无源锁",
|
||||||
|
|||||||
BIN
star_lock/images/main/icon_addUserAddressShowTime.png
Normal file
BIN
star_lock/images/main/icon_addUserAddressShowTime.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
BIN
star_lock/images/main/icon_addUserShowAddress.png
Normal file
BIN
star_lock/images/main/icon_addUserShowAddress.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
@ -1,6 +1,17 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- aj_captcha_flutter (0.0.1):
|
- aj_captcha_flutter (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- AMap3DMap (9.7.0):
|
||||||
|
- AMapFoundation (>= 1.8.0)
|
||||||
|
- amap_flutter_location (0.0.1):
|
||||||
|
- AMapLocation
|
||||||
|
- Flutter
|
||||||
|
- amap_flutter_map (0.0.1):
|
||||||
|
- AMap3DMap
|
||||||
|
- Flutter
|
||||||
|
- AMapFoundation (1.8.2)
|
||||||
|
- AMapLocation (2.10.0):
|
||||||
|
- AMapFoundation (>= 1.8.0)
|
||||||
- device_info_plus (0.0.1):
|
- device_info_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
@ -16,6 +27,8 @@ PODS:
|
|||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- permission_handler_apple (9.1.1):
|
||||||
|
- Flutter
|
||||||
- Protobuf (3.23.4)
|
- Protobuf (3.23.4)
|
||||||
- reactive_ble_mobile (0.0.1):
|
- reactive_ble_mobile (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
@ -31,6 +44,8 @@ PODS:
|
|||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- aj_captcha_flutter (from `.symlinks/plugins/aj_captcha_flutter/ios`)
|
- aj_captcha_flutter (from `.symlinks/plugins/aj_captcha_flutter/ios`)
|
||||||
|
- amap_flutter_location (from `.symlinks/plugins/amap_flutter_location/ios`)
|
||||||
|
- amap_flutter_map (from `.symlinks/plugins/amap_flutter_map/ios`)
|
||||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- flutter_native_contact_picker (from `.symlinks/plugins/flutter_native_contact_picker/ios`)
|
- flutter_native_contact_picker (from `.symlinks/plugins/flutter_native_contact_picker/ios`)
|
||||||
@ -38,12 +53,16 @@ DEPENDENCIES:
|
|||||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
|
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||||
- reactive_ble_mobile (from `.symlinks/plugins/reactive_ble_mobile/ios`)
|
- reactive_ble_mobile (from `.symlinks/plugins/reactive_ble_mobile/ios`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
|
- AMap3DMap
|
||||||
|
- AMapFoundation
|
||||||
|
- AMapLocation
|
||||||
- Protobuf
|
- Protobuf
|
||||||
- SwiftProtobuf
|
- SwiftProtobuf
|
||||||
- Toast
|
- Toast
|
||||||
@ -51,6 +70,10 @@ SPEC REPOS:
|
|||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
aj_captcha_flutter:
|
aj_captcha_flutter:
|
||||||
:path: ".symlinks/plugins/aj_captcha_flutter/ios"
|
:path: ".symlinks/plugins/aj_captcha_flutter/ios"
|
||||||
|
amap_flutter_location:
|
||||||
|
:path: ".symlinks/plugins/amap_flutter_location/ios"
|
||||||
|
amap_flutter_map:
|
||||||
|
:path: ".symlinks/plugins/amap_flutter_map/ios"
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||||
Flutter:
|
Flutter:
|
||||||
@ -65,6 +88,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||||
|
permission_handler_apple:
|
||||||
|
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
||||||
reactive_ble_mobile:
|
reactive_ble_mobile:
|
||||||
:path: ".symlinks/plugins/reactive_ble_mobile/ios"
|
:path: ".symlinks/plugins/reactive_ble_mobile/ios"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
@ -74,6 +99,11 @@ EXTERNAL SOURCES:
|
|||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
aj_captcha_flutter: dd7af1aa064bdd621ae335b819bab07309c3c023
|
aj_captcha_flutter: dd7af1aa064bdd621ae335b819bab07309c3c023
|
||||||
|
AMap3DMap: dce25dd3e51e6b92109caa7d0c97fc6055830fb3
|
||||||
|
amap_flutter_location: 44ff5beb64f42e0bf5feb402fe299dac0013af6f
|
||||||
|
amap_flutter_map: 979e54d227cedac6c7504a2151bfbf3bcf96760a
|
||||||
|
AMapFoundation: 9885c48fc3a78fdfb84a0299a2293e56ea3c9fec
|
||||||
|
AMapLocation: 5248aec2455ebb5d104b367813c946430a2ee033
|
||||||
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
||||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||||
flutter_native_contact_picker: bd430ba0fbf82768bb50c2c52a69a65759a8f907
|
flutter_native_contact_picker: bd430ba0fbf82768bb50c2c52a69a65759a8f907
|
||||||
@ -81,6 +111,7 @@ SPEC CHECKSUMS:
|
|||||||
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
|
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
|
||||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||||
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
|
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
|
||||||
|
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
|
||||||
Protobuf: c6bc59bbab3d38a71c67f62d7cb7ca8f8ea4eca1
|
Protobuf: c6bc59bbab3d38a71c67f62d7cb7ca8f8ea4eca1
|
||||||
reactive_ble_mobile: 9ce6723d37ccf701dbffd202d487f23f5de03b4c
|
reactive_ble_mobile: 9ce6723d37ccf701dbffd202d487f23f5de03b4c
|
||||||
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
|
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
09D8B2FA2B26BA5BFF31AB2A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
09D8B2FA2B26BA5BFF31AB2A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||||
|
33BF41252A96174D009D92E2 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||||
@ -114,6 +115,7 @@
|
|||||||
97C146F01CF9000F007C117D /* Runner */ = {
|
97C146F01CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
33BF41252A96174D009D92E2 /* Runner.entitlements */,
|
||||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
|
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
|
||||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
|
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
|
||||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||||
@ -149,6 +151,7 @@
|
|||||||
97C146EC1CF9000F007C117D /* Resources */,
|
97C146EC1CF9000F007C117D /* Resources */,
|
||||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
|
D9B107A6B141D5F15BC356F2 /* [CP] Copy Pods Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@ -259,6 +262,23 @@
|
|||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||||
};
|
};
|
||||||
|
D9B107A6B141D5F15BC356F2 /* [CP] Copy Pods Resources */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
name = "[CP] Copy Pods Resources";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
@ -351,6 +371,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = YES;
|
ALWAYS_SEARCH_USER_PATHS = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
@ -478,6 +499,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = YES;
|
ALWAYS_SEARCH_USER_PATHS = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
@ -498,6 +520,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = YES;
|
ALWAYS_SEARCH_USER_PATHS = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
|
|||||||
@ -24,6 +24,11 @@
|
|||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSBluetoothAlwaysUsageDescription</key>
|
<key>NSBluetoothAlwaysUsageDescription</key>
|
||||||
@ -38,6 +43,12 @@
|
|||||||
<string>用于音频插件</string>
|
<string>用于音频插件</string>
|
||||||
<key>NSPhotoLibraryUsageDescription</key>
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
<string>用于相册</string>
|
<string>用于相册</string>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string>应用在前台的时候可以搜到更新的位置信息</string>
|
||||||
|
<key>NSLocationAlwaysUsageDescription</key>
|
||||||
|
<string>应用在后台的时候可以搜到更新的位置信息</string>
|
||||||
|
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||||
|
<string>应用在前台和后台的时候可以搜到更新的位置信息</string>
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>UIBackgroundModes</key>
|
<key>UIBackgroundModes</key>
|
||||||
|
|||||||
5
star_lock/ios/Runner/Runner.entitlements
Normal file
5
star_lock/ios/Runner/Runner.entitlements
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict/>
|
||||||
|
</plist>
|
||||||
@ -95,6 +95,10 @@ class BlueManage{
|
|||||||
print("connectDeviceId:$connectDeviceId connectDeviceName:$connectDeviceName");
|
print("connectDeviceId:$connectDeviceId connectDeviceName:$connectDeviceName");
|
||||||
|
|
||||||
EasyLoading.show();
|
EasyLoading.show();
|
||||||
|
Future.delayed(const Duration(seconds: 30), () { //asynchronous delay
|
||||||
|
print("30s之后 菊花没有隐藏的话,强制隐藏菊花");
|
||||||
|
EasyLoading.dismiss();
|
||||||
|
});
|
||||||
_flutterReactiveBle!.connectToDevice(id: connectDeviceId, connectionTimeout: const Duration(seconds: 15)).listen((connectionStateUpdate) async {
|
_flutterReactiveBle!.connectToDevice(id: connectDeviceId, connectionTimeout: const Duration(seconds: 15)).listen((connectionStateUpdate) async {
|
||||||
// 获取状态
|
// 获取状态
|
||||||
deviceConnectionState = connectionStateUpdate.connectionState;
|
deviceConnectionState = connectionStateUpdate.connectionState;
|
||||||
@ -174,6 +178,10 @@ class BlueManage{
|
|||||||
Future<void> judgeReconnect(String deviceMAC, String deviceName, ConnectStateCallBack? connectStateCallBack) async {
|
Future<void> judgeReconnect(String deviceMAC, String deviceName, ConnectStateCallBack? connectStateCallBack) async {
|
||||||
if(deviceConnectionState == DeviceConnectionState.connected){
|
if(deviceConnectionState == DeviceConnectionState.connected){
|
||||||
EasyLoading.show();
|
EasyLoading.show();
|
||||||
|
Future.delayed(const Duration(seconds: 30), () { //asynchronous delay
|
||||||
|
print("30s之后 菊花没有隐藏的话,强制隐藏菊花");
|
||||||
|
EasyLoading.dismiss();
|
||||||
|
});
|
||||||
connectStateCallBack!(deviceConnectionState!);
|
connectStateCallBack!(deviceConnectionState!);
|
||||||
}else{
|
}else{
|
||||||
connect(deviceMAC, deviceName, connectStateCallBack: (state){
|
connect(deviceMAC, deviceName, connectStateCallBack: (state){
|
||||||
|
|||||||
105
star_lock/lib/blue/io_protocol/io_factoryDataReset.dart
Normal file
105
star_lock/lib/blue/io_protocol/io_factoryDataReset.dart
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
|
||||||
|
//TODO:添加用户
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import '../../tools/storage.dart';
|
||||||
|
import '../blue_manage.dart';
|
||||||
|
import '../io_tool/io_manager.dart';
|
||||||
|
import '../io_tool/io_tool.dart';
|
||||||
|
import '../sender_manage.dart';
|
||||||
|
import '../sm4Encipher/sm4.dart';
|
||||||
|
import 'io_reply.dart';
|
||||||
|
import 'io_sender.dart';
|
||||||
|
import 'io_type.dart';
|
||||||
|
import 'package:crypto/crypto.dart' as crypto;
|
||||||
|
|
||||||
|
class FactoryDataResetCommand extends SenderProtocol {
|
||||||
|
|
||||||
|
String? lockID;
|
||||||
|
String? userID;
|
||||||
|
String? keyID;
|
||||||
|
List<int>? publicKey;
|
||||||
|
List<int>? privateKey;
|
||||||
|
List<int>? token;
|
||||||
|
int? needAuthor;
|
||||||
|
FactoryDataResetCommand({
|
||||||
|
this.lockID,
|
||||||
|
this.userID,
|
||||||
|
this.keyID,
|
||||||
|
this.token,
|
||||||
|
this.needAuthor,
|
||||||
|
this.publicKey,
|
||||||
|
this.privateKey,
|
||||||
|
}) : super(CommandType.factoryDataReset);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<int> messageDetail() {
|
||||||
|
List<int> data = [];
|
||||||
|
List<int> ebcData = [];
|
||||||
|
|
||||||
|
// 指令类型
|
||||||
|
int type = commandType!.typeValue;
|
||||||
|
double typeDouble = type / 256;
|
||||||
|
int type1 = typeDouble.toInt();
|
||||||
|
int type2 = type % 256;
|
||||||
|
data.add(type1);
|
||||||
|
data.add(type2);
|
||||||
|
|
||||||
|
// 锁id 40
|
||||||
|
int lockIDLength = utf8.encode(lockID!).length;
|
||||||
|
// print("${commandType!.typeValue}LockIDLength:$lockIDLength utf8.encode(lockID!)${utf8.encode(lockID!)}");
|
||||||
|
data.addAll(utf8.encode(lockID!));
|
||||||
|
data = getFixedLengthList(data, 40 - lockIDLength);
|
||||||
|
|
||||||
|
//userID 20
|
||||||
|
int userIDLength = utf8.encode(userID!).length;
|
||||||
|
// print("${commandType!.typeValue}IDLength:$authUserIDLength utf8.encode(authUserID!)${utf8.encode(authUserID!)}");
|
||||||
|
data.addAll(utf8.encode(userID!));
|
||||||
|
data = getFixedLengthList(data, 20 - userIDLength);
|
||||||
|
|
||||||
|
// token 长度4 首次请求 Token 填 0,如果锁需要鉴权 操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 当token失效或者第一次发送的时候token为0
|
||||||
|
data.addAll(token!);
|
||||||
|
print("恢复出厂设置、pubToken:$token");
|
||||||
|
|
||||||
|
if(needAuthor == 0){
|
||||||
|
//AuthCodeLen 1
|
||||||
|
data.add(0);
|
||||||
|
} else {
|
||||||
|
List<int> authCodeData = [];
|
||||||
|
|
||||||
|
//userID
|
||||||
|
authCodeData.addAll(utf8.encode(lockID!));
|
||||||
|
|
||||||
|
//token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。
|
||||||
|
authCodeData.addAll(token!);
|
||||||
|
|
||||||
|
authCodeData.addAll(publicKey!);
|
||||||
|
|
||||||
|
print("${commandType!.typeValue}-authCodeData:$authCodeData");
|
||||||
|
|
||||||
|
// 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode
|
||||||
|
var authCode = crypto.md5.convert(authCodeData);
|
||||||
|
|
||||||
|
data.add(authCode.bytes.length);
|
||||||
|
data.addAll(authCode.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data.length % 16) != 0) {
|
||||||
|
int add = (16 - data.length % 16);
|
||||||
|
for (int i = 0; i < add; i++) {
|
||||||
|
data.add(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print("${commandType!.typeName} SM4Data:$data");
|
||||||
|
// 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
|
||||||
|
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
|
||||||
|
return ebcData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FactoryDataResetReply extends Reply {
|
||||||
|
FactoryDataResetReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||||
|
: super.parseData(commandType, dataDetail) {
|
||||||
|
data = dataDetail;
|
||||||
|
}
|
||||||
|
}
|
||||||
125
star_lock/lib/blue/io_protocol/io_transferPermissions.dart
Normal file
125
star_lock/lib/blue/io_protocol/io_transferPermissions.dart
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import '../io_tool/io_tool.dart';
|
||||||
|
import '../sm4Encipher/sm4.dart';
|
||||||
|
import 'io_reply.dart';
|
||||||
|
import 'io_sender.dart';
|
||||||
|
import 'io_type.dart';
|
||||||
|
import 'package:crypto/crypto.dart' as crypto;
|
||||||
|
|
||||||
|
//TODO:转移权限
|
||||||
|
class TransferPermissionsCommand extends SenderProtocol {
|
||||||
|
|
||||||
|
String? lockID;
|
||||||
|
String? authUserID;
|
||||||
|
String? keyID;
|
||||||
|
String? oldUserID;
|
||||||
|
String? newUserID;
|
||||||
|
int? needAuthor;
|
||||||
|
List<int>? publicKey;
|
||||||
|
List<int>? privateKey;
|
||||||
|
List<int>? token;
|
||||||
|
TransferPermissionsCommand({
|
||||||
|
this.lockID,
|
||||||
|
this.authUserID,
|
||||||
|
this.keyID,
|
||||||
|
this.oldUserID,
|
||||||
|
this.newUserID,
|
||||||
|
this.needAuthor,
|
||||||
|
this.publicKey,
|
||||||
|
this.privateKey,
|
||||||
|
this.token
|
||||||
|
}) : super(CommandType.transferPermissions);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<int> messageDetail() {
|
||||||
|
List<int> data = [];
|
||||||
|
List<int> ebcData = [];
|
||||||
|
|
||||||
|
// 指令类型
|
||||||
|
int type = commandType!.typeValue;
|
||||||
|
double typeDouble = type / 256;
|
||||||
|
int type1 = typeDouble.toInt();
|
||||||
|
int type2 = type % 256;
|
||||||
|
data.add(type1);
|
||||||
|
data.add(type2);
|
||||||
|
|
||||||
|
// 锁id 40
|
||||||
|
int lockIDLength = utf8.encode(lockID!).length;
|
||||||
|
print("${commandType!.typeValue} lockID:$lockID LockIDLength:$lockIDLength utf8.encode(lockID!)${utf8.encode(lockID!)}");
|
||||||
|
data.addAll(utf8.encode(lockID!));
|
||||||
|
data = getFixedLengthList(data, 40 - lockIDLength);
|
||||||
|
|
||||||
|
//authUserID 20
|
||||||
|
int authUserIDLength = utf8.encode(authUserID!).length;
|
||||||
|
// print("${commandType!.typeValue}IDLength:$authUserIDLength utf8.encode(authUserID!)${utf8.encode(authUserID!)}");
|
||||||
|
data.addAll(utf8.encode(authUserID!));
|
||||||
|
data = getFixedLengthList(data, 20 - authUserIDLength);
|
||||||
|
|
||||||
|
//KeyID 40
|
||||||
|
int keyIDLength = utf8.encode(keyID!).length;
|
||||||
|
// print("${commandType!.typeValue}keyIDLength:$keyIDLength utf8.encode(keyID!)${utf8.encode(keyID!)}");
|
||||||
|
data.addAll(utf8.encode(keyID!));
|
||||||
|
data = getFixedLengthList(data, 40 - keyIDLength);
|
||||||
|
|
||||||
|
//oldUserID 20
|
||||||
|
int oldUserIDLength = utf8.encode(oldUserID!).length;
|
||||||
|
// print("${commandType!.typeValue}userIDLength:$userIDLength utf8.encode(userID!)${utf8.encode(userID!)}");
|
||||||
|
data.addAll(utf8.encode(oldUserID!));
|
||||||
|
data = getFixedLengthList(data, 20 - oldUserIDLength);
|
||||||
|
|
||||||
|
//newUserID 20
|
||||||
|
int newUserIDLength = utf8.encode(newUserID!).length;
|
||||||
|
// print("${commandType!.typeValue}userIDLength:$userIDLength utf8.encode(userID!)${utf8.encode(userID!)}");
|
||||||
|
data.addAll(utf8.encode(newUserID!));
|
||||||
|
data = getFixedLengthList(data, 20 - newUserIDLength);
|
||||||
|
|
||||||
|
// token 长度4 首次请求 Token 填 0,如果锁需要鉴权 操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 当token失效或者第一次发送的时候token为0
|
||||||
|
data.addAll(token!);
|
||||||
|
print("pubToken:$token");
|
||||||
|
|
||||||
|
if(needAuthor == 0){
|
||||||
|
//AuthCodeLen 1
|
||||||
|
data.add(0);
|
||||||
|
} else {
|
||||||
|
List<int> authCodeData = [];
|
||||||
|
|
||||||
|
//authUserID
|
||||||
|
authCodeData.addAll(utf8.encode(authUserID!));
|
||||||
|
|
||||||
|
//KeyID
|
||||||
|
authCodeData.addAll(utf8.encode(keyID!));
|
||||||
|
|
||||||
|
//token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。
|
||||||
|
authCodeData.addAll(token!);
|
||||||
|
|
||||||
|
authCodeData.addAll(publicKey!);
|
||||||
|
|
||||||
|
print("${commandType!.typeValue}-authCodeData:$authCodeData");
|
||||||
|
|
||||||
|
// 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode
|
||||||
|
var authCode = crypto.md5.convert(authCodeData);
|
||||||
|
|
||||||
|
data.add(authCode.bytes.length);
|
||||||
|
data.addAll(authCode.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data.length % 16) != 0) {
|
||||||
|
int add = (16 - data.length % 16);
|
||||||
|
for (int i = 0; i < add; i++) {
|
||||||
|
data.add(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print("${commandType!.typeName} SM4Data:$data");
|
||||||
|
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
|
||||||
|
return ebcData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TransferPermissionsReply extends Reply {
|
||||||
|
TransferPermissionsReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||||
|
: super.parseData(commandType, dataDetail) {
|
||||||
|
data = dataDetail;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,8 @@ const saveBluePublicKey = "BluePublicKey";
|
|||||||
const saveBluePrivateKey = "BluePrivateKey";
|
const saveBluePrivateKey = "BluePrivateKey";
|
||||||
const saveBlueSignKey = "BlueSignKey";
|
const saveBlueSignKey = "BlueSignKey";
|
||||||
const saveBlueToken = "BlueGetToken";
|
const saveBlueToken = "BlueGetToken";
|
||||||
|
const currentConnectionLockId = "CurrentConnectionLockId";
|
||||||
|
const currentConnectionMacAddress = "CurrentConnectionMacAddress";
|
||||||
|
|
||||||
class IoManager {
|
class IoManager {
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,9 @@ import 'package:flutter_easyloading/flutter_easyloading.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_deletUser.dart';
|
import 'package:star_lock/blue/io_protocol/io_deletUser.dart';
|
||||||
import 'package:star_lock/blue/io_protocol/io_editUser.dart';
|
import 'package:star_lock/blue/io_protocol/io_editUser.dart';
|
||||||
|
import 'package:star_lock/blue/io_protocol/io_factoryDataReset.dart';
|
||||||
import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
|
import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
|
||||||
|
import 'package:star_lock/blue/io_protocol/io_transferPermissions.dart';
|
||||||
|
|
||||||
import '../tools/storage.dart';
|
import '../tools/storage.dart';
|
||||||
import 'io_protocol/io_addUser.dart';
|
import 'io_protocol/io_addUser.dart';
|
||||||
@ -73,10 +75,9 @@ class CommandReciverManager {
|
|||||||
// print("getPrivateKeyList$getPrivateKeyList");
|
// print("getPrivateKeyList$getPrivateKeyList");
|
||||||
|
|
||||||
// 解密
|
// 解密
|
||||||
// String key = SM4.createHexKey(key: radixHex16String(getPrivateKeyList!));
|
|
||||||
oriDataList = SM4.decrypt(getDataList, key: getPrivateKeyList, mode: SM4CryptoMode.ECB);
|
oriDataList = SM4.decrypt(getDataList, key: getPrivateKeyList, mode: SM4CryptoMode.ECB);
|
||||||
oriDataList = oriDataList.sublist(0, oriLen);
|
oriDataList = oriDataList.sublist(0, oriLen);
|
||||||
// print("SM4 oriDataList:$oriDataList");
|
print("SM4 oriDataList:$oriDataList");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -132,6 +133,16 @@ class CommandReciverManager {
|
|||||||
reply = EditUserReply.parseData(commandType, data);
|
reply = EditUserReply.parseData(commandType, data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CommandType.transferPermissions:
|
||||||
|
{
|
||||||
|
reply = TransferPermissionsReply.parseData(commandType, data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CommandType.factoryDataReset:
|
||||||
|
{
|
||||||
|
reply = FactoryDataResetReply.parseData(commandType, data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,9 +4,11 @@ import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
|
|||||||
|
|
||||||
import 'io_protocol/io_addUser.dart';
|
import 'io_protocol/io_addUser.dart';
|
||||||
import 'io_protocol/io_editUser.dart';
|
import 'io_protocol/io_editUser.dart';
|
||||||
|
import 'io_protocol/io_factoryDataReset.dart';
|
||||||
import 'io_protocol/io_getPrivateKey.dart';
|
import 'io_protocol/io_getPrivateKey.dart';
|
||||||
import 'io_protocol/io_getPublicKey.dart';
|
import 'io_protocol/io_getPublicKey.dart';
|
||||||
import 'io_protocol/io_openLock.dart';
|
import 'io_protocol/io_openLock.dart';
|
||||||
|
import 'io_protocol/io_transferPermissions.dart';
|
||||||
import 'sender_data.dart';
|
import 'sender_data.dart';
|
||||||
|
|
||||||
class IoSenderManage {
|
class IoSenderManage {
|
||||||
@ -170,4 +172,53 @@ class IoSenderManage {
|
|||||||
privateKey: privateKey,
|
privateKey: privateKey,
|
||||||
), callBack:callBack);
|
), callBack:callBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo:转移权限
|
||||||
|
static void senderTransferPermissions({
|
||||||
|
String? lockID,
|
||||||
|
String? authUserID,
|
||||||
|
String? keyID,
|
||||||
|
String? oldUserID,
|
||||||
|
String? newUserID,
|
||||||
|
int? needAuthor,
|
||||||
|
List<int>? publicKey,
|
||||||
|
List<int>? privateKey,
|
||||||
|
List<int>? token,
|
||||||
|
CommandSendCallBack? callBack}) {
|
||||||
|
CommandSenderManager().managerSendData(
|
||||||
|
command: TransferPermissionsCommand(
|
||||||
|
lockID: lockID,
|
||||||
|
authUserID: authUserID,
|
||||||
|
keyID: keyID,
|
||||||
|
oldUserID: oldUserID,
|
||||||
|
newUserID: newUserID,
|
||||||
|
needAuthor: needAuthor,
|
||||||
|
publicKey: publicKey,
|
||||||
|
privateKey: privateKey,
|
||||||
|
token: token
|
||||||
|
), callBack:callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo:恢复出厂设置
|
||||||
|
static void senderFactoryDataReset({
|
||||||
|
String? lockID,
|
||||||
|
String? userID,
|
||||||
|
String? keyID,
|
||||||
|
List<int>? publicKey,
|
||||||
|
List<int>? privateKey,
|
||||||
|
List<int>? token,
|
||||||
|
int? needAuthor,
|
||||||
|
CommandSendCallBack? callBack}) {
|
||||||
|
CommandSenderManager().managerSendData(
|
||||||
|
command: FactoryDataResetCommand(
|
||||||
|
lockID: lockID,
|
||||||
|
userID: userID,
|
||||||
|
keyID: keyID,
|
||||||
|
needAuthor: needAuthor,
|
||||||
|
publicKey: publicKey,
|
||||||
|
privateKey: privateKey,
|
||||||
|
token: token
|
||||||
|
), callBack:callBack);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -31,7 +31,11 @@ class MyApp extends StatefulWidget {
|
|||||||
State<MyApp> createState() => _MyAppState();
|
State<MyApp> createState() => _MyAppState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 注册 RouteObserver 作为 navigation observer.
|
||||||
|
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
|
class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ScreenUtilInit(
|
return ScreenUtilInit(
|
||||||
@ -41,6 +45,7 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
|
|||||||
|
|
||||||
GetMaterialApp _initMaterialApp() => GetMaterialApp(
|
GetMaterialApp _initMaterialApp() => GetMaterialApp(
|
||||||
title: 'Star Lock',
|
title: 'Star Lock',
|
||||||
|
navigatorObservers: [routeObserver],
|
||||||
translations: TranslationMessage(),
|
translations: TranslationMessage(),
|
||||||
supportedLocales: appDept.deptSupportedLocales,
|
supportedLocales: appDept.deptSupportedLocales,
|
||||||
localizationsDelegates: const [
|
localizationsDelegates: const [
|
||||||
@ -134,4 +139,4 @@ Future _setCommonServices() async {
|
|||||||
await Get.putAsync(() => PlatformInfoService().init());
|
await Get.putAsync(() => PlatformInfoService().init());
|
||||||
await Get.putAsync(() => DeviceInfoService().init());
|
await Get.putAsync(() => DeviceInfoService().init());
|
||||||
Get.log(PlatformInfoService.to.info.version);
|
Get.log(PlatformInfoService.to.info.version);
|
||||||
}
|
}
|
||||||
@ -3,6 +3,7 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||||
import 'package:star_lock/blue/io_protocol/io_editUser.dart';
|
import 'package:star_lock/blue/io_protocol/io_editUser.dart';
|
||||||
|
import 'package:star_lock/blue/io_protocol/io_factoryDataReset.dart';
|
||||||
import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
|
import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
|
||||||
import 'package:star_lock/blue/io_protocol/io_type.dart';
|
import 'package:star_lock/blue/io_protocol/io_type.dart';
|
||||||
|
|
||||||
@ -10,7 +11,6 @@ import '../../../blue/blue_manage.dart';
|
|||||||
import '../../../blue/io_protocol/io_openLock.dart';
|
import '../../../blue/io_protocol/io_openLock.dart';
|
||||||
import '../../../blue/io_protocol/io_reply.dart';
|
import '../../../blue/io_protocol/io_reply.dart';
|
||||||
import '../../../blue/io_tool/io_manager.dart';
|
import '../../../blue/io_tool/io_manager.dart';
|
||||||
import '../../../blue/io_tool/io_model.dart';
|
|
||||||
import '../../../blue/io_tool/io_tool.dart';
|
import '../../../blue/io_tool/io_tool.dart';
|
||||||
import '../../../blue/io_tool/manager_event_bus.dart';
|
import '../../../blue/io_tool/manager_event_bus.dart';
|
||||||
import '../../../blue/sender_manage.dart';
|
import '../../../blue/sender_manage.dart';
|
||||||
@ -21,9 +21,11 @@ import 'lockDetail_state.dart';
|
|||||||
class LockDetailLogic extends BaseGetXController{
|
class LockDetailLogic extends BaseGetXController{
|
||||||
final LockDetailState state = LockDetailState();
|
final LockDetailState state = LockDetailState();
|
||||||
|
|
||||||
|
// 监听设备返回的数据
|
||||||
late StreamSubscription<Reply> _replySubscription;
|
late StreamSubscription<Reply> _replySubscription;
|
||||||
void _initReplySubscription() {
|
void _initReplySubscription() {
|
||||||
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) async {
|
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) async {
|
||||||
|
// 开门
|
||||||
if(reply is OpenDoorReply) {
|
if(reply is OpenDoorReply) {
|
||||||
_replyOpenLock(reply);
|
_replyOpenLock(reply);
|
||||||
}
|
}
|
||||||
@ -37,9 +39,15 @@ class LockDetailLogic extends BaseGetXController{
|
|||||||
if(reply is EditUserReply){
|
if(reply is EditUserReply){
|
||||||
_replyEditUserKey(reply);
|
_replyEditUserKey(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 恢复出厂设置
|
||||||
|
if(reply is FactoryDataResetReply){
|
||||||
|
_replyFactoryDataResetKey(reply);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 开门数据解析
|
||||||
Future<void> _replyOpenLock(Reply reply) async {
|
Future<void> _replyOpenLock(Reply reply) async {
|
||||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
@ -97,6 +105,7 @@ class LockDetailLogic extends BaseGetXController{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取锁状态数据解析
|
||||||
Future<void> _replyGetLockStatus(Reply reply) async {
|
Future<void> _replyGetLockStatus(Reply reply) async {
|
||||||
int status = reply.data[2];
|
int status = reply.data[2];
|
||||||
switch(status){
|
switch(status){
|
||||||
@ -169,6 +178,7 @@ class LockDetailLogic extends BaseGetXController{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 编辑用户数据解析
|
||||||
Future<void> _replyEditUserKey(Reply reply) async {
|
Future<void> _replyEditUserKey(Reply reply) async {
|
||||||
var token = reply.data.sublist(2, 6);
|
var token = reply.data.sublist(2, 6);
|
||||||
var saveStrList = changeIntListToStringList(token);
|
var saveStrList = changeIntListToStringList(token);
|
||||||
@ -217,7 +227,7 @@ class LockDetailLogic extends BaseGetXController{
|
|||||||
break;
|
break;
|
||||||
case 0x09:
|
case 0x09:
|
||||||
// 权限校验错误
|
// 权限校验错误
|
||||||
print("${reply.commandType!.typeValue} 添加用户权限校验错误");
|
print("${reply.commandType!.typeValue} 权限校验错误");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -228,6 +238,63 @@ class LockDetailLogic extends BaseGetXController{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 恢复出厂设置数据解析
|
||||||
|
Future<void> _replyFactoryDataResetKey(Reply reply) async {
|
||||||
|
var token = reply.data.sublist(2, 6);
|
||||||
|
var saveStrList = changeIntListToStringList(token);
|
||||||
|
print("_replyFactoryDataResetKeyToken:$token");
|
||||||
|
Storage.setStringList(saveBlueToken, saveStrList);
|
||||||
|
|
||||||
|
int status = reply.data[6];
|
||||||
|
print("status:$status");
|
||||||
|
|
||||||
|
switch(status){
|
||||||
|
case 0x00:
|
||||||
|
//成功
|
||||||
|
print("${reply.commandType!.typeValue} 数据解析成功");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0x06:
|
||||||
|
//无权限
|
||||||
|
print("${reply.commandType!.typeValue} 需要鉴权");
|
||||||
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
|
||||||
|
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||||
|
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||||
|
|
||||||
|
var token = await Storage.getStringList(saveBlueToken);
|
||||||
|
List<int> getTokenList = changeStringListToIntList(token!);
|
||||||
|
|
||||||
|
IoSenderManage.senderFactoryDataReset(
|
||||||
|
lockID:BlueManage().connectDeviceName,
|
||||||
|
userID:"100001",
|
||||||
|
keyID:"1",
|
||||||
|
needAuthor:1,
|
||||||
|
publicKey:publicKeyDataList,
|
||||||
|
privateKey:getPrivateKeyList,
|
||||||
|
token: getTokenList
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 0x07:
|
||||||
|
//无权限
|
||||||
|
print("${reply.commandType!.typeValue} 用户无权限");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0x09:
|
||||||
|
// 权限校验错误
|
||||||
|
print("${reply.commandType!.typeValue} 权限校验错误");
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//失败
|
||||||
|
print("${reply.commandType!.typeValue} 失败");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击开门事件
|
||||||
Future<void> openDoorAction() async {
|
Future<void> openDoorAction() async {
|
||||||
BlueManage().judgeReconnect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", (DeviceConnectionState state) async {
|
BlueManage().judgeReconnect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", (DeviceConnectionState state) async {
|
||||||
if (state == DeviceConnectionState.connected){
|
if (state == DeviceConnectionState.connected){
|
||||||
@ -255,6 +322,7 @@ class LockDetailLogic extends BaseGetXController{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 编辑用户事件
|
||||||
Future<void> editLockUserAction() async {
|
Future<void> editLockUserAction() async {
|
||||||
BlueManage().judgeReconnect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", (DeviceConnectionState state) async {
|
BlueManage().judgeReconnect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", (DeviceConnectionState state) async {
|
||||||
if (state == DeviceConnectionState.connected){
|
if (state == DeviceConnectionState.connected){
|
||||||
@ -289,19 +357,75 @@ class LockDetailLogic extends BaseGetXController{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 转移权限
|
||||||
|
Future<void> transferPermissionsAction() async {
|
||||||
|
BlueManage().judgeReconnect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", (DeviceConnectionState state) async {
|
||||||
|
if (state == DeviceConnectionState.connected){
|
||||||
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
|
||||||
|
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||||
|
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||||
|
|
||||||
|
var token = await Storage.getStringList(saveBlueToken);
|
||||||
|
List<int> getTokenList = changeStringListToIntList(token!);
|
||||||
|
print("openDoorTokenPubToken:$getTokenList");
|
||||||
|
|
||||||
|
IoSenderManage.senderTransferPermissions(
|
||||||
|
lockID:BlueManage().connectDeviceName,
|
||||||
|
authUserID:"100001",
|
||||||
|
keyID:"1",
|
||||||
|
oldUserID:"100001",
|
||||||
|
newUserID:"100002",
|
||||||
|
needAuthor:1,
|
||||||
|
publicKey:publicKeyDataList,
|
||||||
|
privateKey:getPrivateKeyList,
|
||||||
|
token: getTokenList
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复出厂设置
|
||||||
|
Future<void> factoryDataResetAction() async {
|
||||||
|
BlueManage().judgeReconnect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", (DeviceConnectionState state) async {
|
||||||
|
if (state == DeviceConnectionState.connected){
|
||||||
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
|
||||||
|
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||||
|
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||||
|
|
||||||
|
var token = await Storage.getStringList(saveBlueToken);
|
||||||
|
List<int> getTokenList = changeStringListToIntList(token!);
|
||||||
|
|
||||||
|
IoSenderManage.senderFactoryDataReset(
|
||||||
|
lockID:BlueManage().connectDeviceName,
|
||||||
|
userID:"100001",
|
||||||
|
keyID:"1",
|
||||||
|
needAuthor:1,
|
||||||
|
publicKey:publicKeyDataList,
|
||||||
|
privateKey:getPrivateKeyList,
|
||||||
|
token: getTokenList
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 备用逻辑,进入管理钥匙界面默认连接
|
||||||
Future<void> connectBlue() async {
|
Future<void> connectBlue() async {
|
||||||
// 进来之后首先连接
|
// 进来之后首先连接
|
||||||
// BlueManage().connect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", connectStateCallBack: (DeviceConnectionState state) async {
|
BlueManage().connect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", connectStateCallBack: (DeviceConnectionState state) async {
|
||||||
// if (state == DeviceConnectionState.connected){
|
if (state == DeviceConnectionState.connected){
|
||||||
// var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
// List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
// IoSenderManage.senderGetLockStatu(
|
IoSenderManage.senderGetLockStatu(
|
||||||
// lockID:BlueManage().connectDeviceName,
|
lockID:BlueManage().connectDeviceName,
|
||||||
// userID:"100001",
|
userID:"100001",
|
||||||
// privateKey:getPrivateKeyList,
|
privateKey:getPrivateKeyList,
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -310,6 +434,10 @@ class LockDetailLogic extends BaseGetXController{
|
|||||||
super.onReady();
|
super.onReady();
|
||||||
print("onReady()");
|
print("onReady()");
|
||||||
_initReplySubscription();
|
_initReplySubscription();
|
||||||
|
|
||||||
|
BlueManage().startScan((v){
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -318,8 +446,11 @@ class LockDetailLogic extends BaseGetXController{
|
|||||||
super.onInit();
|
super.onInit();
|
||||||
print("onInit()");
|
print("onInit()");
|
||||||
|
|
||||||
|
BlueManage().connectDeviceName = "TMH_c3570480da8d";
|
||||||
|
BlueManage().connectDeviceId = "AD01447A-30B5-A780-E778-DED3BDCB613E";
|
||||||
|
|
||||||
// 进来第一步开始扫描
|
// 进来第一步开始扫描
|
||||||
connectBlue();
|
// connectBlue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import 'package:get/get.dart';
|
|||||||
|
|
||||||
import '../../../appRouters.dart';
|
import '../../../appRouters.dart';
|
||||||
import '../../../app_settings/app_colors.dart';
|
import '../../../app_settings/app_colors.dart';
|
||||||
|
import '../../../blue/io_tool/io_manager.dart';
|
||||||
|
import '../../../tools/storage.dart';
|
||||||
import '../../../tools/titleAppBar.dart';
|
import '../../../tools/titleAppBar.dart';
|
||||||
import '../../../translations/trans_lib.dart';
|
import '../../../translations/trans_lib.dart';
|
||||||
import 'lockDetail_logic.dart';
|
import 'lockDetail_logic.dart';
|
||||||
@ -21,6 +23,7 @@ class _LockDetailPageState extends State<LockDetailPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
appBar: TitleAppBar(
|
appBar: TitleAppBar(
|
||||||
@ -76,8 +79,10 @@ class _LockDetailPageState extends State<LockDetailPage> {
|
|||||||
Center(
|
Center(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: (){
|
onTap: (){
|
||||||
|
// logic.transferPermissionsAction();
|
||||||
// logic.openDoorAction();
|
// logic.openDoorAction();
|
||||||
logic.editLockUserAction();
|
// logic.editLockUserAction();
|
||||||
|
logic.factoryDataResetAction();
|
||||||
},
|
},
|
||||||
child: Image.asset('images/main/icon_main_openLockBtn.png',
|
child: Image.asset('images/main/icon_main_openLockBtn.png',
|
||||||
width: 268.w, height: 268.w),
|
width: 268.w, height: 268.w),
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
import 'lockMain_logic.dart';
|
import 'lockMain_logic.dart';
|
||||||
|
|
||||||
class LockMainBinding extends Bindings {
|
class LockMainBinding extends Bindings {
|
||||||
|
|||||||
@ -0,0 +1,319 @@
|
|||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:amap_flutter_location/amap_flutter_location.dart';
|
||||||
|
import 'package:amap_flutter_location/amap_location_option.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
import 'package:amap_flutter_map/amap_flutter_map.dart';
|
||||||
|
import 'package:amap_flutter_base/amap_flutter_base.dart';
|
||||||
|
|
||||||
|
import '../../../app_settings/app_colors.dart';
|
||||||
|
import '../../../main.dart';
|
||||||
|
|
||||||
|
class LockAddressGaoDePage extends StatefulWidget {
|
||||||
|
const LockAddressGaoDePage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<LockAddressGaoDePage> createState() => _LockAddressGaoDePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LockAddressGaoDePageState extends State<LockAddressGaoDePage>{
|
||||||
|
// 高德地图
|
||||||
|
Map<String, Object>? _locationResult;
|
||||||
|
StreamSubscription<Map<String, Object>>? _locationListener;
|
||||||
|
final AMapFlutterLocation _locationPlugin = AMapFlutterLocation();
|
||||||
|
late AMapController _mapController;
|
||||||
|
|
||||||
|
static const CameraPosition _kInitialPosition = CameraPosition(
|
||||||
|
target: LatLng(113.919112, 22.653728),
|
||||||
|
zoom: 10.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
List<Widget> get _approvalNumberWidget => <Widget>[];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
/// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看,如果未包含或者没有弹窗展示,高德定位SDK将不会工作
|
||||||
|
///
|
||||||
|
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
|
||||||
|
/// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
|
||||||
|
///
|
||||||
|
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
|
||||||
|
///
|
||||||
|
/// [hasContains] 隐私声明中是否包含高德隐私政策说明
|
||||||
|
///
|
||||||
|
/// [hasShow] 隐私权政策是否弹窗展示告知用户
|
||||||
|
AMapFlutterLocation.updatePrivacyShow(true, true);
|
||||||
|
|
||||||
|
/// 设置是否已经取得用户同意,如果未取得用户同意,高德定位SDK将不会工作
|
||||||
|
///
|
||||||
|
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
|
||||||
|
///
|
||||||
|
/// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
|
||||||
|
///
|
||||||
|
/// [hasAgree] 隐私权政策是否已经取得用户同意
|
||||||
|
AMapFlutterLocation.updatePrivacyAgree(true);
|
||||||
|
|
||||||
|
/// 动态申请定位权限
|
||||||
|
requestPermission();
|
||||||
|
|
||||||
|
///设置Android和iOS的apiKey<br>
|
||||||
|
///key的申请请参考高德开放平台官网说明<br>
|
||||||
|
///Android: https://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key
|
||||||
|
///iOS: https://lbs.amap.com/api/ios-location-sdk/guide/create-project/get-key
|
||||||
|
AMapFlutterLocation.setApiKey("1dbf56e2e8a4d0e4cdc2df9efd36bc71", "dfb64c0463cb53927914364b5c09aba0");
|
||||||
|
|
||||||
|
///iOS 获取native精度类型
|
||||||
|
if (Platform.isIOS) {
|
||||||
|
requestAccuracyAuthorization();
|
||||||
|
}
|
||||||
|
|
||||||
|
///注册定位结果监听
|
||||||
|
_locationListener = _locationPlugin.onLocationChanged().listen((Map<String, Object> result) {
|
||||||
|
setState(() {
|
||||||
|
_locationResult = result;
|
||||||
|
if (_locationResult != null) {
|
||||||
|
_locationResult?.forEach((key, value) {
|
||||||
|
print("key:$key value:$value");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
_startLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
///使用默认属性创建一个地图
|
||||||
|
final AMapWidget map = AMapWidget(
|
||||||
|
apiKey: const AMapApiKey(androidKey: '900f72eeee0f21e435cebb0ef155582a', iosKey: '4dfdec97b7bf0b8c13e94777103015a9'),
|
||||||
|
onMapCreated: onMapCreated,
|
||||||
|
// initialCameraPosition: _kInitialPosition
|
||||||
|
);
|
||||||
|
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: MediaQuery.of(context).size.height,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
child: map,
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 10.w, bottom: 30.h,
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: _approvalNumberWidget),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 20.w, right: 20.w, bottom: 100.h,
|
||||||
|
child: Container(
|
||||||
|
// height: h(106),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.mainColor,
|
||||||
|
borderRadius: BorderRadius.circular(15.w),
|
||||||
|
),
|
||||||
|
child:Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
// height: h(53),
|
||||||
|
padding: EdgeInsets.only(top: 15.h, bottom: 15, left:15.w, right: 15.w),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Image.asset('images/main/icon_addUserShowAddress.png', width: 30.w, height: 30.w),
|
||||||
|
SizedBox(width: 10.w),
|
||||||
|
Expanded(
|
||||||
|
child: Text("广东省深圳市宏发科技园", style: const TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500, overflow: TextOverflow.clip))
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(height: 1.h, color: const Color(0xFF021732),),
|
||||||
|
Container(
|
||||||
|
// height: h(52),
|
||||||
|
padding: EdgeInsets.only(top: 15.h, bottom: 15, left:15.w, right: 15.w),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Image.asset('images/main/icon_addUserAddressShowTime.png', width: 30.w, height: 30.w),
|
||||||
|
SizedBox(width: 10.w,),
|
||||||
|
Expanded(
|
||||||
|
child: Text("2023.8.22 15.14", style: const TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500),)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onMapCreated(AMapController controller) {
|
||||||
|
setState(() {
|
||||||
|
_mapController = controller;
|
||||||
|
getApprovalNumber();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取审图号
|
||||||
|
void getApprovalNumber() async {
|
||||||
|
//普通地图审图号
|
||||||
|
String? mapContentApprovalNumber =
|
||||||
|
await _mapController.getMapContentApprovalNumber();
|
||||||
|
//卫星地图审图号
|
||||||
|
String? satelliteImageApprovalNumber =
|
||||||
|
await _mapController.getSatelliteImageApprovalNumber();
|
||||||
|
setState(() {
|
||||||
|
if (null != mapContentApprovalNumber) {
|
||||||
|
_approvalNumberWidget.add(Text(mapContentApprovalNumber));
|
||||||
|
}
|
||||||
|
if (null != satelliteImageApprovalNumber) {
|
||||||
|
_approvalNumberWidget.add(Text(satelliteImageApprovalNumber));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
print('地图审图号(普通地图): $mapContentApprovalNumber');
|
||||||
|
print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
|
||||||
|
}
|
||||||
|
|
||||||
|
///设置定位参数
|
||||||
|
void _setLocationOption() {
|
||||||
|
AMapLocationOption locationOption = new AMapLocationOption();
|
||||||
|
|
||||||
|
///是否单次定位
|
||||||
|
locationOption.onceLocation = false;
|
||||||
|
|
||||||
|
///是否需要返回逆地理信息
|
||||||
|
locationOption.needAddress = true;
|
||||||
|
|
||||||
|
///逆地理信息的语言类型
|
||||||
|
locationOption.geoLanguage = GeoLanguage.DEFAULT;
|
||||||
|
|
||||||
|
locationOption.desiredLocationAccuracyAuthorizationMode = AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;
|
||||||
|
|
||||||
|
locationOption.fullAccuracyPurposeKey = "AMapLocationScene";
|
||||||
|
|
||||||
|
///设置Android端连续定位的定位间隔
|
||||||
|
locationOption.locationInterval = 2000;
|
||||||
|
|
||||||
|
///设置Android端的定位模式<br>
|
||||||
|
///可选值:<br>
|
||||||
|
///<li>[AMapLocationMode.Battery_Saving]</li>
|
||||||
|
///<li>[AMapLocationMode.Device_Sensors]</li>
|
||||||
|
///<li>[AMapLocationMode.Hight_Accuracy]</li>
|
||||||
|
locationOption.locationMode = AMapLocationMode.Hight_Accuracy;
|
||||||
|
|
||||||
|
///设置iOS端的定位最小更新距离<br>
|
||||||
|
locationOption.distanceFilter = -1;
|
||||||
|
|
||||||
|
///设置iOS端期望的定位精度
|
||||||
|
/// 可选值:<br>
|
||||||
|
/// <li>[DesiredAccuracy.Best] 最高精度</li>
|
||||||
|
/// <li>[DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度 </li>
|
||||||
|
/// <li>[DesiredAccuracy.NearestTenMeters] 10米 </li>
|
||||||
|
/// <li>[DesiredAccuracy.Kilometer] 1000米</li>
|
||||||
|
/// <li>[DesiredAccuracy.ThreeKilometers] 3000米</li>
|
||||||
|
locationOption.desiredAccuracy = DesiredAccuracy.Best;
|
||||||
|
|
||||||
|
///设置iOS端是否允许系统暂停定位
|
||||||
|
locationOption.pausesLocationUpdatesAutomatically = false;
|
||||||
|
|
||||||
|
///将定位参数设置给定位插件
|
||||||
|
_locationPlugin.setLocationOption(locationOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
///开始定位
|
||||||
|
void _startLocation() {
|
||||||
|
///开始定位之前设置定位参数
|
||||||
|
_setLocationOption();
|
||||||
|
_locationPlugin.startLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
///停止定位
|
||||||
|
void _stopLocation() {
|
||||||
|
_locationPlugin.stopLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
///获取iOS native的accuracyAuthorization类型
|
||||||
|
void requestAccuracyAuthorization() async {
|
||||||
|
AMapAccuracyAuthorization currentAccuracyAuthorization = await _locationPlugin.getSystemAccuracyAuthorization();
|
||||||
|
if (currentAccuracyAuthorization == AMapAccuracyAuthorization.AMapAccuracyAuthorizationFullAccuracy) {
|
||||||
|
print("精确定位类型");
|
||||||
|
} else if (currentAccuracyAuthorization == AMapAccuracyAuthorization.AMapAccuracyAuthorizationReducedAccuracy) {
|
||||||
|
print("模糊定位类型");
|
||||||
|
} else {
|
||||||
|
print("未知定位类型");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 动态申请定位权限
|
||||||
|
void requestPermission() async {
|
||||||
|
// 申请权限
|
||||||
|
bool hasLocationPermission = await requestLocationPermission();
|
||||||
|
if (hasLocationPermission) {
|
||||||
|
print("定位权限申请通过");
|
||||||
|
} else {
|
||||||
|
print("定位权限申请不通过");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 申请定位权限
|
||||||
|
/// 授予定位权限返回true, 否则返回false
|
||||||
|
Future<bool> requestLocationPermission() async {
|
||||||
|
//获取当前的权限
|
||||||
|
var status = await Permission.location.status;
|
||||||
|
if (status == PermissionStatus.granted) {
|
||||||
|
//已经授权
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
//未授权则发起一次申请
|
||||||
|
status = await Permission.location.request();
|
||||||
|
if (status == PermissionStatus.granted) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// void dispose() {
|
||||||
|
// super.dispose();
|
||||||
|
//
|
||||||
|
// _stopLocation();
|
||||||
|
//
|
||||||
|
// ///移除定位监听
|
||||||
|
// if (null != _locationListener) {
|
||||||
|
// _locationListener?.cancel();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// ///销毁定位
|
||||||
|
// _locationPlugin.destroy();
|
||||||
|
//
|
||||||
|
// print("高德地图定位销毁了");
|
||||||
|
// }
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
|
||||||
|
_stopLocation();
|
||||||
|
|
||||||
|
///移除定位监听
|
||||||
|
if (null != _locationListener) {
|
||||||
|
_locationListener?.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
///销毁定位
|
||||||
|
_locationPlugin.destroy();
|
||||||
|
|
||||||
|
print("地图界面销毁了");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class LockAddressGooglePage extends StatefulWidget {
|
||||||
|
const LockAddressGooglePage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<LockAddressGooglePage> createState() => _LockAddressGooglePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LockAddressGooglePageState extends State<LockAddressGooglePage> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const Placeholder();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
import '../../../tools/baseGetXController.dart';
|
||||||
|
import 'lockAddress_state.dart';
|
||||||
|
|
||||||
|
class LockAddressLogic extends BaseGetXController {
|
||||||
|
|
||||||
|
final LockAddressState state = LockAddressState();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
// TODO: implement onReady
|
||||||
|
super.onReady();
|
||||||
|
print("onReady()");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
// TODO: implement onInit
|
||||||
|
super.onInit();
|
||||||
|
print("onInit()");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onClose() {
|
||||||
|
// TODO: implement onClose
|
||||||
|
super.onClose();
|
||||||
|
print("地图界面onClose()");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,12 +1,18 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
import '../../../appRouters.dart';
|
import '../../../appRouters.dart';
|
||||||
import '../../../app_settings/app_colors.dart';
|
import '../../../app_settings/app_colors.dart';
|
||||||
|
import '../../../main.dart';
|
||||||
import '../../../tools/titleAppBar.dart';
|
import '../../../tools/titleAppBar.dart';
|
||||||
import '../../../translations/trans_lib.dart';
|
import '../../../translations/trans_lib.dart';
|
||||||
|
|
||||||
|
import 'lockAddressGaoDe_page.dart';
|
||||||
|
|
||||||
class LockAddressPage extends StatefulWidget {
|
class LockAddressPage extends StatefulWidget {
|
||||||
const LockAddressPage({Key? key}) : super(key: key);
|
const LockAddressPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@ -14,27 +20,58 @@ class LockAddressPage extends StatefulWidget {
|
|||||||
State<LockAddressPage> createState() => _LockAddressPageState();
|
State<LockAddressPage> createState() => _LockAddressPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _LockAddressPageState extends State<LockAddressPage> {
|
class _LockAddressPageState extends State<LockAddressPage> with RouteAware{
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColors.mainBackgroundColor,
|
backgroundColor: AppColors.mainBackgroundColor,
|
||||||
appBar: TitleAppBar(
|
appBar: TitleAppBar(
|
||||||
barTitle: "锁地址",
|
barTitle: TranslationLoader.lanKeys!.lockAddress!.tr,
|
||||||
haveBack: true,
|
haveBack: true,
|
||||||
backgroundColor: AppColors.mainColor,
|
backgroundColor: AppColors.mainColor,
|
||||||
actionsList: [
|
actionsList: [
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text(
|
child: Text(
|
||||||
"保存",
|
TranslationLoader.lanKeys!.next!.tr,
|
||||||
style: TextStyle(color: Colors.white, fontSize: 24.sp),
|
style: TextStyle(color: Colors.white, fontSize: 24.sp),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pushNamed(context, Routers.saveLockPage);
|
Get.toNamed(Routers.saveLockPage)!.then((value) {
|
||||||
|
dispose();
|
||||||
|
});
|
||||||
|
// Navigator.pushNamed(context, Routers.saveLockPage);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: Container());
|
body: LockAddressGaoDePage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
routeObserver.unsubscribe(this);
|
||||||
|
print("地图界面销毁了");
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
// 订阅 routeObserver,之后就会尝试调用抽象类 RouteAware 的方法
|
||||||
|
routeObserver.subscribe(this, ModalRoute.of(context) as PageRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didPush() {
|
||||||
|
// 当前页面入栈
|
||||||
|
print("当前页面入栈");
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didPopNext() {
|
||||||
|
// 当前路由的下个路由出栈,且当前页面显示
|
||||||
|
print("当前路由的下个路由出栈,且当前页面显示");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
|
class LockAddressState {
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,12 +1,15 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
import 'package:get_storage/get_storage.dart';
|
import 'package:get_storage/get_storage.dart';
|
||||||
import 'package:star_lock/blue/io_protocol/io_getPrivateKey.dart';
|
import 'package:star_lock/blue/io_protocol/io_getPrivateKey.dart';
|
||||||
import 'package:star_lock/blue/io_protocol/io_getPublicKey.dart';
|
import 'package:star_lock/blue/io_protocol/io_getPublicKey.dart';
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
|
|
||||||
|
import '../../../appRouters.dart';
|
||||||
import '../../../blue/blue_manage.dart';
|
import '../../../blue/blue_manage.dart';
|
||||||
import '../../../blue/io_protocol/io_addUser.dart';
|
import '../../../blue/io_protocol/io_addUser.dart';
|
||||||
import '../../../blue/io_protocol/io_reply.dart';
|
import '../../../blue/io_protocol/io_reply.dart';
|
||||||
@ -38,10 +41,6 @@ class NearbyLockLogic extends BaseGetXController{
|
|||||||
if(reply is GetPrivateKeyReply) {
|
if(reply is GetPrivateKeyReply) {
|
||||||
_replyGetPrivateKeyKey(reply);
|
_replyGetPrivateKeyKey(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(reply is AddUserReply) {
|
|
||||||
_replyAddUserKey(reply);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,34 +90,7 @@ class NearbyLockLogic extends BaseGetXController{
|
|||||||
var savePrivateKeyList = changeIntListToStringList(privateKey);
|
var savePrivateKeyList = changeIntListToStringList(privateKey);
|
||||||
Storage.setStringList(saveBluePrivateKey, savePrivateKeyList);
|
Storage.setStringList(saveBluePrivateKey, savePrivateKeyList);
|
||||||
|
|
||||||
// signKey
|
Get.toNamed(Routers.lockAddressPage);
|
||||||
List<int> signKey = reply.data.sublist(16);
|
|
||||||
var savesignKeyList = changeIntListToStringList(signKey);
|
|
||||||
Storage.setStringList(saveBlueSignKey, savesignKeyList);
|
|
||||||
|
|
||||||
var token = await Storage.getStringList(saveBlueToken);
|
|
||||||
List<int> getTokenList = [0,0,0,0];
|
|
||||||
if(token != null){
|
|
||||||
getTokenList = changeStringListToIntList(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
print("privateKey:$privateKey signKey:$signKey");
|
|
||||||
IoSenderManage.senderAddUser(
|
|
||||||
lockID:BlueManage().connectDeviceName,
|
|
||||||
authUserID:"100001",
|
|
||||||
keyID:"1",
|
|
||||||
userID:"100001",
|
|
||||||
openMode:1,
|
|
||||||
keyType:1,
|
|
||||||
startDate:0x11223344,
|
|
||||||
expireDate:0x11223344,
|
|
||||||
role:255,
|
|
||||||
password:"123456",
|
|
||||||
needAuthor:1,
|
|
||||||
publicKey:publicKeyDataList,
|
|
||||||
privateKey:privateKey,
|
|
||||||
token: getTokenList
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case 0x07:
|
case 0x07:
|
||||||
//无权限
|
//无权限
|
||||||
@ -136,68 +108,6 @@ class NearbyLockLogic extends BaseGetXController{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _replyAddUserKey(Reply reply) async {
|
|
||||||
var lockId = reply.data.sublist(2, 42);
|
|
||||||
print("lockId:$lockId");
|
|
||||||
|
|
||||||
var token = reply.data.sublist(42, 46);
|
|
||||||
List<String> strTokenList = changeIntListToStringList(token);
|
|
||||||
Storage.setStringList(saveBlueToken, strTokenList);
|
|
||||||
print("token:$token");
|
|
||||||
|
|
||||||
int status = reply.data[46];
|
|
||||||
print("status:$status");
|
|
||||||
|
|
||||||
switch(status){
|
|
||||||
case 0x00:
|
|
||||||
//成功
|
|
||||||
print("添加用户数据解析成功");
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 0x06:
|
|
||||||
//无权限
|
|
||||||
print("需要鉴权");
|
|
||||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
|
||||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
|
||||||
|
|
||||||
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
|
||||||
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
|
||||||
|
|
||||||
IoSenderManage.senderAddUser(
|
|
||||||
lockID:BlueManage().connectDeviceName,
|
|
||||||
authUserID:"100001",
|
|
||||||
keyID:"1",
|
|
||||||
userID:"100001",
|
|
||||||
openMode:1,
|
|
||||||
keyType:1,
|
|
||||||
startDate:0x11223344,
|
|
||||||
expireDate:0x11223344,
|
|
||||||
role:255,
|
|
||||||
password:"123456",
|
|
||||||
needAuthor:1,
|
|
||||||
publicKey:publicKeyDataList,
|
|
||||||
privateKey:getPrivateKeyList,
|
|
||||||
token: token
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 0x07:
|
|
||||||
//无权限
|
|
||||||
print("用户无权限");
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 0x09:
|
|
||||||
// 权限校验错误
|
|
||||||
print("添加用户权限校验错误");
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//失败
|
|
||||||
print("领锁失败");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onReady() {
|
void onReady() {
|
||||||
// TODO: implement onReady
|
// TODO: implement onReady
|
||||||
|
|||||||
@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
class SaveLockEntity {
|
||||||
|
int? errorCode;
|
||||||
|
String? description;
|
||||||
|
String? errorMsg;
|
||||||
|
SaveLockEntityData? data;
|
||||||
|
|
||||||
|
SaveLockEntity(
|
||||||
|
{this.errorCode, this.description, this.errorMsg, this.data});
|
||||||
|
|
||||||
|
SaveLockEntity.fromJson(Map<String, dynamic> json) {
|
||||||
|
errorCode = json['errorCode'];
|
||||||
|
description = json['description'];
|
||||||
|
errorMsg = json['errorMsg'];
|
||||||
|
data = json['data'] != null
|
||||||
|
? SaveLockEntityData.fromJson(json['data'])
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['errorCode'] = errorCode;
|
||||||
|
data['description'] = description;
|
||||||
|
data['errorMsg'] = errorMsg;
|
||||||
|
if (this.data != null) {
|
||||||
|
data['data'] = this.data!.toJson();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SaveLockEntityData {
|
||||||
|
String? lockId;
|
||||||
|
String? nbRegisterSuccess;
|
||||||
|
String? keyId;
|
||||||
|
|
||||||
|
SaveLockEntityData(
|
||||||
|
{ this.lockId,
|
||||||
|
this.nbRegisterSuccess,
|
||||||
|
this.keyId});
|
||||||
|
|
||||||
|
SaveLockEntityData.fromJson(Map<String, dynamic> json) {
|
||||||
|
lockId = json['lockId'];
|
||||||
|
nbRegisterSuccess = json['nbRegisterSuccess'];
|
||||||
|
keyId = json['keyId'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['lockId'] = lockId;
|
||||||
|
data['nbRegisterSuccess'] = nbRegisterSuccess;
|
||||||
|
data['keyId'] = keyId;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
281
star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart
Normal file
281
star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import '../../../blue/blue_manage.dart';
|
||||||
|
import '../../../blue/io_protocol/io_addUser.dart';
|
||||||
|
import '../../../blue/io_protocol/io_getLockStatu.dart';
|
||||||
|
import '../../../blue/io_protocol/io_reply.dart';
|
||||||
|
import '../../../blue/io_tool/io_manager.dart';
|
||||||
|
import '../../../blue/io_tool/io_tool.dart';
|
||||||
|
import '../../../blue/io_tool/manager_event_bus.dart';
|
||||||
|
import '../../../blue/sender_manage.dart';
|
||||||
|
import '../../../network/api_repository.dart';
|
||||||
|
import '../../../tools/baseGetXController.dart';
|
||||||
|
import '../../../tools/storage.dart';
|
||||||
|
import 'saveLock_state.dart';
|
||||||
|
|
||||||
|
class SaveLockLogic extends BaseGetXController {
|
||||||
|
|
||||||
|
final SaveLockState state = SaveLockState();
|
||||||
|
|
||||||
|
// 获取解析后的数据
|
||||||
|
late StreamSubscription<Reply> _replySubscription;
|
||||||
|
void _initReplySubscription() {
|
||||||
|
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
|
||||||
|
if(reply is AddUserReply) {
|
||||||
|
_replyAddUserKey(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取锁状态
|
||||||
|
if(reply is GetLockStatuReply) {
|
||||||
|
_replyGetLockStatus(reply);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _replyAddUserKey(Reply reply) async {
|
||||||
|
var lockId = reply.data.sublist(2, 42);
|
||||||
|
print("lockId:$lockId");
|
||||||
|
|
||||||
|
var token = reply.data.sublist(42, 46);
|
||||||
|
List<String> strTokenList = changeIntListToStringList(token);
|
||||||
|
Storage.setStringList(saveBlueToken, strTokenList);
|
||||||
|
print("token:$token");
|
||||||
|
|
||||||
|
int status = reply.data[46];
|
||||||
|
print("status:$status");
|
||||||
|
|
||||||
|
switch(status){
|
||||||
|
case 0x00:
|
||||||
|
//成功
|
||||||
|
print("添加用户数据解析成功");
|
||||||
|
bindBlueAdmin();
|
||||||
|
break;
|
||||||
|
case 0x06:
|
||||||
|
//无权限
|
||||||
|
print("需要鉴权");
|
||||||
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
|
||||||
|
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||||
|
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||||
|
|
||||||
|
IoSenderManage.senderAddUser(
|
||||||
|
lockID:BlueManage().connectDeviceName,
|
||||||
|
authUserID:"100001",
|
||||||
|
keyID:"1",
|
||||||
|
userID:"100001",
|
||||||
|
openMode:1,
|
||||||
|
keyType:1,
|
||||||
|
startDate:0x11223344,
|
||||||
|
expireDate:0x11223344,
|
||||||
|
role:255,
|
||||||
|
password:"123456",
|
||||||
|
needAuthor:1,
|
||||||
|
publicKey:publicKeyDataList,
|
||||||
|
privateKey:getPrivateKeyList,
|
||||||
|
token: token
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 0x07:
|
||||||
|
//无权限
|
||||||
|
print("用户无权限");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0x09:
|
||||||
|
// 权限校验错误
|
||||||
|
print("添加用户权限校验错误");
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//失败
|
||||||
|
print("领锁失败");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取锁状态数据解析
|
||||||
|
Future<void> _replyGetLockStatus(Reply reply) async {
|
||||||
|
int status = reply.data[2];
|
||||||
|
switch(status){
|
||||||
|
case 0x00:
|
||||||
|
//成功
|
||||||
|
print("${reply.commandType}数据解析成功");
|
||||||
|
var softVersion = reply.data.sublist(3, 7);
|
||||||
|
print("softVersion:$softVersion");
|
||||||
|
|
||||||
|
var power = reply.data[7];
|
||||||
|
print("power:$power");
|
||||||
|
|
||||||
|
// APP 用户数量
|
||||||
|
var appUserCount = reply.data.sublist(50, 53);
|
||||||
|
print("appUserCount:$appUserCount");
|
||||||
|
|
||||||
|
// 黑名单用户数量
|
||||||
|
var blacklistCount = reply.data[53];
|
||||||
|
print("blacklistCount:$blacklistCount");
|
||||||
|
|
||||||
|
// 蓝牙钥匙数量
|
||||||
|
var bleKeyCount = reply.data[54];
|
||||||
|
print("bleKeyCount:$bleKeyCount");
|
||||||
|
|
||||||
|
// 剩余可添加用户数量
|
||||||
|
var remainCount = reply.data.sublist(54, 56);
|
||||||
|
print("remainCount:$remainCount");
|
||||||
|
|
||||||
|
// 未上传开锁记录数量
|
||||||
|
var notUploadCount = reply.data.sublist(56, 58);
|
||||||
|
print("notUploadCount:$notUploadCount");
|
||||||
|
|
||||||
|
// 已设置开门密码数量
|
||||||
|
var pwdCount = reply.data[58];
|
||||||
|
print("pwdCount:$pwdCount");
|
||||||
|
|
||||||
|
// 已设置开门指纹数量
|
||||||
|
var fingerprintCount = reply.data[59];
|
||||||
|
print("fingerprintCount:$fingerprintCount");
|
||||||
|
|
||||||
|
// 锁当前时间
|
||||||
|
var lockTime = reply.data.sublist(60, 64);
|
||||||
|
print("lockTime:$lockTime");
|
||||||
|
|
||||||
|
// 硬件版本信息,为固件升级提供判断依据
|
||||||
|
var hardVersion = reply.data.sublist(64, 68);
|
||||||
|
print("hardVersion:$hardVersion");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0x06:
|
||||||
|
//无权限
|
||||||
|
print("${reply.commandType}需要鉴权");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0x07:
|
||||||
|
//无权限
|
||||||
|
print("${reply.commandType}用户无权限");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0x09:
|
||||||
|
// 权限校验错误
|
||||||
|
print("${reply.commandType}权限校验错误");
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//失败
|
||||||
|
print("${reply.commandType}失败");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存事件,先调用蓝牙,蓝牙调用成功后再调用后台接口
|
||||||
|
_saveLockAction(){
|
||||||
|
addUserConnectBlue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加用户
|
||||||
|
Future<void> addUserConnectBlue() async {
|
||||||
|
// 进来之后首先连接
|
||||||
|
BlueManage().connect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", connectStateCallBack: (DeviceConnectionState state) async {
|
||||||
|
if (state == DeviceConnectionState.connected){
|
||||||
|
// 私钥
|
||||||
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
|
||||||
|
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||||
|
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||||
|
|
||||||
|
var token = await Storage.getStringList(saveBlueToken);
|
||||||
|
List<int> getTokenList = [0,0,0,0];
|
||||||
|
if(token != null){
|
||||||
|
getTokenList = changeStringListToIntList(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
IoSenderManage.senderAddUser(
|
||||||
|
lockID:BlueManage().connectDeviceName,
|
||||||
|
authUserID:"100001",
|
||||||
|
keyID:"1",
|
||||||
|
userID:"100001",
|
||||||
|
openMode:1,
|
||||||
|
keyType:1,
|
||||||
|
startDate:0x11223344,
|
||||||
|
expireDate:0x11223344,
|
||||||
|
role:255,
|
||||||
|
password:"123456",
|
||||||
|
needAuthor:1,
|
||||||
|
publicKey:publicKeyDataList,
|
||||||
|
privateKey:getPrivateKeyList,
|
||||||
|
token: getTokenList
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void bindBlueAdmin() async{
|
||||||
|
var lockData = "";
|
||||||
|
var lockDataMap = {};
|
||||||
|
lockDataMap['lockId'] = BlueManage().connectDeviceName;
|
||||||
|
lockDataMap['lockMac'] = BlueManage().connectDeviceId;
|
||||||
|
lockData = json.encode(lockDataMap);
|
||||||
|
|
||||||
|
var entity = await ApiRepository.to.bindingBlueAdmin(
|
||||||
|
bindingDate:DateTime.now().millisecondsSinceEpoch.toString(),
|
||||||
|
hotelMode:"2",
|
||||||
|
lockAlias:state.aliName.value,
|
||||||
|
lockData:lockData,
|
||||||
|
nbInitSuccess:"0",
|
||||||
|
position:"113.918912, 22.653670",
|
||||||
|
deviceNo:"123456"
|
||||||
|
);
|
||||||
|
if(entity.errorCode!.codeIsSuccessful){
|
||||||
|
Get.close(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取锁状态
|
||||||
|
Future<void> _getLockStatus() async {
|
||||||
|
// 进来之后首先连接
|
||||||
|
BlueManage().judgeReconnect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", (DeviceConnectionState state) async {
|
||||||
|
if (state == DeviceConnectionState.connected) {
|
||||||
|
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||||
|
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||||
|
IoSenderManage.senderGetLockStatu(
|
||||||
|
lockID:BlueManage().connectDeviceName,
|
||||||
|
userID:"100001",
|
||||||
|
privateKey:getPrivateKeyList,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
// TODO: implement onReady
|
||||||
|
super.onReady();
|
||||||
|
print("onReady()");
|
||||||
|
|
||||||
|
_initReplySubscription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
// TODO: implement onInit
|
||||||
|
super.onInit();
|
||||||
|
print("onInit()");
|
||||||
|
|
||||||
|
_getLockStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onClose() {
|
||||||
|
// TODO: implement onClose
|
||||||
|
super.onClose();
|
||||||
|
_replySubscription.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
@ -6,6 +7,7 @@ import '../../../app_settings/app_colors.dart';
|
|||||||
import '../../../tools/submitBtn.dart';
|
import '../../../tools/submitBtn.dart';
|
||||||
import '../../../tools/titleAppBar.dart';
|
import '../../../tools/titleAppBar.dart';
|
||||||
import '../../../translations/trans_lib.dart';
|
import '../../../translations/trans_lib.dart';
|
||||||
|
import 'saveLock_logic.dart';
|
||||||
|
|
||||||
class SaveLockPage extends StatefulWidget {
|
class SaveLockPage extends StatefulWidget {
|
||||||
const SaveLockPage({Key? key}) : super(key: key);
|
const SaveLockPage({Key? key}) : super(key: key);
|
||||||
@ -15,6 +17,9 @@ class SaveLockPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SaveLockPageState extends State<SaveLockPage> {
|
class _SaveLockPageState extends State<SaveLockPage> {
|
||||||
|
final logic = Get.put(SaveLockLogic());
|
||||||
|
final state = Get.find<SaveLockLogic>().state;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -37,7 +42,14 @@ class _SaveLockPageState extends State<SaveLockPage> {
|
|||||||
// color: Colors.red,
|
// color: Colors.red,
|
||||||
padding: EdgeInsets.only(left: 50.w, right: 50.w),
|
padding: EdgeInsets.only(left: 50.w, right: 50.w),
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
controller: state.aliNameController,
|
||||||
|
onChanged: (v){
|
||||||
|
state.aliName.value = v;
|
||||||
|
},
|
||||||
textAlign:TextAlign.center,
|
textAlign:TextAlign.center,
|
||||||
|
inputFormatters: [
|
||||||
|
LengthLimitingTextInputFormatter(32),
|
||||||
|
],
|
||||||
// style:TextStyle(height: 1.1, fontSize: 36.sp, fontWeight: FontWeight.w400, color:AppColors.mainColor),
|
// style:TextStyle(height: 1.1, fontSize: 36.sp, fontWeight: FontWeight.w400, color:AppColors.mainColor),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: '请填写信息',
|
hintText: '请填写信息',
|
||||||
|
|||||||
21
star_lock/lib/mine/addLock/saveLock/saveLock_state.dart
Normal file
21
star_lock/lib/mine/addLock/saveLock/saveLock_state.dart
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import '../../../blue/blue_manage.dart';
|
||||||
|
|
||||||
|
class SaveLockState {
|
||||||
|
|
||||||
|
var aliName = ''.obs;
|
||||||
|
TextEditingController aliNameController = TextEditingController();
|
||||||
|
|
||||||
|
SaveLockState() {
|
||||||
|
aliName.value = BlueManage().connectDeviceName;
|
||||||
|
aliNameController.text = aliName.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onClose() {
|
||||||
|
aliNameController.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,4 +17,7 @@ abstract class Api {
|
|||||||
final String keyOperationRecordURL = '/lockRecords/list'; //电子钥匙操作记录
|
final String keyOperationRecordURL = '/lockRecords/list'; //电子钥匙操作记录
|
||||||
final String uploadElectricQuantityURL =
|
final String uploadElectricQuantityURL =
|
||||||
'/room/uploadElectricQuantity'; //锁电量更新
|
'/room/uploadElectricQuantity'; //锁电量更新
|
||||||
|
|
||||||
|
final String bindingBlueAdminURL =
|
||||||
|
'/lock/bindAdmin'; //绑定蓝牙管理员
|
||||||
}
|
}
|
||||||
|
|||||||
@ -195,6 +195,27 @@ class ApiProvider extends BaseProvider {
|
|||||||
'searchStr': searchStr,
|
'searchStr': searchStr,
|
||||||
'timezoneRawOffSet': timezoneRawOffSet
|
'timezoneRawOffSet': timezoneRawOffSet
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// 绑定蓝牙管理员
|
||||||
|
Future<Response> bindingBlueAdmin(
|
||||||
|
String bindingDate,
|
||||||
|
String hotelMode,
|
||||||
|
String lockAlias,
|
||||||
|
String lockData,
|
||||||
|
String nbInitSuccess,
|
||||||
|
String position,
|
||||||
|
String deviceNo) =>
|
||||||
|
post(
|
||||||
|
bindingBlueAdminURL.toUrl,
|
||||||
|
jsonEncode({
|
||||||
|
'bindingDate': bindingDate,
|
||||||
|
'hotelMode': hotelMode,
|
||||||
|
"lockAlias": lockAlias,
|
||||||
|
'lockData': lockData,
|
||||||
|
"nbInitSuccess": nbInitSuccess,
|
||||||
|
'position': position,
|
||||||
|
'deviceNo': deviceNo
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ExtensionString on String {
|
extension ExtensionString on String {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import '../common/safetyVerification/entity/CheckSafetyVerificationEntity.dart';
|
|||||||
import '../common/safetyVerification/entity/SafetyVerificationEntity.dart';
|
import '../common/safetyVerification/entity/SafetyVerificationEntity.dart';
|
||||||
import '../login/login/entity/LoginEntity.dart';
|
import '../login/login/entity/LoginEntity.dart';
|
||||||
import '../login/register/entity/SendValidationCodeEntity.dart';
|
import '../login/register/entity/SendValidationCodeEntity.dart';
|
||||||
|
import '../mine/addLock/saveLock/entity/SaveLockEntity.dart';
|
||||||
import 'api_provider.dart';
|
import 'api_provider.dart';
|
||||||
|
|
||||||
class ApiRepository {
|
class ApiRepository {
|
||||||
@ -168,4 +169,24 @@ class ApiRepository {
|
|||||||
timezoneRawOffSet);
|
timezoneRawOffSet);
|
||||||
return KeyOperationRecordEntity.fromJson(res.body);
|
return KeyOperationRecordEntity.fromJson(res.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 绑定蓝牙管理员
|
||||||
|
Future<SaveLockEntity> bindingBlueAdmin({
|
||||||
|
required String bindingDate,
|
||||||
|
required String hotelMode,
|
||||||
|
required String lockAlias,
|
||||||
|
required String lockData,
|
||||||
|
required String nbInitSuccess,
|
||||||
|
required String position,
|
||||||
|
required String deviceNo}) async {
|
||||||
|
final res = await apiProvider.bindingBlueAdmin(
|
||||||
|
bindingDate,
|
||||||
|
hotelMode,
|
||||||
|
lockAlias,
|
||||||
|
lockData,
|
||||||
|
nbInitSuccess,
|
||||||
|
position,
|
||||||
|
deviceNo);
|
||||||
|
return SaveLockEntity.fromJson(res.body);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,6 +49,7 @@ class LoginInput extends StatelessWidget {
|
|||||||
controller: controller,
|
controller: controller,
|
||||||
onChanged: onchangeAction,
|
onChanged: onchangeAction,
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
|
inputFormatters:inputFormatters,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
//输入里面输入文字内边距设置
|
//输入里面输入文字内边距设置
|
||||||
contentPadding: const EdgeInsets.only(
|
contentPadding: const EdgeInsets.only(
|
||||||
|
|||||||
@ -188,6 +188,7 @@ class LanKeyEntity {
|
|||||||
this.lanChinese,
|
this.lanChinese,
|
||||||
this.multilingual,
|
this.multilingual,
|
||||||
this.addLock,
|
this.addLock,
|
||||||
|
this.lockAddress,
|
||||||
this.selectLockType,
|
this.selectLockType,
|
||||||
this.videoIntercomDoorLock,
|
this.videoIntercomDoorLock,
|
||||||
this.NFCPassiveLock,
|
this.NFCPassiveLock,
|
||||||
@ -573,6 +574,7 @@ class LanKeyEntity {
|
|||||||
lanChinese = json['lanChinese'];
|
lanChinese = json['lanChinese'];
|
||||||
multilingual = json['multilingual'];
|
multilingual = json['multilingual'];
|
||||||
addLock = json['addLock'];
|
addLock = json['addLock'];
|
||||||
|
lockAddress = json["lockAddress"];
|
||||||
selectLockType = json['selectLockType'];
|
selectLockType = json['selectLockType'];
|
||||||
videoIntercomDoorLock = json['videoIntercomDoorLock'];
|
videoIntercomDoorLock = json['videoIntercomDoorLock'];
|
||||||
NFCPassiveLock = json['NFCPassiveLock'];
|
NFCPassiveLock = json['NFCPassiveLock'];
|
||||||
@ -975,6 +977,7 @@ class LanKeyEntity {
|
|||||||
String? lanChinese;
|
String? lanChinese;
|
||||||
String? multilingual;
|
String? multilingual;
|
||||||
String? addLock;
|
String? addLock;
|
||||||
|
String? lockAddress;
|
||||||
String? selectLockType;
|
String? selectLockType;
|
||||||
String? videoIntercomDoorLock;
|
String? videoIntercomDoorLock;
|
||||||
String? NFCPassiveLock;
|
String? NFCPassiveLock;
|
||||||
@ -1374,6 +1377,7 @@ class LanKeyEntity {
|
|||||||
map['lanChinese'] = lanChinese;
|
map['lanChinese'] = lanChinese;
|
||||||
map['multilingual'] = multilingual;
|
map['multilingual'] = multilingual;
|
||||||
map['addLock'] = addLock;
|
map['addLock'] = addLock;
|
||||||
|
map['lockAddress'] = lockAddress;
|
||||||
map['selectLockType'] = selectLockType;
|
map['selectLockType'] = selectLockType;
|
||||||
map['videoIntercomDoorLock'] = videoIntercomDoorLock;
|
map['videoIntercomDoorLock'] = videoIntercomDoorLock;
|
||||||
map['NFCPassiveLock'] = NFCPassiveLock;
|
map['NFCPassiveLock'] = NFCPassiveLock;
|
||||||
|
|||||||
@ -88,6 +88,13 @@ dependencies:
|
|||||||
encrypt: ^5.0.1
|
encrypt: ^5.0.1
|
||||||
crypto: ^3.0.3
|
crypto: ^3.0.3
|
||||||
|
|
||||||
|
#高德地图定位
|
||||||
|
amap_flutter_location: ^3.0.0
|
||||||
|
#权限使用
|
||||||
|
permission_handler: ^10.4.3
|
||||||
|
#高德地图地图
|
||||||
|
amap_flutter_map: ^3.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <aj_captcha_flutter/aj_captcha_flutter_plugin_c_api.h>
|
#include <aj_captcha_flutter/aj_captcha_flutter_plugin_c_api.h>
|
||||||
#include <file_selector_windows/file_selector_windows.h>
|
#include <file_selector_windows/file_selector_windows.h>
|
||||||
|
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
@ -15,6 +16,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|||||||
registry->GetRegistrarForPlugin("AjCaptchaFlutterPluginCApi"));
|
registry->GetRegistrarForPlugin("AjCaptchaFlutterPluginCApi"));
|
||||||
FileSelectorWindowsRegisterWithRegistrar(
|
FileSelectorWindowsRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||||
|
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
aj_captcha_flutter
|
aj_captcha_flutter
|
||||||
file_selector_windows
|
file_selector_windows
|
||||||
|
permission_handler_windows
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user