Merge branch 'talk_flutter'
# Conflicts: # star_lock/ios/Podfile.lock # star_lock/lib/blue/blue_manage.dart # star_lock/lib/main.dart # star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_page.dart # star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart # star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart # star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart
This commit is contained in:
commit
62f3c9fdd3
@ -39,6 +39,10 @@
|
||||
|
||||
<!--允许读设备等信息,用于问题排查-->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<!--允许麦克风权限,用于录音发送-->
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<application
|
||||
android:label="星锁"
|
||||
android:name="${applicationName}"
|
||||
|
||||
1
star_lock/assets/s10-g711.bin
Normal file
1
star_lock/assets/s10-g711.bin
Normal file
File diff suppressed because one or more lines are too long
BIN
star_lock/images/main/icon_lockDetail_hangUp.png
Normal file
BIN
star_lock/images/main/icon_lockDetail_hangUp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
BIN
star_lock/images/main/icon_lockDetail_monitoringAnswerCalls.png
Normal file
BIN
star_lock/images/main/icon_lockDetail_monitoringAnswerCalls.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
BIN
star_lock/images/main/icon_lockDetail_monitoringUnTalkback.png
Normal file
BIN
star_lock/images/main/icon_lockDetail_monitoringUnTalkback.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
@ -90,6 +90,7 @@ post_install do |installer|
|
||||
## dart: PermissionGroup.bluetooth
|
||||
'PERMISSION_BLUETOOTH=1',
|
||||
|
||||
'PERMISSION_MICROPHONE=1',
|
||||
## dart: PermissionGroup.appTrackingTransparency
|
||||
# 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
3364C3F42B0C902100AA5ABC /* lcokStarMain.png in Resources */ = {isa = PBXBuildFile; fileRef = 3364C3F32B0C902100AA5ABC /* lcokStarMain.png */; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
3EF1E85D6F1EE0C0DCF8449F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09D8B2FA2B26BA5BFF31AB2A /* Pods_Runner.framework */; };
|
||||
8297E4102AE75AC500E886FA /* XSFlutterManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8297E40E2AE75AC500E886FA /* XSFlutterManager.m */; };
|
||||
8297E43A2AE75BEE00E886FA /* Msg.m in Sources */ = {isa = PBXBuildFile; fileRef = 8297E4132AE75BEE00E886FA /* Msg.m */; };
|
||||
8297E43B2AE75BEE00E886FA /* udp_data_class.m in Sources */ = {isa = PBXBuildFile; fileRef = 8297E4172AE75BEE00E886FA /* udp_data_class.m */; };
|
||||
@ -125,6 +124,7 @@
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
CD1142BE3A076363977FB03C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED1F1A04428235FB1B6FD471 /* Pods_Runner.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@ -141,9 +141,10 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
09D8B2FA2B26BA5BFF31AB2A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0BEB3ADCCEC961E2916B9004 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; 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>"; };
|
||||
265F8968B3CDB02494B21491 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
3364C3F32B0C902100AA5ABC /* lcokStarMain.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = lcokStarMain.png; 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>"; };
|
||||
@ -303,9 +304,8 @@
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
99F6494C6B1A24363CCC6D32 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
BDB5B400176768766E85D5EB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
DC20461C9C4624BEB2DCD779 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
DAD8EE71BE7C05B99667C256 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
ED1F1A04428235FB1B6FD471 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -313,7 +313,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3EF1E85D6F1EE0C0DCF8449F /* Pods_Runner.framework in Frameworks */,
|
||||
CD1142BE3A076363977FB03C /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -323,9 +323,9 @@
|
||||
780FAA17A040B9755AD6154A /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DC20461C9C4624BEB2DCD779 /* Pods-Runner.debug.xcconfig */,
|
||||
99F6494C6B1A24363CCC6D32 /* Pods-Runner.release.xcconfig */,
|
||||
BDB5B400176768766E85D5EB /* Pods-Runner.profile.xcconfig */,
|
||||
0BEB3ADCCEC961E2916B9004 /* Pods-Runner.debug.xcconfig */,
|
||||
265F8968B3CDB02494B21491 /* Pods-Runner.release.xcconfig */,
|
||||
DAD8EE71BE7C05B99667C256 /* Pods-Runner.profile.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
@ -348,18 +348,18 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8297E4132AE75BEE00E886FA /* Msg.m */,
|
||||
8297E4142AE75BEE00E886FA /* UI.h */,
|
||||
8297E4152AE75BEE00E886FA /* HttpManager.h */,
|
||||
8297E4162AE75BEE00E886FA /* UDP */,
|
||||
8297E41B2AE75BEE00E886FA /* Sformat.m */,
|
||||
8297E41C2AE75BEE00E886FA /* Pub.h */,
|
||||
8297E41D2AE75BEE00E886FA /* sysInfo.h */,
|
||||
8297E41E2AE75BEE00E886FA /* Msg.h */,
|
||||
8297E41F2AE75BEE00E886FA /* Sformat.h */,
|
||||
8297E4202AE75BEE00E886FA /* HttpManager.m */,
|
||||
8297E4142AE75BEE00E886FA /* UI.h */,
|
||||
8297E4212AE75BEE00E886FA /* UI.m */,
|
||||
8297E4222AE75BEE00E886FA /* sysInfo.m */,
|
||||
8297E41C2AE75BEE00E886FA /* Pub.h */,
|
||||
8297E4232AE75BEE00E886FA /* Pub.m */,
|
||||
8297E41F2AE75BEE00E886FA /* Sformat.h */,
|
||||
8297E41B2AE75BEE00E886FA /* Sformat.m */,
|
||||
8297E4152AE75BEE00E886FA /* HttpManager.h */,
|
||||
8297E4202AE75BEE00E886FA /* HttpManager.m */,
|
||||
8297E41D2AE75BEE00E886FA /* sysInfo.h */,
|
||||
8297E4222AE75BEE00E886FA /* sysInfo.m */,
|
||||
8297E4162AE75BEE00E886FA /* UDP */,
|
||||
8297E4242AE75BEE00E886FA /* Talk */,
|
||||
);
|
||||
path = Utils;
|
||||
@ -428,7 +428,6 @@
|
||||
8297E4562AE75D4E00E886FA /* OpenPwd.m */,
|
||||
8297E4572AE75D4E00E886FA /* P2pTest.h */,
|
||||
8297E4582AE75D4E00E886FA /* Web.m */,
|
||||
8297E4592AE75D4E00E886FA /* Call.h */,
|
||||
8297E45A2AE75D4E00E886FA /* Setting.m */,
|
||||
8297E45B2AE75D4E00E886FA /* FaceUpload.m */,
|
||||
8297E45C2AE75D4E00E886FA /* EquAdd.m */,
|
||||
@ -439,8 +438,9 @@
|
||||
8297E4612AE75D4E00E886FA /* P2pTest.m */,
|
||||
8297E4622AE75D4E00E886FA /* EquConfig.h */,
|
||||
8297E4632AE75D4E00E886FA /* Setting.h */,
|
||||
8297E4642AE75D4E00E886FA /* Call.m */,
|
||||
8297E4652AE75D4E00E886FA /* Web.h */,
|
||||
8297E4592AE75D4E00E886FA /* Call.h */,
|
||||
8297E4642AE75D4E00E886FA /* Call.m */,
|
||||
);
|
||||
path = NextPage;
|
||||
sourceTree = "<group>";
|
||||
@ -565,14 +565,6 @@
|
||||
path = img;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9304F75C378DB3447BB2408C /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
09D8B2FA2B26BA5BFF31AB2A /* Pods_Runner.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -591,7 +583,7 @@
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
780FAA17A040B9755AD6154A /* Pods */,
|
||||
9304F75C378DB3447BB2408C /* Frameworks */,
|
||||
B8F749EDCB3FB55CC9253F00 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@ -635,6 +627,14 @@
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B8F749EDCB3FB55CC9253F00 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ED1F1A04428235FB1B6FD471 /* Pods_Runner.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@ -642,14 +642,14 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
03BC065FC3064C0B6EE97546 /* [CP] Check Pods Manifest.lock */,
|
||||
818C8F3353996877C27F8ACC /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
D9B107A6B141D5F15BC356F2 /* [CP] Copy Pods Resources */,
|
||||
C87CD71185302EE14BA1323E /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -783,7 +783,23 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
03BC065FC3064C0B6EE97546 /* [CP] Check Pods Manifest.lock */ = {
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
||||
);
|
||||
name = "Thin Binary";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
|
||||
};
|
||||
818C8F3353996877C27F8ACC /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@ -805,22 +821,6 @@
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
||||
);
|
||||
name = "Thin Binary";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
@ -836,7 +836,7 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
|
||||
};
|
||||
D9B107A6B141D5F15BC356F2 /* [CP] Copy Pods Resources */ = {
|
||||
C87CD71185302EE14BA1323E /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@ -989,6 +989,7 @@
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_NO_COMMON_BLOCKS = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -1106,6 +1107,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "cn.star-lock.starLock";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
@ -1238,6 +1240,7 @@
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_NO_COMMON_BLOCKS = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -1355,6 +1358,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "cn.star-lock.starLock";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
@ -1381,6 +1385,7 @@
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_NO_COMMON_BLOCKS = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -1498,6 +1503,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "cn.star-lock.starLock";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>应用在前台的时候可以搜到更新的位置信息</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>用于音频插件</string>
|
||||
<string>应用请求麦克风用来通话</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>用于相册</string>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
|
||||
@ -97,6 +97,7 @@ static bool isVedioStop;
|
||||
[arecord AudioEnd];
|
||||
}
|
||||
|
||||
// 保持连接
|
||||
- (void)connect_ini {
|
||||
_connect_reg_time = [Sformat timestamp];
|
||||
Byte connect_bb[512];
|
||||
@ -642,22 +643,24 @@ static bool isVedioStop;
|
||||
|
||||
isVedioStop= NO;
|
||||
|
||||
|
||||
// 呼叫应答,呼叫成功
|
||||
memcpy(bbsend, bb, 62);
|
||||
bbsend[7] = 1;
|
||||
bbsend[8] = 4;
|
||||
NSLog(@"replay talk ip=%@;port=%d", ip, port);
|
||||
[[Pub getApp].udp sendDataInMain:bbsend length:512 toHost:ip toPort:port];
|
||||
|
||||
// 门锁发送视频
|
||||
memcpy(bbsend, bb, 62);
|
||||
bbsend[7] = 1;
|
||||
bbsend[8] = 5;
|
||||
NSLog(@"replay talk ip=%@;port=%d", ip, port);
|
||||
[[Pub getApp].udp sendDataInMain:bbsend length:512 toHost:ip toPort:port];
|
||||
|
||||
//定时报告
|
||||
// 定时报告
|
||||
[self connect_ini];
|
||||
[self connect];
|
||||
// 设置定时器,得到连接时间
|
||||
timer = [NSTimer scheduledTimerWithTimeInterval:1
|
||||
target:self selector:@selector(connect)
|
||||
userInfo:nil repeats:YES];
|
||||
@ -855,13 +858,19 @@ static char cnt;
|
||||
}
|
||||
else{//视频数据
|
||||
NSData *data1 = [[NSData alloc] initWithBytes:bb length:60+32];
|
||||
// 音视频数据开始下标
|
||||
BAGLEN = [Pub getShortFromByte:bb at:POS_blen + 2];
|
||||
// 获取帧序号 63
|
||||
iframe_index = [Pub getShortFromByte:bb at:POS_iframe_index];
|
||||
// 获取帧长度 65
|
||||
alen = [Pub getShortFromByte:bb at:POS_alen];
|
||||
blen = [Pub getShortFromByte:bb at:POS_blen];
|
||||
// 当前包号 71
|
||||
bag_index = bb[POS_bag_index]&0xff ;
|
||||
// 总包数 69
|
||||
bag_num = bb[POS_bag_num]&0xff;
|
||||
|
||||
// 数据长度 73
|
||||
blen = [Pub getShortFromByte:bb at:POS_blen];
|
||||
|
||||
if(iframe_index != iframe.iframe_index){
|
||||
iframe = [[IframeInfo alloc] init];
|
||||
iframe.iframe_index = iframe_index;
|
||||
|
||||
@ -42,15 +42,18 @@
|
||||
{
|
||||
_udp_datas = [[NSMutableArray alloc] init];
|
||||
udp_data_class *list;
|
||||
_udp_list = [[udp_data_class alloc] init];
|
||||
// _udp_list = [[udp_data_class alloc] init];
|
||||
|
||||
for (int i=0; i<BUFNUM; i++) {
|
||||
list = [[udp_data_class alloc] init];
|
||||
list.isUsed = FALSE;
|
||||
[_udp_datas addObject:list];
|
||||
}
|
||||
// 没有任何意义 只是为了条件无限循环
|
||||
_udp_send_tag = YES;
|
||||
// 记录子线程发送的次数
|
||||
_udp_send_time = 0;
|
||||
// 创建一个子线程
|
||||
[NSThread detachNewThreadSelector:@selector(udp_send_thr) toTarget:self withObject:nil];
|
||||
|
||||
}
|
||||
@ -58,6 +61,7 @@
|
||||
//upd 线程
|
||||
- (void)udp_send_thr{
|
||||
while(_udp_send_tag){
|
||||
// 如果线程发送的次数小于等于0 不发送等待
|
||||
while (_udp_send_time <= 0) {
|
||||
@try
|
||||
{
|
||||
@ -71,17 +75,23 @@
|
||||
}
|
||||
[_udp_send_Condition lock];
|
||||
//事件
|
||||
// 有事件发送
|
||||
BOOL hasDataSend = YES;
|
||||
while (hasDataSend) {
|
||||
@try
|
||||
{
|
||||
// 如果有事件发送 立马改变状态
|
||||
hasDataSend = FALSE;
|
||||
// 遍历子线程 创建的队列里面的对象
|
||||
for(int i=0; i<BUFNUM; i++) {
|
||||
// 取到创建的队列里面的对象
|
||||
_udp_list = [_udp_datas objectAtIndex:i];
|
||||
//NSLog(@"send to i=%d, port = %d, _udp_datas.count = %lu", i, _udp_list.port, (unsigned long)_udp_datas.count);
|
||||
if (_udp_list.isUsed) { //向服务器发送数据
|
||||
// isUsed为yes 说明有向服务器发送数据
|
||||
if (_udp_list.isUsed) {
|
||||
NSLog(@"hasDataSend:i=%d", i);
|
||||
if(_udp_list.sendtimes < _udp_list.sendtimesneed) { //发送时间超时判断
|
||||
//发送时间超时判断
|
||||
if(_udp_list.sendtimes < _udp_list.sendtimesneed) {
|
||||
hasDataSend = YES;
|
||||
_udp_list.sendtimes ++;
|
||||
[_udp_datas replaceObjectAtIndex:i withObject:_udp_list];
|
||||
@ -557,8 +567,7 @@ void storeDataInByteArray(Byte a[], id data, NSUInteger index) {
|
||||
withTimeout:-1
|
||||
tag:0];
|
||||
[Pub getApp].talk.connect_reg_time = [Sformat timestamp];
|
||||
}
|
||||
else{
|
||||
}else{
|
||||
//NSLog(@"保持连接反馈");
|
||||
[Pub getApp].talk.connect_reg_time = [Sformat timestamp];
|
||||
}
|
||||
@ -572,8 +581,7 @@ void storeDataInByteArray(Byte a[], id data, NSUInteger index) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else{
|
||||
}else{
|
||||
if([self stopSend:@"" rr6:152 rr8:10]>-1){
|
||||
[[Pub getApp] OpenDoorFail:[Pub getEquidFrombb:bb at:9]];
|
||||
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
@ -14,7 +13,7 @@ import 'reciver_data.dart';
|
||||
//连接状态回调
|
||||
typedef ConnectStateCallBack = Function(DeviceConnectionState connectionState);
|
||||
|
||||
class BlueManage{
|
||||
class BlueManage {
|
||||
FlutterReactiveBle? _flutterReactiveBle;
|
||||
final List<DiscoveredDevice> scanDevices = [];
|
||||
|
||||
@ -25,7 +24,7 @@ class BlueManage{
|
||||
// 用来写入的特征id
|
||||
Uuid characteristicIdWrite = Uuid.parse("fff2");
|
||||
|
||||
// 发送监听发送事件
|
||||
// 监听发送事件
|
||||
StreamSubscription<EventSendModel>? _sendStreamSubscription;
|
||||
// 监听蓝牙扫描的事件
|
||||
StreamSubscription? _scanSubscription;
|
||||
@ -37,13 +36,14 @@ class BlueManage{
|
||||
// 当前连接设备的mac地址
|
||||
String connectDeviceMacAddress = "";
|
||||
// 监听蓝牙连接状态
|
||||
DeviceConnectionState? deviceConnectionState = DeviceConnectionState.disconnected;
|
||||
DeviceConnectionState? deviceConnectionState =
|
||||
DeviceConnectionState.disconnected;
|
||||
|
||||
static BlueManage? _manager;
|
||||
BlueManage._init();
|
||||
|
||||
static BlueManage? shareManager(){
|
||||
_manager ??= BlueManage._init();
|
||||
static BlueManage? shareManager() {
|
||||
_manager ??= BlueManage._init();
|
||||
_manager!._initBlue();
|
||||
return _manager;
|
||||
}
|
||||
@ -51,34 +51,42 @@ class BlueManage{
|
||||
factory BlueManage() => shareManager()!;
|
||||
BlueManage? get manager => shareManager();
|
||||
|
||||
void _initBlue(){
|
||||
void _initBlue() {
|
||||
_flutterReactiveBle ??= FlutterReactiveBle();
|
||||
print("蓝牙功能初始化了");
|
||||
_initSendStreamSubscription();
|
||||
}
|
||||
|
||||
void _initSendStreamSubscription() {
|
||||
_sendStreamSubscription ??= EventBusManager().eventBus!.on<EventSendModel>().listen((
|
||||
EventSendModel model) {
|
||||
if (model.sendChannel == DataChannel.ble) {
|
||||
// managerAppWriteData(model.data);
|
||||
writeCharacteristicWithResponse(model.data);
|
||||
}
|
||||
});
|
||||
_sendStreamSubscription ??= EventBusManager()
|
||||
.eventBus!
|
||||
.on<EventSendModel>()
|
||||
.listen((EventSendModel model) {
|
||||
if (model.sendChannel == DataChannel.ble) {
|
||||
// managerAppWriteData(model.data);
|
||||
writeCharacteristicWithResponse(model.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// 开始扫描蓝牙设备
|
||||
void startScan({List<Uuid>? idList}) {
|
||||
scanDevices.clear();
|
||||
_scanSubscription = _flutterReactiveBle!.scanForDevices(withServices: idList??[]).listen((device) {
|
||||
_scanSubscription = _flutterReactiveBle!
|
||||
.scanForDevices(withServices: idList ?? [])
|
||||
.listen((device) {
|
||||
// 判断名字为空的直接剔除
|
||||
if(device.name.isEmpty){
|
||||
if (device.name.isEmpty) {
|
||||
return;
|
||||
}
|
||||
// print("startScanDevice:$device");
|
||||
if (((device.serviceUuids.isNotEmpty ? device.serviceUuids[0] : "").toString().contains("758824")) && (device.rssi >= -100)) {
|
||||
if (((device.serviceUuids.isNotEmpty ? device.serviceUuids[0] : "")
|
||||
.toString()
|
||||
.contains("758824")) &&
|
||||
(device.rssi >= -100)) {
|
||||
// 查询id相同的元素
|
||||
final knownDeviceIndex = scanDevices.indexWhere((d) => d.id == device.id);
|
||||
final knownDeviceIndex =
|
||||
scanDevices.indexWhere((d) => d.id == device.id);
|
||||
// 不存在的时候返回-1
|
||||
if (knownDeviceIndex >= 0) {
|
||||
scanDevices[knownDeviceIndex] = device;
|
||||
@ -93,10 +101,13 @@ class BlueManage{
|
||||
}
|
||||
|
||||
/// 连接监听状态
|
||||
Future<void> connect(String deviceName, ConnectStateCallBack connectStateCallBack, {bool? isFrist = false ,bool isShowLoading = true}) async {
|
||||
Future<void> connect(
|
||||
String deviceName, ConnectStateCallBack connectStateCallBack,
|
||||
{bool? isFrist = false, bool isShowLoading = true}) async {
|
||||
connectDeviceName = deviceName;
|
||||
// 判断数组列表里面是否有这个设备
|
||||
final knownDeviceIndex = scanDevices.indexWhere((d) => d.name == deviceName);
|
||||
final knownDeviceIndex =
|
||||
scanDevices.indexWhere((d) => d.name == deviceName);
|
||||
|
||||
if (knownDeviceIndex >= 0) {
|
||||
// 存在的时候赋值
|
||||
@ -108,7 +119,7 @@ class BlueManage{
|
||||
Timer.periodic(const Duration(milliseconds: 1000), (timer) {
|
||||
///定时任务
|
||||
print("timer index:$index");
|
||||
if(index >= 4){
|
||||
if (index >= 4) {
|
||||
// 当超过5秒的时候取消定时任务 弹窗显示连接失败
|
||||
completer.complete();
|
||||
timer.cancel();
|
||||
@ -116,9 +127,10 @@ class BlueManage{
|
||||
deviceConnectionState = DeviceConnectionState.disconnected;
|
||||
connectStateCallBack(deviceConnectionState!);
|
||||
Toast.show(msg: "未扫描到要连接的设备,请确保在设备附近,设备未被连接,设备已打开");
|
||||
}else{
|
||||
} else {
|
||||
// 每秒判断数组列表里面是否有这个设备
|
||||
final knownDeviceIndex = scanDevices.indexWhere((d) => d.name == deviceName);
|
||||
final knownDeviceIndex =
|
||||
scanDevices.indexWhere((d) => d.name == deviceName);
|
||||
if (knownDeviceIndex >= 0) {
|
||||
// 存在的时候销毁定时器,赋值
|
||||
completer.complete();
|
||||
@ -135,23 +147,33 @@ class BlueManage{
|
||||
await completer.future;
|
||||
// print("111111");
|
||||
}
|
||||
print("connectDeviceId:$connectDeviceMacAddress connectDeviceName:$connectDeviceName");
|
||||
print(
|
||||
"connectDeviceId:$connectDeviceMacAddress connectDeviceName:$connectDeviceName");
|
||||
|
||||
if(connectDeviceMacAddress.isEmpty){
|
||||
if (connectDeviceMacAddress.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
_currentConnectionStream = _flutterReactiveBle!.connectToDevice(id: connectDeviceMacAddress, connectionTimeout: const Duration(milliseconds: 10000)).listen((connectionStateUpdate) async {
|
||||
_currentConnectionStream = _flutterReactiveBle!
|
||||
.connectToDevice(
|
||||
id: connectDeviceMacAddress,
|
||||
connectionTimeout: const Duration(milliseconds: 10000))
|
||||
.listen((connectionStateUpdate) async {
|
||||
// 获取状态
|
||||
deviceConnectionState = connectionStateUpdate.connectionState;
|
||||
print('deviceConnectionState:$deviceConnectionState connectionStateUpdate.connectionState:${connectionStateUpdate.connectionState}');
|
||||
if(connectionStateUpdate.connectionState == DeviceConnectionState.connected){
|
||||
print(
|
||||
'deviceConnectionState:$deviceConnectionState connectionStateUpdate.connectionState:${connectionStateUpdate.connectionState}');
|
||||
if (connectionStateUpdate.connectionState ==
|
||||
DeviceConnectionState.connected) {
|
||||
// 如果状态是连接的开始发现服务
|
||||
try {
|
||||
_subScribeToCharacteristic(QualifiedCharacteristic(characteristicId: characteristicIdSubscription, serviceId: Uuid.parse("fff0"), deviceId: connectDeviceMacAddress));
|
||||
_subScribeToCharacteristic(QualifiedCharacteristic(
|
||||
characteristicId: characteristicIdSubscription,
|
||||
serviceId: Uuid.parse("fff0"),
|
||||
deviceId: connectDeviceMacAddress));
|
||||
print('Discovering services finished');
|
||||
|
||||
if(isFrist == true){
|
||||
if (isFrist == true) {
|
||||
// 第一次添加锁的时候需要先获取公钥
|
||||
IoSenderManage.getPublicKey(lockId: deviceName);
|
||||
}
|
||||
@ -164,59 +186,68 @@ class BlueManage{
|
||||
print('Error occurred when discovering services: $e');
|
||||
rethrow;
|
||||
}
|
||||
} else{
|
||||
} else {
|
||||
deviceConnectionState = connectionStateUpdate.connectionState;
|
||||
connectStateCallBack(deviceConnectionState!);
|
||||
}
|
||||
print('ConnectionState for device $connectDeviceMacAddress : ${connectionStateUpdate.connectionState}');
|
||||
}, onError: (Object e){
|
||||
print(
|
||||
'ConnectionState for device $connectDeviceMacAddress : ${connectionStateUpdate.connectionState}');
|
||||
}, onError: (Object e) {
|
||||
deviceConnectionState = DeviceConnectionState.disconnected;
|
||||
connectStateCallBack(deviceConnectionState!);
|
||||
print('Connecting to device $connectDeviceMacAddress resulted in error $e');
|
||||
}
|
||||
);
|
||||
print(
|
||||
'Connecting to device $connectDeviceMacAddress resulted in error $e');
|
||||
});
|
||||
}
|
||||
|
||||
// 重新连接
|
||||
Future<void> judgeReconnect(String deviceName, ConnectStateCallBack stateCallBack, {bool isShowLoading = true}) async {
|
||||
if(deviceConnectionState != DeviceConnectionState.connected){
|
||||
connect(deviceName, (state){
|
||||
Future<void> judgeReconnect(
|
||||
String deviceName, ConnectStateCallBack stateCallBack,
|
||||
{bool isShowLoading = true}) async {
|
||||
if (deviceConnectionState != DeviceConnectionState.connected) {
|
||||
connect(deviceName, (state) {
|
||||
stateCallBack(deviceConnectionState!);
|
||||
}, isShowLoading: false);
|
||||
}else{
|
||||
} else {
|
||||
stateCallBack(deviceConnectionState!);
|
||||
}
|
||||
}
|
||||
|
||||
// 听上报来的数据,参数来自前面扫描到的结果
|
||||
var allData = <int>[];
|
||||
int? dataLen;
|
||||
_subScribeToCharacteristic(QualifiedCharacteristic characteristic) {
|
||||
_flutterReactiveBle!.subscribeToCharacteristic(characteristic).listen((data) {
|
||||
_flutterReactiveBle!.subscribeToCharacteristic(characteristic).listen(
|
||||
(data) {
|
||||
// code to handle incoming data
|
||||
print("subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data");
|
||||
var dataLen = 0;// 高16位用来指示后面数据块内容的长度
|
||||
|
||||
if((data[0] == 0xEF)&&(data[1] == 0x01)&&(data[2] == 0xEE)&&(data[3] == 0x02)){
|
||||
print(
|
||||
"subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data");
|
||||
if ((data[0] == 0xEF) &&
|
||||
(data[1] == 0x01) &&
|
||||
(data[2] == 0xEE) &&
|
||||
(data[3] == 0x02)) {
|
||||
// 当包有头时
|
||||
// 判断是否需要分包
|
||||
dataLen = data[8] * 256 + data[9];
|
||||
// print("dataLen1111:$dataLen getDataLength:${data.length}");
|
||||
if(dataLen + 12 > data.length){
|
||||
dataLen = data[8] * 256 + data[9]; // 高16位用来指示后面数据块内容的长度
|
||||
print("dataLen1111:$dataLen getDataLength:${data.length}");
|
||||
if (dataLen! + 12 > data.length) {
|
||||
// 当前包的长度小于实际的包时 分包添加 不解析
|
||||
allData.addAll(data);
|
||||
}else{
|
||||
} else {
|
||||
// 当前包的长度小于实际的包时 不分包 解析
|
||||
allData.addAll(data);
|
||||
print("dataLen2222:$dataLen getDataLength:${data.length}");
|
||||
CommandReciverManager.appDataReceive(allData);
|
||||
// 发送完解析初始化数组
|
||||
allData = <int>[];
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
// 当包没有头时 是分包的包 直接添加
|
||||
allData.addAll(data);
|
||||
// var len = allData[8] * 256 + allData[9];
|
||||
// print("dataLen222:$dataLen");
|
||||
if(dataLen <= (allData.length - 14)){
|
||||
print("dataLen3333:$dataLen");
|
||||
if ((dataLen! + 14) <= allData.length) {
|
||||
print("44444数据被解析了");
|
||||
// 当长度小于等于当前包的数据时 直接解析数据
|
||||
CommandReciverManager.appDataReceive(allData);
|
||||
// 发送完解析初始化数组
|
||||
@ -231,17 +262,23 @@ class BlueManage{
|
||||
|
||||
// 写入
|
||||
Future<void> writeCharacteristicWithResponse(List<int> value) async {
|
||||
QualifiedCharacteristic characteristic = QualifiedCharacteristic(characteristicId: characteristicIdWrite, serviceId: serviceId, deviceId: connectDeviceMacAddress);
|
||||
QualifiedCharacteristic characteristic = QualifiedCharacteristic(
|
||||
characteristicId: characteristicIdWrite,
|
||||
serviceId: serviceId,
|
||||
deviceId: connectDeviceMacAddress);
|
||||
// print('Write with characteristicId:${characteristic.characteristicId} serviceId:${characteristic.serviceId} deviceId:${characteristic.deviceId} value : $value \nhexStr:${radixHex16String(value)}');
|
||||
int mtuLength = await _flutterReactiveBle!.requestMtu(deviceId: characteristic.deviceId, mtu: 250);
|
||||
print("mtuLength:$mtuLength");
|
||||
int mtuLength = await _flutterReactiveBle!
|
||||
.requestMtu(deviceId: characteristic.deviceId, mtu: 250);
|
||||
// print("mtuLength:$mtuLength");
|
||||
try {
|
||||
List<int> valueList = value;
|
||||
List subData = splitList(valueList, mtuLength);
|
||||
print('得到的分割数据:$subData');
|
||||
|
||||
for (int i = 0; i < subData.length; i++) {
|
||||
await _flutterReactiveBle!.writeCharacteristicWithResponse(characteristic, value: subData[i]).then((value) async {
|
||||
await _flutterReactiveBle!
|
||||
.writeCharacteristicWithResponse(characteristic, value: subData[i])
|
||||
.then((value) async {
|
||||
await Future.delayed(const Duration(milliseconds: 1))
|
||||
.then((value) async {
|
||||
print('分包发送成功了');
|
||||
@ -257,13 +294,17 @@ class BlueManage{
|
||||
}
|
||||
|
||||
// 读取
|
||||
Future<List<int>> readCharacteristic(QualifiedCharacteristic characteristic) async {
|
||||
Future<List<int>> readCharacteristic(
|
||||
QualifiedCharacteristic characteristic) async {
|
||||
try {
|
||||
final result = await _flutterReactiveBle!.readCharacteristic(characteristic);
|
||||
final result =
|
||||
await _flutterReactiveBle!.readCharacteristic(characteristic);
|
||||
print("readListresult$result");
|
||||
return result;
|
||||
} on Exception catch (e, s) {
|
||||
print('Error occurred when reading ${characteristic.characteristicId} : $e',);
|
||||
print(
|
||||
'Error occurred when reading ${characteristic.characteristicId} : $e',
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
@ -271,8 +312,8 @@ class BlueManage{
|
||||
Future<void> writeCharacteristicWithoutResponse(
|
||||
QualifiedCharacteristic characteristic, List<int> value) async {
|
||||
try {
|
||||
await _flutterReactiveBle!.writeCharacteristicWithoutResponse(characteristic,
|
||||
value: value);
|
||||
await _flutterReactiveBle!
|
||||
.writeCharacteristicWithoutResponse(characteristic, value: value);
|
||||
} on Exception catch (e, s) {
|
||||
// ignore: avoid_print
|
||||
print(s);
|
||||
@ -299,9 +340,9 @@ class BlueManage{
|
||||
}
|
||||
}
|
||||
|
||||
disposed(){
|
||||
disposed() {
|
||||
_sendStreamSubscription?.cancel();
|
||||
_currentConnectionStream?.cancel();
|
||||
_scanSubscription?.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,8 @@ class SenderConfiguringWifiCommand extends SenderProtocol {
|
||||
String? password;
|
||||
int? numberOfServers;
|
||||
List<int>? listOfServers;
|
||||
int? numberOfPhone;
|
||||
List<String>? listOfPhone;
|
||||
List<int>? token;
|
||||
int? needAuthor;
|
||||
List<int>? publicKey;
|
||||
@ -29,6 +31,8 @@ class SenderConfiguringWifiCommand extends SenderProtocol {
|
||||
this.password,
|
||||
this.numberOfServers,
|
||||
this.listOfServers,
|
||||
this.numberOfPhone,
|
||||
this.listOfPhone,
|
||||
this.token,
|
||||
this.needAuthor,
|
||||
this.publicKey,
|
||||
@ -78,6 +82,16 @@ class SenderConfiguringWifiCommand extends SenderProtocol {
|
||||
// listOfServers
|
||||
subData.addAll(listOfServers!);
|
||||
|
||||
// NumberOfPhone
|
||||
subData.add(numberOfPhone!);
|
||||
|
||||
// listOfPhone
|
||||
listOfPhone!.forEach((element) {
|
||||
int phoneLength = utf8.encode(element).length;
|
||||
subData.addAll(utf8.encode(element));
|
||||
subData = getFixedLengthList(subData, 20 - phoneLength);
|
||||
});
|
||||
|
||||
// token
|
||||
// subData.addAll(token!);
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
|
||||
import 'io_type.dart';
|
||||
|
||||
|
||||
|
||||
abstract class Reply{
|
||||
|
||||
CommandType? commandType;
|
||||
|
||||
@ -21,7 +21,7 @@ class IoManager {
|
||||
///蓝牙传输协议
|
||||
void bleTransmission() => _dataTransmissionMode = DataTransmissionMode.ble;
|
||||
|
||||
///割草机协议帧序号
|
||||
///协议帧序号
|
||||
int _commandIndex = 1;
|
||||
configCommandIdx(int idx) => _commandIndex = idx;
|
||||
Future<void> increaseCommandIndex() async {
|
||||
|
||||
@ -3,11 +3,13 @@ import 'package:uuid/uuid.dart';
|
||||
|
||||
///发送数据类
|
||||
enum DataChannel{
|
||||
ble
|
||||
ble,
|
||||
udp
|
||||
}
|
||||
|
||||
extension Extension on DataChannel {
|
||||
bool get isBLE => this == DataChannel.ble;
|
||||
bool get isUDP => this == DataChannel.udp;
|
||||
}
|
||||
|
||||
class EventSendModel {
|
||||
|
||||
@ -24,9 +24,7 @@ class CommandSenderManager {
|
||||
bool canSendControlCommand = false;
|
||||
|
||||
//TODO:发送常规数据
|
||||
Future<void> managerSendData ({
|
||||
required SenderProtocol command,
|
||||
CommandSendCallBack? callBack}) async {
|
||||
Future<void> managerSendData ({required SenderProtocol command, CommandSendCallBack? callBack}) async {
|
||||
if (callBack != null) {
|
||||
// if (!BluetoothManager().connected) {
|
||||
print('❌ 蓝牙断开了');
|
||||
|
||||
@ -519,6 +519,8 @@ class IoSenderManage {
|
||||
required String? password,
|
||||
required int? numberOfServers,
|
||||
required List<int>? listOfServers,
|
||||
required int? numberOfPhone,
|
||||
required List<String>? listOfPhone,
|
||||
required List<int>? token,
|
||||
required int? needAuthor,
|
||||
required List<int>? publicKey,
|
||||
@ -532,6 +534,8 @@ class IoSenderManage {
|
||||
password: password,
|
||||
numberOfServers: numberOfServers,
|
||||
listOfServers: listOfServers,
|
||||
numberOfPhone: numberOfPhone,
|
||||
listOfPhone: listOfPhone,
|
||||
token: token,
|
||||
needAuthor: needAuthor,
|
||||
publicKey: publicKey,
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import 'package:aliyun_push/aliyun_push.dart';
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
// import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_pcm_sound/flutter_pcm_sound.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_sound/flutter_sound.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:star_lock/tools/app_manager.dart';
|
||||
@ -52,6 +55,9 @@ final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
|
||||
class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
|
||||
final _aliyunPush = AliyunPush();
|
||||
var _deviceId = "";
|
||||
// final audioPlayer = AudioPlayer();
|
||||
final FlutterSoundPlayer _audioPlayer = FlutterSoundPlayer();
|
||||
late List<int> allDataBytes;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -81,7 +87,8 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
|
||||
}
|
||||
}
|
||||
// print("localelocalelocalelocalelocale locale:${locale} locale.languageCode:${locale.languageCode} locale.countryCode:${locale.countryCode} supportedLocales:${supportedLocales}");
|
||||
AppManager().setLanCode(code: '${locale!.languageCode}_${locale.countryCode}');
|
||||
AppManager()
|
||||
.setLanCode(code: '${locale!.languageCode}_${locale.countryCode}');
|
||||
return locale;
|
||||
},
|
||||
// locale: StoreService.to.getLanguageCode().isNotEmpty ? appDept.deptSupportedLocales.where((element) => element.languageCode == StoreService.to.getLanguageCode()).first : Get.deviceLocale,
|
||||
@ -187,25 +194,25 @@ Future _setCommonServices() async {
|
||||
// Get.log(PlatformInfoService.to.info.version);
|
||||
}
|
||||
|
||||
void openBlueScan(){
|
||||
if(Platform.isIOS){
|
||||
void openBlueScan() {
|
||||
if (Platform.isIOS) {
|
||||
print("有蓝牙权限开始扫描");
|
||||
startScanAction();
|
||||
}else{
|
||||
} else {
|
||||
getMicrophonePermission().then((value) {
|
||||
if (value) {
|
||||
// 有权限
|
||||
print("有蓝牙权限开始扫描");
|
||||
startScanAction();
|
||||
}else{
|
||||
} else {
|
||||
//没有权限
|
||||
openAppSettings();//打开app系统设置
|
||||
openAppSettings(); //打开app系统设置
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void startScanAction(){
|
||||
void startScanAction() {
|
||||
BlueManage().startScan();
|
||||
}
|
||||
|
||||
@ -226,18 +233,3 @@ Future<bool> getMicrophonePermission() async {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//播放本地音频
|
||||
// void playAudio() async {
|
||||
// const String audioPath = "assets/ring1.mp3";
|
||||
// AudioPlayer audioPlayer = AudioPlayer();
|
||||
// // int result = await audioPlayer.play(audioPath, isLocal: true);
|
||||
|
||||
// if (result == 1) {
|
||||
// // 播放成功
|
||||
// print("Audio playback successful!");
|
||||
// } else {
|
||||
// // 播放失败
|
||||
// print("Error playing audio");
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:get/get.dart';
|
||||
@ -138,35 +137,49 @@ class CheckingInAddStaffLogic extends BaseGetXController{
|
||||
have: state.appUnHaveAccount.value ? "2" : "1",
|
||||
staffName: state.staffNameController.text,
|
||||
countryCode: state.countryCode.value,
|
||||
usernameType:usernameType,
|
||||
usernameType: usernameType,
|
||||
);
|
||||
if(entity.errorCode!.codeIsSuccessful){
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
eventBus.fire(RefreshCheckInStaffListDataEvent());
|
||||
Get.close(2);
|
||||
}else if(entity.errorCode! == 425){
|
||||
} else if (entity.errorCode! == 425) {
|
||||
Toast.show(msg: entity.errorMsg!);
|
||||
}
|
||||
}
|
||||
|
||||
//获取密码请求
|
||||
void getKeyboardPwdRequest() async {
|
||||
if(state.staffNameController.text.isEmpty){
|
||||
if (state.staffNameController.text.isEmpty) {
|
||||
Toast.show(msg: "请输入姓名");
|
||||
return;
|
||||
}
|
||||
// var entity = await ApiRepository.to.getPasswordKey(
|
||||
// "0",
|
||||
// '0',
|
||||
// state.staffNameController.text,
|
||||
// 2.toString(),
|
||||
// '0',
|
||||
// state.getKeyInfosData.value.lockId.toString(),
|
||||
// '0',
|
||||
// "0",
|
||||
// '0',
|
||||
// 0,
|
||||
// 0,
|
||||
// 1);
|
||||
var entity = await ApiRepository.to.getPasswordKey(
|
||||
"0",
|
||||
'0',
|
||||
state.staffNameController.text,
|
||||
2.toString(),
|
||||
'0',
|
||||
state.getKeyInfosData.value.lockId.toString(),
|
||||
'0',
|
||||
"0",
|
||||
'0',
|
||||
0,
|
||||
0,
|
||||
1);
|
||||
endDate: "0",
|
||||
isExclusive: '0',
|
||||
keyboardPwdName: state.staffNameController.text,
|
||||
keyboardPwdType: 2.toString(),
|
||||
keyboardPwdVersion: '0',
|
||||
lockId: state.getKeyInfosData.value.lockId.toString(),
|
||||
operatorUid: '0',
|
||||
startDate: '0',
|
||||
timezoneRawOffSet: '0',
|
||||
startHours: 0,
|
||||
endHours: 0,
|
||||
isCoerced: 1);
|
||||
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
print('获取密码成功');
|
||||
if (entity.data != null) {
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetailChangeDate/electronicKeyDetailChangeDate_state.dart';
|
||||
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart';
|
||||
import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKeyEntity.dart';
|
||||
import 'package:star_lock/network/api_repository.dart';
|
||||
import 'package:star_lock/tools/baseGetXController.dart';
|
||||
import 'package:star_lock/tools/toast.dart';
|
||||
|
||||
class ElectronicKeyDetailChangeDateLogic extends BaseGetXController {
|
||||
final ElectronicKeyDetailChangeDateState state =
|
||||
ElectronicKeyDetailChangeDateState();
|
||||
|
||||
//更新密码请求
|
||||
Future<void> updatePwdRequest() async {
|
||||
PasswordKeyEntity entity = await ApiRepository.to.updatePasswordKey(
|
||||
lockId: state.itemData.value.lockId!,
|
||||
keyboardPwdId: state.pwdId.value.toString(),
|
||||
keyboardPwdName: state.inputNameController.text,
|
||||
newKeyboardPwd: state.inputPwdController.text,
|
||||
startDate: state.startDate.value,
|
||||
endDate: state.endDate.value,
|
||||
changeType: state.changeType.value,
|
||||
hoursStart: state.hoursStart.value,
|
||||
hoursEnd: state.hoursEnd.value,
|
||||
isCoerced: state.isCoerced.value);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
Toast.show(msg: "修改成功");
|
||||
Get.back();
|
||||
}
|
||||
}
|
||||
|
||||
//修改钥匙名称请求
|
||||
Future<void> updateKeyDateRequest() async {
|
||||
KeyOperationRecordEntity entity = await ApiRepository.to.updateKeyDate(
|
||||
state.itemData.value.keyId.toString(),
|
||||
state.itemData.value.lockId.toString(),
|
||||
state.failureDateTime.millisecondsSinceEpoch.toString(),
|
||||
state.endDay.value,
|
||||
'',
|
||||
state.effectiveDateTime.millisecondsSinceEpoch.toString(),
|
||||
state.startDay.value,
|
||||
state.weekDays.value);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
Toast.show(msg: "修改成功");
|
||||
Get.back();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_pickers/pickers.dart';
|
||||
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart';
|
||||
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart';
|
||||
import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKeyEntity.dart';
|
||||
import 'package:star_lock/network/api_repository.dart';
|
||||
import 'package:star_lock/tools/baseGetXController.dart';
|
||||
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/electronicKeyDetailChangeDate/electronicKeyDetailChangeDate_logic.dart';
|
||||
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||
import 'package:star_lock/tools/toast.dart';
|
||||
|
||||
import '../../../../../app_settings/app_colors.dart';
|
||||
import '../../../../../tools/commonItem.dart';
|
||||
@ -27,34 +20,11 @@ class ElectronicKeyDetailChangeDate extends StatefulWidget {
|
||||
|
||||
class _ElectronicKeyDetailChangeDateState
|
||||
extends State<ElectronicKeyDetailChangeDate> {
|
||||
ElectronicKeyListItem itemData = ElectronicKeyListItem();
|
||||
|
||||
String _selectEffectiveDate = ''; //生效时间
|
||||
String _selectFailureDate = ''; //失效时间
|
||||
late DateTime _effectiveDateTime;
|
||||
late DateTime _failureDateTime;
|
||||
late String endDay = '';
|
||||
late String startDay = '';
|
||||
late List weekDays = [];
|
||||
late String pwdId = '';
|
||||
late String lockId = '';
|
||||
late String fromType = ''; // 1 从指纹详情进入
|
||||
final logic = Get.put(ElectronicKeyDetailChangeDateLogic());
|
||||
final state = Get.find<ElectronicKeyDetailChangeDateLogic>().state;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
dynamic obj = ModalRoute.of(context)?.settings.arguments;
|
||||
if (obj != null && (obj["itemData"] != null)) {
|
||||
itemData = obj["itemData"];
|
||||
}
|
||||
if (obj != null && (obj["pwdId"] != null)) {
|
||||
pwdId = obj["pwdId"];
|
||||
}
|
||||
if (obj != null && (obj["lockId"] != null)) {
|
||||
lockId = obj["lockId"];
|
||||
}
|
||||
if (obj != null && (obj["fromType"] != null)) {
|
||||
fromType = obj["fromType"];
|
||||
}
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.mainBackgroundColor,
|
||||
appBar: TitleAppBar(
|
||||
@ -69,12 +39,12 @@ class _ElectronicKeyDetailChangeDateState
|
||||
style: TextStyle(color: Colors.white, fontSize: 24.sp),
|
||||
),
|
||||
onPressed: () {
|
||||
if (fromType == "1") {
|
||||
if (state.fromType.value == "1") {
|
||||
} else {
|
||||
if (lockId.isNotEmpty && pwdId.isNotEmpty) {
|
||||
updatePwdRequest();
|
||||
if (state.lockId.value != 0 && state.pwdId.value.isNotEmpty) {
|
||||
logic.updatePwdRequest();
|
||||
} else {
|
||||
updateKeyDateRequest();
|
||||
logic.updateKeyDateRequest();
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -88,77 +58,37 @@ class _ElectronicKeyDetailChangeDateState
|
||||
Widget buildMainUI() {
|
||||
return Column(
|
||||
children: [
|
||||
CommonItem(
|
||||
Obx(() => CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.effectiveTime!.tr,
|
||||
rightTitle: _selectEffectiveDate,
|
||||
rightTitle: state.selectEffectiveDate.value,
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||
onConfirm: (p) {
|
||||
setState(() {
|
||||
_selectEffectiveDate =
|
||||
'${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}';
|
||||
_effectiveDateTime = DateTime.parse(_selectEffectiveDate);
|
||||
});
|
||||
state.selectEffectiveDate.value =
|
||||
'${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}';
|
||||
state.effectiveDateTime =
|
||||
DateTime.parse(state.selectEffectiveDate.value);
|
||||
});
|
||||
}),
|
||||
CommonItem(
|
||||
})),
|
||||
Obx(() => CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.failureTime!.tr,
|
||||
rightTitle: _selectFailureDate,
|
||||
rightTitle: state.selectFailureDate.value,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||
onConfirm: (p) {
|
||||
setState(() {
|
||||
_selectFailureDate =
|
||||
'${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}';
|
||||
_failureDateTime = DateTime.parse(_selectFailureDate);
|
||||
});
|
||||
state.selectFailureDate.value =
|
||||
'${p.year}-${intToStr(p.month!)}-${intToStr(p.day!)} ${intToStr(p.hour!)}:${intToStr(p.minute!)}';
|
||||
state.failureDateTime =
|
||||
DateTime.parse(state.selectFailureDate.value);
|
||||
});
|
||||
}),
|
||||
})),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
//修改钥匙名称请求
|
||||
Future<void> updateKeyDateRequest() async {
|
||||
KeyOperationRecordEntity entity = await ApiRepository.to.updateKeyDate(
|
||||
itemData.keyId.toString(),
|
||||
itemData.lockId.toString(),
|
||||
_failureDateTime.millisecondsSinceEpoch.toString(),
|
||||
endDay,
|
||||
'',
|
||||
_effectiveDateTime.millisecondsSinceEpoch.toString(),
|
||||
startDay,
|
||||
weekDays);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
print("修改要是名称成功啦啦啦啦啦");
|
||||
Toast.show(msg: "修改成功");
|
||||
setState(() {
|
||||
Navigator.pop(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//更新密码请求
|
||||
Future<void> updatePwdRequest() async {
|
||||
PasswordKeyEntity entity = await ApiRepository.to.updatePasswordKey(
|
||||
lockId,
|
||||
pwdId,
|
||||
'',
|
||||
'',
|
||||
_effectiveDateTime.millisecondsSinceEpoch.toString(),
|
||||
_failureDateTime.millisecondsSinceEpoch.toString(),
|
||||
'');
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
Toast.show(msg: "修改成功");
|
||||
setState(() {
|
||||
Navigator.pop(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
String intToStr(int v) {
|
||||
return (v < 10) ? "0$v" : "$v";
|
||||
}
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart';
|
||||
|
||||
class ElectronicKeyDetailChangeDateState {
|
||||
final itemData = ElectronicKeyListItem().obs;
|
||||
final TextEditingController inputPwdController = TextEditingController();
|
||||
final TextEditingController inputNameController = TextEditingController();
|
||||
final changeType = '1'
|
||||
.obs; //1-通过APP走蓝牙修改,不传默认1,必需先通过APP SDK蓝牙修改后调用该接口 2-通过网关或WiFi锁修改,如果是WiFi锁或有连接网关,则可以传2,直接调用该接口修改生效
|
||||
final isCoerced = '1'.obs; //胁迫指纹:1;非胁迫指纹:2(胁迫指纹开锁触发报警)
|
||||
final hoursStart = 0.obs;
|
||||
final hoursEnd = 0.obs;
|
||||
final startDate = 0.obs;
|
||||
final endDate = 0.obs;
|
||||
final pwdId = ''.obs;
|
||||
final lockId = 0.obs;
|
||||
final fromType = ''.obs;
|
||||
final selectEffectiveDate = ''.obs; //生效时间
|
||||
final selectFailureDate = ''.obs; //失效时间
|
||||
DateTime effectiveDateTime = DateTime.now();
|
||||
DateTime failureDateTime = DateTime.now();
|
||||
final endDay = ''.obs;
|
||||
final startDay = ''.obs;
|
||||
final weekDays = [].obs;
|
||||
|
||||
ElectronicKeyDetailChangeDateState() {
|
||||
Map map = Get.arguments;
|
||||
// itemData.value = map["itemData"];
|
||||
if ((map["itemData"] != null)) {
|
||||
itemData.value = map["itemData"];
|
||||
}
|
||||
if ((map["pwdId"] != null)) {
|
||||
pwdId.value = map["pwdId"];
|
||||
}
|
||||
if ((map["lockId"] != null)) {
|
||||
lockId.value = map["lockId"];
|
||||
}
|
||||
if ((map["fromType"] != null)) {
|
||||
fromType.value = map["fromType"];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||
import 'package:network_info_plus/network_info_plus.dart';
|
||||
@ -14,12 +16,15 @@ 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 '../../../../login/login/entity/LoginData.dart';
|
||||
import '../../../../mine/mine/starLockMine_state.dart';
|
||||
import '../../../../network/api_repository.dart';
|
||||
import '../../../../tools/storage.dart';
|
||||
import 'configuringWifi_state.dart';
|
||||
|
||||
class ConfiguringWifiLogic extends BaseGetXController{
|
||||
final ConfiguringWifiState state = ConfiguringWifiState();
|
||||
final StarLockMineState getInfostate = StarLockMineState();
|
||||
|
||||
Future<void> getWifiLockServiceIpAndPort() async {
|
||||
var entity = await ApiRepository.to.getWifiLockServiceIpAndPort();
|
||||
@ -58,7 +63,7 @@ class ConfiguringWifiLogic extends BaseGetXController{
|
||||
|
||||
// WIFI配网结果
|
||||
Future<void> _replySenderConfiguringWifi(Reply reply) async {
|
||||
int status = reply.data[6];
|
||||
int status = reply.data[5];
|
||||
print("status:$status");
|
||||
|
||||
switch(status){
|
||||
@ -97,6 +102,7 @@ class ConfiguringWifiLogic extends BaseGetXController{
|
||||
serversList.add(type2);
|
||||
}
|
||||
|
||||
var phoneList = [getInfostate.mobile()];
|
||||
IoSenderManage.senderConfiguringWifiCommand(
|
||||
keyID: state.lockSetInfoData.value.lockBasicInfo!.keyId.toString(),
|
||||
userID: await Storage.getUid(),
|
||||
@ -104,6 +110,8 @@ class ConfiguringWifiLogic extends BaseGetXController{
|
||||
password: state.wifiPWDController.text,
|
||||
numberOfServers: state.configuringWifiEntity.value.data!.serviceNum,
|
||||
listOfServers: serversList,
|
||||
numberOfPhone: phoneList.length,
|
||||
listOfPhone: phoneList,
|
||||
token: tokenData,
|
||||
needAuthor: 1,
|
||||
publicKey: publicKeyDataList,
|
||||
@ -147,18 +155,35 @@ class ConfiguringWifiLogic extends BaseGetXController{
|
||||
var serversList = <int>[];
|
||||
for(int i = 0; i<state.configuringWifiEntity.value.data!.serviceList!.length; i++){
|
||||
var item = state.configuringWifiEntity.value.data!.serviceList![i];
|
||||
var itemList = item.serviceIp!.split(".");
|
||||
itemList.forEach((element) {
|
||||
serversList.add(int.parse(element));
|
||||
});
|
||||
if(item.serviceIp!.contains("192")){
|
||||
var itemList = item.serviceIp!.split(".");
|
||||
for (var element in itemList) {
|
||||
serversList.add(int.parse(element));
|
||||
}
|
||||
}else{
|
||||
List<InternetAddress> addresses = await InternetAddress.lookup(item.serviceIp!);
|
||||
var itemList = addresses.first.address.split(".");
|
||||
for (var element in itemList) {
|
||||
serversList.add(int.parse(element));
|
||||
}
|
||||
print('Resolved google.com to address: ${addresses.first.address} serversList:${serversList}');
|
||||
|
||||
double typeDouble = int.parse(item.port!) / 256;
|
||||
int type1 = typeDouble.toInt();
|
||||
int type2 = int.parse(item.port!) % 256;
|
||||
serversList.add(type1);
|
||||
serversList.add(type2);
|
||||
double typeDouble = int.parse(item.port!) / 256;
|
||||
int type1 = typeDouble.toInt();
|
||||
int type2 = int.parse(item.port!) % 256;
|
||||
serversList.add(type1);
|
||||
serversList.add(type2);
|
||||
}
|
||||
}
|
||||
|
||||
String? phone = '';
|
||||
final data = await Storage.getString('userLoginData');
|
||||
if (data != null && data.isNotEmpty) {
|
||||
phone = LoginData.fromJson(jsonDecode(data)).mobile;
|
||||
}
|
||||
var phoneList = [phone!];
|
||||
print("phoneList:$phoneList");
|
||||
|
||||
IoSenderManage.senderConfiguringWifiCommand(
|
||||
keyID: state.lockSetInfoData.value.lockBasicInfo!.keyId.toString(),
|
||||
userID: await Storage.getUid(),
|
||||
@ -166,6 +191,8 @@ class ConfiguringWifiLogic extends BaseGetXController{
|
||||
password: state.wifiPWDController.text,
|
||||
numberOfServers: state.configuringWifiEntity.value.data!.serviceNum,
|
||||
listOfServers: serversList,
|
||||
numberOfPhone: phoneList.length,
|
||||
listOfPhone: phoneList,
|
||||
token: getTokenList,
|
||||
needAuthor: 1,
|
||||
publicKey: publicKeyDataList,
|
||||
|
||||
@ -427,7 +427,7 @@ class LockSetLogic extends BaseGetXController {
|
||||
password: state.passwordTF.text,
|
||||
);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
// deletLockInfoData();
|
||||
deletLockInfoData();
|
||||
|
||||
blockDeletNumberCheckPasswordCallback();
|
||||
// if(state.currentDeviceUUid.value.isEmpty){
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
@ -49,49 +48,45 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
children: [
|
||||
Expanded(
|
||||
child: Obx(() => ListView(
|
||||
children: getListWidget(),
|
||||
)),
|
||||
children: getListWidget(),
|
||||
)),
|
||||
),
|
||||
],
|
||||
)
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
// 根据权限显示不同的列表
|
||||
List<Widget> getListWidget(){
|
||||
|
||||
print("state.lockBasicInfo.value.isLockOwner:${state.lockBasicInfo.value.isLockOwner} state.lockBasicInfo.value.keyRight:${state.lockBasicInfo.value.keyRight}");
|
||||
if(state.lockBasicInfo.value.isLockOwner == 1 || state.lockBasicInfo.value.keyRight == 1){
|
||||
List<Widget> getListWidget() {
|
||||
print(
|
||||
"state.lockBasicInfo.value.isLockOwner:${state.lockBasicInfo.value.isLockOwner} state.lockBasicInfo.value.keyRight:${state.lockBasicInfo.value.keyRight}");
|
||||
if (state.lockBasicInfo.value.isLockOwner == 1 ||
|
||||
state.lockBasicInfo.value.keyRight == 1) {
|
||||
// 超级管理员、授权管理员
|
||||
return getAllWidget();
|
||||
}else{
|
||||
} else {
|
||||
return getNormalWidget();
|
||||
}
|
||||
}
|
||||
|
||||
// 普通用户
|
||||
List<Widget> getNormalWidget() {
|
||||
var showWidgetArr = [
|
||||
var showWidgetArr = [
|
||||
// 基本信息
|
||||
CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.basicInformation!.tr,
|
||||
leftTitel: TranslationLoader.lanKeys!.basicInformation!.tr,
|
||||
rightTitle: "",
|
||||
isHaveLine: false,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.basicInformationPage, arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
Get.toNamed(Routers.basicInformationPage,
|
||||
arguments: {'lockSetInfoData': state.lockSetInfoData.value});
|
||||
}),
|
||||
SizedBox(height: 10.h),
|
||||
// 自动闭锁
|
||||
Obx(() => Visibility(
|
||||
visible:
|
||||
state.lockFeature.value.autoLock == 1 ? true : false,
|
||||
visible: state.lockFeature.value.autoLock == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.automaticBlocking!.tr,
|
||||
leftTitel: TranslationLoader.lanKeys!.automaticBlocking!.tr,
|
||||
rightTitle: (state.lockSettingInfo.value.autoLock ?? 0) > 0
|
||||
? "${state.lockSetInfoData.value.lockSettingInfo!.autoLockSecond ?? 0}s"
|
||||
: TranslationLoader.lanKeys!.closed!.tr,
|
||||
@ -102,32 +97,27 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
// ? "${state.lockSetInfoData.value.lockSetting!.autoLockSecond ?? 0}s"
|
||||
// : TranslationLoader.lanKeys!.closed!.tr),
|
||||
action: () {
|
||||
Get.toNamed(Routers.automaticBlockingPage,
|
||||
arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value,
|
||||
// 'lockBasicInfo': state.lockBasicInfo.value
|
||||
});
|
||||
Get.toNamed(Routers.automaticBlockingPage, arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value,
|
||||
// 'lockBasicInfo': state.lockBasicInfo.value
|
||||
});
|
||||
}))),
|
||||
// 常开模式
|
||||
Obx(() => Visibility(
|
||||
visible: state.lockFeature.value.passageMode == 1 ? true : false,
|
||||
// visible:true,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.normallyOpenMode!.tr,
|
||||
rightTitle:
|
||||
(state.lockSettingInfo.value.passageMode ?? 0) ==
|
||||
1
|
||||
leftTitel: TranslationLoader.lanKeys!.normallyOpenMode!.tr,
|
||||
rightTitle: (state.lockSettingInfo.value.passageMode ?? 0) == 1
|
||||
? TranslationLoader.lanKeys!.opened!.tr
|
||||
: TranslationLoader.lanKeys!.closed!.tr,
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.normallyOpenModePage,
|
||||
arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value,
|
||||
'lockBasicInfo': state.lockBasicInfo.value
|
||||
});
|
||||
Get.toNamed(Routers.normallyOpenModePage, arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value,
|
||||
'lockBasicInfo': state.lockBasicInfo.value
|
||||
});
|
||||
}))),
|
||||
Visibility(
|
||||
visible: true,
|
||||
@ -143,8 +133,7 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
})),
|
||||
SizedBox(height: 30.h),
|
||||
Container(
|
||||
padding:
|
||||
EdgeInsets.only(left: 20.w, right: 20.w, bottom: 30.h),
|
||||
padding: EdgeInsets.only(left: 20.w, right: 20.w, bottom: 30.h),
|
||||
child: SubmitBtn(
|
||||
btnName: TranslationLoader.lanKeys!.delete!.tr,
|
||||
isDelete: true,
|
||||
@ -165,25 +154,20 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
var showWidgetArr = [
|
||||
// 基本信息
|
||||
CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.basicInformation!.tr,
|
||||
leftTitel: TranslationLoader.lanKeys!.basicInformation!.tr,
|
||||
rightTitle: "",
|
||||
isHaveLine: false,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.basicInformationPage, arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
Get.toNamed(Routers.basicInformationPage,
|
||||
arguments: {'lockSetInfoData': state.lockSetInfoData.value});
|
||||
}),
|
||||
SizedBox(height: 10.h),
|
||||
// 门磁
|
||||
Obx(() => Visibility(
|
||||
visible: state.lockFeature.value.doorStatus == 1
|
||||
? true
|
||||
: false,
|
||||
visible: state.lockFeature.value.doorStatus == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.doorMagnetic!.tr,
|
||||
leftTitel: TranslationLoader.lanKeys!.doorMagnetic!.tr,
|
||||
rightTitle: "",
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
@ -193,12 +177,9 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
}))),
|
||||
// 无线键盘
|
||||
Obx(() => Visibility(
|
||||
visible: state.lockFeature.value.wirelessKeyboard == 1
|
||||
? true
|
||||
: false,
|
||||
visible: state.lockFeature.value.wirelessKeyboard == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.wirelessKeyboard!.tr,
|
||||
leftTitel: TranslationLoader.lanKeys!.wirelessKeyboard!.tr,
|
||||
rightTitle: "",
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
@ -208,9 +189,7 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
}))),
|
||||
// 照明
|
||||
Obx(() => Visibility(
|
||||
visible: state.lockFeature.value.lightingTime == 1
|
||||
? true
|
||||
: false,
|
||||
visible: state.lockFeature.value.lightingTime == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.illumination!.tr,
|
||||
rightTitle: "",
|
||||
@ -233,11 +212,9 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
SizedBox(height: 10.h),
|
||||
// 自动闭锁
|
||||
Obx(() => Visibility(
|
||||
visible:
|
||||
state.lockFeature.value.autoLock == 1 ? true : false,
|
||||
visible: state.lockFeature.value.autoLock == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.automaticBlocking!.tr,
|
||||
leftTitel: TranslationLoader.lanKeys!.automaticBlocking!.tr,
|
||||
rightTitle: (state.lockSettingInfo.value.autoLock ?? 0) > 0
|
||||
? "${state.lockSetInfoData.value.lockSettingInfo!.autoLockSecond ?? 0}s"
|
||||
: TranslationLoader.lanKeys!.closed!.tr,
|
||||
@ -248,17 +225,15 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
// ? "${state.lockSetInfoData.value.lockSetting!.autoLockSecond ?? 0}s"
|
||||
// : TranslationLoader.lanKeys!.closed!.tr),
|
||||
action: () {
|
||||
Get.toNamed(Routers.automaticBlockingPage,
|
||||
arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
Get.toNamed(Routers.automaticBlockingPage, arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
}))),
|
||||
// 锁声音
|
||||
Obx(() {
|
||||
var titleStr = "";
|
||||
if ((state.lockSettingInfo.value.lockSound ?? 0) == 1) {
|
||||
switch (
|
||||
state.lockSettingInfo.value.lockSoundVolume ?? 0) {
|
||||
switch (state.lockSettingInfo.value.lockSoundVolume ?? 0) {
|
||||
case 1:
|
||||
titleStr = TranslationLoader.lanKeys!.low!.tr;
|
||||
break;
|
||||
@ -279,9 +254,7 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
titleStr = TranslationLoader.lanKeys!.closed!.tr;
|
||||
}
|
||||
return Visibility(
|
||||
visible: state.lockFeature.value.lockSound == 1
|
||||
? true
|
||||
: false,
|
||||
visible: state.lockFeature.value.lockSound == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.lockSound!.tr,
|
||||
rightTitle: titleStr,
|
||||
@ -295,14 +268,10 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
}),
|
||||
// 防撬报警
|
||||
Obx(() => Visibility(
|
||||
visible: state.lockFeature.value.antiPrySwitch == 1
|
||||
? true
|
||||
: false,
|
||||
visible: state.lockFeature.value.antiPrySwitch == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.burglarAlarm!.tr,
|
||||
rightTitle:
|
||||
(state.lockSettingInfo.value.antiPrySwitch ?? 0) == 1
|
||||
leftTitel: TranslationLoader.lanKeys!.burglarAlarm!.tr,
|
||||
rightTitle: (state.lockSettingInfo.value.antiPrySwitch ?? 0) == 1
|
||||
? TranslationLoader.lanKeys!.opened!.tr
|
||||
: TranslationLoader.lanKeys!.closed!.tr,
|
||||
isHaveLine: true,
|
||||
@ -315,57 +284,41 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
SizedBox(height: 10.h),
|
||||
// 常开模式
|
||||
Obx(() => Visibility(
|
||||
visible: state.lockFeature.value.passageMode == 1
|
||||
? true
|
||||
: false,
|
||||
visible: state.lockFeature.value.passageMode == 1 ? true : false,
|
||||
// visible:true,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.normallyOpenMode!.tr,
|
||||
rightTitle:
|
||||
(state.lockSettingInfo.value.passageMode ?? 0) ==
|
||||
1
|
||||
leftTitel: TranslationLoader.lanKeys!.normallyOpenMode!.tr,
|
||||
rightTitle: (state.lockSettingInfo.value.passageMode ?? 0) == 1
|
||||
? TranslationLoader.lanKeys!.opened!.tr
|
||||
: TranslationLoader.lanKeys!.closed!.tr,
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.normallyOpenModePage,
|
||||
arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
Get.toNamed(Routers.normallyOpenModePage, arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
}))),
|
||||
// 远程开锁
|
||||
Obx(() => Visibility(
|
||||
visible: state.lockFeature.value.remoteUnlock == 1
|
||||
? true
|
||||
: false,
|
||||
visible: state.lockFeature.value.remoteUnlock == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.remoteUnlocking!.tr,
|
||||
rightTitle:
|
||||
(state.lockSettingInfo.value.remoteUnlock ?? 0) ==
|
||||
1
|
||||
leftTitel: TranslationLoader.lanKeys!.remoteUnlocking!.tr,
|
||||
rightTitle: (state.lockSettingInfo.value.remoteUnlock ?? 0) == 1
|
||||
? TranslationLoader.lanKeys!.opened!.tr
|
||||
: TranslationLoader.lanKeys!.closed!.tr,
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.remoteUnlockingPage,
|
||||
arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
Get.toNamed(Routers.remoteUnlockingPage, arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
}))),
|
||||
// 重置键
|
||||
Obx(() => Visibility(
|
||||
visible: state.lockFeature.value.resetSwitch == 1
|
||||
? true
|
||||
: false,
|
||||
visible: state.lockFeature.value.resetSwitch == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.resetButton!.tr,
|
||||
rightTitle:
|
||||
(state.lockSettingInfo.value.resetSwitch ?? 0) ==
|
||||
1
|
||||
rightTitle: (state.lockSettingInfo.value.resetSwitch ?? 0) == 1
|
||||
? TranslationLoader.lanKeys!.opened!.tr
|
||||
: TranslationLoader.lanKeys!.closed!.tr,
|
||||
isHaveLine: true,
|
||||
@ -484,32 +437,24 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
title = TranslationLoader.lanKeys!.leisure!.tr;
|
||||
}
|
||||
return Visibility(
|
||||
visible: state.lockStatus.value.roomStatus == 1
|
||||
? true
|
||||
: false,
|
||||
visible: state.lockStatus.value.roomStatus == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.markedHouseState!.tr,
|
||||
leftTitel: TranslationLoader.lanKeys!.markedHouseState!.tr,
|
||||
rightTitle: title,
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.markedHouseStatePage,
|
||||
arguments: {
|
||||
'lockSetInfoData':
|
||||
state.lockSetInfoData.value
|
||||
});
|
||||
Get.toNamed(Routers.markedHouseStatePage, arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
}));
|
||||
}),
|
||||
// 考勤
|
||||
Obx(
|
||||
() => Visibility(
|
||||
visible: state.lockFeature.value.attendance == 1
|
||||
? true
|
||||
: false,
|
||||
() => Visibility(
|
||||
visible: state.lockFeature.value.attendance == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.checkingIn!.tr,
|
||||
leftTitel: TranslationLoader.lanKeys!.checkingIn!.tr,
|
||||
rightTitle: "",
|
||||
isHaveLine: true,
|
||||
isHaveRightWidget: true,
|
||||
@ -517,7 +462,7 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
),
|
||||
// 开锁提醒
|
||||
Obx(
|
||||
() => Visibility(
|
||||
() => Visibility(
|
||||
visible: state.lockFeature.value.unlockReminder == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.unlockReminder!.tr,
|
||||
@ -527,38 +472,34 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
rightWidget: _lockRemindSwitch())),
|
||||
),
|
||||
// APP开锁时是否需联网
|
||||
Obx(() =>
|
||||
Visibility(
|
||||
visible: state.lockFeature.value.appUnlockOnline == 1 ? true : false,
|
||||
child:
|
||||
CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.whetherInternetRequiredWhenUnlocking!.tr,
|
||||
rightTitle: "",
|
||||
isHaveLine: false,
|
||||
isHaveRightWidget: true,
|
||||
rightWidget: _openLockNeedOnlineSwitch()),
|
||||
),
|
||||
Obx(
|
||||
() => Visibility(
|
||||
visible: state.lockFeature.value.appUnlockOnline == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel: TranslationLoader
|
||||
.lanKeys!.whetherInternetRequiredWhenUnlocking!.tr,
|
||||
rightTitle: "",
|
||||
isHaveLine: false,
|
||||
isHaveRightWidget: true,
|
||||
rightWidget: _openLockNeedOnlineSwitch()),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
// wifi配网
|
||||
Obx(
|
||||
() => Visibility(
|
||||
visible:
|
||||
state.lockFeature.value.wifi == 1 ? true : false,
|
||||
child:
|
||||
CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.wifiDistributionNetwork!.tr,
|
||||
() => Visibility(
|
||||
visible: state.lockFeature.value.wifi == 1 ? true : false,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.wifiDistributionNetwork!.tr,
|
||||
rightTitle: "",
|
||||
isHaveLine: true,
|
||||
isHaveDirection: true,
|
||||
action: () {
|
||||
Get.toNamed(Routers.configuringWifiPage,
|
||||
arguments: {
|
||||
'lockSetInfoData':
|
||||
state.lockSetInfoData.value
|
||||
});
|
||||
})
|
||||
),
|
||||
Get.toNamed(Routers.configuringWifiPage, arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
})),
|
||||
),
|
||||
// Obx(() =>
|
||||
// 锁时间
|
||||
@ -621,8 +562,7 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
Visibility(
|
||||
visible: true,
|
||||
child: CommonItem(
|
||||
leftTitel:
|
||||
TranslationLoader.lanKeys!.lockEscalation!.tr,
|
||||
leftTitel: TranslationLoader.lanKeys!.lockEscalation!.tr,
|
||||
rightTitle: "",
|
||||
isHaveLine: false,
|
||||
isHaveDirection: true,
|
||||
@ -632,8 +572,7 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
|
||||
// ),
|
||||
SizedBox(height: 30.h),
|
||||
Container(
|
||||
padding:
|
||||
EdgeInsets.only(left: 20.w, right: 20.w, bottom: 30.h),
|
||||
padding: EdgeInsets.only(left: 20.w, right: 20.w, bottom: 30.h),
|
||||
child: SubmitBtn(
|
||||
btnName: TranslationLoader.lanKeys!.delete!.tr,
|
||||
isDelete: true,
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
@ -28,15 +27,16 @@ import '../lockOperatingRecord/lockOperatingRecordGetLastRecordTime_entity.dart'
|
||||
import 'lockDetail_state.dart';
|
||||
import 'lockNetToken_entity.dart';
|
||||
|
||||
class LockDetailLogic extends BaseGetXController{
|
||||
class LockDetailLogic extends BaseGetXController {
|
||||
final LockDetailState state = LockDetailState();
|
||||
|
||||
// 监听设备返回的数据
|
||||
late StreamSubscription<Reply> _replySubscription;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -46,17 +46,17 @@ class LockDetailLogic extends BaseGetXController{
|
||||
// }
|
||||
|
||||
// 获取星锁状态信息
|
||||
if(reply is GetStarLockStatuInfoReply){
|
||||
if (reply is GetStarLockStatuInfoReply) {
|
||||
_replyGetStarLockStatusInfo(reply);
|
||||
}
|
||||
|
||||
// 开完锁之后上传记录
|
||||
if(reply is SenderReferEventRecordTimeReply) {
|
||||
if (reply is SenderReferEventRecordTimeReply) {
|
||||
_replyReferEventRecordTime(reply);
|
||||
}
|
||||
|
||||
// 添加用户
|
||||
if(reply is AddUserReply) {
|
||||
if (reply is AddUserReply) {
|
||||
_replyAddUserKey(reply);
|
||||
}
|
||||
});
|
||||
@ -64,76 +64,76 @@ class LockDetailLogic extends BaseGetXController{
|
||||
|
||||
// 开门数据解析
|
||||
Future<void> _replyOpenLock(Reply reply) async {
|
||||
var tokenData = reply.data.sublist(2, 6);
|
||||
var saveStrList = changeIntListToStringList(tokenData);
|
||||
print("openDoorToken:$tokenData");
|
||||
Storage.setStringList(saveBlueToken, saveStrList);
|
||||
var tokenData = reply.data.sublist(2, 6);
|
||||
var saveStrList = changeIntListToStringList(tokenData);
|
||||
print("openDoorToken:$tokenData");
|
||||
Storage.setStringList(saveBlueToken, saveStrList);
|
||||
|
||||
int status = reply.data[6];
|
||||
print("status:$status");
|
||||
int status = reply.data[6];
|
||||
print("status:$status");
|
||||
|
||||
switch(status){
|
||||
case 0x00:
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
|
||||
// 电量
|
||||
int power = reply.data[7];
|
||||
state.electricQuantity.value = power;
|
||||
// 电量
|
||||
int power = reply.data[7];
|
||||
state.electricQuantity.value = power;
|
||||
|
||||
getLockRecordLastUploadDataTime();
|
||||
state.lockState.value = 2;
|
||||
state.animationController.reset();
|
||||
state.animationController.forward();
|
||||
// state.animationController.isCompleted;
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
var signKey = await Storage.getStringList(saveBlueSignKey);
|
||||
List<int> signKeyDataList = changeStringListToIntList(signKey!);
|
||||
|
||||
IoSenderManage.senderOpenLock(
|
||||
keyID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
openMode: 1,
|
||||
openTime: DateTime.now().millisecondsSinceEpoch~/1000,
|
||||
onlineToken:state.lockNetToken,
|
||||
token: tokenData,
|
||||
needAuthor: 1,
|
||||
signKey: signKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
getLockRecordLastUploadDataTime();
|
||||
state.lockState.value = 2;
|
||||
state.animationController.reset();
|
||||
state.animationController.forward();
|
||||
// state.animationController.isCompleted;
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
var signKey = await Storage.getStringList(saveBlueSignKey);
|
||||
List<int> signKeyDataList = changeStringListToIntList(signKey!);
|
||||
|
||||
IoSenderManage.senderOpenLock(
|
||||
keyID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
openMode: 1,
|
||||
openTime: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
onlineToken: state.lockNetToken,
|
||||
token: tokenData,
|
||||
needAuthor: 1,
|
||||
signKey: signKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
print("${reply.commandType}校验错误");
|
||||
print("${reply.commandType}校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
print("${reply.commandType}失败");
|
||||
print("${reply.commandType}失败");
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取锁状态数据解析
|
||||
Future<void> _replyGetStarLockStatusInfo(Reply reply) async {
|
||||
int status = reply.data[2];
|
||||
switch(status){
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
// 厂商名称
|
||||
var vendor = reply.data.sublist(3, 23);
|
||||
@ -189,22 +189,22 @@ class LockDetailLogic extends BaseGetXController{
|
||||
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
//无权限
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
// 权限校验错误
|
||||
print("${reply.commandType}权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
//失败
|
||||
print("${reply.commandType}失败");
|
||||
|
||||
break;
|
||||
@ -214,17 +214,17 @@ class LockDetailLogic extends BaseGetXController{
|
||||
// 根据时间查解析数据
|
||||
Future<void> _replyReferEventRecordTime(Reply reply) async {
|
||||
int status = reply.data[2];
|
||||
switch(status){
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
if(reply.data[5] > 0){
|
||||
if (reply.data[5] > 0) {
|
||||
reply.data.removeRange(0, 6);
|
||||
// 把得到的数据按8位分割成数组 然后塞进一个新的数组里面
|
||||
var getList = splitList(reply.data, 8);
|
||||
// print("getList:$getList");
|
||||
var uploadList = [];
|
||||
for(int i = 0; i<getList.length; i++){
|
||||
for (int i = 0; i < getList.length; i++) {
|
||||
var indexList = getList[i];
|
||||
// print("indexList:$indexList");
|
||||
var indexMap = {};
|
||||
@ -235,13 +235,13 @@ class LockDetailLogic extends BaseGetXController{
|
||||
indexMap["type"] = indexList[1].toString();
|
||||
|
||||
int value = ((0xff & indexList[(4)]) << 24 |
|
||||
(0xff & indexList[5]) << 16 |
|
||||
(0xff & indexList[6]) << 8 |
|
||||
(0xFF & indexList[7]));
|
||||
(0xff & indexList[5]) << 16 |
|
||||
(0xff & indexList[6]) << 8 |
|
||||
(0xFF & indexList[7]));
|
||||
// indexMap["date"] = DateTool().dateToYMDHNSString("$value");
|
||||
// print("value:${DateTool().dateToYMDHNSString("$value")}");
|
||||
|
||||
indexMap["date"] = "${value*1000}";
|
||||
indexMap["date"] = "${value * 1000}";
|
||||
uploadList.add(indexMap);
|
||||
}
|
||||
lockRecordUploadData(uploadList);
|
||||
@ -249,22 +249,22 @@ class LockDetailLogic extends BaseGetXController{
|
||||
}
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
//无权限
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
// 权限校验错误
|
||||
print("${reply.commandType}权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
//失败
|
||||
print("${reply.commandType}失败");
|
||||
|
||||
break;
|
||||
@ -285,22 +285,22 @@ class LockDetailLogic extends BaseGetXController{
|
||||
// print("status:$status reply.data:${reply.data}");
|
||||
|
||||
print("status:$status");
|
||||
switch(status){
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
//成功
|
||||
print("添加用户数据解析成功");
|
||||
state.lockUserNo = reply.data[47] + 1;
|
||||
// updateLockUserNo();
|
||||
|
||||
if(state.isOpenLockNeedOnline.value == 0){
|
||||
if (state.isOpenLockNeedOnline.value == 0) {
|
||||
openDoorAction();
|
||||
}else{
|
||||
} else {
|
||||
getLockNetToken();
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
//无权限
|
||||
print("需要鉴权");
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
@ -310,33 +310,32 @@ class LockDetailLogic extends BaseGetXController{
|
||||
|
||||
IoSenderManage.senderAddUser(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
authUserID:state.senderUserId.toString(),
|
||||
keyID:state.keyInfos.value.keyId.toString(),
|
||||
userID:await Storage.getUid(),
|
||||
openMode:1,
|
||||
keyType:0,
|
||||
startDate:DateTime.now().millisecondsSinceEpoch,
|
||||
expireDate:0x11223344,
|
||||
role:0,
|
||||
password:"123456",
|
||||
needAuthor:1,
|
||||
publicKey:publicKeyDataList,
|
||||
privateKey:getPrivateKeyList,
|
||||
token: token
|
||||
);
|
||||
authUserID: state.senderUserId.toString(),
|
||||
keyID: state.keyInfos.value.keyId.toString(),
|
||||
userID: await Storage.getUid(),
|
||||
openMode: 1,
|
||||
keyType: 0,
|
||||
startDate: DateTime.now().millisecondsSinceEpoch,
|
||||
expireDate: 0x11223344,
|
||||
role: 0,
|
||||
password: "123456",
|
||||
needAuthor: 1,
|
||||
publicKey: publicKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
token: token);
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
//无权限
|
||||
print("用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
// 权限校验错误
|
||||
print("添加用户权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
//失败
|
||||
print("领锁失败");
|
||||
|
||||
break;
|
||||
@ -349,9 +348,11 @@ class LockDetailLogic extends BaseGetXController{
|
||||
// Toast.show(msg: "正在连接设备,请稍等。");
|
||||
// return;
|
||||
// }
|
||||
BlueManage().judgeReconnect(state.keyInfos.value.bluetooth!.bluetoothDeviceName!, (DeviceConnectionState deviceConnectionState) async {
|
||||
BlueManage()
|
||||
.judgeReconnect(state.keyInfos.value.bluetooth!.bluetoothDeviceName!,
|
||||
(DeviceConnectionState deviceConnectionState) async {
|
||||
print("77777777:$deviceConnectionState");
|
||||
if (deviceConnectionState == DeviceConnectionState.connected){
|
||||
if (deviceConnectionState == DeviceConnectionState.connected) {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
@ -360,27 +361,29 @@ class LockDetailLogic extends BaseGetXController{
|
||||
|
||||
bool isHave = await Storage.ifHaveKey(saveBlueToken);
|
||||
List<int> getTokenList;
|
||||
if(isHave){
|
||||
if (isHave) {
|
||||
var token = await Storage.getStringList(saveBlueToken);
|
||||
getTokenList = changeStringListToIntList(token!);
|
||||
}else{
|
||||
getTokenList = [0,0,0,0];
|
||||
} else {
|
||||
getTokenList = [0, 0, 0, 0];
|
||||
}
|
||||
print("openDoorTokenPubToken:$getTokenList getPrivateKeyList:$getPrivateKeyList");
|
||||
print(
|
||||
"openDoorTokenPubToken:$getTokenList getPrivateKeyList:$getPrivateKeyList");
|
||||
|
||||
print("millisecondsSinceEpoch/1000:${DateTime.now().millisecondsSinceEpoch~/1000}");
|
||||
print(
|
||||
"millisecondsSinceEpoch/1000:${DateTime.now().millisecondsSinceEpoch ~/ 1000}");
|
||||
IoSenderManage.senderOpenLock(
|
||||
keyID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
openMode: 1,
|
||||
openTime: DateTime.now().millisecondsSinceEpoch~/1000,
|
||||
onlineToken:state.lockNetToken,
|
||||
openTime: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
onlineToken: state.lockNetToken,
|
||||
token: getTokenList,
|
||||
needAuthor: 1,
|
||||
signKey: signKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
}else if (deviceConnectionState == DeviceConnectionState.disconnected){
|
||||
} else if (deviceConnectionState == DeviceConnectionState.disconnected) {
|
||||
// Toast.show(msg: "连接设备失败,请确保在设备附近,设备未被连接,设备已打开");
|
||||
|
||||
state.lockState.value = 4;
|
||||
@ -425,15 +428,15 @@ class LockDetailLogic extends BaseGetXController{
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
// 备用逻辑,进入管理钥匙界面获取锁状态
|
||||
Future<void> connectBlue(String bluetoothDeviceName) async {
|
||||
// 进来之后首先连接
|
||||
BlueManage().connect(bluetoothDeviceName, (DeviceConnectionState state) async {
|
||||
if(EasyLoading.isShow){
|
||||
BlueManage().connect(bluetoothDeviceName,
|
||||
(DeviceConnectionState state) async {
|
||||
if (EasyLoading.isShow) {
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
if (state == DeviceConnectionState.connected){
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
// var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
// List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
// // IoSenderManage.senderGetLockStatu(
|
||||
@ -452,7 +455,8 @@ class LockDetailLogic extends BaseGetXController{
|
||||
|
||||
// 查询事件记录(时间查询)
|
||||
Future<void> senderReferEventRecordTime(int time) async {
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceName, (DeviceConnectionState state) async {
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceName,
|
||||
(DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
@ -464,15 +468,15 @@ class LockDetailLogic extends BaseGetXController{
|
||||
List<int> getPublicKeyList = changeStringListToIntList(publicKey!);
|
||||
|
||||
IoSenderManage.senderReferEventRecordTimeCommand(
|
||||
keyID:BlueManage().connectDeviceName,
|
||||
userID:await Storage.getUid(),
|
||||
logsCount:20,
|
||||
keyID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
logsCount: 20,
|
||||
// time:DateTime.now().millisecondsSinceEpoch~/1000,
|
||||
time: time,
|
||||
token:getTokenList,
|
||||
needAuthor:1,
|
||||
publicKey:getPublicKeyList,
|
||||
privateKey:getPrivateKeyList,
|
||||
token: getTokenList,
|
||||
needAuthor: 1,
|
||||
publicKey: getPublicKeyList,
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
}
|
||||
}, isShowLoading: false);
|
||||
@ -481,8 +485,9 @@ class LockDetailLogic extends BaseGetXController{
|
||||
// 添加用户(普通用户接收电子钥匙)
|
||||
Future<void> addUserConnectBlue() async {
|
||||
// 进来之后首先连接
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceName, (DeviceConnectionState deviceConnectionState) async {
|
||||
if (deviceConnectionState == DeviceConnectionState.connected){
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceName,
|
||||
(DeviceConnectionState deviceConnectionState) async {
|
||||
if (deviceConnectionState == DeviceConnectionState.connected) {
|
||||
// 私钥
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
@ -491,27 +496,27 @@ class LockDetailLogic extends BaseGetXController{
|
||||
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||
|
||||
var token = await Storage.getStringList(saveBlueToken);
|
||||
List<int> getTokenList = [0,0,0,0];
|
||||
if(token != null){
|
||||
List<int> getTokenList = [0, 0, 0, 0];
|
||||
if (token != null) {
|
||||
getTokenList = changeStringListToIntList(token);
|
||||
}
|
||||
print("BlueManage().connectDeviceName:${BlueManage().connectDeviceName} authUserID:${state.senderUserId.toString()} keyID:${state.keyInfos.value.keyId.toString()} userID:${await Storage.getUid()}");
|
||||
print(
|
||||
"BlueManage().connectDeviceName:${BlueManage().connectDeviceName} authUserID:${state.senderUserId.toString()} keyID:${state.keyInfos.value.keyId.toString()} userID:${await Storage.getUid()}");
|
||||
IoSenderManage.senderAddUser(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
authUserID:state.senderUserId.toString(),
|
||||
keyID:state.keyInfos.value.keyId.toString(),
|
||||
userID:await Storage.getUid(),
|
||||
openMode:1,
|
||||
keyType:0,
|
||||
startDate:DateTime.now().millisecondsSinceEpoch,
|
||||
expireDate:0x11223344,
|
||||
role:0,
|
||||
password:"123456",
|
||||
needAuthor:1,
|
||||
publicKey:publicKeyDataList,
|
||||
privateKey:getPrivateKeyList,
|
||||
token: getTokenList
|
||||
);
|
||||
authUserID: state.senderUserId.toString(),
|
||||
keyID: state.keyInfos.value.keyId.toString(),
|
||||
userID: await Storage.getUid(),
|
||||
openMode: 1,
|
||||
keyType: 0,
|
||||
startDate: DateTime.now().millisecondsSinceEpoch,
|
||||
expireDate: 0x11223344,
|
||||
role: 0,
|
||||
password: "123456",
|
||||
needAuthor: 1,
|
||||
publicKey: publicKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
token: getTokenList);
|
||||
}
|
||||
}, isShowLoading: false);
|
||||
}
|
||||
@ -521,14 +526,14 @@ class LockDetailLogic extends BaseGetXController{
|
||||
state.lockState.value = 1;
|
||||
state.animationController.forward();
|
||||
|
||||
if(state.lockUserNo == 0){
|
||||
if (state.lockUserNo == 0) {
|
||||
// 电子钥匙lockUserNo为0 要先添加用户
|
||||
addUserConnectBlue();
|
||||
}else{
|
||||
if(state.isOpenLockNeedOnline.value == 0){
|
||||
} else {
|
||||
if (state.isOpenLockNeedOnline.value == 0) {
|
||||
// 不需要联网
|
||||
openDoorAction();
|
||||
}else{
|
||||
} else {
|
||||
// 需要联网
|
||||
getLockNetToken();
|
||||
}
|
||||
@ -536,13 +541,12 @@ class LockDetailLogic extends BaseGetXController{
|
||||
}
|
||||
|
||||
//关闭连接
|
||||
stopConnect() {
|
||||
|
||||
}
|
||||
stopConnect() {}
|
||||
|
||||
// 获取手机联网token,根据锁设置里面获取的开锁时是否联网来判断是否调用这个接口
|
||||
void getLockNetToken() async {
|
||||
LockNetTokenEntity entity = await ApiRepository.to.getLockNetToken(lockId: state.keyInfos.value.lockId.toString());
|
||||
LockNetTokenEntity entity = await ApiRepository.to
|
||||
.getLockNetToken(lockId: state.keyInfos.value.lockId.toString());
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
state.lockNetToken = entity.data!.token!;
|
||||
print("state.lockNetToken:${state.lockNetToken}");
|
||||
@ -552,11 +556,13 @@ class LockDetailLogic extends BaseGetXController{
|
||||
|
||||
// 普通用户接收电子钥匙之后 更新锁用户NO
|
||||
void updateLockUserNo() async {
|
||||
LockNetTokenEntity entity = await ApiRepository.to.updateLockUserNo(keyId: state.keyInfos.value.keyId.toString(), lockUserNo: state.lockUserNo.toString());
|
||||
LockNetTokenEntity entity = await ApiRepository.to.updateLockUserNo(
|
||||
keyId: state.keyInfos.value.keyId.toString(),
|
||||
lockUserNo: state.lockUserNo.toString());
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
if(state.isOpenLockNeedOnline.value == 0){
|
||||
if (state.isOpenLockNeedOnline.value == 0) {
|
||||
openDoorAction();
|
||||
}else{
|
||||
} else {
|
||||
getLockNetToken();
|
||||
}
|
||||
}
|
||||
@ -564,33 +570,37 @@ class LockDetailLogic extends BaseGetXController{
|
||||
|
||||
// 查询锁记录最后时间
|
||||
void getLockRecordLastUploadDataTime() async {
|
||||
LockOperatingRecordGetLastRecordTimeEntity entity = await ApiRepository.to.getLockRecordLastUploadDataTime(lockId: state.keyInfos.value.lockId.toString());
|
||||
LockOperatingRecordGetLastRecordTimeEntity entity = await ApiRepository.to
|
||||
.getLockRecordLastUploadDataTime(
|
||||
lockId: state.keyInfos.value.lockId.toString());
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
senderReferEventRecordTime(entity.data!.operateDate!~/1000);
|
||||
senderReferEventRecordTime(entity.data!.operateDate! ~/ 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// 操作记录上传
|
||||
void lockRecordUploadData(List list) async {
|
||||
KeyOperationRecordEntity entity =
|
||||
await ApiRepository.to.lockRecordUploadData(
|
||||
lockId: state.keyInfos.value.lockId.toString(),
|
||||
records: list);
|
||||
KeyOperationRecordEntity entity = await ApiRepository.to
|
||||
.lockRecordUploadData(
|
||||
lockId: state.keyInfos.value.lockId.toString(), records: list);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
// mockNetworkDataRequest();
|
||||
}
|
||||
}
|
||||
|
||||
/// 锁设置里面开启关闭考勤刷新锁详情
|
||||
StreamSubscription? _lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent;
|
||||
StreamSubscription?
|
||||
_lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent;
|
||||
void initLockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceAction() {
|
||||
// 蓝牙协议通知传输跟蓝牙之外的数据传输类不一样 eventBus
|
||||
_lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent = eventBus.on<LockSetChangeSetRefreshLockDetailWithType>().listen((event) {
|
||||
if(event.type == 0){
|
||||
_lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent = eventBus
|
||||
.on<LockSetChangeSetRefreshLockDetailWithType>()
|
||||
.listen((event) {
|
||||
if (event.type == 0) {
|
||||
// 0考勤
|
||||
state.isAttendance.value = event.setResult;
|
||||
state.keyInfos.value.lockSetting!.attendance = event.setResult;
|
||||
}else if(event.type == 1){
|
||||
} else if (event.type == 1) {
|
||||
// 1 开锁时是否需联网
|
||||
state.isOpenLockNeedOnline.value = event.setResult;
|
||||
state.keyInfos.value.lockSetting!.appUnlockOnline = event.setResult;
|
||||
@ -626,6 +636,8 @@ class LockDetailLogic extends BaseGetXController{
|
||||
super.onInit();
|
||||
// print("lockDetail_onInit()");
|
||||
|
||||
print("lockDetail_onInit()");
|
||||
|
||||
// 进来获取锁状态
|
||||
// connectBlue();
|
||||
// factoryDataResetAction();
|
||||
@ -639,4 +651,4 @@ class LockDetailLogic extends BaseGetXController{
|
||||
_replySubscription.cancel();
|
||||
_lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent!.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,6 +65,7 @@ class _LockDetailPageState extends State<LockDetailPage> with TickerProviderStat
|
||||
var saveSignKeyList = changeIntListToStringList(signKeyData);
|
||||
Storage.setStringList(saveBlueSignKey, saveSignKeyList);
|
||||
|
||||
Storage.setStringList(saveBlueToken, [0, 0, 0, 0]);
|
||||
// logic.startScanAction();
|
||||
|
||||
listeningAnimations();
|
||||
|
||||
@ -1,9 +1,402 @@
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_voice_processor/flutter_voice_processor.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
import '../../../../talk/call/g711.dart';
|
||||
import '../../../../talk/udp/udp_manage.dart';
|
||||
import '../../../../talk/udp/udp_senderManage.dart';
|
||||
import '../../../../tools/baseGetXController.dart';
|
||||
import '../../../../tools/eventBusEventManage.dart';
|
||||
import 'lockMonitoring_state.dart';
|
||||
|
||||
class LockMonitoringLogic extends BaseGetXController {
|
||||
final LockMonitoringState state = LockMonitoringState();
|
||||
|
||||
/// 初始化发送声音
|
||||
initRecorder() {
|
||||
state.voiceProcessor = VoiceProcessor.instance;
|
||||
}
|
||||
|
||||
}
|
||||
/// 收到视频流数据
|
||||
StreamSubscription? _getTVDataRefreshUIEvent;
|
||||
void _getTVDataRefreshUIAction() {
|
||||
// 蓝牙协议通知传输跟蓝牙之外的数据传输类不一样 eventBus
|
||||
_getTVDataRefreshUIEvent =
|
||||
eventBus.on<GetTVDataRefreshUI>().listen((event) {
|
||||
if (event.tvList.isNotEmpty) {
|
||||
// 预加载图片数据
|
||||
Uint8List imageData = Uint8List.fromList(event.tvList);
|
||||
// 更新状态
|
||||
state.listData.value = imageData;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// 收到UDP发送的状态
|
||||
StreamSubscription? _getUDPStatusRefreshUIEvent;
|
||||
void _getUDPStatusRefreshUIAction() {
|
||||
_getUDPStatusRefreshUIEvent = eventBus.on<GetUDPStatusRefreshUI>().listen((event) {
|
||||
state.udpStatus.value = event.udpStatus;
|
||||
if(state.udpStatus.value == 8){
|
||||
// 接听成功了,然后刷新界面的时间 60秒以后自动挂断
|
||||
state.oneMinuteTimeTimer = Timer.periodic(const Duration(seconds:1), (Timer t) async {
|
||||
state.oneMinuteTime.value++;
|
||||
// Get.log('state.oneMinuteTime.value:${state.oneMinuteTime.value}');
|
||||
if(state.oneMinuteTime.value >= 60){
|
||||
// 超过60秒了
|
||||
state.oneMinuteTimeTimer.cancel();
|
||||
state.oneMinuteTime.value = 0;
|
||||
// 挂断
|
||||
UDPSenderManage.sendMainProtocol(
|
||||
command: 150,
|
||||
commandTypeIsCalling: 1,
|
||||
subCommand: 30,
|
||||
lockID: UDPManage().lockId,
|
||||
lockIP: UDPManage().host,
|
||||
userMobile: await state.userMobile,
|
||||
userMobileIP: await state.userMobileIP,
|
||||
endData: []);
|
||||
|
||||
// 关闭当前界面
|
||||
Get.back();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// 接听
|
||||
udpAnswerAction() async {
|
||||
UDPSenderManage.sendMainProtocol(
|
||||
command: 150,
|
||||
commandTypeIsCalling: 1,
|
||||
subCommand: 6,
|
||||
lockID: UDPManage().lockId,
|
||||
lockIP: UDPManage().host,
|
||||
userMobile: await state.userMobile,
|
||||
userMobileIP: await state.userMobileIP,
|
||||
endData: []
|
||||
);
|
||||
}
|
||||
|
||||
/// 挂断
|
||||
udpHangUpAction() async {
|
||||
UDPSenderManage.sendMainProtocol(
|
||||
command: 150,
|
||||
commandTypeIsCalling: 1,
|
||||
subCommand: 30,
|
||||
lockID: UDPManage().lockId,
|
||||
lockIP: UDPManage().host,
|
||||
userMobile: await state.userMobile,
|
||||
userMobileIP: await state.userMobileIP,
|
||||
endData: []);
|
||||
}
|
||||
|
||||
/// 开门
|
||||
udpOpenDoorAction() async {
|
||||
UDPSenderManage.sendMainProtocol(
|
||||
command: 150,
|
||||
commandTypeIsCalling: 1,
|
||||
subCommand: 10,
|
||||
lockID: UDPManage().lockId,
|
||||
lockIP: UDPManage().host,
|
||||
userMobile: await state.userMobile,
|
||||
userMobileIP: await state.userMobileIP,
|
||||
endData: []);
|
||||
Get.back();
|
||||
}
|
||||
|
||||
Future<void> _readG711Data() async {
|
||||
String filePath = 'assets/s10-g711.bin';
|
||||
List<int> audioData = await G711().readAssetFile(filePath);
|
||||
// Get.log('发送读取711文件数据为:$audioData');// 数据为:$audioData
|
||||
// return;
|
||||
// print('发送读取711文件数据长度为:${audioData.length}');// 数据为:$audioData
|
||||
if (audioData.isNotEmpty) {
|
||||
// 在这里处理你的音频数据
|
||||
// pcmBytes = G711().convertList(audioData);
|
||||
// print('发送转换pcmBytes数据长度为:${pcmBytes.length}');
|
||||
|
||||
int start = 0;
|
||||
int length = 320;
|
||||
while (start < audioData.length) {
|
||||
// await Future.delayed(const Duration(milliseconds: 50));
|
||||
|
||||
int end = (start + length > audioData.length) ? audioData.length : start + length;
|
||||
List<int> sublist = audioData.sublist(start, end);
|
||||
sendRecordData({
|
||||
"bytes": sublist,
|
||||
// "udpSendDataFrameNumber": 0,
|
||||
"lockID": UDPManage().lockId,
|
||||
"lockIP": UDPManage().host,
|
||||
"userMobile": await state.userMobile,
|
||||
"userMobileIP": await state.userMobileIP,
|
||||
});
|
||||
print(sublist);
|
||||
start += length;
|
||||
}
|
||||
print('G711数据发送完成');
|
||||
} else {
|
||||
print('Failed to read audio data.');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> startProcessing() async {
|
||||
frameListener(List<int> frame) async {
|
||||
// Get.log('Get data.length:${frame.length} Received data:$frame');
|
||||
for (int i = 0; i < frame.length; i++) {
|
||||
frame[i] = linearToULaw(frame[i]);
|
||||
}
|
||||
// Get.log('change Get data.length:${frame.length} change Received data:$frame');
|
||||
await Future.delayed(const Duration(milliseconds: 50));
|
||||
sendRecordData({
|
||||
"bytes": frame,
|
||||
// "udpSendDataFrameNumber": 0,
|
||||
"lockID": UDPManage().lockId,
|
||||
"lockIP": UDPManage().host,
|
||||
"userMobile": await state.userMobile,
|
||||
"userMobileIP": await state.userMobileIP,
|
||||
});
|
||||
}
|
||||
|
||||
errorListener(VoiceProcessorException error) {
|
||||
print("VoiceProcessorException: $error");
|
||||
};
|
||||
state.voiceProcessor?.addFrameListener(frameListener);
|
||||
state.voiceProcessor?.addErrorListener(errorListener);
|
||||
|
||||
try {
|
||||
if (await state.voiceProcessor?.hasRecordAudioPermission() ?? false) {
|
||||
await state.voiceProcessor?.start(320, 8000);
|
||||
bool? isRecording = await state.voiceProcessor?.isRecording();
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
} on PlatformException catch (ex) {
|
||||
Get.log("PlatformException: $ex");
|
||||
} finally {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> stopProcessing() async {
|
||||
try {
|
||||
await state.voiceProcessor?.stop();
|
||||
} on PlatformException catch (ex) {
|
||||
Get.log("PlatformException: $ex");
|
||||
} finally {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void onError(Object e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
sendRecordData(Map<String, dynamic> args) async {
|
||||
|
||||
List<int> bytes = args["bytes"];
|
||||
// int udpSendDataFrameNumber = args["udpSendDataFrameNumber"];
|
||||
String? lockID = args["lockID"];
|
||||
String? lockIP = args["lockIP"];
|
||||
String? userMobile = args["userMobile"];
|
||||
String? userMobileIP = args["userMobileIP"];
|
||||
|
||||
// int length = 320; // 每个子List的长度
|
||||
// List<int> list = state.listAudioData.value.sublist(0, 320);
|
||||
// for (int i = 0; i < bytes.length; i += length) {
|
||||
// int end = (i + length < bytes.length) ? i + length : bytes.length;
|
||||
// bytes.sublist(i, end);
|
||||
// // _sendRecordData(bytes.sublist(i, end));
|
||||
// // // 刚进来是接听状态,然后改为长按对讲
|
||||
// }
|
||||
|
||||
// while(list.isNotEmpty) {
|
||||
state.udpSendDataFrameNumber++;
|
||||
if (state.udpSendDataFrameNumber >= 65536) state.udpSendDataFrameNumber=1;
|
||||
// 57
|
||||
List<int> topBytes = [];
|
||||
|
||||
// var cID = "XXXCID";
|
||||
// List<int> cIDData = utf8.encode(cID!);
|
||||
// topBytes.addAll(cIDData);
|
||||
// // topBytes = getFixedLengthList(cIDData, 20 - cIDData.length);
|
||||
// for (int i = 0; i < 6 - cIDData.length; i++) {
|
||||
// topBytes.add(0);
|
||||
// }
|
||||
//
|
||||
// // 命令
|
||||
// topBytes.add(150);
|
||||
//
|
||||
// // 命令类型
|
||||
// topBytes.add(1);
|
||||
//
|
||||
// // 子命令
|
||||
// topBytes.add(8);
|
||||
//
|
||||
// // lockID
|
||||
// List<int> lockIDData = utf8.encode(lockID!);
|
||||
// topBytes.addAll(lockIDData);
|
||||
// // topBytes = getFixedLengthList(lockIDData, 20 - lockIDData.length);
|
||||
// for (int i = 0; i < 20 - lockIDData.length; i++) {
|
||||
// topBytes.add(0);
|
||||
// }
|
||||
//
|
||||
// // lockIP
|
||||
// var lockIPList = lockIP!.split(".");
|
||||
// lockIPList.forEach((element) {
|
||||
// topBytes.add(int.parse(element));
|
||||
// });
|
||||
//
|
||||
// // userMobile
|
||||
// List<int> userMobileData = utf8.encode(userMobile!);
|
||||
// topBytes.addAll(userMobileData);
|
||||
// // topBytes = getFixedLengthList(topBytes, 20 - userMobileData.length);
|
||||
// for (int i = 0; i < 20 - userMobileData.length; i++) {
|
||||
// topBytes.add(0);
|
||||
// }
|
||||
//
|
||||
// // userMobileIP
|
||||
// var userMobileIPList = userMobileIP!.split(".");
|
||||
// userMobileIPList.forEach((element) {
|
||||
// topBytes.add(int.parse(element));
|
||||
// });
|
||||
|
||||
topBytes.addAll([
|
||||
1, 1, 1, 1, // 时间戳
|
||||
1, 0, // 音频
|
||||
1, 0, // 帧序号
|
||||
64, 0, 0, 0, // 帧长度
|
||||
1, 0, // 总包数
|
||||
1, 0, // 当前包号
|
||||
64, 1, // 数据长度
|
||||
176, 4, // 保留
|
||||
]);
|
||||
|
||||
topBytes[6] = (state.udpSendDataFrameNumber & 0x000000FF);
|
||||
topBytes[7] = ((state.udpSendDataFrameNumber & 0x0000FF00) >> 8);
|
||||
|
||||
print("udpSendDataFrameNumber:${state.udpSendDataFrameNumber} topBytes[63]:${topBytes[6]} topBytes[64]:${topBytes[7]}");
|
||||
topBytes.addAll(bytes);
|
||||
Get.log("setVoiceBytes:$topBytes");
|
||||
|
||||
UDPSenderManage.sendMainProtocol(
|
||||
command: 150,
|
||||
commandTypeIsCalling: 1,
|
||||
subCommand: 8,
|
||||
lockID: lockID,
|
||||
lockIP: lockIP,
|
||||
userMobile: userMobile,
|
||||
userMobileIP: userMobileIP,
|
||||
endData: topBytes
|
||||
);
|
||||
|
||||
// UDPManage().sendData(topBytes);
|
||||
}
|
||||
|
||||
// 拿到的音频转化成pcm
|
||||
int linearToULaw(int pcmVal) {
|
||||
int mask;
|
||||
int seg;
|
||||
int uval;
|
||||
|
||||
if (pcmVal < 0) {
|
||||
pcmVal = 0x84 - pcmVal;
|
||||
mask = 0x7F;
|
||||
} else {
|
||||
pcmVal += 0x84;
|
||||
mask = 0xFF;
|
||||
}
|
||||
|
||||
seg = search(pcmVal);
|
||||
if (seg >= 8) {
|
||||
return 0x7F ^ mask;
|
||||
} else {
|
||||
uval = (seg << 4);
|
||||
uval |= ((pcmVal >> (seg + 3)) & 0xF);
|
||||
return uval ^ mask;
|
||||
}
|
||||
}
|
||||
|
||||
int search(int val) {
|
||||
List<int> table = [0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF];
|
||||
int size = 8;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (val <= table[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
double _calculateVolumeLevel(List<int> frame) {
|
||||
double rms = 0.0;
|
||||
for (int sample in frame) {
|
||||
rms += pow(sample, 2);
|
||||
}
|
||||
rms = sqrt(rms / frame.length);
|
||||
|
||||
double dbfs = 20 * log(rms / 32767.0) / log(10);
|
||||
double normalizedValue = (dbfs + 50) / 50;
|
||||
return normalizedValue.clamp(0.0, 1.0);
|
||||
}
|
||||
|
||||
Future<bool> getPermissionStatus() async {
|
||||
Permission permission = Permission.microphone;
|
||||
//granted 通过,denied 被拒绝,permanentlyDenied 拒绝且不在提示
|
||||
PermissionStatus status = await permission.status;
|
||||
if (status.isGranted) {
|
||||
return true;
|
||||
} else if (status.isDenied) {
|
||||
requestPermission(permission);
|
||||
} else if (status.isPermanentlyDenied) {
|
||||
openAppSettings();
|
||||
} else if (status.isRestricted) {
|
||||
requestPermission(permission);
|
||||
} else {}
|
||||
return false;
|
||||
}
|
||||
|
||||
///申请权限
|
||||
void requestPermission(Permission permission) async {
|
||||
PermissionStatus status = await permission.request();
|
||||
if (status.isPermanentlyDenied) {
|
||||
openAppSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
// TODO: implement onReady
|
||||
super.onReady();
|
||||
print("onReady()");
|
||||
|
||||
_getTVDataRefreshUIAction();
|
||||
_getUDPStatusRefreshUIAction();
|
||||
|
||||
initRecorder();
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
// TODO: implement onInit
|
||||
super.onInit();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// TODO: implement onClose
|
||||
print("锁详情界面销毁了");
|
||||
_getTVDataRefreshUIEvent!.cancel();
|
||||
_getUDPStatusRefreshUIEvent!.cancel();
|
||||
state.oneMinuteTimeTimer.cancel();
|
||||
stopProcessing();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../../../appRouters.dart';
|
||||
import '../../../../app_settings/app_colors.dart';
|
||||
import '../../../../talk/udp/udp_manage.dart';
|
||||
import '../../../../talk/udp/udp_senderManage.dart';
|
||||
import '../../../../tools/showTFView.dart';
|
||||
import '../../../../tools/toast.dart';
|
||||
import 'lockMonitoring_logic.dart';
|
||||
|
||||
|
||||
class LockMonitoringPage extends StatefulWidget {
|
||||
const LockMonitoringPage({Key? key}) : super(key: key);
|
||||
|
||||
@ -21,133 +24,211 @@ class _LockMonitoringPageState extends State<LockMonitoringPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
return SizedBox(
|
||||
width: 1.sw,
|
||||
height: 1.sh,
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
child: Stack(
|
||||
children: [
|
||||
Stack(
|
||||
// alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
Image.asset("images/icon_test20231113.png", width: 1.sw, height: 1.sh, fit: BoxFit.cover),
|
||||
Positioned(
|
||||
top: ScreenUtil().statusBarHeight + 30.h,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: 30.w),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(30.h)
|
||||
),
|
||||
padding: EdgeInsets.all(10.w),
|
||||
child: Image(width: 40.w, height: 40.w, image: const AssetImage("images/icon_left_black.png"),),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 10.w,
|
||||
child: Container(
|
||||
width: 1.sw - 30.w*2,
|
||||
// height: 300.h,
|
||||
margin: EdgeInsets.all(30.w),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xC83C3F41),
|
||||
borderRadius: BorderRadius.circular(20.h)
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 20.h),
|
||||
bottomTopBtnWidget(),
|
||||
SizedBox(height: 20.h),
|
||||
bottomBottomBtnWidget(),
|
||||
SizedBox(height: 20.h),
|
||||
],
|
||||
),
|
||||
))
|
||||
],
|
||||
Obx(() => state.listData.value.isEmpty
|
||||
? Container(color: Colors.transparent)
|
||||
: Image.memory(
|
||||
state.listData.value,
|
||||
// key: ValueKey<int>(state.listData.value.hashCode),
|
||||
gaplessPlayback: true,
|
||||
width: 1.sw,
|
||||
height: 1.sh,
|
||||
fit: BoxFit.cover,
|
||||
)),
|
||||
Positioned(
|
||||
top: ScreenUtil().statusBarHeight + 30.h,
|
||||
width: 1.sw,
|
||||
child: Obx(() {
|
||||
var sec = (state.oneMinuteTime.value % 60).toString().padLeft(2,'0');
|
||||
var min = (state.oneMinuteTime.value ~/ 60).toString().padLeft(2,'0');
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text("$min:$sec", style: TextStyle(fontSize: 26.sp, color: Colors.white)),
|
||||
// SizedBox(width: 30.w),
|
||||
// GestureDetector(
|
||||
// onTap: () {
|
||||
// Get.back();
|
||||
// },
|
||||
// child: Container(
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// borderRadius: BorderRadius.circular(25.h)),
|
||||
// padding: EdgeInsets.all(10.w),
|
||||
// child: Image(
|
||||
// width: 40.w,
|
||||
// height: 40.w,
|
||||
// image: const AssetImage("images/icon_left_black.png"),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
]
|
||||
);
|
||||
}),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 10.w,
|
||||
child: Container(
|
||||
width: 1.sw - 30.w * 2,
|
||||
// height: 300.h,
|
||||
margin: EdgeInsets.all(30.w),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xC83C3F41),
|
||||
borderRadius: BorderRadius.circular(20.h)),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 20.h),
|
||||
bottomTopBtnWidget(),
|
||||
SizedBox(height: 20.h),
|
||||
bottomBottomBtnWidget(),
|
||||
SizedBox(height: 20.h),
|
||||
],
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget bottomTopBtnWidget(){
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// 打开关闭声音
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
state.isOpenVoice.value = !state.isOpenVoice.value;
|
||||
},
|
||||
child: Container(
|
||||
width: 50.w,
|
||||
height: 50.w,
|
||||
padding: EdgeInsets.all(5.w),
|
||||
child: Obx(() => Image(
|
||||
width: 40.w,
|
||||
height: 40.w,
|
||||
image: state.isOpenVoice.value
|
||||
? const AssetImage("images/main/icon_lockDetail_monitoringCloseVoice.png")
|
||||
: const AssetImage("images/main/icon_lockDetail_monitoringOpenVoice.png")
|
||||
)),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 60.w),
|
||||
// 截图
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
// Get.toNamed(Routers.monitoringRealTimeScreenPage);
|
||||
},
|
||||
child: Container(
|
||||
width: 50.w,
|
||||
height: 50.w,
|
||||
padding: EdgeInsets.all(5.w),
|
||||
child: Image(width: 40.w, height: 40.w, image: const AssetImage("images/main/icon_lockDetail_monitoringScreenshot.png")),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 60.w),
|
||||
// 录制
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
// Get.toNamed(Routers.monitoringRealTimeScreenPage);
|
||||
},
|
||||
child: Container(
|
||||
width: 50.w,
|
||||
height: 50.w,
|
||||
padding: EdgeInsets.all(5.w),
|
||||
child: Image(width: 40.w, height: 40.w, image: const AssetImage("images/main/icon_lockDetail_monitoringScreenRecording.png")),
|
||||
),
|
||||
),
|
||||
]);
|
||||
Widget bottomTopBtnWidget() {
|
||||
return Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
// 打开关闭声音
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
state.isOpenVoice.value = !state.isOpenVoice.value;
|
||||
},
|
||||
child: Container(
|
||||
width: 50.w,
|
||||
height: 50.w,
|
||||
padding: EdgeInsets.all(5.w),
|
||||
child: Obx(() => Image(
|
||||
width: 40.w,
|
||||
height: 40.w,
|
||||
image: state.isOpenVoice.value
|
||||
? const AssetImage(
|
||||
"images/main/icon_lockDetail_monitoringCloseVoice.png")
|
||||
: const AssetImage(
|
||||
"images/main/icon_lockDetail_monitoringOpenVoice.png"))),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 60.w),
|
||||
// 截图
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
// Get.toNamed(Routers.monitoringRealTimeScreenPage);
|
||||
},
|
||||
child: Container(
|
||||
width: 50.w,
|
||||
height: 50.w,
|
||||
padding: EdgeInsets.all(5.w),
|
||||
child: Image(
|
||||
width: 40.w,
|
||||
height: 40.w,
|
||||
image: const AssetImage(
|
||||
"images/main/icon_lockDetail_monitoringScreenshot.png")),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 60.w),
|
||||
// 录制
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
// Get.toNamed(Routers.monitoringRealTimeScreenPage);
|
||||
},
|
||||
child: Container(
|
||||
width: 50.w,
|
||||
height: 50.w,
|
||||
padding: EdgeInsets.all(5.w),
|
||||
child: Image(
|
||||
width: 40.w,
|
||||
height: 40.w,
|
||||
image: const AssetImage(
|
||||
"images/main/icon_lockDetail_monitoringScreenRecording.png")),
|
||||
),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
Widget bottomBottomBtnWidget(){
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
bottomBtnItemWidget("images/main/icon_lockDetail_monitoringTalkback.png", "点击对讲", Colors.white,(){
|
||||
Widget bottomBottomBtnWidget() {
|
||||
return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
|
||||
// 接听
|
||||
Obx(() => bottomBtnItemWidget(getAnswerBtnImg(), getAnswerBtnName(), Colors.white, () async {
|
||||
//获取麦克风权限
|
||||
await logic.getPermissionStatus().then((value) async {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
}),
|
||||
bottomBtnItemWidget("images/main/icon_lockDetail_monitoringUnlock.png", "长按开锁", AppColors.mainColor,(){
|
||||
// state.isSenderAudioData.value = false;
|
||||
print("发送接听了");
|
||||
// 刚进来是接听状态,然后改为长按对讲
|
||||
logic.udpAnswerAction();
|
||||
});
|
||||
},
|
||||
longPress: (){
|
||||
// 开始长按
|
||||
print("onLongPress");
|
||||
state.listAudioData.value = <int>[];
|
||||
if (state.udpStatus.value == 8) {
|
||||
state.udpStatus.value = 9;
|
||||
}
|
||||
// logic.readG711Data();
|
||||
logic.startProcessing();
|
||||
},
|
||||
longPressUp: () async {
|
||||
// 长按结束
|
||||
print("onLongPressUp");
|
||||
if (state.udpStatus.value == 9) {
|
||||
state.udpStatus.value = 8;
|
||||
}
|
||||
}
|
||||
)
|
||||
),
|
||||
bottomBtnItemWidget("images/main/icon_lockDetail_hangUp.png", "挂断", Colors.red, () async {
|
||||
logic.stopProcessing();
|
||||
|
||||
})
|
||||
]);
|
||||
// 挂断
|
||||
logic.udpHangUpAction();
|
||||
}),
|
||||
bottomBtnItemWidget("images/main/icon_lockDetail_monitoringUnlock.png", "开锁", AppColors.mainColor, () {
|
||||
showDeletPasswordAlertDialog(context);
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
Widget bottomBtnItemWidget(String iconUrl, String name, Color backgroundColor, Function() onClick) {
|
||||
String getAnswerBtnImg() {
|
||||
switch (state.udpStatus.value) {
|
||||
case 8:
|
||||
return "images/main/icon_lockDetail_monitoringUnTalkback.png";
|
||||
case 9:
|
||||
return "images/main/icon_lockDetail_monitoringTalkback.png";
|
||||
default:
|
||||
return "images/main/icon_lockDetail_monitoringAnswerCalls.png";
|
||||
}
|
||||
}
|
||||
|
||||
String getAnswerBtnName() {
|
||||
switch (state.udpStatus.value) {
|
||||
case 8:
|
||||
return "长按说话";
|
||||
case 9:
|
||||
return "松开发送";
|
||||
default:
|
||||
return "接听";
|
||||
}
|
||||
}
|
||||
|
||||
Widget bottomBtnItemWidget(String iconUrl, String name, Color backgroundColor, Function() onClick, {Function()? longPress, Function()? longPressUp}) {
|
||||
var wh = 80.w;
|
||||
return GestureDetector(
|
||||
onTap: onClick,
|
||||
onLongPress: longPress,
|
||||
onLongPressUp: longPressUp,
|
||||
child: SizedBox(
|
||||
height: 140.h,
|
||||
height: 140.h,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
@ -156,15 +237,54 @@ class _LockMonitoringPageState extends State<LockMonitoringPage> {
|
||||
height: wh,
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
borderRadius: BorderRadius.circular((wh+ 10.w*2)/2)
|
||||
),
|
||||
borderRadius: BorderRadius.circular((wh + 10.w * 2) / 2)),
|
||||
padding: EdgeInsets.all(20.w),
|
||||
child: Image.asset(iconUrl, fit: BoxFit.fitWidth),
|
||||
),
|
||||
SizedBox(height: 20.w),
|
||||
Expanded(child: Text(name, style: TextStyle(fontSize: 20.sp, color: Colors.white), textAlign: TextAlign.center))
|
||||
Expanded(
|
||||
child: Text(name,
|
||||
style: TextStyle(fontSize: 20.sp, color: Colors.white),
|
||||
textAlign: TextAlign.center))
|
||||
],
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
void showDeletPasswordAlertDialog(BuildContext context) {
|
||||
showDialog(
|
||||
barrierDismissible: false,
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return ShowTFView(
|
||||
title: "请输入六位数字开锁密码",
|
||||
tipTitle: "",
|
||||
controller: state.passwordTF,
|
||||
inputFormatters: [
|
||||
LengthLimitingTextInputFormatter(6), //限制长度
|
||||
FilteringTextInputFormatter.allow(RegExp("[0-9]")),
|
||||
],
|
||||
sureClick: () async {
|
||||
//发送删除锁请求
|
||||
if (state.passwordTF.text.isEmpty) {
|
||||
Toast.show(msg: "请输入开锁密码");
|
||||
return;
|
||||
}
|
||||
|
||||
// 开锁
|
||||
logic.udpOpenDoorAction();
|
||||
},
|
||||
cancelClick: () {
|
||||
Get.back();
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,35 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_voice_processor/flutter_voice_processor.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:network_info_plus/network_info_plus.dart';
|
||||
|
||||
import '../../../../tools/storage.dart';
|
||||
|
||||
class LockMonitoringState {
|
||||
var isOpenVoice = false.obs;
|
||||
var udpSendDataFrameNumber = 0;// 帧序号
|
||||
// var isSenderAudioData = false.obs;// 是否要发送音频数据
|
||||
|
||||
}
|
||||
var userMobileIP = NetworkInfo().getWifiIP();
|
||||
var userMobile = Storage.getMobile();
|
||||
|
||||
var udpStatus = 0.obs; //0:初始状态 1:等待监视 2: 3:监视中 4:呼叫成功 5:主角通话中 6:被叫通话 8:被叫通话中 9:长按说话
|
||||
var passwordTF = TextEditingController();
|
||||
|
||||
var listData = Uint8List(0).obs; //得到的视频流字节数据
|
||||
var listAudioData = <int>[].obs; //得到的音频流字节数据
|
||||
|
||||
late final VoiceProcessor? voiceProcessor;
|
||||
|
||||
|
||||
late Timer oneMinuteTimeTimer;// 定时器超过60秒关闭当前界面
|
||||
var oneMinuteTime = 0.obs;// 定时器秒数
|
||||
|
||||
// 定时器如果发送了接听的命令 而没收到回复就每秒重复发送10次
|
||||
late Timer answerTimer;
|
||||
late Timer hangUpTimer;
|
||||
late Timer openDoorTimer;
|
||||
}
|
||||
|
||||
@ -23,13 +23,16 @@ class PasswordKeyDetailLogic extends BaseGetXController {
|
||||
//更新密码请求
|
||||
Future<void> updatePwdRequest() async {
|
||||
PasswordKeyEntity entity = await ApiRepository.to.updatePasswordKey(
|
||||
state.itemData.value.lockId.toString(),
|
||||
state.itemData.value.keyboardPwdId.toString(),
|
||||
state.inputNameController.text,
|
||||
state.inputPwdController.text,
|
||||
'',
|
||||
'',
|
||||
'');
|
||||
lockId: state.itemData.value.lockId!,
|
||||
keyboardPwdId: state.itemData.value.keyboardPwdId.toString(),
|
||||
keyboardPwdName: state.inputNameController.text,
|
||||
newKeyboardPwd: state.inputPwdController.text,
|
||||
startDate: state.startDate.value,
|
||||
endDate: state.endDate.value,
|
||||
changeType: state.changeType.value,
|
||||
hoursStart: state.hoursStart.value,
|
||||
hoursEnd: state.hoursEnd.value,
|
||||
isCoerced: state.isCoerced.value);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
Toast.show(msg: "修改成功");
|
||||
Get.back();
|
||||
|
||||
@ -55,10 +55,19 @@ class _PasswordKeyDetailPageState extends State<PasswordKeyDetailPage> {
|
||||
rightTitle: state.inputPwdController.text.isNotEmpty
|
||||
? state.inputPwdController.text
|
||||
: state.itemData.value.keyboardPwd,
|
||||
isHaveDirection: true,
|
||||
isHaveDirection: (state.itemData.value.keyboardPwdType == 1 ||
|
||||
state.itemData.value.keyboardPwdType == 4)
|
||||
? false
|
||||
: true,
|
||||
isHaveLine: true,
|
||||
action: () {
|
||||
showCupertinoAlertDialog(context, state.inputPwdController);
|
||||
if (state.itemData.value.keyboardPwdType == 1 ||
|
||||
state.itemData.value.keyboardPwdType == 4) {
|
||||
return;
|
||||
} else {
|
||||
showCupertinoAlertDialog(
|
||||
context, state.inputPwdController);
|
||||
}
|
||||
}),
|
||||
CommonItem(
|
||||
leftTitel: TranslationLoader.lanKeys!.name!.tr,
|
||||
|
||||
@ -6,6 +6,13 @@ class PasswordKeyDetailState {
|
||||
final itemData = PasswordKeyListItem().obs;
|
||||
final TextEditingController inputPwdController = TextEditingController();
|
||||
final TextEditingController inputNameController = TextEditingController();
|
||||
final changeType = '1'
|
||||
.obs; //1-通过APP走蓝牙修改,不传默认1,必需先通过APP SDK蓝牙修改后调用该接口 2-通过网关或WiFi锁修改,如果是WiFi锁或有连接网关,则可以传2,直接调用该接口修改生效
|
||||
final isCoerced = '1'.obs; //胁迫指纹:1;非胁迫指纹:2(胁迫指纹开锁触发报警)
|
||||
final hoursStart = 0.obs;
|
||||
final hoursEnd = 0.obs;
|
||||
final startDate = 0.obs;
|
||||
final endDate = 0.obs;
|
||||
|
||||
PasswordKeyDetailState() {
|
||||
Map map = Get.arguments;
|
||||
|
||||
@ -12,9 +12,8 @@ class PasswordKeyListLogic extends BaseGetXController {
|
||||
//请求密码钥匙列表
|
||||
void mockNetworkDataRequest() async {
|
||||
PasswordKeyListEntity entity = await ApiRepository.to.passwordKeyList(
|
||||
'0',
|
||||
state.keyInfo.value.keyStatus.toString(),
|
||||
state.keyInfo.value.lockId.toString(),
|
||||
'0',
|
||||
state.pageNum.toString(),
|
||||
state.pageSize.toString(),
|
||||
state.searchController.text);
|
||||
@ -35,9 +34,10 @@ class PasswordKeyListLogic extends BaseGetXController {
|
||||
}
|
||||
|
||||
//删除密码请求 deleteType:1-蓝牙 2-网关
|
||||
Future<void> deletePwdRequest(String lockId, String keyboardPwdId, int deleteType) async {
|
||||
PasswordKeyEntity entity = await ApiRepository.to.deleteKeyboardPwd(
|
||||
lockId, keyboardPwdId, deleteType);
|
||||
Future<void> deletePwdRequest(
|
||||
String lockId, String keyboardPwdId, int deleteType) async {
|
||||
PasswordKeyEntity entity = await ApiRepository.to
|
||||
.deleteKeyboardPwd(lockId, keyboardPwdId, deleteType);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
Toast.show(msg: "删除成功");
|
||||
mockNetworkDataRequest();
|
||||
|
||||
@ -90,18 +90,18 @@ class PasswordKeyPerpetualLogic extends BaseGetXController {
|
||||
state.effectiveDateTime.value.millisecondsSinceEpoch.toString();
|
||||
}
|
||||
var entity = await ApiRepository.to.getPasswordKey(
|
||||
getFailureDateTime,
|
||||
'0',
|
||||
state.nameController.text,
|
||||
getKeyType,
|
||||
'0',
|
||||
lockId,
|
||||
'0',
|
||||
getEffectiveDateTime,
|
||||
'0',
|
||||
state.loopStartHours.value,
|
||||
state.loopEndHours.value,
|
||||
1);
|
||||
endDate: getFailureDateTime,
|
||||
isExclusive: '0',
|
||||
keyboardPwdName: state.nameController.text,
|
||||
keyboardPwdType: getKeyType,
|
||||
keyboardPwdVersion: '0',
|
||||
lockId: lockId,
|
||||
operatorUid: '0',
|
||||
startDate: getEffectiveDateTime,
|
||||
timezoneRawOffSet: '0',
|
||||
startHours: state.loopStartHours.value,
|
||||
endHours: state.loopEndHours.value,
|
||||
isCoerced: 1);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
print('获取密码成功');
|
||||
state.isSendSuccess.value = true;
|
||||
|
||||
@ -1,13 +1,8 @@
|
||||
|
||||
|
||||
import '../../../../tools/baseGetXController.dart';
|
||||
import '../../../../tools/storage.dart';
|
||||
import 'demoModeLockDetail_state.dart';
|
||||
|
||||
class DemoModeLockDetailLogic extends BaseGetXController {
|
||||
DemoModeLockDetailState state = DemoModeLockDetailState();
|
||||
|
||||
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
|
||||
@ -19,7 +19,7 @@ class DemoModeLockDetailPage extends StatefulWidget {
|
||||
|
||||
class _DemoModeLockDetailPageState extends State<DemoModeLockDetailPage> {
|
||||
final logic = Get.put(DemoModeLockDetailLogic());
|
||||
final state = Get.find<DemoModeLockDetailLogic>().state;
|
||||
// final state = Get.find<DemoModeLockDetailLogic>().state;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
|
||||
|
||||
class DemoModeLockDetailState {
|
||||
|
||||
}
|
||||
@ -1,10 +1,13 @@
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
import 'package:star_lock/talk/udp/udp_senderManage.dart';
|
||||
|
||||
import '../../../blue/io_tool/manager_event_bus.dart';
|
||||
import '../../../network/api_repository.dart';
|
||||
import '../../../talk/udp/udp_help.dart';
|
||||
import '../../../tools/baseGetXController.dart';
|
||||
import '../../../tools/eventBusEventManage.dart';
|
||||
import '../entity/lockListInfo_entity.dart';
|
||||
@ -106,7 +109,6 @@ class LockMainLogic extends BaseGetXController {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
// TODO: implement onReady
|
||||
@ -114,6 +116,9 @@ class LockMainLogic extends BaseGetXController {
|
||||
print("onReady()");
|
||||
|
||||
_initLoadDataAction();
|
||||
|
||||
// 开启UDP
|
||||
UdpHelp().openUDP();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -133,6 +138,7 @@ class LockMainLogic extends BaseGetXController {
|
||||
|
||||
// refreshController.dispose();
|
||||
_teamEvent.cancel();
|
||||
// state.timer.cancel();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import '../entity/lockListInfo_entity.dart';
|
||||
|
||||
@ -7,4 +9,6 @@ class LockMainState {
|
||||
// 0是无数据 1是有一条数据 2是有很多条数据
|
||||
var dataLength = 100.obs;
|
||||
var lockListInfoEntity = LockListInfoEntity().obs;
|
||||
|
||||
// late Timer timer;
|
||||
}
|
||||
@ -1,11 +1,8 @@
|
||||
|
||||
import '../../../../tools/baseGetXController.dart';
|
||||
import 'lockAddress_state.dart';
|
||||
|
||||
class LockAddressLogic extends BaseGetXController {
|
||||
|
||||
final LockAddressState state = LockAddressState();
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
// TODO: implement onReady
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
|
||||
|
||||
class LockAddressState {
|
||||
|
||||
}
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@ -23,37 +22,36 @@ import '../../../tools/dateTool.dart';
|
||||
import '../../../tools/storage.dart';
|
||||
import 'nearbyLock_state.dart';
|
||||
|
||||
class NearbyLockLogic extends BaseGetXController{
|
||||
|
||||
class NearbyLockLogic extends BaseGetXController {
|
||||
final NearbyLockState state = NearbyLockState();
|
||||
|
||||
// 点击连接设备
|
||||
void connect(String lockId, String deviceName){
|
||||
void connect(String lockId, String deviceName) {
|
||||
// BlueManage().stopScan();
|
||||
// BlueManage().judgeReconnect(lockId, deviceName, (DeviceConnectionState state) async {
|
||||
// if (state == DeviceConnectionState.connected) {
|
||||
// IoSenderManage.getPublicKey(lockId: deviceName);
|
||||
// }
|
||||
// }, isShowLoading: true);
|
||||
BlueManage().connect(deviceName, (state){
|
||||
|
||||
}, isFrist: true, isShowLoading: true);
|
||||
BlueManage()
|
||||
.connect(deviceName, (state) {}, isFrist: true, isShowLoading: true);
|
||||
}
|
||||
|
||||
// 获取解析后的数据
|
||||
late StreamSubscription<Reply> _replySubscription;
|
||||
void _initReplySubscription() {
|
||||
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
|
||||
if(reply is GetPublicKeyReply) {
|
||||
_replySubscription =
|
||||
EventBusManager().eventBus!.on<Reply>().listen((reply) {
|
||||
if (reply is GetPublicKeyReply) {
|
||||
_replyGetPublicKey(reply);
|
||||
}
|
||||
|
||||
if(reply is GetPrivateKeyReply) {
|
||||
if (reply is GetPrivateKeyReply) {
|
||||
_replyGetPrivateKeyKey(reply);
|
||||
}
|
||||
|
||||
// 获取锁状态信息
|
||||
if(reply is GetStarLockStatuInfoReply) {
|
||||
if (reply is GetStarLockStatuInfoReply) {
|
||||
_replyGetStarLockStatusInfo(reply);
|
||||
}
|
||||
});
|
||||
@ -61,25 +59,25 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
|
||||
Future<void> _replyGetPublicKey(Reply reply) async {
|
||||
// 获取公钥
|
||||
switch(reply.status){
|
||||
switch (reply.status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
print("获取公钥成功");
|
||||
// 储存公钥
|
||||
var publicKey = reply.data.sublist(3);
|
||||
var saveStrList = changeIntListToStringList(publicKey);
|
||||
Storage.setStringList(saveBluePublicKey, saveStrList);
|
||||
//成功
|
||||
print("获取公钥成功");
|
||||
// 储存公钥
|
||||
var publicKey = reply.data.sublist(3);
|
||||
var saveStrList = changeIntListToStringList(publicKey);
|
||||
Storage.setStringList(saveBluePublicKey, saveStrList);
|
||||
|
||||
IoSenderManage.getPrivateKey(
|
||||
lockId:BlueManage().connectDeviceName,
|
||||
keyID:"1",
|
||||
authUserID:await Storage.getUid(),
|
||||
nowTime:DateTime.now().millisecondsSinceEpoch~/1000,
|
||||
publicKeyData:publicKey,
|
||||
needAuthor:1);
|
||||
IoSenderManage.getPrivateKey(
|
||||
lockId: BlueManage().connectDeviceName,
|
||||
keyID: "1",
|
||||
authUserID: await Storage.getUid(),
|
||||
nowTime: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
publicKeyData: publicKey,
|
||||
needAuthor: 1);
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
//无权限
|
||||
print("获取公钥无权限");
|
||||
break;
|
||||
case 0x0f:
|
||||
@ -87,14 +85,14 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
print("获取公钥用户已存在");
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
//失败
|
||||
print("获取公钥失败");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _replyGetPrivateKeyKey(Reply reply) async {
|
||||
switch(reply.status){
|
||||
switch (reply.status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
print('获取私钥成功');
|
||||
@ -115,8 +113,7 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
|
||||
// 时间戳
|
||||
List<int> timestamp = reply.data.sublist(32, 36);
|
||||
state.timestampValue = (
|
||||
(0xff & timestamp[(0)]) << 24 |
|
||||
state.timestampValue = ((0xff & timestamp[(0)]) << 24 |
|
||||
(0xff & timestamp[1]) << 16 |
|
||||
(0xff & timestamp[2]) << 8 |
|
||||
(0xFF & timestamp[3]));
|
||||
@ -126,7 +123,7 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
_getStarLockStatus();
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
//无权限
|
||||
print('获取私钥无权限');
|
||||
|
||||
break;
|
||||
@ -144,15 +141,15 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
// 获取星锁状态
|
||||
Future<void> _replyGetStarLockStatusInfo(Reply reply) async {
|
||||
int status = reply.data[2];
|
||||
switch(status){
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
//成功
|
||||
print("${reply.commandType}数据解析成功");
|
||||
|
||||
// 厂商名称
|
||||
var vendor = reply.data.sublist(3, 23);
|
||||
print("vendor:$vendor reply.data:${reply.data}");
|
||||
var vendorStr = utf8String(vendor);
|
||||
var vendorStr = utf8String(vendor);
|
||||
state.lockInfo["vendor"] = vendorStr;
|
||||
// print("vendor:$vendor vendorStr:$vendorStr vendorStr.length${vendorStr.length}");
|
||||
|
||||
@ -163,38 +160,39 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
|
||||
// 产品名称
|
||||
var model = reply.data.sublist(24, 44);
|
||||
var modelStr = utf8String(model);
|
||||
var modelStr = utf8String(model);
|
||||
state.lockInfo["model"] = modelStr;
|
||||
// print("model:$model modelStr:$modelStr modelStr:${modelStr.length}");
|
||||
|
||||
// 软件版本
|
||||
var fwVersion = reply.data.sublist(44, 64);
|
||||
var fwVersionStr = utf8String(fwVersion);
|
||||
var fwVersionStr = utf8String(fwVersion);
|
||||
state.lockInfo["fwVersion"] = fwVersionStr;
|
||||
// print("fwVersion:$fwVersion fwVersionStr:$fwVersionStr fwVersionStr:${fwVersionStr.length}");
|
||||
|
||||
// 硬件版本
|
||||
var hwVersion = reply.data.sublist(64, 84);
|
||||
var hwVersionStr = utf8String(hwVersion);
|
||||
var hwVersionStr = utf8String(hwVersion);
|
||||
state.lockInfo["hwVersion"] = hwVersionStr;
|
||||
// print("hwVersion:$hwVersion hwVersionStr:${hwVersionStr.length}");
|
||||
|
||||
// 厂商序列号
|
||||
var serialNum0 = reply.data.sublist(84, 100);
|
||||
var serialNum0Str = utf8String(serialNum0);
|
||||
var serialNum0Str = utf8String(serialNum0);
|
||||
// state.lockInfo["serialNum0"] = serialNum0Str;
|
||||
state.lockInfo["serialNum0"] = "${DateTime.now().millisecondsSinceEpoch~/10}";
|
||||
state.lockInfo["serialNum0"] =
|
||||
"${DateTime.now().millisecondsSinceEpoch ~/ 10}";
|
||||
// print("serialNum0Str:$serialNum0Str serialNum0Str:${serialNum0Str.length}");
|
||||
|
||||
// 成品商序列号
|
||||
var serialNum1 = reply.data.sublist(100, 116);
|
||||
var serialNum1Str = utf8String(serialNum1);
|
||||
var serialNum1Str = utf8String(serialNum1);
|
||||
state.lockInfo["serialNum1"] = serialNum1Str;
|
||||
// print("serialNum1Str:$serialNum1Str serialNum1Str:${serialNum1Str.length}");
|
||||
|
||||
// 蓝牙名称
|
||||
var btDeviceName = reply.data.sublist(116, 132);
|
||||
var btDeviceNameStr = utf8String(btDeviceName);
|
||||
var btDeviceNameStr = utf8String(btDeviceName);
|
||||
state.lockInfo["btDeviceName"] = btDeviceNameStr;
|
||||
// print("btDeviceName:$btDeviceName btDeviceNameStr:$btDeviceNameStr btDeviceNameStr:${btDeviceNameStr.length}");
|
||||
|
||||
@ -205,32 +203,39 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
|
||||
// 重置次数
|
||||
var restoreCounter = reply.data.sublist(133, 135);
|
||||
state.lockInfo["restoreCount"] = restoreCounter[0] * 256 + restoreCounter[1];
|
||||
state.lockInfo["restoreCount"] =
|
||||
restoreCounter[0] * 256 + restoreCounter[1];
|
||||
// print("restoreCounter:$restoreCounter");
|
||||
|
||||
// 重置时间
|
||||
var restoreDate = reply.data.sublist(135, 139);
|
||||
int restoreDateValue = ((0xff & restoreDate[(0)]) << 24 | (0xff & restoreDate[1]) << 16 | (0xff & restoreDate[2]) << 8 | (0xFF & restoreDate[3]));
|
||||
int restoreDateValue = ((0xff & restoreDate[(0)]) << 24 |
|
||||
(0xff & restoreDate[1]) << 16 |
|
||||
(0xff & restoreDate[2]) << 8 |
|
||||
(0xFF & restoreDate[3]));
|
||||
// String restoreDateStr = DateTool().dateToYMDHNSString(restoreDateValue.toString());
|
||||
state.lockInfo["restoreDate"] = restoreDateValue*1000;
|
||||
state.lockInfo["restoreDate"] = restoreDateValue * 1000;
|
||||
// print("restoreDate:$restoreDate restoreDateValue:$restoreDateValue");
|
||||
|
||||
// 主控芯片型号
|
||||
var icPartNo = reply.data.sublist(139, 149);
|
||||
var icPartNoStr = utf8String(icPartNo);
|
||||
var icPartNoStr = utf8String(icPartNo);
|
||||
state.lockInfo["icPartNo"] = icPartNoStr;
|
||||
// print("icPartNo:$icPartNo icPartNoStr:$icPartNoStr");
|
||||
|
||||
// 有效时间
|
||||
var indate = reply.data.sublist(149, 153);
|
||||
int indateValue = ((0xff & indate[(0)]) << 24 | (0xff & indate[1]) << 16 | (0xff & indate[2]) << 8 | (0xFF & indate[3]));
|
||||
int indateValue = ((0xff & indate[(0)]) << 24 |
|
||||
(0xff & indate[1]) << 16 |
|
||||
(0xff & indate[2]) << 8 |
|
||||
(0xFF & indate[3]));
|
||||
// String indateStr = DateTool().dateToYMDHNSString("$indateValue");
|
||||
state.lockInfo["indate"] = indateValue*1000;
|
||||
state.lockInfo["indate"] = indateValue * 1000;
|
||||
// print("indate:$indate indateValue:$indateValue");
|
||||
|
||||
// mac地址
|
||||
var macAddress = reply.data.sublist(153, 173);
|
||||
var macAddressStr = utf8String(macAddress);
|
||||
var macAddressStr = utf8String(macAddress);
|
||||
state.lockInfo["mac"] = macAddressStr;
|
||||
print("macAddress:$macAddress macAddressStr:$macAddressStr");
|
||||
|
||||
@ -239,7 +244,8 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
var featureValueLength = reply.data[173];
|
||||
// 锁特征值说明(本机能支持的功能)
|
||||
// 获取到锁给的字符数组
|
||||
var featureValue = reply.data.sublist(index+1, index + featureValueLength+1);
|
||||
var featureValue =
|
||||
reply.data.sublist(index + 1, index + featureValueLength + 1);
|
||||
String featureValueStr = asciiString(featureValue);
|
||||
state.featureValue = featureValueStr;
|
||||
// List allFeatureValueTwoList = charListChangeIntList(featureValue);
|
||||
@ -249,7 +255,8 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
// 使能特征值字符串长度
|
||||
var featureEnValLength = reply.data[index];
|
||||
// 使能锁特征值说明(本机启用的功能)
|
||||
var featureEnVal = reply.data.sublist(index+1, index + featureEnValLength+1);
|
||||
var featureEnVal =
|
||||
reply.data.sublist(index + 1, index + featureEnValLength + 1);
|
||||
String featureEnValStr = asciiString(featureValue);
|
||||
state.featureSettingValue = featureEnValStr;
|
||||
// List allFeatureEnValTwoList = charListChangeIntList(featureEnVal);
|
||||
@ -264,7 +271,7 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
// print("featureParaTotalList:$featureParaTotalList");
|
||||
|
||||
Get.toNamed(Routers.lockAddressGaoDePage, arguments: {
|
||||
"pwdTimestamp": state.timestampValue*1000,
|
||||
"pwdTimestamp": state.timestampValue * 1000,
|
||||
"lockInfo": state.lockInfo,
|
||||
"featureValue": state.featureValue,
|
||||
"featureSettingValue": state.featureSettingValue,
|
||||
@ -273,22 +280,22 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
//无权限
|
||||
print("${reply.commandType}需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
//无权限
|
||||
print("${reply.commandType}用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
// 权限校验错误
|
||||
print("${reply.commandType}权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
//失败
|
||||
print("${reply.commandType}失败");
|
||||
|
||||
break;
|
||||
@ -315,7 +322,8 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
Future<void> _getStarLockStatus() async {
|
||||
// print("connectDeviceMacAddress:${BlueManage().connectDeviceMacAddress} connectDeviceName:${BlueManage().connectDeviceName}");
|
||||
// 进来之后首先连接
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceName, (DeviceConnectionState state) async {
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceName,
|
||||
(DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
@ -325,21 +333,27 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
// privateKey:getPrivateKeyList,
|
||||
// );
|
||||
IoSenderManage.senderGetStarLockStatuInfo(
|
||||
lockID:BlueManage().connectDeviceName,
|
||||
userID:await Storage.getUid(),
|
||||
privateKey:getPrivateKeyList,
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
}
|
||||
}, isShowLoading: false);
|
||||
}
|
||||
|
||||
late StreamSubscription<List<DiscoveredDevice>> _scanListDiscoveredDeviceSubscription;
|
||||
late StreamSubscription<List<DiscoveredDevice>>
|
||||
_scanListDiscoveredDeviceSubscription;
|
||||
void _scanListDiscoveredDeviceSubscriptionAction() {
|
||||
_scanListDiscoveredDeviceSubscription = EventBusManager().eventBus!.on<List<DiscoveredDevice>>().listen((List<DiscoveredDevice> list) {
|
||||
_scanListDiscoveredDeviceSubscription = EventBusManager()
|
||||
.eventBus!
|
||||
.on<List<DiscoveredDevice>>()
|
||||
.listen((List<DiscoveredDevice> list) {
|
||||
state.devices.clear();
|
||||
for(int i = 0;i<list.length;i++){
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
DiscoveredDevice device = list[i];
|
||||
if(((device.serviceUuids.isNotEmpty ? device.serviceUuids[0] : "").toString()[31] != "1")){
|
||||
if (((device.serviceUuids.isNotEmpty ? device.serviceUuids[0] : "")
|
||||
.toString()[31] !=
|
||||
"1")) {
|
||||
state.devices.add(list[i]);
|
||||
}
|
||||
}
|
||||
@ -371,6 +385,4 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
_scanListDiscoveredDeviceSubscription.cancel();
|
||||
// BlueManage().stopScan();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||
@ -24,8 +23,9 @@ class SaveLockLogic extends BaseGetXController {
|
||||
// 获取解析后的数据
|
||||
late StreamSubscription<Reply> _replySubscription;
|
||||
void _initReplySubscription() {
|
||||
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
|
||||
if(reply is AddUserReply) {
|
||||
_replySubscription =
|
||||
EventBusManager().eventBus!.on<Reply>().listen((reply) {
|
||||
if (reply is AddUserReply) {
|
||||
_replyAddUserKey(reply);
|
||||
}
|
||||
});
|
||||
@ -45,16 +45,16 @@ class SaveLockLogic extends BaseGetXController {
|
||||
// print("status:$status reply.data:${reply.data}");
|
||||
|
||||
print("status:$status");
|
||||
switch(status){
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
//成功
|
||||
print("添加用户数据解析成功");
|
||||
state.lockUserNo = reply.data[47] + 1;
|
||||
|
||||
bindBlueAdmin();
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
//无权限
|
||||
print("需要鉴权");
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
@ -64,33 +64,32 @@ class SaveLockLogic extends BaseGetXController {
|
||||
|
||||
IoSenderManage.senderAddUser(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
authUserID:await Storage.getUid(),
|
||||
keyID:"1",
|
||||
userID:await Storage.getUid(),
|
||||
openMode:1,
|
||||
keyType:1,
|
||||
startDate:DateTime.now().millisecondsSinceEpoch,
|
||||
expireDate:0x11223344,
|
||||
role:255,
|
||||
password:"123456",
|
||||
needAuthor:1,
|
||||
publicKey:publicKeyDataList,
|
||||
privateKey:getPrivateKeyList,
|
||||
token: token
|
||||
);
|
||||
authUserID: await Storage.getUid(),
|
||||
keyID: "1",
|
||||
userID: await Storage.getUid(),
|
||||
openMode: 1,
|
||||
keyType: 1,
|
||||
startDate: DateTime.now().millisecondsSinceEpoch,
|
||||
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;
|
||||
@ -98,15 +97,16 @@ class SaveLockLogic extends BaseGetXController {
|
||||
}
|
||||
|
||||
// 保存事件,先调用蓝牙,蓝牙调用成功后再调用后台接口
|
||||
saveLockAction(){
|
||||
saveLockAction() {
|
||||
addUserConnectBlue();
|
||||
}
|
||||
|
||||
// 添加用户
|
||||
Future<void> addUserConnectBlue() async {
|
||||
// 进来之后首先连接
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceName, (DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected){
|
||||
BlueManage().judgeReconnect(BlueManage().connectDeviceName,
|
||||
(DeviceConnectionState state) async {
|
||||
if (state == DeviceConnectionState.connected) {
|
||||
// 私钥
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
@ -115,32 +115,31 @@ class SaveLockLogic extends BaseGetXController {
|
||||
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||
|
||||
var token = await Storage.getStringList(saveBlueToken);
|
||||
List<int> getTokenList = [0,0,0,0];
|
||||
if(token != null){
|
||||
List<int> getTokenList = [0, 0, 0, 0];
|
||||
if (token != null) {
|
||||
getTokenList = changeStringListToIntList(token);
|
||||
}
|
||||
|
||||
IoSenderManage.senderAddUser(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
authUserID:await Storage.getUid(),
|
||||
keyID:"1",
|
||||
userID:await Storage.getUid(),
|
||||
openMode:1,
|
||||
keyType:1,
|
||||
startDate:DateTime.now().millisecondsSinceEpoch,
|
||||
expireDate:0x11223344,
|
||||
role:255,
|
||||
password:"123456",
|
||||
needAuthor:1,
|
||||
publicKey:publicKeyDataList,
|
||||
privateKey:getPrivateKeyList,
|
||||
token: getTokenList
|
||||
);
|
||||
authUserID: await Storage.getUid(),
|
||||
keyID: "1",
|
||||
userID: await Storage.getUid(),
|
||||
openMode: 1,
|
||||
keyType: 1,
|
||||
startDate: DateTime.now().millisecondsSinceEpoch,
|
||||
expireDate: 0x11223344,
|
||||
role: 255,
|
||||
password: "123456",
|
||||
needAuthor: 1,
|
||||
publicKey: publicKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
token: getTokenList);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void bindBlueAdmin() async{
|
||||
void bindBlueAdmin() async {
|
||||
print("state.lockInfo:${state.lockInfo}");
|
||||
|
||||
var positionMap = {};
|
||||
@ -172,17 +171,17 @@ class SaveLockLogic extends BaseGetXController {
|
||||
// print("addUser:publicKeyDataList$publicKeyDataList getPrivateKeyList:$getPrivateKeyList signKeyDataList:$signKeyDataList");
|
||||
|
||||
var entity = await ApiRepository.to.bindingBlueAdmin(
|
||||
lockAlias:state.aliName.value,
|
||||
position:positionMap,
|
||||
bluetooth:bluetooth,
|
||||
lockInfo: state.lockInfo,
|
||||
lockUserNo:state.lockUserNo.toString(),
|
||||
pwdTimestamp:state.pwdTimestamp.value.toString(),
|
||||
featureValue:state.featureValue,
|
||||
featureSettingValue:state.featureSettingValue,
|
||||
featureSettingParams:state.featureSettingParams,
|
||||
lockAlias: state.aliName.value,
|
||||
position: positionMap,
|
||||
bluetooth: bluetooth,
|
||||
lockInfo: state.lockInfo,
|
||||
lockUserNo: state.lockUserNo.toString(),
|
||||
pwdTimestamp: state.pwdTimestamp.value.toString(),
|
||||
featureValue: state.featureValue,
|
||||
featureSettingValue: state.featureSettingValue,
|
||||
featureSettingParams: state.featureSettingParams,
|
||||
);
|
||||
if(entity.errorCode!.codeIsSuccessful){
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
eventBus.fire(RefreshLockListInfoDataEvent());
|
||||
Get.offAllNamed(Routers.starLockMain);
|
||||
}
|
||||
@ -202,7 +201,6 @@ class SaveLockLogic extends BaseGetXController {
|
||||
// TODO: implement onInit
|
||||
super.onInit();
|
||||
print("onInit()");
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
@ -211,5 +209,4 @@ class SaveLockLogic extends BaseGetXController {
|
||||
super.onClose();
|
||||
_replySubscription.cancel();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ class StarLockMineState {
|
||||
}
|
||||
|
||||
String mobile() {
|
||||
return loginData.value.mobile ?? '-';
|
||||
return loginData.value.mobile ?? '';
|
||||
}
|
||||
|
||||
String email() {
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
|
||||
|
||||
import '../tools/baseGetXController.dart';
|
||||
import 'navState.dart';
|
||||
|
||||
class NavLogic extends BaseGetXController {
|
||||
final NavState state = NavState();
|
||||
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
|
||||
|
||||
class NavState{
|
||||
|
||||
}
|
||||
@ -1,7 +1,9 @@
|
||||
abstract class Api {
|
||||
static String baseAddress = "https://pre.lock.star-lock.cn:8093"; //预发布环境
|
||||
// static String baseAddress = "http://192.168.56.101:8099"; //联调环境
|
||||
|
||||
final String baseUrl = "$baseAddress/api";
|
||||
|
||||
// final String baseUrl = "http://test.lock.star-lock.cn/api"; // 葛工
|
||||
// final String baseUrl = "https://lock.star-lock.cn/api"; // 测试环境
|
||||
// final String baseUrl = "http://wenlin.lock.star-lock.cn/api"; //曾工
|
||||
|
||||
@ -362,19 +362,13 @@ class ApiProvider extends BaseProvider {
|
||||
Future<Response> getWifiLockServiceIpAndPort() =>
|
||||
post(getWifiServiceIpURL.toUrl, jsonEncode({}));
|
||||
|
||||
Future<Response> passwordKeyList(
|
||||
String keyStatus,
|
||||
String lockId,
|
||||
String operatorUid,
|
||||
String pageNo,
|
||||
String pageSize,
|
||||
String searchStr) =>
|
||||
Future<Response> passwordKeyList(String keyStatus, String lockId,
|
||||
String pageNo, String pageSize, String searchStr) =>
|
||||
post(
|
||||
passwordKeyListURL.toUrl,
|
||||
jsonEncode({
|
||||
'keyStatus': keyStatus,
|
||||
'lockId': lockId,
|
||||
'operatorUid': operatorUid,
|
||||
'pageNo': pageNo,
|
||||
'pageSize': pageSize,
|
||||
'searchStr': searchStr
|
||||
@ -436,14 +430,16 @@ class ApiProvider extends BaseProvider {
|
||||
}));
|
||||
|
||||
Future<Response> updateKeyboardPwd(
|
||||
String lockId,
|
||||
String keyboardPwdId,
|
||||
String keyboardPwdName,
|
||||
String newKeyboardPwd,
|
||||
String startDate,
|
||||
String endDate,
|
||||
String changeType,
|
||||
) =>
|
||||
int lockId,
|
||||
String keyboardPwdId,
|
||||
String keyboardPwdName,
|
||||
String newKeyboardPwd,
|
||||
int startDate,
|
||||
int endDate,
|
||||
String changeType,
|
||||
String isCoerced,
|
||||
int hoursStart,
|
||||
int hoursEnd) =>
|
||||
post(
|
||||
updatePasswordKeyURL.toUrl,
|
||||
jsonEncode({
|
||||
@ -454,6 +450,9 @@ class ApiProvider extends BaseProvider {
|
||||
'startDate': startDate,
|
||||
'endDate': endDate,
|
||||
'changeType': changeType,
|
||||
'isCoerced': isCoerced,
|
||||
'hoursStart': hoursStart,
|
||||
'hoursEnd': hoursEnd
|
||||
}));
|
||||
|
||||
Future<Response> clearOperationRecord(String lockId) =>
|
||||
|
||||
@ -323,15 +323,10 @@ class ApiRepository {
|
||||
}
|
||||
|
||||
//密码列表
|
||||
Future<PasswordKeyListEntity> passwordKeyList(
|
||||
String keyStatus,
|
||||
String lockId,
|
||||
String operatorUid,
|
||||
String pageNo,
|
||||
String pageSize,
|
||||
String searchStr) async {
|
||||
Future<PasswordKeyListEntity> passwordKeyList(String keyStatus, String lockId,
|
||||
String pageNo, String pageSize, String searchStr) async {
|
||||
final res = await apiProvider.passwordKeyList(
|
||||
keyStatus, lockId, operatorUid, pageNo, pageSize, searchStr);
|
||||
keyStatus, lockId, pageNo, pageSize, searchStr);
|
||||
return PasswordKeyListEntity.fromJson(res.body);
|
||||
}
|
||||
|
||||
@ -357,43 +352,47 @@ class ApiRepository {
|
||||
}
|
||||
|
||||
// 获取所有锁设置信息
|
||||
Future<LockSetInfoEntity> getLockSettingInfoData({required String lockId}) async {
|
||||
Future<LockSetInfoEntity> getLockSettingInfoData(
|
||||
{required String lockId}) async {
|
||||
final res = await apiProvider.getLockSettingInfoData(lockId);
|
||||
return LockSetInfoEntity.fromJson(res.body);
|
||||
}
|
||||
|
||||
// 删除锁
|
||||
Future<LockListInfoEntity> deletOwnerLockData({required String lockId}) async {
|
||||
Future<LockListInfoEntity> deletOwnerLockData(
|
||||
{required String lockId}) async {
|
||||
final res = await apiProvider.deletLockInfo(lockId);
|
||||
return LockListInfoEntity.fromJson(res.body);
|
||||
}
|
||||
|
||||
// 删除钥匙
|
||||
Future<LockListInfoEntity> deletOwnerKeyData({required String lockId, required String keyId}) async {
|
||||
Future<LockListInfoEntity> deletOwnerKeyData(
|
||||
{required String lockId, required String keyId}) async {
|
||||
final res = await apiProvider.deletOwnerKeyInfo(lockId, keyId);
|
||||
return LockListInfoEntity.fromJson(res.body);
|
||||
}
|
||||
|
||||
// 检查账户密码
|
||||
Future<LockListInfoEntity> checkLoginPassword({required String password}) async {
|
||||
Future<LockListInfoEntity> checkLoginPassword(
|
||||
{required String password}) async {
|
||||
final res = await apiProvider.checkLoginPassword(password);
|
||||
return LockListInfoEntity.fromJson(res.body);
|
||||
}
|
||||
|
||||
//获取密码
|
||||
Future<PasswordKeyEntity> getPasswordKey(
|
||||
String endDate,
|
||||
String isExclusive,
|
||||
String keyboardPwdName,
|
||||
String keyboardPwdType,
|
||||
String keyboardPwdVersion,
|
||||
String lockId,
|
||||
String operatorUid,
|
||||
String startDate,
|
||||
String timezoneRawOffSet,
|
||||
int startHours,
|
||||
int endHours,
|
||||
int isCoerced) async {
|
||||
{required String endDate,
|
||||
required String isExclusive,
|
||||
required String keyboardPwdName,
|
||||
required String keyboardPwdType,
|
||||
required String keyboardPwdVersion,
|
||||
required String lockId,
|
||||
required String operatorUid,
|
||||
required String startDate,
|
||||
required String timezoneRawOffSet,
|
||||
required int startHours,
|
||||
required int endHours,
|
||||
required int isCoerced}) async {
|
||||
final res = await apiProvider.getKeyboardPwd(
|
||||
endDate,
|
||||
isExclusive,
|
||||
@ -427,16 +426,27 @@ class ApiRepository {
|
||||
|
||||
//修改密码
|
||||
Future<PasswordKeyEntity> updatePasswordKey(
|
||||
String lockId,
|
||||
String keyboardPwdId,
|
||||
String keyboardPwdName,
|
||||
String newKeyboardPwd,
|
||||
String startDate,
|
||||
String endDate,
|
||||
String changeType,
|
||||
) async {
|
||||
final res = await apiProvider.updateKeyboardPwd(lockId, keyboardPwdId,
|
||||
keyboardPwdName, newKeyboardPwd, startDate, endDate, changeType);
|
||||
{required int lockId,
|
||||
required String keyboardPwdId,
|
||||
required String keyboardPwdName,
|
||||
required String newKeyboardPwd,
|
||||
required int startDate,
|
||||
required int endDate,
|
||||
required String changeType,
|
||||
required String isCoerced,
|
||||
required int hoursStart,
|
||||
required int hoursEnd}) async {
|
||||
final res = await apiProvider.updateKeyboardPwd(
|
||||
lockId,
|
||||
keyboardPwdId,
|
||||
keyboardPwdName,
|
||||
newKeyboardPwd,
|
||||
startDate,
|
||||
endDate,
|
||||
changeType,
|
||||
isCoerced,
|
||||
hoursStart,
|
||||
hoursEnd);
|
||||
return PasswordKeyEntity.fromJson(res.body);
|
||||
}
|
||||
|
||||
|
||||
155
star_lock/lib/talk/call/callTalk.dart
Normal file
155
star_lock/lib/talk/call/callTalk.dart
Normal file
@ -0,0 +1,155 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/talk/call/g711.dart';
|
||||
import 'package:star_lock/talk/call/iFrameInfo.dart';
|
||||
import '../../tools/eventBusEventManage.dart';
|
||||
import 'package:flutter_pcm_sound/flutter_pcm_sound.dart';
|
||||
import 'package:flutter_sound/flutter_sound.dart';
|
||||
|
||||
class CallTalk {
|
||||
static CallTalk? _manager;
|
||||
static int POS_iframe_index = 63;
|
||||
static int POS_alen = 65;
|
||||
static int POS_blen = 73;
|
||||
static int POS_bag_index = 71;
|
||||
static int POS_bag_num = 69;
|
||||
static int POS_data = 77;
|
||||
static int ABUF_NUM = 100;
|
||||
static int FIRSTINDEX = 1;
|
||||
|
||||
int status = 0; // 假设有这个成员变量
|
||||
IframeInfo? iframe; // 假设有这个成员变量
|
||||
var growableList;
|
||||
bool getFirstFrame = false; //是否得到了第一帧
|
||||
List<int> allDataBytes = <int>[]; //音频数据
|
||||
|
||||
CallTalk._init() {
|
||||
iframe = IframeInfo();
|
||||
FlutterPcmSound.setLogLevel(LogLevel.error);
|
||||
FlutterPcmSound.setup(sampleRate: 8000, channelCount: 1);
|
||||
FlutterPcmSound.setFeedThreshold(8000 ~/ 2);
|
||||
}
|
||||
|
||||
static CallTalk _share() {
|
||||
_manager ??= CallTalk._init();
|
||||
return _manager!;
|
||||
}
|
||||
|
||||
factory CallTalk() => _share();
|
||||
CallTalk get manager => _share();
|
||||
|
||||
Future<void> getAVData(Uint8List bb, int len) async {
|
||||
// 音频数据
|
||||
if (bb[61] == 1) {
|
||||
Uint8List g711Data = bb.sublist(77, bb.length);
|
||||
|
||||
List<int> pcmBytes;
|
||||
try {
|
||||
// 将 ALaw 转为 Linear
|
||||
pcmBytes = G711().convertList(g711Data);
|
||||
allDataBytes.addAll(pcmBytes);
|
||||
|
||||
// String filePath = 'assets/s10-g711.bin';
|
||||
//
|
||||
// List<int> audioData = await G711().readAssetFile(filePath);
|
||||
// pcmBytes = G711().convertList(audioData);
|
||||
// allDataBytes = pcmBytes.sublist(0, 640);
|
||||
|
||||
_initializeAudioPlayer(pcmBytes);
|
||||
} catch (e) {
|
||||
print('Error decoding G.711 to PCM: $e');
|
||||
}
|
||||
}
|
||||
// 视频数据
|
||||
else {
|
||||
// 音视频数据开始下标
|
||||
var bagLen = bb[POS_blen + 2] + bb[POS_blen + 3] * 256;
|
||||
// print('音视频数据开始下标 bagLen:$bagLen');
|
||||
|
||||
// 获取帧序号 63
|
||||
int getIframeIndex =
|
||||
bb[POS_iframe_index] + bb[POS_iframe_index + 1] * 256;
|
||||
// print('获取帧序号 getIframeIndex:$getIframeIndex');
|
||||
|
||||
// 获取帧长度 65
|
||||
// int alen = bb[POS_alen] & 0xff;
|
||||
// var alenList = bb.sublist(POS_alen, POS_alen + 4);
|
||||
// int alen = ((0xff & alenList[(0)]) << 24 |
|
||||
// (0xff & alenList[1]) << 16 |
|
||||
// (0xff & alenList[2]) << 8 |
|
||||
// (0xFF & alenList[3]));
|
||||
// print('获取帧长度 alen:$alen');
|
||||
|
||||
// 当前包号 71
|
||||
int getBagIndex = bb[POS_bag_index] & 0xff;
|
||||
// print('当前包号 getBagIndex:$getBagIndex');
|
||||
// 总包数 69
|
||||
int getBagNum = bb[POS_bag_num] & 0xff;
|
||||
// print('总包数 getBagNum:$getBagNum');
|
||||
// 数据长度 73
|
||||
int blen = bb[POS_blen] + bb[POS_blen + 1] * 256;
|
||||
// print('数据长度 blen:$blen');
|
||||
|
||||
// 这里判断是否是同一帧,如果不是同一帧就重新创建一个 IframeInfo
|
||||
if (getIframeIndex != iframe!.iframeIndex) {
|
||||
iframe = IframeInfo();
|
||||
iframe!.iframeIndex = getIframeIndex;
|
||||
iframe!.bagNum = getBagNum;
|
||||
// iframe!.cur_len = alen;
|
||||
// iframe!.bb = Uint8List(alen);
|
||||
growableList = iframe!.bb!.toList(growable: true);
|
||||
}
|
||||
|
||||
iframe!.bagReceive++;
|
||||
|
||||
// 如果是同一帧就添加起来
|
||||
if (getIframeIndex == iframe!.iframeIndex) {
|
||||
var getList = bb.sublist(77, bb.length);
|
||||
growableList.addAll(getList);
|
||||
}
|
||||
// print('iframe.bagNum: ${iframe!.bagNum} iframe.bagReceive: ${iframe!.bagReceive}');
|
||||
|
||||
// 如果收到的包数等于总包数,说明这一帧数据已经接收完毕
|
||||
if (iframe!.bagNum == iframe!.bagReceive) {
|
||||
// print('播放第${iframe!.iframeIndex}帧 一帧图片的hexStringData: ${Uint8List.fromList(growableList)}');
|
||||
|
||||
//判断第一帧是否接收到
|
||||
if (iframe!.iframeIndex == 0) {
|
||||
getFirstFrame = true;
|
||||
eventBus.fire(GetFirstFrameGoPush(getFirstFrame));
|
||||
}
|
||||
|
||||
eventBus.fire(GetTVDataRefreshUI(growableList));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//音频相关处理
|
||||
Future<void> _initializeAudioPlayer(List<int> audioData) async {
|
||||
Get.log('_initializeAudioPlayer audioData:$audioData');
|
||||
|
||||
PcmArrayInt16 fromList = PcmArrayInt16.fromList(audioData);
|
||||
// FlutterPcmSound.setFeedCallback(onFeed);
|
||||
await FlutterPcmSound.feed(fromList);
|
||||
FlutterPcmSound.play();
|
||||
}
|
||||
|
||||
void onFeed(int remainingFrames) async {
|
||||
int framesToFeed = 320;
|
||||
|
||||
if (allDataBytes.length >= framesToFeed) {
|
||||
List<int> frames = allDataBytes.sublist(0, framesToFeed);
|
||||
allDataBytes.removeRange(0, framesToFeed);
|
||||
|
||||
// 将数据传递给 FlutterPcmSound
|
||||
PcmArrayInt16 fromList = PcmArrayInt16.fromList(frames);
|
||||
await FlutterPcmSound.feed(fromList);
|
||||
FlutterPcmSound.play();
|
||||
} else {
|
||||
// 处理长度不足的情况,可以等待更多数据或者采取其他措施
|
||||
print("Not enough data in allPcmData.");
|
||||
}
|
||||
}
|
||||
}
|
||||
43
star_lock/lib/talk/call/g711.dart
Normal file
43
star_lock/lib/talk/call/g711.dart
Normal file
@ -0,0 +1,43 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class G711 {
|
||||
Future<List<int>> readAssetFile(String assetPath) async {
|
||||
ByteData data = await rootBundle.load(assetPath);
|
||||
List<int> bytes = data.buffer.asUint8List();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int ALawToLinear(int aVal) {
|
||||
// 取反
|
||||
aVal = ~aVal;
|
||||
|
||||
// 计算偏移
|
||||
int t = ((aVal & 0x0F) << 3) + 0x84;
|
||||
t <<= (aVal & 0x70) >> 4;
|
||||
|
||||
// 根据符号位决定返回值的正负
|
||||
return (aVal & 0x80) != 0 ? 0x84 - t : t - 0x84;
|
||||
}
|
||||
|
||||
//711解码为pcm数据
|
||||
List<int> convertList(List<int> aLawList) {
|
||||
// 将 ALawToLinear 函数应用于 List<int>
|
||||
List<int> linearList = aLawList.map(ALawToLinear).toList();
|
||||
return linearList;
|
||||
}
|
||||
|
||||
//List<int>转为Uint8List
|
||||
Uint8List convertToInt8ListLittleEndian(List<int> intList) {
|
||||
List<int> int8List = [];
|
||||
|
||||
for (int intValue in intList) {
|
||||
intValue = intValue * 2;
|
||||
// 将 int 拆分为两个字节,采用小端序
|
||||
int8List.add(intValue & 0xFF); // 低 8 位
|
||||
int8List.add((intValue & 0xFF00) >> 8); // 高 8 位
|
||||
}
|
||||
|
||||
return Uint8List.fromList(int8List);
|
||||
}
|
||||
}
|
||||
22
star_lock/lib/talk/call/iFrameInfo.dart
Normal file
22
star_lock/lib/talk/call/iFrameInfo.dart
Normal file
@ -0,0 +1,22 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
class IframeInfo {
|
||||
int iframeIndex = -1;
|
||||
int iframeTime = 0;
|
||||
int bagNum = 0;
|
||||
int bagReceive = 0;
|
||||
bool isFull = false;
|
||||
int cur_len = 0;
|
||||
int bb_len = 0;
|
||||
Uint8List? bb;
|
||||
int codecMode = 0;
|
||||
|
||||
IframeInfo() {
|
||||
iframeIndex = -1;
|
||||
bagNum = 0;
|
||||
bagReceive = 0;
|
||||
isFull = false;
|
||||
cur_len = 0;
|
||||
bb = Uint8List(0);
|
||||
}
|
||||
}
|
||||
90
star_lock/lib/talk/udp/io_protocol/udp_heart.dart
Normal file
90
star_lock/lib/talk/udp/io_protocol/udp_heart.dart
Normal file
@ -0,0 +1,90 @@
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:star_lock/tools/toast.dart';
|
||||
|
||||
import '../../../blue/io_tool/io_tool.dart';
|
||||
import 'package:fast_gbk/fast_gbk.dart';
|
||||
|
||||
import '../io_udpSender.dart';
|
||||
import '../io_udpType.dart';
|
||||
import '../udp_reply.dart';
|
||||
|
||||
class UDPSendHeartCommand extends UDPSenderProtocol {
|
||||
|
||||
String? userName;
|
||||
List<int>? ipList;
|
||||
String? tokenStr;
|
||||
|
||||
UDPSendHeartCommand({
|
||||
this.userName,
|
||||
this.ipList,
|
||||
this.tokenStr,
|
||||
}) : super(CommandUDPType.heart);
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = [];
|
||||
|
||||
// 命令
|
||||
data.add(4);
|
||||
|
||||
// 命令类型
|
||||
data.add(1);
|
||||
|
||||
// 用户名 P18682150237
|
||||
// var pStr = "P18682150237";
|
||||
data.addAll(utf8.encode(userName!));
|
||||
data = getFixedLengthList(data, 20 - utf8.encode(userName!).length);
|
||||
|
||||
// data.add(0);
|
||||
|
||||
// mac地址
|
||||
// var macAddress = "02:00:00:00:00:00";
|
||||
// data.addAll(utf8.encode(macAddress));
|
||||
// data = getFixedLengthList(data, 6 - utf8.encode(macAddress).length);
|
||||
data.addAll([0, 0, 0, 0, 0, 0]);
|
||||
|
||||
// 预留4个字节
|
||||
data.addAll([0, 0, 0, 0]);
|
||||
|
||||
// ip地址
|
||||
// var ipStr = "192.168.9.7";
|
||||
// data.addAll(utf8.encode(ipStr!));
|
||||
// data = getFixedLengthList(data, 12 - utf8.encode(ipStr!).length);
|
||||
data.addAll(ipList!);
|
||||
|
||||
// 预留8个字节
|
||||
data.addAll([0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
// token
|
||||
var token = "token";
|
||||
data.addAll(gbk.encode(token));
|
||||
data = getFixedLengthList(data, 10 - gbk.encode(token).length);
|
||||
// print("gbk.encode(token):${gbk.encode(token)}");
|
||||
|
||||
// tokenStr
|
||||
// var tokenStr = "b989fa15f75c2ac02718b7c9bb64f80e";
|
||||
data.addAll(gbk.encode(tokenStr!));
|
||||
// print("gbk.encode(tokenStr):${gbk.encode(tokenStr!)}");
|
||||
|
||||
var tokenStrLength = gbk.encode(tokenStr!).length;
|
||||
List<int> tokenStrLengthArr = [];
|
||||
tokenStrLengthArr.add((tokenStrLength & 0xff));
|
||||
tokenStrLengthArr.add((tokenStrLength & 0xff00) >> 8);
|
||||
tokenStrLengthArr.add((tokenStrLength & 0xff0000) >> 16);
|
||||
tokenStrLengthArr.add((tokenStrLength & 0xff000000) >> 24);
|
||||
data.setRange(37, 41, tokenStrLengthArr);
|
||||
|
||||
// print("UDPSendHeartData:$data");
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class UDPSendHeartReply extends UDPReply {
|
||||
UDPSendHeartReply.parseData(CommandUDPType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
data = dataDetail;
|
||||
}
|
||||
}
|
||||
85
star_lock/lib/talk/udp/io_protocol/udp_mainProtocol.dart
Normal file
85
star_lock/lib/talk/udp/io_protocol/udp_mainProtocol.dart
Normal file
@ -0,0 +1,85 @@
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../../blue/io_tool/io_tool.dart';
|
||||
|
||||
import '../io_udpSender.dart';
|
||||
import '../io_udpType.dart';
|
||||
import '../udp_reply.dart';
|
||||
|
||||
class UDPMainProtocolCommand extends UDPSenderProtocol {
|
||||
|
||||
int? command;
|
||||
int? commandTypeIsCalling;
|
||||
int? subCommand;
|
||||
String? lockID;
|
||||
String? lockIP;
|
||||
String? userMobile;
|
||||
String? userMobileIP;
|
||||
List<int>? endData;
|
||||
|
||||
UDPMainProtocolCommand({
|
||||
this.command,
|
||||
this.commandTypeIsCalling,
|
||||
this.subCommand,
|
||||
this.lockID,
|
||||
this.lockIP,
|
||||
this.userMobile,
|
||||
this.userMobileIP,
|
||||
this.endData,
|
||||
}) : super(CommandUDPType.heart);
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = [];
|
||||
|
||||
// 命令
|
||||
data.add(command!);
|
||||
|
||||
// 命令类型
|
||||
data.add(commandTypeIsCalling!);
|
||||
|
||||
// 子命令
|
||||
data.add(subCommand!);
|
||||
|
||||
// lockID
|
||||
List<int> lockIDData = utf8.encode(lockID!);
|
||||
data.addAll(lockIDData);
|
||||
// topBytes = getFixedLengthList(lockIDData, 20 - lockIDData.length);
|
||||
for (int i = 0; i < 20 - lockIDData.length; i++) {
|
||||
data.add(0);
|
||||
}
|
||||
|
||||
// lockIP
|
||||
var lockIPList = lockIP!.split(".");
|
||||
lockIPList.forEach((element) {
|
||||
data.add(int.parse(element));
|
||||
});
|
||||
|
||||
// userMobile
|
||||
List<int> userMobileData = utf8.encode(userMobile!);
|
||||
data.addAll(userMobileData);
|
||||
// topBytes = getFixedLengthList(topBytes, 20 - userMobileData.length);
|
||||
for (int i = 0; i < 20 - userMobileData.length; i++) {
|
||||
data.add(0);
|
||||
}
|
||||
|
||||
// userMobileIP
|
||||
var userMobileIPList = lockIP!.split(".");
|
||||
userMobileIPList.forEach((element) {
|
||||
data.add(int.parse(element));
|
||||
});
|
||||
|
||||
data.addAll(endData!);
|
||||
|
||||
// print("datadatadata:$data");
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class UDPMainProtocolReply extends UDPReply {
|
||||
UDPMainProtocolReply.parseData(CommandUDPType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
data = dataDetail;
|
||||
}
|
||||
}
|
||||
2
star_lock/lib/talk/udp/io_protocol/udp_openDoor.dart
Normal file
2
star_lock/lib/talk/udp/io_protocol/udp_openDoor.dart
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
40
star_lock/lib/talk/udp/io_udpSender.dart
Normal file
40
star_lock/lib/talk/udp/io_udpSender.dart
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../blue/io_tool/io_tool.dart';
|
||||
import 'io_udpType.dart';
|
||||
|
||||
abstract class IOData {
|
||||
List<int> messageDetail();
|
||||
}
|
||||
|
||||
abstract class UDPSenderProtocol extends IOData {
|
||||
// var uint8View1 = Uint8List(300);
|
||||
|
||||
CommandUDPType? commandType; //指令类型
|
||||
// final List<int> header = [0XEF, 0X01, 0XEE, 0X02]; //帧头 固定取值 0XEF01EE02,长度 4 字节
|
||||
// final int ask = 0X01 ; // 包类型:0X01 表示请求包,0X11 表示应答包,长度 1 字节
|
||||
|
||||
List<int>? commandData = []; //数据块
|
||||
|
||||
UDPSenderProtocol(this.commandType) {
|
||||
|
||||
}
|
||||
|
||||
//TODO:拼装数据
|
||||
List<int> packageData() {
|
||||
commandData = messageDetail();
|
||||
List<int> commandList = [];
|
||||
|
||||
var cID = "XXXCID";
|
||||
commandList.addAll(utf8.encode(cID));
|
||||
commandList = getFixedLengthList(commandList, 6 - utf8.encode(cID).length);
|
||||
|
||||
// 数据块
|
||||
commandList.addAll(commandData!); //数据块
|
||||
// print("commandList:$commandList");
|
||||
return commandList;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
50
star_lock/lib/talk/udp/io_udpType.dart
Normal file
50
star_lock/lib/talk/udp/io_udpType.dart
Normal file
@ -0,0 +1,50 @@
|
||||
|
||||
//TODO:发送指令类型
|
||||
enum CommandUDPType {
|
||||
heart, //心跳 = 4
|
||||
mainProtocol, // 150
|
||||
}
|
||||
|
||||
extension ExtensionCommandType on CommandUDPType {
|
||||
|
||||
static CommandUDPType getCommandType(int value){
|
||||
CommandUDPType type = CommandUDPType.heart;
|
||||
switch(value){
|
||||
case 0x04:
|
||||
{
|
||||
type = CommandUDPType.heart;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
int get typeValue {
|
||||
int type = 0x04;
|
||||
switch(this){
|
||||
case CommandUDPType.heart:
|
||||
type = 0x04;
|
||||
break;
|
||||
case CommandUDPType.mainProtocol:
|
||||
type = 0x96;
|
||||
break;
|
||||
}
|
||||
// AppLog.log('数组组装指令类型:$name commandIndex:${IoManager
|
||||
// ().commandIndex}');
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
String get typeName {
|
||||
String t = '';
|
||||
switch(typeValue){
|
||||
case 0x04:
|
||||
t = '心跳';
|
||||
break;
|
||||
case 0x96:
|
||||
t = 'UDP主协议';
|
||||
break;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
158
star_lock/lib/talk/udp/udp_help.dart
Normal file
158
star_lock/lib/talk/udp/udp_help.dart
Normal file
@ -0,0 +1,158 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../network/api_repository.dart';
|
||||
import '../../tools/storage.dart';
|
||||
import 'udp_manage.dart';
|
||||
import 'udp_senderManage.dart';
|
||||
|
||||
class UdpHelp {
|
||||
Timer? timer;
|
||||
|
||||
openUDP() async {
|
||||
// 从服务器获取ip跟端口
|
||||
var entity = await ApiRepository.to.getWifiLockServiceIpAndPort();
|
||||
if (entity.errorCode! == 0) {
|
||||
UDPManage();
|
||||
// UDPManage().initUdp();
|
||||
UDPManage().port = int.parse(entity.data!.serviceList![0].port!);
|
||||
|
||||
var serversList = <int>[];
|
||||
for (int i = 0; i < entity.data!.serviceList!.length; i++) {
|
||||
var item = entity.data!.serviceList![i];
|
||||
if (item.serviceIp!.contains("192")) {
|
||||
UDPManage().host = entity.data!.serviceList![0].serviceIp!;
|
||||
var itemList = item.serviceIp!.split(".");
|
||||
for (var element in itemList) {
|
||||
serversList.add(int.parse(element));
|
||||
}
|
||||
} else {
|
||||
List<InternetAddress> addresses =
|
||||
await InternetAddress.lookup(item.serviceIp!);
|
||||
UDPManage().host = addresses.first.address;
|
||||
var itemList = addresses.first.address.split(".");
|
||||
for (var element in itemList) {
|
||||
serversList.add(int.parse(element));
|
||||
}
|
||||
print(
|
||||
'Resolved google.com to address: ${addresses.first.address} serversList:$serversList');
|
||||
}
|
||||
}
|
||||
|
||||
var mobile = await Storage.getMobile();
|
||||
timer = Timer.periodic(1.seconds, (timer) async {
|
||||
UDPSenderManage.sendHeart(
|
||||
userName: mobile,
|
||||
ipList: serversList,
|
||||
tokenStr: "b989fa15f75c2ac02718b7c9bb64f80e",
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Future<void> getWifiLockServiceIpAndPort() async {
|
||||
// var entity = await ApiRepository.to.getWifiLockServiceIpAndPort();
|
||||
// if(entity.errorCode! == 0){
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
dispose() {
|
||||
timer!.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
class UdpData {
|
||||
bool isUsed = false;
|
||||
}
|
||||
|
||||
// class UdpSendThread {
|
||||
// List<UdpData> udpDatas = [];
|
||||
// bool udpSendTag = true;
|
||||
// int udpSendTime = 0;
|
||||
//
|
||||
// UdpSendThread() {
|
||||
// for (int i = 0; i < BUFNUM; i++) {
|
||||
// udpDatas.add(UdpData());
|
||||
// }
|
||||
// udpSend();
|
||||
// }
|
||||
//
|
||||
// void udpSend() async {
|
||||
// while (udpSendTag) {
|
||||
// while (udpSendTime <= 0) {
|
||||
// await Future.delayed(Duration(seconds: 1));
|
||||
// }
|
||||
// bool hasDataSend = true;
|
||||
// while (hasDataSend) {
|
||||
// hasDataSend = false;
|
||||
// for (int i = 0; i < BUFNUM; i++) {
|
||||
// UdpData udpList = udpDatas[i];
|
||||
// if (udpList.isUsed) {
|
||||
// // Do something
|
||||
// } else {
|
||||
// // Do something else
|
||||
// }
|
||||
// }
|
||||
// await Future.delayed(Duration(seconds: 1));
|
||||
// }
|
||||
// udpSendTime--;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// import 'dart:async';
|
||||
//
|
||||
// class UdpSendCondition {
|
||||
// bool udpSendTag = true;
|
||||
// int udpSendTime = 0;
|
||||
// List udpDatas = [];
|
||||
// Isolate isolate;
|
||||
//
|
||||
// void start() async {
|
||||
// final receivePort = ReceivePort();
|
||||
// isolate = await Isolate.spawn(_isolateEntry, receivePort.sendPort);
|
||||
//
|
||||
// receivePort.listen((message) {
|
||||
// if (message == 'done') {
|
||||
// udpSendTime--;
|
||||
// if (udpSendTime <= 0) {
|
||||
// stop();
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// void stop() {
|
||||
// if (isolate != null) {
|
||||
// isolate.kill(priority: Isolate.immediate);
|
||||
// isolate = null;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// void _isolateEntry(SendPort sendPort) async {
|
||||
// bool hasDataSend = true;
|
||||
// while (hasDataSend) {
|
||||
// hasDataSend = false;
|
||||
// for (int i = 0; i < BUFNUM; i++) {
|
||||
// var udpList = udpDatas[i];
|
||||
// if (udpList.isUsed) {
|
||||
// // Do something
|
||||
// } else {
|
||||
// // Do something else
|
||||
// }
|
||||
// }
|
||||
// await Future.delayed(Duration(seconds: 1));
|
||||
// }
|
||||
// sendPort.send('done');
|
||||
// }
|
||||
116
star_lock/lib/talk/udp/udp_manage.dart
Normal file
116
star_lock/lib/talk/udp/udp_manage.dart
Normal file
@ -0,0 +1,116 @@
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:star_lock/talk/udp/udp_reciverData.dart';
|
||||
|
||||
import '../../blue/io_tool/io_model.dart';
|
||||
import '../../blue/io_tool/manager_event_bus.dart';
|
||||
|
||||
class UDPManage{
|
||||
static UDPManage? _manager;
|
||||
|
||||
UDPManage._init() {
|
||||
initUdp();
|
||||
_streamSubscription = EventBusManager().eventBus!.on<EventSendModel>().listen((EventSendModel sendModel) {
|
||||
// print("sendModel.sendChannel:${sendModel.sendChannel}");
|
||||
if(sendModel.sendChannel == DataChannel.udp){
|
||||
List<int> data = sendModel.data;
|
||||
sendData(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static UDPManage _share(){
|
||||
_manager ??= UDPManage._init();
|
||||
return _manager!;
|
||||
}
|
||||
factory UDPManage() => _share();
|
||||
UDPManage get manager => _share();
|
||||
|
||||
StreamSubscription<EventSendModel>? _streamSubscription;
|
||||
RawDatagramSocket? _udpSocket;
|
||||
// String host = '47.106.143.213';
|
||||
// int port = 8056;
|
||||
// String? _mIp = '';
|
||||
String host = '';
|
||||
int port = 0;
|
||||
String lockId = '';// 锁id 通过锁id来判断是哪把锁发对讲过来
|
||||
|
||||
void initUdp() async {
|
||||
var listAddress = InternetAddress.lookup(host!);
|
||||
listAddress.then((list) {
|
||||
list.forEach((element) {
|
||||
// print('Udp ----> element.address:${element.address} element.host:${element.host}');
|
||||
host = element.address;
|
||||
});
|
||||
});
|
||||
await _initUdp();
|
||||
}
|
||||
|
||||
Future<Null> _initUdp() async {
|
||||
if(port == 0){
|
||||
print('❌ Udp ----> _port == 0');
|
||||
return;
|
||||
}
|
||||
print('Udp ----> host:$host port:$port');
|
||||
var addressIListenFrom = InternetAddress.anyIPv4;
|
||||
int portIListenOn = 62288;
|
||||
RawDatagramSocket.bind(addressIListenFrom, portIListenOn).then((RawDatagramSocket socket){
|
||||
_udpSocket = socket;
|
||||
///广播功能
|
||||
_udpSocket!.broadcastEnabled = true;
|
||||
_onReceiveData(socket);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void _onReceiveData(RawDatagramSocket socket) {
|
||||
socket.listen((RawSocketEvent event) {
|
||||
if(event == RawSocketEvent.read){
|
||||
Datagram? dg = socket.receive();
|
||||
try {
|
||||
// print('Did received data on the stream (length --> ${dg!.data.length}) dg!.data:${dg!.data}');
|
||||
// EventBusManager().eventBusFir(EventReceiveModel(data: dg?.data,sendChannel: DataChannel.udp));
|
||||
CommandUDPReciverManager.appDataReceive(dg!.data);
|
||||
} catch (e) {
|
||||
print('❌ Udp ----> $e');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void sendData(List<int> data) {
|
||||
if(null == _udpSocket || null == data || data.isEmpty || host == ''){
|
||||
if(null == _udpSocket ){
|
||||
print('❌ Udp ----> null == _udpSocket');
|
||||
initUdp();
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// print("sendData:$data");
|
||||
var result = _udpSocket?.send(data, InternetAddress(host!), port!);
|
||||
if(result != data.length) {
|
||||
print('❌Udp ----> send data $result ${data.length}');
|
||||
_udpSocket = null;
|
||||
}
|
||||
}catch (e){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool exit() {
|
||||
if(null != _udpSocket) {
|
||||
print('❌ Udp ----> close');
|
||||
_udpSocket?.close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void disposed() {
|
||||
_streamSubscription?.cancel();
|
||||
}
|
||||
|
||||
}
|
||||
206
star_lock/lib/talk/udp/udp_reciverData.dart
Normal file
206
star_lock/lib/talk/udp/udp_reciverData.dart
Normal file
@ -0,0 +1,206 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/talk/udp/udp_manage.dart';
|
||||
|
||||
import '../../blue/io_tool/io_tool.dart';
|
||||
import '../../tools/eventBusEventManage.dart';
|
||||
import '../../tools/toast.dart';
|
||||
import '../call/callTalk.dart';
|
||||
import 'udp_talkClass.dart';
|
||||
|
||||
class CommandUDPReciverManager {
|
||||
|
||||
|
||||
static void appDataReceive(List<int> data) async {
|
||||
///解析数据
|
||||
if (data.isEmpty) {
|
||||
return;
|
||||
}
|
||||
int dataSize = data.length;
|
||||
if (dataSize < 4) {
|
||||
return;
|
||||
}
|
||||
// print("appReceiveUDPData:$data");
|
||||
|
||||
Uint8List data1 = Uint8List.fromList(data);
|
||||
if (data1.length == 1) {
|
||||
if (data[0] == 0x30 || data[0] == 0x31) {
|
||||
print("p2p打洞");
|
||||
}
|
||||
}
|
||||
|
||||
if (data[6] == 4) {
|
||||
if (data[7] == 2) {
|
||||
// print("心跳包反馈 在线状态");
|
||||
|
||||
} else if (data[7] == 3) {
|
||||
[Toast.show(msg: "您已在其他设备登录")];
|
||||
}
|
||||
} else if (data[6] == 150) {
|
||||
// if( [Pub getApp].isBack){
|
||||
// [_udp receiveWithTimeout:-1 tag:0];
|
||||
// return YES;
|
||||
// }
|
||||
|
||||
// 对讲命令
|
||||
var beiCallType = data[8] & 0xff;
|
||||
// print("被呼叫类型$beiCallType");
|
||||
switch (beiCallType) {
|
||||
case 1:
|
||||
{
|
||||
//被叫
|
||||
// lockId
|
||||
var lockId = data.sublist(9, 29);
|
||||
var lockIdStr = utf8String(lockId);
|
||||
UDPManage().lockId = lockIdStr;
|
||||
UDPTalkClass().status = 0;
|
||||
UDPTalkClass().beCallW(data: data);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
{
|
||||
//接听
|
||||
if ((data[7] & 0x3) == 2) {
|
||||
//被叫 接听反馈
|
||||
print("接听反馈");
|
||||
UDPTalkClass().status = 8;
|
||||
// 停止声音
|
||||
UDPTalkClass().stopLocalAudio();
|
||||
eventBus.fire(GetUDPStatusRefreshUI(UDPTalkClass().status));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
{
|
||||
//音视频数据
|
||||
// print("音视频数据");
|
||||
CallTalk cllTalk = CallTalk();
|
||||
cllTalk.getAVData(data1, data1.length);
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
{
|
||||
if ((data[7] & 0x3) == 1) {
|
||||
//对方保持连接
|
||||
//print("对方保持连接");
|
||||
data[7] = 2;
|
||||
} else {
|
||||
//print("保持连接反馈");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
{
|
||||
//开门反馈
|
||||
print("appReceiveUDPData:$data");
|
||||
if ((data[7] & 0x3) == 2) {
|
||||
print("开门成功");
|
||||
Toast.show(msg: "开门成功");
|
||||
} else {
|
||||
print("开门失败");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 30:
|
||||
{
|
||||
// 挂断
|
||||
if ((data[7] & 0x3) == 1) {
|
||||
// 对方结束对讲
|
||||
print("对方结束对讲");
|
||||
} else {
|
||||
//结束对讲反馈
|
||||
print("结束对讲反馈");
|
||||
}
|
||||
UDPTalkClass().status = 0;
|
||||
UDPTalkClass().isBeCall = false;
|
||||
Get.back();
|
||||
UDPTalkClass().stopLocalAudio();
|
||||
eventBus.fire(GetUDPStatusRefreshUI(UDPTalkClass().status));
|
||||
}
|
||||
break;
|
||||
case 140:
|
||||
{
|
||||
// p2p测试
|
||||
}
|
||||
break;
|
||||
case 141:
|
||||
{
|
||||
// p2p测试
|
||||
}
|
||||
break;
|
||||
case 142:
|
||||
{
|
||||
// p2p测试
|
||||
}
|
||||
break;
|
||||
case 143:
|
||||
{
|
||||
//p2p测试 NSAsk
|
||||
print("p2pNSAskNSAsk");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (data[6] == 152) {
|
||||
// 监视命令
|
||||
switch (data[8] & 0xff) {
|
||||
case 2:
|
||||
{
|
||||
//被叫
|
||||
print("对方忙");
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
//监视成功
|
||||
print("监视成功");
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
{
|
||||
//音视频数据
|
||||
//print("音视频数据");
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
{
|
||||
//保持连接
|
||||
if ((data[7] & 0x3) == 1) {
|
||||
//对方保持连接
|
||||
//print("对方保持连接");
|
||||
data[7] = 2;
|
||||
} else {
|
||||
//print("保持连接反馈");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
{
|
||||
//开门反馈
|
||||
if ((data[7] & 0x3) == 2) {
|
||||
print("开门成功");
|
||||
} else {}
|
||||
}
|
||||
break;
|
||||
case 30:
|
||||
{
|
||||
// 监视结束
|
||||
if ((data[7] & 0x3) == 1) {
|
||||
// 对方结束监视
|
||||
print("对方结束监视");
|
||||
} else {
|
||||
//结束对讲反馈
|
||||
print("结束监视反馈");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
star_lock/lib/talk/udp/udp_reply.dart
Normal file
13
star_lock/lib/talk/udp/udp_reply.dart
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
import 'io_udpType.dart';
|
||||
|
||||
abstract class UDPReply{
|
||||
|
||||
CommandUDPType? commandType;
|
||||
|
||||
//command key flag
|
||||
int status = 0;
|
||||
List<int> data = [];
|
||||
UDPReply.parseData(this.commandType, List<int> dataDetail);
|
||||
|
||||
}
|
||||
46
star_lock/lib/talk/udp/udp_senderData.dart
Normal file
46
star_lock/lib/talk/udp/udp_senderData.dart
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
import '../../app_settings/app_settings.dart';
|
||||
import '../../blue/io_tool/io_model.dart';
|
||||
import '../../blue/io_tool/manager_event_bus.dart';
|
||||
import 'io_udpSender.dart';
|
||||
|
||||
typedef CommandUDPSendCallBack = void Function(ErrorType errorType);
|
||||
|
||||
class CommandUDPSenderManager {
|
||||
|
||||
static final CommandUDPSenderManager _manager = CommandUDPSenderManager._init();
|
||||
factory CommandUDPSenderManager()=>_manager;
|
||||
static CommandUDPSenderManager getInstance()=>_manager;
|
||||
CommandUDPSenderManager._init(){
|
||||
init();
|
||||
}
|
||||
|
||||
init(){
|
||||
|
||||
}
|
||||
|
||||
//TODO:发送常规数据
|
||||
Future<void> managerSendData ({required UDPSenderProtocol command, CommandUDPSendCallBack? callBack}) async {
|
||||
if (callBack != null) {
|
||||
// if (!BluetoothManager().connected) {
|
||||
print('❌ 蓝牙断开了');
|
||||
if (callBack != null) {
|
||||
print('managerSendData ❌ callBack');
|
||||
// EasyLoading.dismiss();
|
||||
callBack(ErrorType.notConnected);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
List<int> value = command.packageData();
|
||||
// print("sendData:${value}");
|
||||
_sendNormalData(value);
|
||||
}
|
||||
|
||||
void _sendNormalData(List<int> data) async {
|
||||
if (data.isNotEmpty) {
|
||||
EventBusManager().eventBusFir(EventSendModel(data: data, sendChannel: DataChannel.udp));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
41
star_lock/lib/talk/udp/udp_senderManage.dart
Normal file
41
star_lock/lib/talk/udp/udp_senderManage.dart
Normal file
@ -0,0 +1,41 @@
|
||||
|
||||
|
||||
import 'io_protocol/udp_heart.dart';
|
||||
import 'io_protocol/udp_mainProtocol.dart';
|
||||
import 'udp_senderData.dart';
|
||||
|
||||
class UDPSenderManage {
|
||||
|
||||
//todo:UDP心跳
|
||||
static void sendHeart({String? userName, List<int>? ipList, String? tokenStr, CommandUDPSendCallBack? callBack}) {
|
||||
CommandUDPSenderManager().managerSendData(command: UDPSendHeartCommand(
|
||||
userName: userName,
|
||||
ipList: ipList,
|
||||
tokenStr: tokenStr,
|
||||
), callBack: callBack);
|
||||
}
|
||||
|
||||
//todo:主通讯协议
|
||||
static void sendMainProtocol({
|
||||
int? command,
|
||||
int? commandTypeIsCalling,
|
||||
int? subCommand,
|
||||
String? lockID,
|
||||
String? lockIP,
|
||||
String? userMobile,
|
||||
String? userMobileIP,
|
||||
List<int>? endData,
|
||||
CommandUDPSendCallBack? callBack}) {
|
||||
CommandUDPSenderManager().managerSendData(command: UDPMainProtocolCommand(
|
||||
command: command,
|
||||
commandTypeIsCalling: commandTypeIsCalling,
|
||||
subCommand: subCommand,
|
||||
lockID: lockID,
|
||||
lockIP: lockIP,
|
||||
userMobile: userMobile,
|
||||
userMobileIP: userMobileIP,
|
||||
endData: endData,
|
||||
), callBack: callBack);
|
||||
}
|
||||
|
||||
}
|
||||
152
star_lock/lib/talk/udp/udp_talkClass.dart
Normal file
152
star_lock/lib/talk/udp/udp_talkClass.dart
Normal file
@ -0,0 +1,152 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:fast_gbk/fast_gbk.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/tools/eventBusEventManage.dart';
|
||||
|
||||
import '../../appRouters.dart';
|
||||
import '../../main/lockDetail/monitoring/monitoring/lockMonitoring_page.dart';
|
||||
import '../../tools/storage.dart';
|
||||
import 'udp_manage.dart';
|
||||
|
||||
class UDPTalkClass {
|
||||
static UDPTalkClass? _manager;
|
||||
static UDPTalkClass _share() {
|
||||
_manager ??= UDPTalkClass._init();
|
||||
return _manager!;
|
||||
}
|
||||
|
||||
factory UDPTalkClass() => _share();
|
||||
UDPTalkClass get manager => _share();
|
||||
|
||||
UDPTalkClass._init();
|
||||
|
||||
// var status = 0; //0:初始状态 1:等待监视 2: 3:监视中 4:呼叫成功 5:主角通话中 6:被叫通话 8:被叫通话中
|
||||
int status = 0;
|
||||
|
||||
var remoteEquid; // 手机号
|
||||
late Timer timer;
|
||||
// 该字段是为了判断是否跳转到接听界面 挂断或者退出接听界面要记得变更状态
|
||||
var isBeCall = false;
|
||||
final audioPlayer = AudioPlayer();
|
||||
|
||||
beCallW({List<int>? data, String? ip, int? port}) async {
|
||||
print("beCall status:$status");
|
||||
// if (await isCallMe(data)) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (status == 0) {
|
||||
// 空闲
|
||||
// 响铃
|
||||
// [[Pub getApp] ring];
|
||||
remoteEquid = getEquidFrombb(data, 9);
|
||||
status = 6;
|
||||
|
||||
// 呼叫应答,呼叫成功
|
||||
data![7] = 1;
|
||||
data[8] = 4;
|
||||
UDPManage().sendData(data);
|
||||
|
||||
// 门锁发送视频
|
||||
data[7] = 1;
|
||||
data[8] = 5;
|
||||
UDPManage().sendData(data);
|
||||
|
||||
// Get.to(MaterialPageRoute(
|
||||
// builder: (context) {
|
||||
// return const LockMonitoringPage();
|
||||
// },
|
||||
// fullscreenDialog: true
|
||||
// ));
|
||||
|
||||
if (isBeCall == false) {
|
||||
isBeCall = true;
|
||||
// 保持连接
|
||||
timer = Timer.periodic(1.seconds, (timer) {
|
||||
data[7] = 1;
|
||||
data[8] = 9;
|
||||
UDPManage().sendData(data);
|
||||
});
|
||||
|
||||
// _getFirstFrameGoPushAction();
|
||||
// Future.delayed(const Duration(seconds: 1), () {
|
||||
// 在这里写要延迟执行的代码
|
||||
Get.toNamed(Routers.lockMonitoringPage, arguments: {"lockId": "111"});
|
||||
// });
|
||||
}
|
||||
|
||||
playLocalAudio();
|
||||
} else {
|
||||
// 忙
|
||||
}
|
||||
}
|
||||
|
||||
void _getFirstFrameGoPushAction() {
|
||||
// 蓝牙协议通知传输跟蓝牙之外的数据传输类不一样 eventBus
|
||||
StreamSubscription _GetFirstFrameGoPushEvent =
|
||||
eventBus.on<GetFirstFrameGoPush>().listen((event) {
|
||||
if (event.isFirstFrame == true) {
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
// 在这里写要延迟执行的代码
|
||||
Get.toNamed(Routers.lockMonitoringPage, arguments: {"lockId": "111"});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 判断是否是call的本人
|
||||
Future<bool> isCallMe(List<int>? data) async {
|
||||
final loginData = await Storage.getLoginData();
|
||||
print("getEquidFrombb(data, 1000):${getEquidFrombb(data, 12)}");
|
||||
if (loginData!.mobile == getEquidFrombb(data, 12)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
String getEquidFrombb(List<int>? bb, int pos) {
|
||||
var equid = "";
|
||||
int equlen = 8;
|
||||
|
||||
if (bb![pos] == 77) {
|
||||
//M
|
||||
equlen = 8;
|
||||
} else if (bb[pos] == 87) {
|
||||
//W
|
||||
equlen = 5;
|
||||
} else if (bb[pos] == 72) {
|
||||
//H
|
||||
equlen = 12;
|
||||
} else if (bb[pos] == 83) {
|
||||
//S
|
||||
equlen = 12;
|
||||
} else if (bb[pos] == 0x50) {
|
||||
//P
|
||||
equlen = 12;
|
||||
} else if (bb[pos] == 0x54) {
|
||||
//T
|
||||
equlen = 16;
|
||||
} else {
|
||||
equlen = 12;
|
||||
}
|
||||
|
||||
List<int> tempbb = bb.sublist(pos, pos + equlen);
|
||||
equid = gbk.decode(tempbb);
|
||||
return equid;
|
||||
}
|
||||
|
||||
//播放本地音频
|
||||
void playLocalAudio() async {
|
||||
audioPlayer.setReleaseMode(ReleaseMode.loop);
|
||||
await audioPlayer.play(AssetSource('ring1.mp3'));
|
||||
}
|
||||
|
||||
// 停止播放本地音频
|
||||
void stopLocalAudio() async {
|
||||
audioPlayer.setReleaseMode(ReleaseMode.loop);
|
||||
await audioPlayer.stop();
|
||||
}
|
||||
}
|
||||
@ -6,52 +6,70 @@ import '../main/lockDetail/lcokSet/lockSet/lockSetInfo_entity.dart';
|
||||
EventBus eventBus = EventBus();
|
||||
|
||||
/// 刷新锁列表数据
|
||||
class RefreshLockListInfoDataEvent{
|
||||
class RefreshLockListInfoDataEvent {
|
||||
RefreshLockListInfoDataEvent();
|
||||
}
|
||||
|
||||
/// 刷新考勤员工列表
|
||||
class RefreshCheckInStaffListDataEvent{
|
||||
class RefreshCheckInStaffListDataEvent {
|
||||
RefreshCheckInStaffListDataEvent();
|
||||
}
|
||||
|
||||
/// 传递当前锁信息
|
||||
class PassCurrentLockInformationEvent{
|
||||
class PassCurrentLockInformationEvent {
|
||||
LockSetInfoData lockSetInfoData;
|
||||
PassCurrentLockInformationEvent(this.lockSetInfoData);
|
||||
}
|
||||
|
||||
/// 卡、密码、指纹修改之后刷新列表
|
||||
class OtherTypeRefreshListEvent{
|
||||
class OtherTypeRefreshListEvent {
|
||||
OtherTypeRefreshListEvent();
|
||||
}
|
||||
|
||||
/// 考情添加员工卡、指纹之后回调卡、指纹number
|
||||
class ChickInAddStaffCardAndFingerprintBlockNumberEvent{
|
||||
class ChickInAddStaffCardAndFingerprintBlockNumberEvent {
|
||||
String number;
|
||||
ChickInAddStaffCardAndFingerprintBlockNumberEvent(this.number);
|
||||
}
|
||||
|
||||
/// Uuid删除当前锁时 有可能锁被初始化了 但后台没被初始化 当打开APP的时候扫描如果未被连接就传uuid过去 判断直接删除数据
|
||||
class ScanAllDeviceFindCurrentDeviceConnectedEvent{
|
||||
class ScanAllDeviceFindCurrentDeviceConnectedEvent {
|
||||
String uuid;
|
||||
ScanAllDeviceFindCurrentDeviceConnectedEvent(this.uuid);
|
||||
}
|
||||
|
||||
/// 多语言 切换之后传值到上一级界面
|
||||
class ChangeLanguageBlockLastLanguageEvent{
|
||||
class ChangeLanguageBlockLastLanguageEvent {
|
||||
String languageTitle;
|
||||
ChangeLanguageBlockLastLanguageEvent(this.languageTitle);
|
||||
}
|
||||
|
||||
/// 锁分组添加或者删除锁之后刷新首页数据
|
||||
class LockGroupEditGroupLockRefreshEvent{
|
||||
class LockGroupEditGroupLockRefreshEvent {
|
||||
LockGroupEditGroupLockRefreshEvent();
|
||||
}
|
||||
|
||||
/// 锁设置里面开启关闭刷新锁详情
|
||||
class LockSetChangeSetRefreshLockDetailWithType{
|
||||
int type;// 0 考勤 1开锁时是否需联网
|
||||
class LockSetChangeSetRefreshLockDetailWithType {
|
||||
int type; // 0 考勤 1开锁时是否需联网
|
||||
int setResult;
|
||||
LockSetChangeSetRefreshLockDetailWithType(this.type, this.setResult);
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取到视频流数据然后刷新界面
|
||||
class GetTVDataRefreshUI {
|
||||
List<int> tvList;
|
||||
GetTVDataRefreshUI(this.tvList);
|
||||
}
|
||||
|
||||
/// 获取到UDP接收状态然后刷新界面
|
||||
class GetUDPStatusRefreshUI {
|
||||
int udpStatus;
|
||||
GetUDPStatusRefreshUI(this.udpStatus);
|
||||
}
|
||||
|
||||
/// 获取到第一帧图片数据后跳转
|
||||
class GetFirstFrameGoPush {
|
||||
bool isFirstFrame;
|
||||
GetFirstFrameGoPush(this.isFirstFrame);
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
@ -9,6 +10,7 @@ class ShowTFView extends StatelessWidget {
|
||||
String? title;
|
||||
String? tipTitle;
|
||||
TextEditingController? controller;
|
||||
List<TextInputFormatter>? inputFormatters;
|
||||
Function()? sureClick;
|
||||
Function()? cancelClick;
|
||||
|
||||
@ -17,6 +19,7 @@ class ShowTFView extends StatelessWidget {
|
||||
this.title,
|
||||
this.tipTitle,
|
||||
this.controller,
|
||||
this.inputFormatters,
|
||||
this.sureClick,
|
||||
this.cancelClick})
|
||||
: super(key: key);
|
||||
@ -44,6 +47,7 @@ class ShowTFView extends StatelessWidget {
|
||||
maxLines: 1,
|
||||
controller: controller,
|
||||
autofocus: false,
|
||||
inputFormatters: inputFormatters,
|
||||
decoration: InputDecoration(
|
||||
contentPadding:
|
||||
const EdgeInsets.only(left: 5, top: -8, bottom: 6),
|
||||
|
||||
@ -136,13 +136,33 @@ class Storage {
|
||||
}
|
||||
|
||||
static Future<String?> getUid() async {
|
||||
String? userId = '';
|
||||
String? uid = '';
|
||||
final data = await Storage.getString('userLoginData');
|
||||
if (data != null && data.isNotEmpty) {
|
||||
userId = LoginData.fromJson(jsonDecode(data)).uid.toString();
|
||||
uid = LoginData.fromJson(jsonDecode(data)).uid.toString();
|
||||
}
|
||||
print("pubUserId:$userId");
|
||||
return userId;
|
||||
// print("pubUid:$uid");
|
||||
return uid;
|
||||
}
|
||||
|
||||
static Future<String?> getMobile() async {
|
||||
String? mobile = '';
|
||||
final data = await Storage.getString('userLoginData');
|
||||
if (data != null && data.isNotEmpty) {
|
||||
mobile = LoginData.fromJson(jsonDecode(data)).mobile.toString();
|
||||
}
|
||||
// print("mobile:$mobile");
|
||||
return mobile;
|
||||
}
|
||||
|
||||
static Future<LoginData?> getLoginData() async {
|
||||
LoginData? loginData;
|
||||
final data = await Storage.getString('userLoginData');
|
||||
if (data != null && data.isNotEmpty) {
|
||||
loginData = LoginData.fromJson(jsonDecode(data));
|
||||
}
|
||||
print("loginData:$loginData");
|
||||
return loginData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <aj_captcha_flutter/aj_captcha_flutter_plugin.h>
|
||||
#include <audioplayers_linux/audioplayers_linux_plugin.h>
|
||||
#include <file_selector_linux/file_selector_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
@ -14,6 +15,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) aj_captcha_flutter_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "AjCaptchaFlutterPlugin");
|
||||
aj_captcha_flutter_plugin_register_with_registrar(aj_captcha_flutter_registrar);
|
||||
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin");
|
||||
audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
||||
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
aj_captcha_flutter
|
||||
audioplayers_linux
|
||||
file_selector_linux
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
@ -6,8 +6,12 @@ import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import aj_captcha_flutter
|
||||
import audio_session
|
||||
import audioplayers_darwin
|
||||
import device_info_plus
|
||||
import file_selector_macos
|
||||
import flutter_pcm_sound
|
||||
import just_audio
|
||||
import network_info_plus
|
||||
import package_info_plus
|
||||
import path_provider_foundation
|
||||
@ -17,8 +21,12 @@ import url_launcher_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AjCaptchaFlutterPlugin.register(with: registry.registrar(forPlugin: "AjCaptchaFlutterPlugin"))
|
||||
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
|
||||
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||
FlutterPcmSoundPlugin.register(with: registry.registrar(forPlugin: "FlutterPcmSoundPlugin"))
|
||||
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
|
||||
NetworkInfoPlusPlugin.register(with: registry.registrar(forPlugin: "NetworkInfoPlusPlugin"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
|
||||
@ -117,13 +117,26 @@ dependencies:
|
||||
video_player: ^2.7.2
|
||||
#控制横竖屏控件
|
||||
auto_orientation: ^2.3.1
|
||||
audioplayers: ^5.2.1
|
||||
g711_flutter: ^2.0.0
|
||||
ffi: ^2.1.0
|
||||
flutter_mjpeg: ^2.0.4
|
||||
image_gallery_saver: ^2.0.3
|
||||
convert: ^3.1.1
|
||||
just_audio: ^0.9.36
|
||||
flutter_sound: ^9.2.13
|
||||
# ffmpeg_kit_flutter: 5.1.0-LTS
|
||||
fast_gbk: ^1.0.0
|
||||
flutter_pcm_sound: ^1.1.0
|
||||
# flutter_audio_capture: <1.1.5
|
||||
|
||||
flutter_voice_processor: ^1.1.0
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
# The "flutter_lints" package below contains a set of recommended lints to
|
||||
# encourage good coding practices. The lint set provided by the package is
|
||||
# encourage good coding practices. The lint fset provided by the package is
|
||||
# activated in the `analysis_options.yaml` file located at the root of your
|
||||
# package. See that file for information about deactivating specific lint
|
||||
# rules and activating additional ones.
|
||||
@ -148,6 +161,7 @@ flutter:
|
||||
- images/lan/
|
||||
- images/mine/
|
||||
- images/lockType/
|
||||
- assets/
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <aj_captcha_flutter/aj_captcha_flutter_plugin_c_api.h>
|
||||
#include <audioplayers_windows/audioplayers_windows_plugin.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>
|
||||
@ -14,6 +15,8 @@
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
AjCaptchaFlutterPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("AjCaptchaFlutterPluginCApi"));
|
||||
AudioplayersWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
|
||||
FileSelectorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
aj_captcha_flutter
|
||||
audioplayers_windows
|
||||
file_selector_windows
|
||||
permission_handler_windows
|
||||
url_launcher_windows
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user