Merge branch 'develop_liyi' of http://code.star-lock.cn/StarlockTeam/app-starlock into develop_liyi
This commit is contained in:
commit
cc8babf730
@ -91,6 +91,8 @@ generate_git_tag:
|
|||||||
stage: generate_tag_or_version
|
stage: generate_tag_or_version
|
||||||
extends: .generate_tag_rule
|
extends: .generate_tag_rule
|
||||||
before_script:
|
before_script:
|
||||||
|
- bash pre_build.sh xhj
|
||||||
|
- bash pre_build.sh sky
|
||||||
- project_url=$(echo $CI_PROJECT_URL | sed 's/http:\/\///')
|
- project_url=$(echo $CI_PROJECT_URL | sed 's/http:\/\///')
|
||||||
- echo "project_url:$project_url"
|
- echo "project_url:$project_url"
|
||||||
- git remote set-url origin http://gitlab-ci-token:${GITLAB_ACCESS_TOKEN}@$project_url.git
|
- git remote set-url origin http://gitlab-ci-token:${GITLAB_ACCESS_TOKEN}@$project_url.git
|
||||||
|
|||||||
@ -7,7 +7,9 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
04C1FC572D13F1A2000C959E /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 04C1FC562D13F1A2000C959E /* InfoPlist.xcstrings */; };
|
04717D692D1B97E100089BD3 /* InfoPlist_sky.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04717D672D1B97E100089BD3 /* InfoPlist_sky.strings */; };
|
||||||
|
04717D6D2D1B983300089BD3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04717D6B2D1B983200089BD3 /* InfoPlist.strings */; };
|
||||||
|
04717D712D1B9B5A00089BD3 /* InfoPlist_xhj.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04717D6F2D1B9B5A00089BD3 /* InfoPlist_xhj.strings */; };
|
||||||
04D0CC262D06CE570042EF10 /* launchImage_xhj.png in Resources */ = {isa = PBXBuildFile; fileRef = 82B657662C919BDF0079121C /* launchImage_xhj.png */; };
|
04D0CC262D06CE570042EF10 /* launchImage_xhj.png in Resources */ = {isa = PBXBuildFile; fileRef = 82B657662C919BDF0079121C /* launchImage_xhj.png */; };
|
||||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||||
25B2A1422F9A2CCCBBCBBB97 /* skyRelease.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 35F02D170492750B437D6AB6 /* skyRelease.xcconfig */; };
|
25B2A1422F9A2CCCBBCBBB97 /* skyRelease.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 35F02D170492750B437D6AB6 /* skyRelease.xcconfig */; };
|
||||||
@ -98,8 +100,13 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
0420903B2C0EEAA50073E654 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = "<group>"; };
|
0420903B2C0EEAA50073E654 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = "<group>"; };
|
||||||
|
04717D682D1B97E100089BD3 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist_sky.strings"; sourceTree = "<group>"; };
|
||||||
|
04717D6A2D1B97E800089BD3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist_sky.strings; sourceTree = "<group>"; };
|
||||||
|
04717D6C2D1B983200089BD3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
|
04717D6E2D1B983900089BD3 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||||
|
04717D702D1B9B5A00089BD3 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist_xhj.strings"; sourceTree = "<group>"; };
|
||||||
|
04717D722D1B9B5D00089BD3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist_xhj.strings; sourceTree = "<group>"; };
|
||||||
04BFC4482BCFE05100688FCA /* RunnerRelease-xhj.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "RunnerRelease-xhj.entitlements"; sourceTree = "<group>"; };
|
04BFC4482BCFE05100688FCA /* RunnerRelease-xhj.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "RunnerRelease-xhj.entitlements"; sourceTree = "<group>"; };
|
||||||
04C1FC562D13F1A2000C959E /* InfoPlist.xcstrings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = "<group>"; };
|
|
||||||
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>"; };
|
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>"; };
|
||||||
0D02C18E16914A687A4A1AC2 /* devDebug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = devDebug.xcconfig; path = Flutter/devDebug.xcconfig; sourceTree = "<group>"; };
|
0D02C18E16914A687A4A1AC2 /* devDebug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = devDebug.xcconfig; path = Flutter/devDebug.xcconfig; sourceTree = "<group>"; };
|
||||||
126D1370182AB44291C67A10 /* Pods-Runner.dev-release-sky.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.dev-release-sky.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.dev-release-sky.xcconfig"; sourceTree = "<group>"; };
|
126D1370182AB44291C67A10 /* Pods-Runner.dev-release-sky.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.dev-release-sky.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.dev-release-sky.xcconfig"; sourceTree = "<group>"; };
|
||||||
@ -343,7 +350,7 @@
|
|||||||
97C146F01CF9000F007C117D /* Runner */ = {
|
97C146F01CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
04C1FC562D13F1A2000C959E /* InfoPlist.xcstrings */,
|
04717D6B2D1B983200089BD3 /* InfoPlist.strings */,
|
||||||
E0B3E9EC2D04B36C00907A95 /* info_dev.plist */,
|
E0B3E9EC2D04B36C00907A95 /* info_dev.plist */,
|
||||||
E0B3E9EB2D04B36C00907A95 /* info_pre.plist */,
|
E0B3E9EB2D04B36C00907A95 /* info_pre.plist */,
|
||||||
E0B3E9EA2D04B36C00907A95 /* info_sky.plist */,
|
E0B3E9EA2D04B36C00907A95 /* info_sky.plist */,
|
||||||
@ -366,6 +373,8 @@
|
|||||||
82BD91212ADA72360018E523 /* CommonDefine.h */,
|
82BD91212ADA72360018E523 /* CommonDefine.h */,
|
||||||
76C3321F45DA6AE46ED83204 /* RunnerDebug-dev.entitlements */,
|
76C3321F45DA6AE46ED83204 /* RunnerDebug-dev.entitlements */,
|
||||||
16D90D130794DF74DA656999 /* RunnerRelease-sky.entitlements */,
|
16D90D130794DF74DA656999 /* RunnerRelease-sky.entitlements */,
|
||||||
|
04717D672D1B97E100089BD3 /* InfoPlist_sky.strings */,
|
||||||
|
04717D6F2D1B9B5A00089BD3 /* InfoPlist_xhj.strings */,
|
||||||
);
|
);
|
||||||
path = Runner;
|
path = Runner;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -431,6 +440,7 @@
|
|||||||
9740EEB61CF901F6004384FC /* Run Script */,
|
9740EEB61CF901F6004384FC /* Run Script */,
|
||||||
97C146EA1CF9000F007C117D /* Sources */,
|
97C146EA1CF9000F007C117D /* Sources */,
|
||||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||||
|
04717D732D1B9CCA00089BD3 /* ShellScript */,
|
||||||
97C146EC1CF9000F007C117D /* Resources */,
|
97C146EC1CF9000F007C117D /* Resources */,
|
||||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
@ -487,12 +497,14 @@
|
|||||||
04D0CC262D06CE570042EF10 /* launchImage_xhj.png in Resources */,
|
04D0CC262D06CE570042EF10 /* launchImage_xhj.png in Resources */,
|
||||||
82F1ED1C2BE8BA8F00265D59 /* BioAuthEngine.bundle in Resources */,
|
82F1ED1C2BE8BA8F00265D59 /* BioAuthEngine.bundle in Resources */,
|
||||||
82B657692C919DA70079121C /* launchImage_sky.png in Resources */,
|
82B657692C919DA70079121C /* launchImage_sky.png in Resources */,
|
||||||
|
04717D712D1B9B5A00089BD3 /* InfoPlist_xhj.strings in Resources */,
|
||||||
82F1ED1A2BE8BA7D00265D59 /* OCRXMedia.bundle in Resources */,
|
82F1ED1A2BE8BA7D00265D59 /* OCRXMedia.bundle in Resources */,
|
||||||
82F1ED182BE8BA6900265D59 /* APBToygerFacadeSuitable.bundle in Resources */,
|
82F1ED182BE8BA6900265D59 /* APBToygerFacadeSuitable.bundle in Resources */,
|
||||||
82F1ED162BE8BA2000265D59 /* APBToygerFacade.bundle in Resources */,
|
82F1ED162BE8BA2000265D59 /* APBToygerFacade.bundle in Resources */,
|
||||||
E0B3E9ED2D04B36C00907A95 /* info_xhj.plist in Resources */,
|
E0B3E9ED2D04B36C00907A95 /* info_xhj.plist in Resources */,
|
||||||
82F1ED142BE8B9F400265D59 /* ToygerService.bundle in Resources */,
|
82F1ED142BE8B9F400265D59 /* ToygerService.bundle in Resources */,
|
||||||
82C026542AE8AC6D0011FE6A /* AliyunEmasServices-Info.plist in Resources */,
|
82C026542AE8AC6D0011FE6A /* AliyunEmasServices-Info.plist in Resources */,
|
||||||
|
04717D6D2D1B983300089BD3 /* InfoPlist.strings in Resources */,
|
||||||
E0A496C92CA30C2C00E376BB /* xhjDevRelease.xcconfig in Resources */,
|
E0A496C92CA30C2C00E376BB /* xhjDevRelease.xcconfig in Resources */,
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||||
E0A496CD2CA30CA900E376BB /* skyDevRelease.xcconfig in Resources */,
|
E0A496CD2CA30CA900E376BB /* skyDevRelease.xcconfig in Resources */,
|
||||||
@ -510,9 +522,9 @@
|
|||||||
9C453CBFAB0703DFA762337C /* preProfile.xcconfig in Resources */,
|
9C453CBFAB0703DFA762337C /* preProfile.xcconfig in Resources */,
|
||||||
44827AC367F1EAB110A97660 /* preRelease.xcconfig in Resources */,
|
44827AC367F1EAB110A97660 /* preRelease.xcconfig in Resources */,
|
||||||
D7EF77645AB1C3CEEA536468 /* skyDebug.xcconfig in Resources */,
|
D7EF77645AB1C3CEEA536468 /* skyDebug.xcconfig in Resources */,
|
||||||
04C1FC572D13F1A2000C959E /* InfoPlist.xcstrings in Resources */,
|
|
||||||
7B54002BF45E5D8B295B6447 /* skyProfile.xcconfig in Resources */,
|
7B54002BF45E5D8B295B6447 /* skyProfile.xcconfig in Resources */,
|
||||||
25B2A1422F9A2CCCBBCBBB97 /* skyRelease.xcconfig in Resources */,
|
25B2A1422F9A2CCCBBCBBB97 /* skyRelease.xcconfig in Resources */,
|
||||||
|
04717D692D1B97E100089BD3 /* InfoPlist_sky.strings in Resources */,
|
||||||
ADF948FD9EE8BD1AE71F0984 /* xhjDebug.xcconfig in Resources */,
|
ADF948FD9EE8BD1AE71F0984 /* xhjDebug.xcconfig in Resources */,
|
||||||
E0B3E9F02D04B36D00907A95 /* info_dev.plist in Resources */,
|
E0B3E9F02D04B36D00907A95 /* info_dev.plist in Resources */,
|
||||||
EE0A7A61CF36BC83ACA6EE3E /* xhjProfile.xcconfig in Resources */,
|
EE0A7A61CF36BC83ACA6EE3E /* xhjProfile.xcconfig in Resources */,
|
||||||
@ -527,6 +539,24 @@
|
|||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
04717D732D1B9CCA00089BD3 /* ShellScript */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
alwaysOutOfDate = 1;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n# env\nCONFIGURATION_NAME=\"${CONFIGURATION}\"\necho \"-----===${CONFIGURATION_NAME}===------\"\nSTRINGS_FILE=\"\"\nif [[ \"$CONFIGURATION_NAME\" == *\"sky\"* ]]; then\n STRINGS_FILE=\"InfoPlist_sky.strings\"\nelif [[ \"$CONFIGURATION_NAME\" == *\"xhj\"* ]]; then\n STRINGS_FILE=\"InfoPlist_xhj.strings\"\nelse\n STRINGS_FILE=\"InfoPlist.strings\"\nfi\necho \"-----===${STRINGS_FILE}===------\"\necho \"=====${SRCROOT}====\"\nif [[ \"$STRINGS_FILE\" == \"InfoPlist.strings\" ]]; then\n echo \"=====use Default InfoPlist.strings====\"\n exit 0;\nfi\n# 替换目标目录中的 InfoPlist.strings\nfor lang in $(ls \"${SRCROOT}/Runner\" | grep .lproj); do\n echo \"-----===${lang}===------\"\n cp \"${SRCROOT}/Runner/${lang}/${STRINGS_FILE}\" \"${SRCROOT}/Runner/${lang}/InfoPlist.strings\"\ndone\n";
|
||||||
|
};
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
@ -614,6 +644,33 @@
|
|||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
/* Begin PBXVariantGroup section */
|
||||||
|
04717D672D1B97E100089BD3 /* InfoPlist_sky.strings */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
04717D682D1B97E100089BD3 /* zh-Hans */,
|
||||||
|
04717D6A2D1B97E800089BD3 /* en */,
|
||||||
|
);
|
||||||
|
name = InfoPlist_sky.strings;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
04717D6B2D1B983200089BD3 /* InfoPlist.strings */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
04717D6C2D1B983200089BD3 /* en */,
|
||||||
|
04717D6E2D1B983900089BD3 /* zh-Hans */,
|
||||||
|
);
|
||||||
|
name = InfoPlist.strings;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
04717D6F2D1B9B5A00089BD3 /* InfoPlist_xhj.strings */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
04717D702D1B9B5A00089BD3 /* zh-Hans */,
|
||||||
|
04717D722D1B9B5D00089BD3 /* en */,
|
||||||
|
);
|
||||||
|
name = InfoPlist_xhj.strings;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -703,8 +760,10 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-sky.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-sky.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
DEVELOPMENT_TEAM = SF86QP26TZ;
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = NAQ5PL2DYC;
|
||||||
INFOPLIST_FILE = Runner/info_sky.plist;
|
INFOPLIST_FILE = Runner/info_sky.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@ -714,6 +773,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = com.starlock.lock.local;
|
PRODUCT_BUNDLE_IDENTIFIER = com.starlock.lock.local;
|
||||||
PRODUCT_NAME = Runner;
|
PRODUCT_NAME = Runner;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Debug_com.starlock.lock.local.mobileprovision;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
@ -798,8 +858,10 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-xhj.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-xhj.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
DEVELOPMENT_TEAM = SF86QP26TZ;
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = NAQ5PL2DYC;
|
||||||
INFOPLIST_FILE = Runner/info_xhj.plist;
|
INFOPLIST_FILE = Runner/info_xhj.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@ -809,6 +871,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = com.starlock.lock.local;
|
PRODUCT_BUNDLE_IDENTIFIER = com.starlock.lock.local;
|
||||||
PRODUCT_NAME = Runner;
|
PRODUCT_NAME = Runner;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Debug_com.starlock.lock.local.mobileprovision;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
@ -822,8 +885,10 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-sky.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-sky.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||||
DEVELOPMENT_TEAM = NAQ5PL2DYC;
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = NAQ5PL2DYC;
|
||||||
INFOPLIST_FILE = Runner/info_sky.plist;
|
INFOPLIST_FILE = Runner/info_sky.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@ -832,6 +897,7 @@
|
|||||||
);
|
);
|
||||||
PRODUCT_NAME = Runner;
|
PRODUCT_NAME = Runner;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Appstore_com.skychip.lock.mobileprovision;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
@ -845,8 +911,10 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-xhj.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-xhj.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||||
DEVELOPMENT_TEAM = P8997RW3V8;
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = P8997RW3V8;
|
||||||
INFOPLIST_FILE = Runner/info_xhj.plist;
|
INFOPLIST_FILE = Runner/info_xhj.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@ -856,6 +924,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = com.xhjcn.lock;
|
PRODUCT_BUNDLE_IDENTIFIER = com.xhjcn.lock;
|
||||||
PRODUCT_NAME = Runner;
|
PRODUCT_NAME = Runner;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Appstore_com.xhjcn.lock.mobileprovision;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
@ -1088,8 +1157,10 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerDebug-dev.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerDebug-dev.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
DEVELOPMENT_TEAM = SF86QP26TZ;
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = NAQ5PL2DYC;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@ -1099,6 +1170,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = com.starlock.lock.local;
|
PRODUCT_BUNDLE_IDENTIFIER = com.starlock.lock.local;
|
||||||
PRODUCT_NAME = Runner;
|
PRODUCT_NAME = Runner;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Debug_com.starlock.lock.local.mobileprovision;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
@ -1183,8 +1255,10 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-sky.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-sky.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||||
DEVELOPMENT_TEAM = NAQ5PL2DYC;
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = NAQ5PL2DYC;
|
||||||
INFOPLIST_FILE = Runner/info_sky.plist;
|
INFOPLIST_FILE = Runner/info_sky.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@ -1194,6 +1268,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = com.skychip.lock.pre;
|
PRODUCT_BUNDLE_IDENTIFIER = com.skychip.lock.pre;
|
||||||
PRODUCT_NAME = Runner;
|
PRODUCT_NAME = Runner;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Adhoc_com.skychip.lock.pre.mobileprovision;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
@ -1278,8 +1353,10 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-sky.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-sky.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||||
DEVELOPMENT_TEAM = NAQ5PL2DYC;
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = NAQ5PL2DYC;
|
||||||
INFOPLIST_FILE = Runner/info_sky.plist;
|
INFOPLIST_FILE = Runner/info_sky.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@ -1289,6 +1366,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = com.skychip.lock.dev;
|
PRODUCT_BUNDLE_IDENTIFIER = com.skychip.lock.dev;
|
||||||
PRODUCT_NAME = Runner;
|
PRODUCT_NAME = Runner;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Adhoc_com.skychip.lock.dev.mobileprovision;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
@ -1373,8 +1451,10 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-xhj.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-xhj.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||||
DEVELOPMENT_TEAM = P8997RW3V8;
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = P8997RW3V8;
|
||||||
INFOPLIST_FILE = Runner/info_xhj.plist;
|
INFOPLIST_FILE = Runner/info_xhj.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@ -1384,6 +1464,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = com.xhjcn.lock.pre;
|
PRODUCT_BUNDLE_IDENTIFIER = com.xhjcn.lock.pre;
|
||||||
PRODUCT_NAME = Runner;
|
PRODUCT_NAME = Runner;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Adhoc_com.xhjcn.lock.pre.mobileprovision;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
@ -1468,8 +1549,10 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-xhj.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-xhj.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||||
DEVELOPMENT_TEAM = P8997RW3V8;
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = P8997RW3V8;
|
||||||
INFOPLIST_FILE = Runner/info_xhj.plist;
|
INFOPLIST_FILE = Runner/info_xhj.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@ -1479,6 +1562,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = com.xhjcn.lock.dev;
|
PRODUCT_BUNDLE_IDENTIFIER = com.xhjcn.lock.dev;
|
||||||
PRODUCT_NAME = Runner;
|
PRODUCT_NAME = Runner;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Adhoc_com.xhjcn.lock.dev.mobileprovision;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
</Testables>
|
</Testables>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug-pre-xhj"
|
buildConfiguration = "Debug-sky"
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
launchStyle = "0"
|
launchStyle = "0"
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
</Testables>
|
</Testables>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug-pre-xhj"
|
buildConfiguration = "Debug-xhj"
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
launchStyle = "0"
|
launchStyle = "0"
|
||||||
|
|||||||
@ -1,8 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
InfoPlist.strings
|
InfoPlist_xhj.strings
|
||||||
Runner
|
Runner
|
||||||
|
|
||||||
Created by mac on 2024/11/21.
|
Created by Mac on 2024/12/25.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
"AppName"="Star Lock";
|
CFBundleName="StarLock";
|
||||||
|
CFBundleDisplayName="StarLock";
|
||||||
|
NSBluetoothAlwaysUsageDescription="The app uses bluetooth to find, connect and transfer data between different devices";
|
||||||
|
NSBluetoothPeripheralUsageDescription="The app uses bluetooth to find, connect and transfer data between different devices";
|
||||||
|
NSCameraUsageDescription="The application requests the camera to take photos for avatar upload and face authentication";
|
||||||
|
NSContactsUsageDescription="Access the address book to send electronic keys to contacts in the address book";
|
||||||
|
NSLocationAlwaysAndWhenInUseUsageDescription="updated location information when applying in the front and backend";
|
||||||
|
NSLocationAlwaysUsageDescription="updated location information when the app is in the background";
|
||||||
|
NSLocationWhenInUseUsageDescription="updated location information when the app is in the foreground";
|
||||||
|
NSMicrophoneUsageDescription="request microphone for calls";
|
||||||
|
NSPhotoLibraryUsageDescription="request photo album for avatar upload";
|
||||||
|
|||||||
18
ios/Runner/en.lproj/InfoPlist_sky.strings
Normal file
18
ios/Runner/en.lproj/InfoPlist_sky.strings
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
InfoPlist_sky.strings
|
||||||
|
Runner
|
||||||
|
|
||||||
|
Created by Mac on 2024/12/25.
|
||||||
|
|
||||||
|
*/
|
||||||
|
CFBundleName="TTLock Pro";
|
||||||
|
CFBundleDisplayName="TTLock Pro";
|
||||||
|
NSBluetoothAlwaysUsageDescription="The app uses bluetooth to find, connect and transfer data between different devices";
|
||||||
|
NSBluetoothPeripheralUsageDescription="The app uses bluetooth to find, connect and transfer data between different devices";
|
||||||
|
NSCameraUsageDescription="The application requests the camera to take photos for avatar upload and face authentication";
|
||||||
|
NSContactsUsageDescription="Access the address book to send electronic keys to contacts in the address book";
|
||||||
|
NSLocationAlwaysAndWhenInUseUsageDescription="updated location information when applying in the front and backend";
|
||||||
|
NSLocationAlwaysUsageDescription="updated location information when the app is in the background";
|
||||||
|
NSLocationWhenInUseUsageDescription="updated location information when the app is in the foreground";
|
||||||
|
NSMicrophoneUsageDescription="request microphone for calls";
|
||||||
|
NSPhotoLibraryUsageDescription="request photo album for avatar upload";
|
||||||
18
ios/Runner/en.lproj/InfoPlist_xhj.strings
Normal file
18
ios/Runner/en.lproj/InfoPlist_xhj.strings
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
InfoPlist_xhj.strings
|
||||||
|
Runner
|
||||||
|
|
||||||
|
Created by Mac on 2024/12/25.
|
||||||
|
|
||||||
|
*/
|
||||||
|
CFBundleName="StarLock Pro";
|
||||||
|
CFBundleDisplayName="StarLock Pro";
|
||||||
|
NSBluetoothAlwaysUsageDescription="The app uses bluetooth to find, connect and transfer data between different devices";
|
||||||
|
NSBluetoothPeripheralUsageDescription="The app uses bluetooth to find, connect and transfer data between different devices";
|
||||||
|
NSCameraUsageDescription="The application requests the camera to take photos for avatar upload and face authentication";
|
||||||
|
NSContactsUsageDescription="Access the address book to send electronic keys to contacts in the address book";
|
||||||
|
NSLocationAlwaysAndWhenInUseUsageDescription="updated location information when applying in the front and backend";
|
||||||
|
NSLocationAlwaysUsageDescription="updated location information when the app is in the background";
|
||||||
|
NSLocationWhenInUseUsageDescription="updated location information when the app is in the foreground";
|
||||||
|
NSMicrophoneUsageDescription="request microphone for calls";
|
||||||
|
NSPhotoLibraryUsageDescription="request photo album for avatar upload";
|
||||||
@ -7,7 +7,7 @@
|
|||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>$(BUNDLE_DISPLAY_NAME)</string>
|
<string>$(BUNDLE_NAME)</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
|
|||||||
23
ios/Runner/info_sky.xcstrings
Normal file
23
ios/Runner/info_sky.xcstrings
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"sourceLanguage" : "zh-Hans",
|
||||||
|
"strings" : {
|
||||||
|
"CFBundleDisplayName" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "TTLock Pro"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "锁通通"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"version" : "1.0"
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@
|
|||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>$(BUNDLE_DISPLAY_NAME)</string>
|
<string>$(BUNDLE_NAME)</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
|
|||||||
@ -1,8 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
InfoPlist.strings
|
InfoPlist_xhj.strings
|
||||||
Runner
|
Runner
|
||||||
|
|
||||||
Created by mac on 2024/11/21.
|
Created by Mac on 2024/12/25.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
"AppName"="星锁";
|
CFBundleName="星锁";
|
||||||
|
CFBundleDisplayName="星锁";
|
||||||
|
NSBluetoothAlwaysUsageDescription="该应用程序使用蓝牙在不同设备之间查找、连接和传输数据";
|
||||||
|
NSBluetoothPeripheralUsageDescription="该应用程序使用蓝牙在不同设备之间查找、连接和传输数据";
|
||||||
|
NSCameraUsageDescription="应用请求相机,以便于拍摄照片,用于头像上传及人脸认证";
|
||||||
|
NSContactsUsageDescription="应用访问通讯录,用于给通讯录中的联系人发送电子钥匙";
|
||||||
|
NSLocationAlwaysAndWhenInUseUsageDescription="应用在前台和后台的时候可以搜到更新的位置信息";
|
||||||
|
NSLocationAlwaysUsageDescription="应用在后台的时候可以搜到更新的位置信息";
|
||||||
|
NSLocationWhenInUseUsageDescription="应用在前台的时候可以搜到更新的位置信息";
|
||||||
|
NSMicrophoneUsageDescription="应用请求麦克风用来通话";
|
||||||
|
NSPhotoLibraryUsageDescription="应用请求相册用于头像上传";
|
||||||
|
|||||||
18
ios/Runner/zh-Hans.lproj/InfoPlist_sky.strings
Normal file
18
ios/Runner/zh-Hans.lproj/InfoPlist_sky.strings
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
InfoPlist_sky.strings
|
||||||
|
Runner
|
||||||
|
|
||||||
|
Created by Mac on 2024/12/25.
|
||||||
|
|
||||||
|
*/
|
||||||
|
CFBundleName="锁通通";
|
||||||
|
CFBundleDisplayName="锁通通";
|
||||||
|
NSBluetoothAlwaysUsageDescription="该应用程序使用蓝牙在不同设备之间查找、连接和传输数据";
|
||||||
|
NSBluetoothPeripheralUsageDescription="该应用程序使用蓝牙在不同设备之间查找、连接和传输数据";
|
||||||
|
NSCameraUsageDescription="应用请求相机,以便于拍摄照片,用于头像上传及人脸认证";
|
||||||
|
NSContactsUsageDescription="应用访问通讯录,用于给通讯录中的联系人发送电子钥匙";
|
||||||
|
NSLocationAlwaysAndWhenInUseUsageDescription="应用在前台和后台的时候可以搜到更新的位置信息";
|
||||||
|
NSLocationAlwaysUsageDescription="应用在后台的时候可以搜到更新的位置信息";
|
||||||
|
NSLocationWhenInUseUsageDescription="应用在前台的时候可以搜到更新的位置信息";
|
||||||
|
NSMicrophoneUsageDescription="应用请求麦克风用来通话";
|
||||||
|
NSPhotoLibraryUsageDescription="应用请求相册用于头像上传";
|
||||||
18
ios/Runner/zh-Hans.lproj/InfoPlist_xhj.strings
Normal file
18
ios/Runner/zh-Hans.lproj/InfoPlist_xhj.strings
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
InfoPlist_xhj.strings
|
||||||
|
Runner
|
||||||
|
|
||||||
|
Created by Mac on 2024/12/25.
|
||||||
|
|
||||||
|
*/
|
||||||
|
CFBundleName="星星锁";
|
||||||
|
CFBundleDisplayName="星星锁";
|
||||||
|
NSBluetoothAlwaysUsageDescription="该应用程序使用蓝牙在不同设备之间查找、连接和传输数据";
|
||||||
|
NSBluetoothPeripheralUsageDescription="该应用程序使用蓝牙在不同设备之间查找、连接和传输数据";
|
||||||
|
NSCameraUsageDescription="应用请求相机,以便于拍摄照片,用于头像上传及人脸认证";
|
||||||
|
NSContactsUsageDescription="应用访问通讯录,用于给通讯录中的联系人发送电子钥匙";
|
||||||
|
NSLocationAlwaysAndWhenInUseUsageDescription="应用在前台和后台的时候可以搜到更新的位置信息";
|
||||||
|
NSLocationAlwaysUsageDescription="应用在后台的时候可以搜到更新的位置信息";
|
||||||
|
NSLocationWhenInUseUsageDescription="应用在前台的时候可以搜到更新的位置信息";
|
||||||
|
NSMicrophoneUsageDescription="应用请求麦克风用来通话";
|
||||||
|
NSPhotoLibraryUsageDescription="应用请求相册用于头像上传";
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "اتبع النظام"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Следете система"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "এক্ফক্লোসিস্টেম"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Sledovat systém"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Følg systemet"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "System folgen"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Ακολουθήστε το σύστημα"
|
||||||
}
|
}
|
||||||
@ -1011,6 +1011,7 @@
|
|||||||
"请在锁设置中开启远程开锁": "Please enable remote unlocking in the lock settings",
|
"请在锁设置中开启远程开锁": "Please enable remote unlocking in the lock settings",
|
||||||
"接听": "Answer",
|
"接听": "Answer",
|
||||||
"截图已保存到相册": "Screenshot saved to album",
|
"截图已保存到相册": "Screenshot saved to album",
|
||||||
|
"录屏已保存到相册": "Screen recording file saved to album",
|
||||||
"添加遥控": "Add remote control",
|
"添加遥控": "Add remote control",
|
||||||
"已连接到锁,请按遥控": "Connected to the lock, please press the remote control",
|
"已连接到锁,请按遥控": "Connected to the lock, please press the remote control",
|
||||||
"遥控号": "Remote control number",
|
"遥控号": "Remote control number",
|
||||||
@ -1121,5 +1122,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Follow system"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Seguir sistema"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Süsteemi jälgimine"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Seuraa järjestelmää"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Suivre le système"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "מערכת מעקב"
|
||||||
}
|
}
|
||||||
@ -1046,39 +1046,39 @@
|
|||||||
"英文": "英语",
|
"英文": "英语",
|
||||||
"简体中文": "简体中文",
|
"简体中文": "简体中文",
|
||||||
"繁体中文": "繁體中文",
|
"繁体中文": "繁體中文",
|
||||||
"法语": "法语",
|
"法语": "Français",
|
||||||
"俄语": "Русский",
|
"俄语": "Русский",
|
||||||
"德语": "多伊奇",
|
"德语": "Deutsch",
|
||||||
"日语": "日本語",
|
"日语": "日本語",
|
||||||
"韩语": "嘻嘻哈哈",
|
"韩语": "한국어",
|
||||||
"意大利语": "意大利语",
|
"意大利语": "Italiano",
|
||||||
"乌克兰语": "Українська",
|
"乌克兰语": "Українська",
|
||||||
"葡萄牙语": "葡萄牙商业银行",
|
"葡萄牙语": "Português",
|
||||||
"西班牙语": "西班牙语",
|
"西班牙语": "Español",
|
||||||
"阿拉伯语": "العربية",
|
"阿拉伯语": "العربية",
|
||||||
"越南语": "Tiếng Việt",
|
"越南语": "Tiếng Việt",
|
||||||
"马来语": "马来语",
|
"马来语": "Bahasa Melayu",
|
||||||
"荷兰语": "荷兰语",
|
"荷兰语": "Nederlands",
|
||||||
"罗马尼亚语": "罗马ă",
|
"罗马尼亚语": "Română",
|
||||||
"立陶宛语": "Lietuvių",
|
"立陶宛语": "Lietuvių",
|
||||||
"瑞典语": "瑞典语",
|
"瑞典语": "Svenska",
|
||||||
"爱沙尼亚语": "Eesti",
|
"爱沙尼亚语": "Eesti",
|
||||||
"波兰语": "波兰语",
|
"波兰语": "Polski",
|
||||||
"斯洛伐克语": "懒散的人č艾娜",
|
"斯洛伐克语": "Slovenčina",
|
||||||
"捷克语": "Češ蒂娜",
|
"捷克语": "Čeština",
|
||||||
"希腊语": "Ελληνικά",
|
"希腊语": "Ελληνικά",
|
||||||
"希伯来语": "עברית",
|
"希伯来语": "עברית",
|
||||||
"塞尔维亚语": "Српски",
|
"塞尔维亚语": "Српски",
|
||||||
"土耳其语": "Turkce",
|
"土耳其语": "Turkce",
|
||||||
"匈牙利语": "马札尔人的",
|
"匈牙利语": "Magyar",
|
||||||
"保加利亚语": "Български",
|
"保加利亚语": "Български",
|
||||||
"哈萨克斯坦语": "Қазақ",
|
"哈萨克斯坦语": "Қазақ",
|
||||||
"孟加拉语": "বাংলা",
|
"孟加拉语": "বাংলা",
|
||||||
"克罗地亚语": "Hrvatski",
|
"克罗地亚语": "Hrvatski",
|
||||||
"泰语": "ไทย",
|
"泰语": "ไทย",
|
||||||
"印度尼西亚语": "印度尼西亚语",
|
"印度尼西亚语": "Bahasa Indonesia",
|
||||||
"芬兰语": "芬兰语",
|
"芬兰语": "Suomi",
|
||||||
"丹麦语": "丹麦语",
|
"丹麦语": "Dansk",
|
||||||
"重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "重置后,锁上的掌骨静脉会被删除。你确定要重置吗?",
|
"重置后,该锁的掌静脉都将被删除哦,确认要重置吗?": "重置后,锁上的掌骨静脉会被删除。你确定要重置吗?",
|
||||||
"在线": "在线",
|
"在线": "在线",
|
||||||
"离线": "离线",
|
"离线": "离线",
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "跟踪系统"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Prati sistem:"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Follow system"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Sistem mengikuti"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Seguire il sistema"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "システムに従う"
|
||||||
}
|
}
|
||||||
@ -1014,6 +1014,7 @@
|
|||||||
"请在锁设置中开启远程开锁": "请在锁设置中开启远程开锁",
|
"请在锁设置中开启远程开锁": "请在锁设置中开启远程开锁",
|
||||||
"接听": "接听",
|
"接听": "接听",
|
||||||
"截图已保存到相册": "截图已保存到相册",
|
"截图已保存到相册": "截图已保存到相册",
|
||||||
|
"录屏已保存到相册": "录屏已保存到相册",
|
||||||
"添加遥控": "添加遥控",
|
"添加遥控": "添加遥控",
|
||||||
"已连接到锁,请按遥控": "已连接到锁,请按遥控",
|
"已连接到锁,请按遥控": "已连接到锁,请按遥控",
|
||||||
"遥控号": "遥控号",
|
"遥控号": "遥控号",
|
||||||
@ -1121,5 +1122,6 @@
|
|||||||
"月简称": "月简称",
|
"月简称": "月简称",
|
||||||
"日简称": "日简称",
|
"日简称": "日简称",
|
||||||
"时简称": "时简称",
|
"时简称": "时简称",
|
||||||
"分简称": "分简称"
|
"分简称": "分简称",
|
||||||
|
"跟随系统": "跟随系统"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Жүйені қолдану"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "시스템을 따르십시오"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Sekti sistema"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Ikut system"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Systeem volgen"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Śledź system"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Siga o sistema"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Urmează sistemul:"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Следуйте системе"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Sledovať systém"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Пратите систем"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Följ system"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "ระบบติดตามผล"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Sistemi takip et"
|
||||||
}
|
}
|
||||||
@ -1118,6 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "跟蹤系統"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Система стеження за"
|
||||||
}
|
}
|
||||||
@ -1118,5 +1118,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "Hệ thống theo dõi"
|
||||||
}
|
}
|
||||||
@ -1013,6 +1013,7 @@
|
|||||||
"请在锁设置中开启远程开锁": "请在锁设置中开启远程开锁",
|
"请在锁设置中开启远程开锁": "请在锁设置中开启远程开锁",
|
||||||
"接听": "接听",
|
"接听": "接听",
|
||||||
"截图已保存到相册": "截图已保存到相册",
|
"截图已保存到相册": "截图已保存到相册",
|
||||||
|
"录屏已保存到相册": "录屏已保存到相册",
|
||||||
"添加遥控": "添加遥控",
|
"添加遥控": "添加遥控",
|
||||||
"已连接到锁,请按遥控": "已连接到锁,请按遥控",
|
"已连接到锁,请按遥控": "已连接到锁,请按遥控",
|
||||||
"遥控号": "遥控号",
|
"遥控号": "遥控号",
|
||||||
@ -1122,5 +1123,6 @@
|
|||||||
"月简称": "M",
|
"月简称": "M",
|
||||||
"日简称": "D",
|
"日简称": "D",
|
||||||
"时简称": "H",
|
"时简称": "H",
|
||||||
"分简称": "M"
|
"分简称": "M",
|
||||||
|
"跟随系统": "跟随系统"
|
||||||
}
|
}
|
||||||
|
|||||||
45
lib/app.dart
45
lib/app.dart
@ -33,9 +33,14 @@ class MyApp extends StatefulWidget {
|
|||||||
class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
|
class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ScreenUtilInit(
|
return FutureBuilder(
|
||||||
designSize: const Size(585, 1265),
|
future: Get.updateLocale(CurrentLocaleTool.getCurrentLocale()),
|
||||||
builder: (BuildContext w, Widget? a) => _initMaterialApp());
|
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
||||||
|
return ScreenUtilInit(
|
||||||
|
designSize: const Size(585, 1265),
|
||||||
|
builder: (BuildContext w, Widget? a) => _initMaterialApp());
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetMaterialApp _initMaterialApp() {
|
GetMaterialApp _initMaterialApp() {
|
||||||
@ -60,23 +65,23 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
|
|||||||
GlobalWidgetsLocalizations.delegate,
|
GlobalWidgetsLocalizations.delegate,
|
||||||
],
|
],
|
||||||
// localeResolutionCallback用于在启动时动态确定应该使用哪种语言和地区。
|
// localeResolutionCallback用于在启动时动态确定应该使用哪种语言和地区。
|
||||||
localeResolutionCallback:
|
// localeResolutionCallback:
|
||||||
(Locale? locale, Iterable<Locale> supportedLocales) {
|
// (Locale? locale, Iterable<Locale> supportedLocales) {
|
||||||
AppLog.log(
|
// AppLog.log(
|
||||||
'System device locale: ${Get.deviceLocale} locale:$locale');
|
// 'System device locale: ${Get.deviceLocale} locale:$locale');
|
||||||
// if (widget.isLogin) {
|
// // if (widget.isLogin) {
|
||||||
// 登录之后调用存储的语言
|
// // 登录之后调用存储的语言
|
||||||
locale = CurrentLocaleTool.getCurrentLocale();
|
// locale = CurrentLocaleTool.getCurrentLocale();
|
||||||
// } else {
|
// // } else {
|
||||||
// // 没登录之前调用系统的语言
|
// // // 没登录之前调用系统的语言
|
||||||
// locale = Get.deviceLocale;
|
// // locale = Get.deviceLocale;
|
||||||
// }
|
// // }
|
||||||
locale = CurrentLocaleTool.convertLocale(locale);
|
// locale = CurrentLocaleTool.convertLocale(locale);
|
||||||
AppLog.log('localeResolutionCallback locale: $locale');
|
// AppLog.log('localeResolutionCallback locale: $locale');
|
||||||
AppManager()
|
// AppManager()
|
||||||
.setLanCode(code: '${locale.languageCode}_${locale.countryCode}');
|
// .setLanCode(code: '${locale.languageCode}_${locale.countryCode}');
|
||||||
return Locale(locale.languageCode, locale.countryCode);
|
// return Locale(locale.languageCode, locale.countryCode);
|
||||||
},
|
// },
|
||||||
// 用来指定应用当前使用的语言和地区。它定义了应用在启动时加载的默认语言环境。
|
// 用来指定应用当前使用的语言和地区。它定义了应用在启动时加载的默认语言环境。
|
||||||
locale: CurrentLocaleTool.getCurrentLocale(),
|
locale: CurrentLocaleTool.getCurrentLocale(),
|
||||||
// locale: Get.deviceLocale,
|
// locale: Get.deviceLocale,
|
||||||
|
|||||||
@ -36,7 +36,6 @@ import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/msgNotific
|
|||||||
import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/nDaysUnopened/nDaysUnopened_page.dart';
|
import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/nDaysUnopened/nDaysUnopened_page.dart';
|
||||||
import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/openDoorNotify/openDoorNotify_page.dart';
|
import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/openDoorNotify/openDoorNotify_page.dart';
|
||||||
import 'package:star_lock/main/lockDetail/messageWarn/notificationMode/notificationMode_page.dart';
|
import 'package:star_lock/main/lockDetail/messageWarn/notificationMode/notificationMode_page.dart';
|
||||||
import 'package:star_lock/main/lockDetail/monitoring/star_chart_h264/star_chart_page.dart';
|
|
||||||
import 'package:star_lock/main/lockDetail/palm/addPalm/addPalm_page.dart';
|
import 'package:star_lock/main/lockDetail/palm/addPalm/addPalm_page.dart';
|
||||||
import 'package:star_lock/main/lockDetail/palm/palmList/palmList_page.dart';
|
import 'package:star_lock/main/lockDetail/palm/palmList/palmList_page.dart';
|
||||||
import 'package:star_lock/main/lockDetail/passwordKey/passwordKeyDetailChangeDate/passwordKeyDetailChangeDate_page.dart';
|
import 'package:star_lock/main/lockDetail/passwordKey/passwordKeyDetailChangeDate/passwordKeyDetailChangeDate_page.dart';
|
||||||
@ -61,6 +60,7 @@ import 'package:star_lock/mine/mineSet/transferSmartLock/transferSmartLockList/t
|
|||||||
import 'package:star_lock/mine/valueAddedServices/advancedFeaturesWeb/advancedFeaturesWeb_page.dart';
|
import 'package:star_lock/mine/valueAddedServices/advancedFeaturesWeb/advancedFeaturesWeb_page.dart';
|
||||||
import 'package:star_lock/mine/valueAddedServices/advancedFunctionRecord/advancedFunctionRecord_page.dart';
|
import 'package:star_lock/mine/valueAddedServices/advancedFunctionRecord/advancedFunctionRecord_page.dart';
|
||||||
import 'package:star_lock/mine/valueAddedServices/valueAddedServicesRecord/value_added_services_record_page.dart';
|
import 'package:star_lock/mine/valueAddedServices/valueAddedServicesRecord/value_added_services_record_page.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/views/talkView/talk_view_page.dart';
|
||||||
|
|
||||||
import 'common/safetyVerification/safetyVerification_page.dart';
|
import 'common/safetyVerification/safetyVerification_page.dart';
|
||||||
import 'login/forgetPassword/starLock_forgetPassword_page.dart';
|
import 'login/forgetPassword/starLock_forgetPassword_page.dart';
|
||||||
@ -514,6 +514,7 @@ abstract class Routers {
|
|||||||
static const String googleHomePage = '/googleHomePage'; //GoogleHome
|
static const String googleHomePage = '/googleHomePage'; //GoogleHome
|
||||||
static const String doubleLockLinkPage = '/doubleLockLinkPage'; //双锁联动
|
static const String doubleLockLinkPage = '/doubleLockLinkPage'; //双锁联动
|
||||||
static const String starChartPage = '/starChartPage'; //星图
|
static const String starChartPage = '/starChartPage'; //星图
|
||||||
|
static const String starChartTalkView = '/starChartTalkView'; //星图对讲页面
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AppRouters {
|
abstract class AppRouters {
|
||||||
@ -747,7 +748,8 @@ abstract class AppRouters {
|
|||||||
GetPage<dynamic>(
|
GetPage<dynamic>(
|
||||||
name: Routers.lockTimePage,
|
name: Routers.lockTimePage,
|
||||||
page: () => const LockTimePage(),
|
page: () => const LockTimePage(),
|
||||||
), // 诊断
|
),
|
||||||
|
// 诊断
|
||||||
GetPage<dynamic>(
|
GetPage<dynamic>(
|
||||||
name: Routers.diagnosePage,
|
name: Routers.diagnosePage,
|
||||||
page: () => const DiagnosePage(),
|
page: () => const DiagnosePage(),
|
||||||
@ -1192,6 +1194,6 @@ abstract class AppRouters {
|
|||||||
name: Routers.doubleLockLinkPage,
|
name: Routers.doubleLockLinkPage,
|
||||||
page: () => const DoubleLockLinkPage()),
|
page: () => const DoubleLockLinkPage()),
|
||||||
GetPage<dynamic>(
|
GetPage<dynamic>(
|
||||||
name: Routers.starChartPage, page: () => const StarChartPage()),
|
name: Routers.starChartTalkView, page: () => const TalkViewPage()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -213,9 +213,7 @@ class BlueManage {
|
|||||||
message: '指定设备名称的扫描蓝牙设备 监听扫描结果失败',
|
message: '指定设备名称的扫描蓝牙设备 监听扫描结果失败',
|
||||||
detail: '打印失败问题 e:${e.toString()}',
|
detail: '打印失败问题 e:${e.toString()}',
|
||||||
upload: false);
|
upload: false);
|
||||||
AppLog.log(
|
AppLog.log('扫描失败:$e');
|
||||||
'扫描失败:$e',
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
FlutterBluePlus.cancelWhenScanComplete(subscription);
|
FlutterBluePlus.cancelWhenScanComplete(subscription);
|
||||||
await completer.future;
|
await completer.future;
|
||||||
|
|||||||
@ -21,4 +21,12 @@ class EventBusManager {
|
|||||||
eventBusFir(dynamic event) {
|
eventBusFir(dynamic event) {
|
||||||
eventBus?.fire(event);
|
eventBus?.fire(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 发送事件
|
||||||
|
void fireEvent(dynamic event) {
|
||||||
|
eventBus?.fire(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取 EventBus 实例
|
||||||
|
EventBus? get bus => eventBus;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,210 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
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 'package:star_lock/app_settings/app_settings.dart';
|
|
||||||
import 'package:star_lock/blue/io_tool/manager_event_bus.dart';
|
|
||||||
import 'package:star_lock/main/lockDetail/monitoring/star_chart_h264/star_chart_state.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/events/talk_status_change_event.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/start_chart_talk_status.dart';
|
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
|
||||||
import 'package:star_lock/tools/eventBusEventManage.dart';
|
|
||||||
|
|
||||||
class StarChartLogic extends BaseGetXController {
|
|
||||||
final StarChartState state = StarChartState();
|
|
||||||
|
|
||||||
/// 收到Talk发送的状态
|
|
||||||
StreamSubscription? _getTalkStatusRefreshUIEvent;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onReady() {
|
|
||||||
super.onReady();
|
|
||||||
_getTalkStatusRefreshUIAction();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _getTalkStatusRefreshUIAction() {
|
|
||||||
_getTalkStatusRefreshUIEvent = EventBusManager()
|
|
||||||
.eventBus!
|
|
||||||
.on<TalkStatusChangeEvent>()
|
|
||||||
.listen((TalkStatusChangeEvent event) async {
|
|
||||||
state.talkStatus.value = event.newStatus.index;
|
|
||||||
state.oneMinuteTime.value = 0;
|
|
||||||
if (state.talkStatus.value == TalkStatus.rejected.index ||
|
|
||||||
state.talkStatus.value == TalkStatus.notTalkData.index ||
|
|
||||||
state.talkStatus.value == TalkStatus.notTalkPing.index ||
|
|
||||||
state.talkStatus.value == TalkStatus.end.index) {
|
|
||||||
_cancelTimers();
|
|
||||||
// 状态错误,返回页面
|
|
||||||
Get.back();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.talkStatus.value == TalkStatus.duringCall.index) {
|
|
||||||
_startCallTimer();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _startCallTimer() {
|
|
||||||
state.oneMinuteTimeTimer.cancel();
|
|
||||||
state.oneMinuteTimeTimer =
|
|
||||||
Timer.periodic(const Duration(seconds: 1), (Timer t) {
|
|
||||||
state.oneMinuteTime.value++;
|
|
||||||
if (state.oneMinuteTime.value >= 60) {
|
|
||||||
t.cancel();
|
|
||||||
initiateHangUpCommand();
|
|
||||||
AppLog.log('通话时间超过60秒,自动挂断');
|
|
||||||
state.oneMinuteTime.value = 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _cancelTimers() {
|
|
||||||
state.oneMinuteTimeTimer.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发起接听命令
|
|
||||||
void initiateAnswerCommand() {
|
|
||||||
StartChartManage().sendTalkAcceptMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发起挂断命令
|
|
||||||
void initiateHangUpCommand() {
|
|
||||||
_cancelTimers();
|
|
||||||
if (state.talkStatus.value == TalkStatus.duringCall.index) {
|
|
||||||
// 如果是通话中就挂断
|
|
||||||
StartChartManage().sendTalkHangupMessage();
|
|
||||||
} else {
|
|
||||||
// 拒绝
|
|
||||||
StartChartManage().sendTalkRejectMessage();
|
|
||||||
}
|
|
||||||
Get.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _onFrame(List<int> frame) async {
|
|
||||||
state.allFrames.add(frame);
|
|
||||||
final List<int> concatenatedFrames = concatenateFrames(state.allFrames);
|
|
||||||
AppLog.log('pcm数据:$concatenatedFrames');
|
|
||||||
|
|
||||||
final List<int> pcmBytes = listLinearToULaw(frame);
|
|
||||||
//发起发送录音命令
|
|
||||||
// StartChartManage().sendTalkAudioMessage(pcmBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<int> listLinearToULaw(List<int> pcmList) {
|
|
||||||
return pcmList.map(linearToULaw).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<int> concatenateFrames(List<List<int>> frames) {
|
|
||||||
return frames.expand((frame) => frame).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> startProcessing() async {
|
|
||||||
// state.isButtonDisabled.value = true;
|
|
||||||
//
|
|
||||||
// state.voiceProcessor?.addFrameListener(_onFrame);
|
|
||||||
// state.voiceProcessor?.addErrorListener(_onError);
|
|
||||||
// try {
|
|
||||||
// if (await state.voiceProcessor?.hasRecordAudioPermission() ?? false) {
|
|
||||||
// await state.voiceProcessor?.start(state.frameLength, state.sampleRate);
|
|
||||||
// state.isProcessing.value =
|
|
||||||
// await state.voiceProcessor?.isRecording() ?? false;
|
|
||||||
// } else {
|
|
||||||
// state.errorMessage.value = 'Recording permission not granted';
|
|
||||||
// }
|
|
||||||
// } on PlatformException catch (ex) {
|
|
||||||
// state.errorMessage.value = 'Failed to start recorder: $ex';
|
|
||||||
// } finally {
|
|
||||||
// state.isButtonDisabled.value = false;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onError(VoiceProcessorException error) {
|
|
||||||
state.errorMessage.value = error.message!;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> stopProcessing() async {
|
|
||||||
// 检查 voiceProcessor 是否已经初始化
|
|
||||||
// if (state.voiceProcessor == null) {
|
|
||||||
// state.errorMessage.value = 'Voice processor is not initialized.';
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// state.isButtonDisabled.value = true;
|
|
||||||
// try {
|
|
||||||
// await state.voiceProcessor?.stop();
|
|
||||||
// state.voiceProcessor?.removeFrameListener(_onFrame);
|
|
||||||
// state.udpSendDataFrameNumber = 0;
|
|
||||||
// } on PlatformException catch (ex) {
|
|
||||||
// state.errorMessage.value = 'Failed to stop recorder: $ex';
|
|
||||||
// } finally {
|
|
||||||
// state.isProcessing.value =
|
|
||||||
// await state.voiceProcessor?.isRecording() ?? false;
|
|
||||||
// state.isButtonDisabled.value = false;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
final List<int> table = [
|
|
||||||
0xFF,
|
|
||||||
0x1FF,
|
|
||||||
0x3FF,
|
|
||||||
0x7FF,
|
|
||||||
0xFFF,
|
|
||||||
0x1FFF,
|
|
||||||
0x3FFF,
|
|
||||||
0x7FFF
|
|
||||||
];
|
|
||||||
for (int i = 0; i < table.length; i++) {
|
|
||||||
if (val <= table[i]) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return table.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> getPermissionStatus() async {
|
|
||||||
const Permission permission = Permission.microphone;
|
|
||||||
final PermissionStatus status = await permission.status;
|
|
||||||
if (status.isGranted) {
|
|
||||||
return true;
|
|
||||||
} else if (status.isDenied || status.isRestricted) {
|
|
||||||
await requestPermission(permission);
|
|
||||||
} else if (status.isPermanentlyDenied) {
|
|
||||||
openAppSettings();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> requestPermission(Permission permission) async {
|
|
||||||
final PermissionStatus status = await permission.request();
|
|
||||||
if (status.isPermanentlyDenied) {
|
|
||||||
openAppSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,396 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:ui' as ui;
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/rendering.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:image_gallery_saver/image_gallery_saver.dart';
|
|
||||||
import 'package:path_provider/path_provider.dart';
|
|
||||||
import 'package:star_lock/app_settings/app_colors.dart';
|
|
||||||
import 'package:star_lock/app_settings/app_settings.dart';
|
|
||||||
import 'package:star_lock/main/lockDetail/monitoring/star_chart_h264/star_chart_logic.dart';
|
|
||||||
import 'package:star_lock/main/lockDetail/monitoring/star_chart_h264/star_chart_state.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/start_chart_talk_status.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/webView/h264_web_view.dart';
|
|
||||||
import 'package:star_lock/talk/udp/udp_manage.dart';
|
|
||||||
import 'package:star_lock/tools/eventBusEventManage.dart';
|
|
||||||
import 'package:star_lock/tools/showTFView.dart';
|
|
||||||
|
|
||||||
class StarChartPage extends StatefulWidget {
|
|
||||||
const StarChartPage({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<StarChartPage> createState() => _StarChartPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _StarChartPageState extends State<StarChartPage> {
|
|
||||||
final StarChartLogic logic = Get.put(StarChartLogic());
|
|
||||||
final StarChartState state = Get.find<StarChartLogic>().state;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
|
|
||||||
initAsync();
|
|
||||||
_getTVDataRefreshUIAction();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> initAsync() async {
|
|
||||||
await requestMicrophonePermission();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return PopScope(
|
|
||||||
canPop: false,
|
|
||||||
child: RepaintBoundary(
|
|
||||||
key: state.globalKey,
|
|
||||||
child: Container(
|
|
||||||
width: 1.sw,
|
|
||||||
height: 1.sh,
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: _buildTalkView(isMpeg4: true),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildTopButtons() {
|
|
||||||
return Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
buildIconButton(
|
|
||||||
icon: state.isOpenVoice.value
|
|
||||||
? 'images/main/icon_lockDetail_monitoringCloseVoice.png'
|
|
||||||
: 'images/main/icon_lockDetail_monitoringOpenVoice.png',
|
|
||||||
onTap: () {
|
|
||||||
state.isOpenVoice.value = !state.isOpenVoice.value;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(width: 60.w),
|
|
||||||
buildIconButton(
|
|
||||||
icon: 'images/main/icon_lockDetail_monitoringScreenshot.png',
|
|
||||||
onTap: captureAndSavePng,
|
|
||||||
),
|
|
||||||
SizedBox(width: 60.w),
|
|
||||||
buildIconButton(
|
|
||||||
icon: 'images/main/icon_lockDetail_monitoringScreenRecording.png',
|
|
||||||
onTap: () {
|
|
||||||
// Get.toNamed(Routers.monitoringRealTimeScreenPage);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildBottomButtons() {
|
|
||||||
return Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
||||||
children: <Widget>[
|
|
||||||
buildAnswerButton(),
|
|
||||||
buildIconButton(
|
|
||||||
icon: 'images/main/icon_lockDetail_hangUp.png',
|
|
||||||
label: '挂断'.tr,
|
|
||||||
color: Colors.red,
|
|
||||||
onTap: () async {
|
|
||||||
logic.initiateHangUpCommand();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
buildIconButton(
|
|
||||||
icon: 'images/main/icon_lockDetail_monitoringUnlock.png',
|
|
||||||
label: '开锁'.tr,
|
|
||||||
color: AppColors.mainColor,
|
|
||||||
onTap: () {
|
|
||||||
if (UDPManage().remoteUnlock == 1) {
|
|
||||||
showDeletPasswordAlertDialog(context);
|
|
||||||
} else {
|
|
||||||
logic.showToast('请在锁设置中开启远程开锁'.tr);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildAnswerButton() {
|
|
||||||
return Obx(() {
|
|
||||||
// final bool isDuringCall =
|
|
||||||
// state.talkStatus.value == TalkStatus.duringCall.index;
|
|
||||||
return buildIconButton(
|
|
||||||
icon: state.talkStatus.value == TalkStatus.duringCall.index
|
|
||||||
? 'images/main/icon_lockDetail_monitoringUnTalkback.png'
|
|
||||||
: 'images/main/icon_lockDetail_monitoringAnswerCalls.png',
|
|
||||||
label: state.talkStatus.value == TalkStatus.duringCall.index
|
|
||||||
? '长按说话'.tr
|
|
||||||
: '接听'.tr,
|
|
||||||
onTap: () async {
|
|
||||||
if (state.talkStatus.value == TalkStatus.waitingAnswer.index) {
|
|
||||||
logic.initiateAnswerCommand();
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLongPress: () {
|
|
||||||
state.listAudioData.value = <int>[];
|
|
||||||
logic.startProcessing();
|
|
||||||
},
|
|
||||||
onLongPressUp: () {
|
|
||||||
logic.stopProcessing();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildIconButton({
|
|
||||||
required String icon,
|
|
||||||
String? label,
|
|
||||||
Color color = Colors.white,
|
|
||||||
required Function() onTap,
|
|
||||||
Function()? onLongPress,
|
|
||||||
Function()? onLongPressUp,
|
|
||||||
}) {
|
|
||||||
final double wh = 80.w;
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: onTap,
|
|
||||||
onLongPress: onLongPress,
|
|
||||||
onLongPressUp: onLongPressUp,
|
|
||||||
child: SizedBox(
|
|
||||||
height: 140.h,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
Container(
|
|
||||||
width: wh,
|
|
||||||
height: wh,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: color,
|
|
||||||
borderRadius: BorderRadius.circular((wh + 10.w * 2) / 2),
|
|
||||||
),
|
|
||||||
padding: EdgeInsets.all(20.w),
|
|
||||||
child: Image.asset(icon, fit: BoxFit.fitWidth),
|
|
||||||
),
|
|
||||||
if (label != null) ...[
|
|
||||||
SizedBox(height: 20.w),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
label,
|
|
||||||
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: '请输入6位数字开锁密码'.tr,
|
|
||||||
tipTitle: '',
|
|
||||||
controller: state.passwordTF,
|
|
||||||
inputFormatters: <TextInputFormatter>[
|
|
||||||
LengthLimitingTextInputFormatter(6), //限制长度
|
|
||||||
FilteringTextInputFormatter.allow(RegExp('[0-9]')),
|
|
||||||
],
|
|
||||||
sureClick: () async {
|
|
||||||
if (state.passwordTF.text.isEmpty) {
|
|
||||||
logic.showToast('请输入开锁密码'.tr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final List<int> numbers = <int>[];
|
|
||||||
final List<int> lockIDData = utf8.encode(state.passwordTF.text);
|
|
||||||
numbers.addAll(lockIDData);
|
|
||||||
for (int i = 0; i < 6 - lockIDData.length; i++) {
|
|
||||||
numbers.add(0);
|
|
||||||
}
|
|
||||||
//todo: 开门暂未实现
|
|
||||||
// logic.udpOpenDoorAction(numbers);
|
|
||||||
},
|
|
||||||
cancelClick: () {
|
|
||||||
Get.back();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> requestMicrophonePermission() async {
|
|
||||||
await logic.getPermissionStatus().then((bool value) async {
|
|
||||||
if (!value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> captureAndSavePng() async {
|
|
||||||
try {
|
|
||||||
if (state.globalKey.currentContext == null) {
|
|
||||||
AppLog.log('截图失败: 未找到当前上下文');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final RenderRepaintBoundary boundary = state.globalKey.currentContext!
|
|
||||||
.findRenderObject()! as RenderRepaintBoundary;
|
|
||||||
final ui.Image image = await boundary.toImage();
|
|
||||||
final ByteData? byteData =
|
|
||||||
await image.toByteData(format: ui.ImageByteFormat.png);
|
|
||||||
if (byteData == null) {
|
|
||||||
AppLog.log('截图失败: 图像数据为空');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final Uint8List pngBytes = byteData.buffer.asUint8List();
|
|
||||||
|
|
||||||
final Directory directory = await getApplicationDocumentsDirectory();
|
|
||||||
final String imagePath = '${directory.path}/screenshot.png';
|
|
||||||
|
|
||||||
final File imgFile = File(imagePath);
|
|
||||||
await imgFile.writeAsBytes(pngBytes);
|
|
||||||
|
|
||||||
await ImageGallerySaver.saveFile(imagePath);
|
|
||||||
|
|
||||||
AppLog.log('截图保存路径: $imagePath');
|
|
||||||
logic.showToast('截图已保存到相册'.tr);
|
|
||||||
} catch (e) {
|
|
||||||
AppLog.log('截图失败: $e');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _getTVDataRefreshUIAction() {
|
|
||||||
state.getTVDataRefreshUIEvent = eventBus
|
|
||||||
.on<GetTVDataRefreshUI>()
|
|
||||||
.listen((GetTVDataRefreshUI event) async {
|
|
||||||
if (event.tvList.isNotEmpty && event.tvList.length > 100) {
|
|
||||||
final Uint8List imageData = Uint8List.fromList(event.tvList);
|
|
||||||
if (!listEquals(state.listPhotoData.value, imageData)) {
|
|
||||||
state.listPhotoData.value = imageData;
|
|
||||||
state.shouldUpdateUI.value = true;
|
|
||||||
if (state.shouldUpdateUI.value) {
|
|
||||||
setState(() {});
|
|
||||||
state.shouldUpdateUI.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
logic.stopProcessing();
|
|
||||||
state.getTVDataRefreshUIEvent!.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildTalkView({required bool isMpeg4}) {
|
|
||||||
return isMpeg4 ? _buildMpeg4TalkView() : _buildH264TalkView();
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMpeg4TalkView() {
|
|
||||||
return Stack(
|
|
||||||
children: <Widget>[
|
|
||||||
Image.memory(
|
|
||||||
state.listPhotoData.value,
|
|
||||||
gaplessPlayback: true,
|
|
||||||
width: 1.sw,
|
|
||||||
height: 1.sh,
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
filterQuality: FilterQuality.high,
|
|
||||||
errorBuilder:
|
|
||||||
(BuildContext context, Object error, StackTrace? stackTrace) {
|
|
||||||
return Container(color: Colors.transparent);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
top: ScreenUtil().statusBarHeight + 30.h,
|
|
||||||
width: 1.sw,
|
|
||||||
child: Obx(() {
|
|
||||||
final String sec =
|
|
||||||
(state.oneMinuteTime.value % 60).toString().padLeft(2, '0');
|
|
||||||
final String min =
|
|
||||||
(state.oneMinuteTime.value ~/ 60).toString().padLeft(2, '0');
|
|
||||||
return Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
Text('$min:$sec',
|
|
||||||
style: TextStyle(fontSize: 26.sp, color: Colors.white)),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
bottom: 10.w,
|
|
||||||
child: Container(
|
|
||||||
width: 1.sw - 30.w * 2,
|
|
||||||
margin: EdgeInsets.all(30.w),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: const Color(0xC83C3F41),
|
|
||||||
borderRadius: BorderRadius.circular(20.h),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
SizedBox(height: 20.h),
|
|
||||||
buildTopButtons(),
|
|
||||||
SizedBox(height: 20.h),
|
|
||||||
buildBottomButtons(),
|
|
||||||
SizedBox(height: 20.h),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildH264TalkView() {
|
|
||||||
return Stack(
|
|
||||||
children: <Widget>[
|
|
||||||
H264WebView(),
|
|
||||||
Positioned(
|
|
||||||
top: ScreenUtil().statusBarHeight + 30.h,
|
|
||||||
width: 1.sw,
|
|
||||||
child: Obx(() {
|
|
||||||
final String sec =
|
|
||||||
(state.oneMinuteTime.value % 60).toString().padLeft(2, '0');
|
|
||||||
final String min =
|
|
||||||
(state.oneMinuteTime.value ~/ 60).toString().padLeft(2, '0');
|
|
||||||
return Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
Text('$min:$sec',
|
|
||||||
style: TextStyle(fontSize: 26.sp, color: Colors.white)),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
bottom: 10.w,
|
|
||||||
child: Container(
|
|
||||||
width: 1.sw - 30.w * 2,
|
|
||||||
margin: EdgeInsets.all(30.w),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: const Color(0xC83C3F41),
|
|
||||||
borderRadius: BorderRadius.circular(20.h),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
SizedBox(height: 20.h),
|
|
||||||
buildTopButtons(),
|
|
||||||
SizedBox(height: 20.h),
|
|
||||||
buildBottomButtons(),
|
|
||||||
SizedBox(height: 20.h),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
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 'package:star_lock/talk/startChart/start_chart_talk_status.dart';
|
|
||||||
|
|
||||||
import '../../../../tools/storage.dart';
|
|
||||||
|
|
||||||
class StarChartState {
|
|
||||||
RxBool isOpenVoice = false.obs;
|
|
||||||
int udpSendDataFrameNumber = 0; // 帧序号
|
|
||||||
// var isSenderAudioData = false.obs;// 是否要发送音频数据
|
|
||||||
StreamSubscription? getTVDataRefreshUIEvent; //收到视频流数据
|
|
||||||
RxBool shouldUpdateUI = false.obs; //是否需要更新UI
|
|
||||||
|
|
||||||
Future<String?> userMobileIP = NetworkInfo().getWifiIP();
|
|
||||||
Future<String?> userUid = Storage.getUid();
|
|
||||||
|
|
||||||
// RxInt udpStatus =
|
|
||||||
// 0.obs; //0:初始状态 1:等待监视 2: 3:监视中 4:呼叫成功 5:主角通话中 6:被叫通话 8:被叫通话中 9:长按说话
|
|
||||||
TextEditingController passwordTF = TextEditingController();
|
|
||||||
|
|
||||||
Rx<Uint8List> listPhotoData = Uint8List(0).obs; //得到的视频流字节数据
|
|
||||||
RxList<int> listAudioData = <int>[].obs; //得到的音频流字节数据
|
|
||||||
|
|
||||||
//录音相关
|
|
||||||
late VoiceProcessor? voiceProcessor;
|
|
||||||
RxBool isProcessing = false.obs; //是否正在处理音频数据
|
|
||||||
RxBool isButtonDisabled = false.obs; //是否禁用按钮
|
|
||||||
final int frameLength = 320; //音视频帧长度为320
|
|
||||||
final int sampleRate = 8000; //音频采样率为8000
|
|
||||||
RxString errorMessage = ''.obs;
|
|
||||||
List<List<int>> allFrames = <List<int>>[];
|
|
||||||
|
|
||||||
GlobalKey globalKey = GlobalKey();
|
|
||||||
|
|
||||||
late Timer oneMinuteTimeTimer =
|
|
||||||
Timer(const Duration(seconds: 1), () {}); // 定时器超过60秒关闭当前界面
|
|
||||||
RxInt oneMinuteTime = 0.obs; // 定时器秒数
|
|
||||||
|
|
||||||
// 定时器如果发送了接听的命令 而没收到回复就每秒重复发送10次
|
|
||||||
late Timer answerTimer = Timer(const Duration(seconds: 1), () {}); //接听命令定时器
|
|
||||||
RxInt answerSeconds = 0.obs;
|
|
||||||
RxBool isClickAnswer = false.obs; //是否点击了接听按钮
|
|
||||||
|
|
||||||
late Timer hangUpTimer = Timer(const Duration(seconds: 1), () {}); //挂断命令定时器
|
|
||||||
RxInt hangUpSeconds = 0.obs;
|
|
||||||
RxBool isClickHangUp = false.obs; //是否点击了挂断按钮
|
|
||||||
|
|
||||||
late Timer openDoorTimer = Timer(const Duration(seconds: 1), () {}); //开门命令定时器
|
|
||||||
RxInt openDoorSeconds = 0.obs;
|
|
||||||
|
|
||||||
RxInt talkStatus = 0.obs; //星图对讲状态
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
@ -32,6 +32,7 @@ class LockMainXHJLogic extends BaseGetXController {
|
|||||||
final String languageCodeAndCountryCode = entity.data!.lang!;
|
final String languageCodeAndCountryCode = entity.data!.lang!;
|
||||||
if (languageCodeAndCountryCode.isEmpty) {
|
if (languageCodeAndCountryCode.isEmpty) {
|
||||||
await StoreService.to.saveLanguageCode('');
|
await StoreService.to.saveLanguageCode('');
|
||||||
|
await Get.updateLocale(Get.deviceLocale!);
|
||||||
} else if (languageCodeAndCountryCode.contains('-')) {
|
} else if (languageCodeAndCountryCode.contains('-')) {
|
||||||
final List<String> parts = languageCodeAndCountryCode.split('-');
|
final List<String> parts = languageCodeAndCountryCode.split('-');
|
||||||
final Locale locale = Locale(parts[0], parts[1]);
|
final Locale locale = Locale(parts[0], parts[1]);
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import 'flavors.dart';
|
|||||||
import 'main.dart' as runner;
|
import 'main.dart' as runner;
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
F.appFlavor = Flavor.local;
|
F.appFlavor = Flavor.sky;
|
||||||
// AppLog.log('local调用了main函数');
|
// AppLog.log('local调用了main函数');
|
||||||
await runner.main();
|
await runner.main();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
class GatewayConnectionLockListEntity {
|
class GatewayConnectionLockListEntity {
|
||||||
|
|
||||||
GatewayConnectionLockListEntity(
|
GatewayConnectionLockListEntity(
|
||||||
{this.errorCode, this.description, this.errorMsg, this.data});
|
{this.errorCode, this.description, this.errorMsg, this.data});
|
||||||
|
|
||||||
@ -27,7 +26,6 @@ class GatewayConnectionLockListEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Data {
|
class Data {
|
||||||
|
|
||||||
Data({this.list, this.total, this.pageNo, this.pageSize});
|
Data({this.list, this.total, this.pageNo, this.pageSize});
|
||||||
|
|
||||||
Data.fromJson(Map<String, dynamic> json) {
|
Data.fromJson(Map<String, dynamic> json) {
|
||||||
@ -59,23 +57,23 @@ class Data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class GatewayConnectionLockItemEntity {
|
class GatewayConnectionLockItemEntity {
|
||||||
|
GatewayConnectionLockItemEntity(
|
||||||
GatewayConnectionLockItemEntity({this.lockId, this.lockAlias, this.rssi});
|
{this.lockId, this.lockAlias, this.gatewayRssi});
|
||||||
|
|
||||||
GatewayConnectionLockItemEntity.fromJson(Map<String, dynamic> json) {
|
GatewayConnectionLockItemEntity.fromJson(Map<String, dynamic> json) {
|
||||||
lockId = json['lockId'];
|
lockId = json['lockId'];
|
||||||
lockAlias = json['lockAlias'];
|
lockAlias = json['lockAlias'];
|
||||||
rssi = json['rssi'];
|
gatewayRssi = json['gatewayRssi'];
|
||||||
}
|
}
|
||||||
int? lockId;
|
int? lockId;
|
||||||
String? lockAlias;
|
String? lockAlias;
|
||||||
int? rssi;
|
int? gatewayRssi;
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final Map<String, dynamic> data = <String, dynamic>{};
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
data['lockId'] = lockId;
|
data['lockId'] = lockId;
|
||||||
data['lockAlias'] = lockAlias;
|
data['lockAlias'] = lockAlias;
|
||||||
data['rssi'] = rssi;
|
data['gatewayRssi'] = gatewayRssi;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,7 +56,7 @@ class _GatewayConnectionLockListPageState
|
|||||||
return _gatewayConnectionLockListItem(
|
return _gatewayConnectionLockListItem(
|
||||||
'images/mine/icon_mine_gatewaySignal_prompt.png',
|
'images/mine/icon_mine_gatewaySignal_prompt.png',
|
||||||
entity.lockAlias ?? '',
|
entity.lockAlias ?? '',
|
||||||
'信号强'.tr, () {
|
entity.gatewayRssi.toString(), () {
|
||||||
// Navigator.pushNamed(context, Routers.gatewayDetailPage);
|
// Navigator.pushNamed(context, Routers.gatewayDetailPage);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|||||||
@ -15,22 +15,27 @@ class MineMultiLanguageLogic extends GetxController {
|
|||||||
|
|
||||||
//更新个人信息
|
//更新个人信息
|
||||||
Future<void> updateUserLangInfo(Locale l) async {
|
Future<void> updateUserLangInfo(Locale l) async {
|
||||||
// AppLog.log('lanTypeTitle: $lanTypeTitle');
|
AppLog.log('selet: ${l.toString()}}');
|
||||||
String lang = l.toString();
|
String lang = l.toString();
|
||||||
if (state.currentLanguageType.value == LanguageType.system) {
|
if (state.currentLanguageType.value == LanguageType.system) {
|
||||||
lang = '';
|
lang = '';
|
||||||
}
|
}
|
||||||
|
String currentLanguage = StoreService.to.getLanguageCode()!;
|
||||||
|
await StoreService.to.saveLanguageCode(lang);
|
||||||
final PasswordKeyListEntity entity =
|
final PasswordKeyListEntity entity =
|
||||||
await ApiRepository.to.updateUserLangInfo(lang: lang);
|
await ApiRepository.to.updateUserLangInfo(lang: lang);
|
||||||
if (entity.errorCode!.codeIsSuccessful) {
|
if (entity.errorCode!.codeIsSuccessful) {
|
||||||
await changeLanguage(l);
|
await Get.updateLocale(l);
|
||||||
|
AppLog.log('saveLocale: ${l.toString()}}');
|
||||||
eventBus.fire(ChangeLanguageBlockLastLanguageEvent());
|
eventBus.fire(ChangeLanguageBlockLastLanguageEvent());
|
||||||
|
} else {
|
||||||
|
await StoreService.to.saveLanguageCode(currentLanguage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> changeLanguage(Locale l) async {
|
// Future<void> changeLanguage(Locale l) async {
|
||||||
await Get.updateLocale(l);
|
// await StoreService.to.saveLanguageCode(l.toString());
|
||||||
await StoreService.to.saveLanguageCode(
|
// await Get.updateLocale(l);
|
||||||
CurrentLocaleTool.convertLocale(Get.locale!).toString());
|
// AppLog.log('saveLocale: ${l.toString()}}');
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,8 @@ class _MineMultiLanguagePageState extends State<MineMultiLanguagePage> {
|
|||||||
final String lanTypeTitle =
|
final String lanTypeTitle =
|
||||||
ExtensionLanguageType.fromLocale(state.seletLocale)
|
ExtensionLanguageType.fromLocale(state.seletLocale)
|
||||||
.lanTitle;
|
.lanTitle;
|
||||||
Get.back(result: {'currentLanguage': lanTypeTitle});
|
Get.back(
|
||||||
|
result: {'currentLanguage': state.seletLocale.toString()});
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'保存'.tr,
|
'保存'.tr,
|
||||||
@ -59,7 +60,7 @@ class _MineMultiLanguagePageState extends State<MineMultiLanguagePage> {
|
|||||||
final List<Widget> l = <Widget>[];
|
final List<Widget> l = <Widget>[];
|
||||||
l.add(
|
l.add(
|
||||||
CommonItem(
|
CommonItem(
|
||||||
leftTitel: '跟随系统',
|
leftTitel: '跟随系统'.tr,
|
||||||
rightTitle: '',
|
rightTitle: '',
|
||||||
isHaveLine: true,
|
isHaveLine: true,
|
||||||
isHaveDirection: false,
|
isHaveDirection: false,
|
||||||
|
|||||||
@ -15,7 +15,9 @@ class MineMultiLanguageState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rx<LanguageType> currentLanguageType =
|
Rx<LanguageType> currentLanguageType =
|
||||||
ExtensionLanguageType.fromLocale(Get.locale!).obs;
|
StoreService.to.getLanguageCode()!.isEmpty
|
||||||
|
? LanguageType.system.obs
|
||||||
|
: ExtensionLanguageType.fromLocale(Get.locale!).obs;
|
||||||
|
|
||||||
late Locale seletLocale;
|
late Locale seletLocale;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,17 +2,14 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get/get_state_manager/get_state_manager.dart';
|
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:star_lock/app_settings/app_settings.dart';
|
import 'package:star_lock/app_settings/app_settings.dart';
|
||||||
import 'package:star_lock/flavors.dart';
|
import 'package:star_lock/flavors.dart';
|
||||||
import 'package:star_lock/mine/mineSet/mineSet/mineSet_logic.dart';
|
import 'package:star_lock/mine/mineSet/mineSet/mineSet_logic.dart';
|
||||||
import 'package:star_lock/mine/mineSet/mineSet/mineSet_state.dart';
|
import 'package:star_lock/mine/mineSet/mineSet/mineSet_state.dart';
|
||||||
import 'package:star_lock/tools/langue/langue_tool.dart';
|
|
||||||
import 'package:star_lock/tools/wechat/customer_tool.dart';
|
import 'package:star_lock/tools/wechat/customer_tool.dart';
|
||||||
import '../../../appRouters.dart';
|
import '../../../appRouters.dart';
|
||||||
import '../../../app_settings/app_colors.dart';
|
import '../../../app_settings/app_colors.dart';
|
||||||
@ -22,7 +19,8 @@ import '../../../tools/submitBtn.dart';
|
|||||||
import '../../../tools/titleAppBar.dart';
|
import '../../../tools/titleAppBar.dart';
|
||||||
import '../../../tools/wechat/wechatManageTool.dart';
|
import '../../../tools/wechat/wechatManageTool.dart';
|
||||||
import '../../../tools/wechat/wx_push_miniProgram/wx_push_miniProgram.dart';
|
import '../../../tools/wechat/wx_push_miniProgram/wx_push_miniProgram.dart';
|
||||||
import '../../../translations/trans_lib.dart';
|
import '../../../translations/app_dept.dart';
|
||||||
|
import '../../../translations/current_locale_tool.dart';
|
||||||
|
|
||||||
class MineSetPage extends StatefulWidget {
|
class MineSetPage extends StatefulWidget {
|
||||||
MineSetPage({Key? key, this.showAppBar = true, this.showAbout = false})
|
MineSetPage({Key? key, this.showAppBar = true, this.showAbout = false})
|
||||||
@ -303,10 +301,10 @@ class _MineSetPageState extends State<MineSetPage>
|
|||||||
isHaveDirection: true,
|
isHaveDirection: true,
|
||||||
action: () async {
|
action: () async {
|
||||||
// Get.toNamed(Routers.mineMultiLanguagePage);
|
// Get.toNamed(Routers.mineMultiLanguagePage);
|
||||||
await Get.toNamed(Routers.mineMultiLanguagePage)!.then(
|
await Get.toNamed(Routers.mineMultiLanguagePage)!.then((value) {
|
||||||
(value) => {
|
state.currentLanguage.value = value['currentLanguage'];
|
||||||
state.currentLanguage.value = value['currentLanguage']
|
setState(() {});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
/* 2024-01-12 会议确定去掉“锁屏” by DaisyWu
|
/* 2024-01-12 会议确定去掉“锁屏” by DaisyWu
|
||||||
@ -516,11 +514,23 @@ class _MineSetPageState extends State<MineSetPage>
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Text(leftTitle!, style: TextStyle(fontSize: 22.sp))),
|
child: Text(leftTitle!, style: TextStyle(fontSize: 22.sp))),
|
||||||
SizedBox(width: 10.w),
|
SizedBox(width: 10.w),
|
||||||
Image.asset(
|
if (CurrentLocaleTool.getCurrentLocaleString() ==
|
||||||
'images/icon_right_grey.png',
|
ExtensionLanguageType.fromLanguageType(LanguageType.hebrew)
|
||||||
width: 12.w,
|
.toString() ||
|
||||||
height: 21.w,
|
CurrentLocaleTool.getCurrentLocaleString() ==
|
||||||
),
|
ExtensionLanguageType.fromLanguageType(LanguageType.arabic)
|
||||||
|
.toString())
|
||||||
|
Image.asset(
|
||||||
|
'images/icon_left_grey.png',
|
||||||
|
width: 21.w,
|
||||||
|
height: 21.w,
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Image.asset(
|
||||||
|
'images/icon_right_grey.png',
|
||||||
|
width: 12.w,
|
||||||
|
height: 21.w,
|
||||||
|
),
|
||||||
SizedBox(width: 5.w),
|
SizedBox(width: 5.w),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/app_settings/app_settings.dart';
|
||||||
import 'package:star_lock/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_entity.dart';
|
import 'package:star_lock/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_entity.dart';
|
||||||
import 'package:star_lock/mine/mineSet/mineSet/userSettingInfoEntity.dart';
|
import 'package:star_lock/mine/mineSet/mineSet/userSettingInfoEntity.dart';
|
||||||
|
|
||||||
|
import '../../../tools/store_service.dart';
|
||||||
import '../../../translations/app_dept.dart';
|
import '../../../translations/app_dept.dart';
|
||||||
import '../../../translations/current_locale_tool.dart';
|
import '../../../translations/current_locale_tool.dart';
|
||||||
|
|
||||||
@ -24,10 +26,14 @@ class MineSetState {
|
|||||||
|
|
||||||
/// 获取翻译后的国家名称
|
/// 获取翻译后的国家名称
|
||||||
String get currentLanguageName {
|
String get currentLanguageName {
|
||||||
return ExtensionLanguageType.fromLocale(
|
AppLog.log(
|
||||||
CurrentLocaleTool.getCurrentLocaleWithLanguageCode(
|
'currentLanguage.value:${currentLanguage.value} fsgdsgddfg:${CurrentLocaleTool.getCurrentLocaleWithLanguageCode(currentLanguage.value)}');
|
||||||
currentLanguage.value))
|
return StoreService.to.getLanguageCode()!.isEmpty
|
||||||
.lanTitle;
|
? '跟随系统'.tr
|
||||||
|
: ExtensionLanguageType.fromLocale(CurrentLocaleTool.convertLocale(
|
||||||
|
CurrentLocaleTool.getCurrentLocaleWithLanguageCode(
|
||||||
|
currentLanguage.value)))
|
||||||
|
.lanTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
RxBool isAmazonAlexa = false.obs; //亚马逊Alexa
|
RxBool isAmazonAlexa = false.obs; //亚马逊Alexa
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import 'dart:typed_data';
|
|||||||
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart';
|
import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/constant/protocol_flag_constant.dart';
|
import 'package:star_lock/talk/startChart/constant/protocol_flag_constant.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/udp_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||||
@ -17,12 +18,12 @@ import 'package:star_lock/talk/startChart/proto/talk_request.pb.dart';
|
|||||||
|
|
||||||
class MessageCommand {
|
class MessageCommand {
|
||||||
// 全局字典,用于存储每个 ToPeerId 对应的当前 messageId
|
// 全局字典,用于存储每个 ToPeerId 对应的当前 messageId
|
||||||
|
// 单个会话的messageId需要递增
|
||||||
static Map<String, int> _messageIdMap = {};
|
static Map<String, int> _messageIdMap = {};
|
||||||
static int _maxIntValue = 9223372036854775807; // Dart 中 int 的最大值
|
static int _maxIntValue = 9223372036854775807; // Dart 中 int 的最大值
|
||||||
|
|
||||||
// 获取并递增消息ID
|
// 获取并递增消息ID
|
||||||
static int getNextMessageId(String toPeerId, {bool increment = true}) {
|
static int getNextMessageId(String toPeerId, {bool increment = true}) {
|
||||||
|
|
||||||
if (_messageIdMap.containsKey(toPeerId)) {
|
if (_messageIdMap.containsKey(toPeerId)) {
|
||||||
if (increment) {
|
if (increment) {
|
||||||
_messageIdMap[toPeerId] = _messageIdMap[toPeerId]! + 1;
|
_messageIdMap[toPeerId] = _messageIdMap[toPeerId]! + 1;
|
||||||
@ -51,7 +52,6 @@ class MessageCommand {
|
|||||||
SpIndex: 1,
|
SpIndex: 1,
|
||||||
FromPeerId: FromPeerId,
|
FromPeerId: FromPeerId,
|
||||||
ToPeerId: ToPeerId,
|
ToPeerId: ToPeerId,
|
||||||
Payload: [0],
|
|
||||||
PayloadCRC: 0,
|
PayloadCRC: 0,
|
||||||
PayloadLength: 0,
|
PayloadLength: 0,
|
||||||
PayloadType: PayloadTypeConstant.goOnline,
|
PayloadType: PayloadTypeConstant.goOnline,
|
||||||
@ -295,7 +295,7 @@ class MessageCommand {
|
|||||||
static List<int> talkExpectMessage({
|
static List<int> talkExpectMessage({
|
||||||
required String FromPeerId,
|
required String FromPeerId,
|
||||||
required String ToPeerId,
|
required String ToPeerId,
|
||||||
required TalkExpect talkExpect,
|
required TalkExpectReq talkExpect,
|
||||||
int? MessageId,
|
int? MessageId,
|
||||||
}) {
|
}) {
|
||||||
final payload = talkExpect.writeToBuffer();
|
final payload = talkExpect.writeToBuffer();
|
||||||
@ -324,8 +324,8 @@ class MessageCommand {
|
|||||||
int? MessageId,
|
int? MessageId,
|
||||||
}) {
|
}) {
|
||||||
final genericResp = GenericResp();
|
final genericResp = GenericResp();
|
||||||
genericResp.message = 'ok';
|
genericResp.message = UdpConstant.genericRespSuccessMsg;
|
||||||
genericResp.code = 0;
|
genericResp.code = UdpConstant.genericRespSuccessCode;
|
||||||
final payload = genericResp.writeToBuffer();
|
final payload = genericResp.writeToBuffer();
|
||||||
ScpMessage message = ScpMessage(
|
ScpMessage message = ScpMessage(
|
||||||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||||||
@ -350,10 +350,11 @@ class MessageCommand {
|
|||||||
required String ToPeerId,
|
required String ToPeerId,
|
||||||
required int PayloadType,
|
required int PayloadType,
|
||||||
int? MessageId,
|
int? MessageId,
|
||||||
|
String? errorMessageText,
|
||||||
}) {
|
}) {
|
||||||
final genericResp = GenericResp();
|
final genericResp = GenericResp();
|
||||||
genericResp.message = 'error';
|
genericResp.message = errorMessageText ?? UdpConstant.genericRespErrorMsg;
|
||||||
genericResp.code = -1;
|
genericResp.code = UdpConstant.genericRespErrorCode;
|
||||||
final payload = genericResp.writeToBuffer();
|
final payload = genericResp.writeToBuffer();
|
||||||
ScpMessage message = ScpMessage(
|
ScpMessage message = ScpMessage(
|
||||||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||||||
|
|||||||
3
lib/talk/startChart/constant/exception_constant.dart
Normal file
3
lib/talk/startChart/constant/exception_constant.dart
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
class ExceptionConstant{
|
||||||
|
static const String relay = 'relay';
|
||||||
|
}
|
||||||
18
lib/talk/startChart/constant/talk_status.dart
Normal file
18
lib/talk/startChart/constant/talk_status.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
|
||||||
|
enum TalkStatus {
|
||||||
|
none, // 无状态
|
||||||
|
waitingAnswer, // 等待接听
|
||||||
|
answeredSuccessfully, // 接听成功
|
||||||
|
waitingData, // 等待数据
|
||||||
|
duringCall, // 通话中
|
||||||
|
hangingUpDuring, // 通话中挂断
|
||||||
|
rejected, // 被拒绝
|
||||||
|
uninitialized, // 未初始化
|
||||||
|
initializationCompleted, // 初始化完成
|
||||||
|
notTalkData, // 暂无通话数据
|
||||||
|
notTalkPing, // 暂无通话保持
|
||||||
|
error, // 错误状态
|
||||||
|
end, // 结束
|
||||||
|
}
|
||||||
|
|
||||||
@ -2,4 +2,7 @@ class UdpConstant{
|
|||||||
// generic成功响应
|
// generic成功响应
|
||||||
static const int genericRespSuccessCode = 0;
|
static const int genericRespSuccessCode = 0;
|
||||||
static const String genericRespSuccessMsg = 'ok';
|
static const String genericRespSuccessMsg = 'ok';
|
||||||
|
// generic失败响应
|
||||||
|
static const int genericRespErrorCode = -1;
|
||||||
|
static const String genericRespErrorMsg = 'error';
|
||||||
}
|
}
|
||||||
@ -1,37 +1,55 @@
|
|||||||
class HeartbeatResponse {
|
class HeartbeatResponse {
|
||||||
int? statusCode;
|
int? statusCode;
|
||||||
int? nextPingTime;
|
int? nextPingTime;
|
||||||
|
String? clientAddr;
|
||||||
|
|
||||||
HeartbeatResponse({
|
HeartbeatResponse({
|
||||||
this.statusCode,
|
this.statusCode,
|
||||||
this.nextPingTime,
|
this.nextPingTime,
|
||||||
|
this.clientAddr,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory HeartbeatResponse.fromBytes(List<int> bytes) {
|
factory HeartbeatResponse.fromBytes(List<int> bytes) {
|
||||||
final message = HeartbeatResponse();
|
final message = HeartbeatResponse();
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
// Set default value for statusCode
|
// 检查是否有足够的数据来解析状态码
|
||||||
message.statusCode = 0; // 或者其他默认值
|
if (bytes.length < 1) {
|
||||||
|
|
||||||
// Check if the entire array has at least 2 bytes for nextPingTime
|
|
||||||
if (bytes.length < 2) {
|
|
||||||
throw FormatException("Insufficient data for HeartbeatResponse");
|
throw FormatException("Insufficient data for HeartbeatResponse");
|
||||||
}
|
}
|
||||||
|
|
||||||
// nextPingTime (2 bytes, little-endian)
|
// 解析状态码 (1 byte)
|
||||||
if (bytes.length - offset >= 2) {
|
message.statusCode = bytes[offset];
|
||||||
message.nextPingTime = (bytes[offset + 1] << 8) | bytes[offset];
|
offset += 1;
|
||||||
offset += 2;
|
|
||||||
} else {
|
// 检查是否有足够的数据来解析 nextPingTime
|
||||||
throw FormatException("Invalid nextPingTime length");
|
if (bytes.length < offset + 2) {
|
||||||
|
throw FormatException("Insufficient data for nextPingTime");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解析 nextPingTime (2 bytes, little-endian)
|
||||||
|
message.nextPingTime = (bytes[offset + 1] << 8) | bytes[offset];
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
// 解析 clientAddr (null-terminated string)
|
||||||
|
final clientAddrBytes = <int>[];
|
||||||
|
while (offset < bytes.length && bytes[offset] != 0) {
|
||||||
|
clientAddrBytes.add(bytes[offset]);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳过 null terminator
|
||||||
|
if (offset < bytes.length && bytes[offset] == 0) {
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.clientAddr = String.fromCharCodes(clientAddrBytes);
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'HeartbeatResponse{statusCode: $statusCode, nextPingTime: $nextPingTime}';
|
return 'HeartbeatResponse{statusCode: $statusCode, nextPingTime: $nextPingTime, clientAddr: $clientAddr}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,32 +1,11 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:get/get.dart';
|
import 'dart:typed_data';
|
||||||
import 'package:protobuf/protobuf.dart';
|
|
||||||
import 'package:star_lock/app_settings/app_settings.dart';
|
import 'package:star_lock/app_settings/app_settings.dart';
|
||||||
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
import 'package:star_lock/talk/startChart/exception/start_chart_message_exception.dart';
|
||||||
import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/heartbeat_response.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handler_factory.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/login_response.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/handle/other/talk_data_repository.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/ble_message.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/gateway_transfer.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/remote_unlock.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/talk_accept.pbserver.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/talk_data.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/talk_expect.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/talk_hangup.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/talk_ping.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/talk_push.pbserver.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/talk_receiver_transfer.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/talk_reject.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/talk_request.pb.dart';
|
|
||||||
|
|
||||||
class ScpMessage {
|
class ScpMessage {
|
||||||
/// 分包缓冲区
|
|
||||||
// 存储每个 messageId 对应的分包数据
|
|
||||||
static Map<int, List<List<int>>> _packetBuffer = {};
|
|
||||||
|
|
||||||
ScpMessage({
|
ScpMessage({
|
||||||
this.ProtocolFlag,
|
this.ProtocolFlag,
|
||||||
this.MessageType,
|
this.MessageType,
|
||||||
@ -167,15 +146,17 @@ class ScpMessage {
|
|||||||
return bytesToHexString;
|
return bytesToHexString;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScpMessage deserialize(List<int> bytes) {
|
static ScpMessage deserialize(Uint8List bytes) {
|
||||||
final message = ScpMessage();
|
final message = ScpMessage();
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
// Convert byte array to hex string with zero padding and without spaces
|
|
||||||
String hexString =
|
|
||||||
bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
|
|
||||||
|
|
||||||
// Log the hex string
|
// String hexString =
|
||||||
_log(text: '原始字节数组: $hexString');
|
// bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
|
||||||
|
// // _log(text: 'result bytes hex: ${hexString}');
|
||||||
|
// _log(
|
||||||
|
// text:
|
||||||
|
// '\n result bytes hex: ${hexString} \n payload hex: ${hexString.substring(210)}');
|
||||||
|
|
||||||
// ProtocolFlag (4 bytes)
|
// ProtocolFlag (4 bytes)
|
||||||
if (bytes.length - offset >= 4) {
|
if (bytes.length - offset >= 4) {
|
||||||
message.ProtocolFlag = utf8.decode(bytes.sublist(offset, offset + 4));
|
message.ProtocolFlag = utf8.decode(bytes.sublist(offset, offset + 4));
|
||||||
@ -276,9 +257,6 @@ class ScpMessage {
|
|||||||
spTotal: message.SpTotal,
|
spTotal: message.SpTotal,
|
||||||
messageId: message.MessageId,
|
messageId: message.MessageId,
|
||||||
);
|
);
|
||||||
// if (message.Payload != null && message.Payload is List<int>) {
|
|
||||||
// message.PayloadLength = message.Payload.length;
|
|
||||||
// }
|
|
||||||
} else {
|
} else {
|
||||||
throw FormatException("Invalid Payload or PayloadLength");
|
throw FormatException("Invalid Payload or PayloadLength");
|
||||||
}
|
}
|
||||||
@ -298,203 +276,23 @@ class ScpMessage {
|
|||||||
int? messageId,
|
int? messageId,
|
||||||
}) {
|
}) {
|
||||||
try {
|
try {
|
||||||
switch (payloadType) {
|
// 构造工厂
|
||||||
case PayloadTypeConstant.goOnline:
|
final ScpMessageHandler handler =
|
||||||
// 上线
|
ScpMessageHandlerFactory.createHandler(payloadType);
|
||||||
LoginResponse loginResp = LoginResponse.fromBytes(byte);
|
// 处理荷载信息并返回
|
||||||
return loginResp;
|
final payload = handler.deserializePayload(
|
||||||
case PayloadTypeConstant.heartbeat:
|
payloadType: payloadType,
|
||||||
// 心跳
|
messageType: messageType,
|
||||||
HeartbeatResponse heartbeatResponse =
|
byte: byte,
|
||||||
HeartbeatResponse.fromBytes(byte);
|
offset: offset,
|
||||||
return heartbeatResponse;
|
PayloadLength: PayloadLength,
|
||||||
case PayloadTypeConstant.echoTest:
|
spTotal: spTotal,
|
||||||
// 回声测试
|
spIndex: spIndex,
|
||||||
if (spTotal != null &&
|
messageId: messageId,
|
||||||
spTotal > 1 &&
|
);
|
||||||
messageId != null &&
|
return payload;
|
||||||
spIndex != null) {
|
|
||||||
// 分包处理
|
|
||||||
return _handleFragmentedPayload(
|
|
||||||
messageId: messageId,
|
|
||||||
spTotal: spTotal,
|
|
||||||
spIndex: spIndex,
|
|
||||||
byte: byte,
|
|
||||||
payloadType: payloadType,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// 如果 spTotal 为 1 或者没有分包信息,直接处理 byte 数据
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.gatewayReset:
|
|
||||||
// 初始化网关
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GatewayResetResp gatewayResetResp =
|
|
||||||
GatewayResetResp.fromBuffer(byte);
|
|
||||||
return gatewayResetResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.Req) {
|
|
||||||
final GatewayResetReq gatewayResetReq =
|
|
||||||
GatewayResetReq.fromBuffer(byte);
|
|
||||||
return gatewayResetReq;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.callRequest:
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
|
||||||
return genericResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.Req) {
|
|
||||||
final TalkReq talkReq = TalkReq.fromBuffer(byte);
|
|
||||||
return talkReq;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.talkAccept:
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
|
||||||
return genericResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.Req) {
|
|
||||||
final TalkAcceptReq talkAccept = TalkAcceptReq.fromBuffer(byte);
|
|
||||||
return talkAccept;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.gatewayTransfer:
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
|
||||||
return genericResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.Req) {
|
|
||||||
final GatewayTransferReq gatewayTransferReq =
|
|
||||||
GatewayTransferReq.fromBuffer(byte);
|
|
||||||
return gatewayTransferReq;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.blePassthrough:
|
|
||||||
final BleResp bleResp = BleResp.fromBuffer(byte);
|
|
||||||
return bleResp;
|
|
||||||
case PayloadTypeConstant.remoteUnlock:
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
|
||||||
return genericResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.Req) {
|
|
||||||
final RemoteUnlockResp remoteUnlockResp =
|
|
||||||
RemoteUnlockResp.fromBuffer(byte);
|
|
||||||
return remoteUnlockResp;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.talkReceiverTransfer:
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
|
||||||
return genericResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.Req) {
|
|
||||||
final TalkReceiverTransfer talkReceiverTransfer =
|
|
||||||
TalkReceiverTransfer.fromBuffer(byte);
|
|
||||||
return talkReceiverTransfer;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.talkPush:
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
|
||||||
return genericResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.Req) {
|
|
||||||
final TalkPush talkPush = TalkPush.fromBuffer(byte);
|
|
||||||
return talkPush;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.talkReject:
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
|
||||||
return genericResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.Req) {
|
|
||||||
final TalkReject talkReject = TalkReject.fromBuffer(byte);
|
|
||||||
return talkReject;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.talkPing:
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
|
||||||
return genericResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.Req) {
|
|
||||||
final TalkPing talkPing = TalkPing.fromBuffer(byte);
|
|
||||||
return talkPing;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.talkExpect:
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
|
||||||
return genericResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.Req) {
|
|
||||||
final TalkExpect talkExpect = TalkExpect.fromBuffer(byte);
|
|
||||||
return talkExpect;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.talkData:
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
|
||||||
return genericResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.RealTimeData) {
|
|
||||||
// 回声测试
|
|
||||||
if (spTotal != null &&
|
|
||||||
spTotal > 1 &&
|
|
||||||
messageId != null &&
|
|
||||||
spIndex != null) {
|
|
||||||
// 分包处理
|
|
||||||
return _handleFragmentedPayload(
|
|
||||||
messageId: messageId,
|
|
||||||
spTotal: spTotal,
|
|
||||||
spIndex: spIndex,
|
|
||||||
byte: byte,
|
|
||||||
payloadType: payloadType,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// 没有分包直接解析
|
|
||||||
final TalkData talkData = TalkData.fromBuffer(byte);
|
|
||||||
return talkData;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
case PayloadTypeConstant.talkHangup:
|
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
|
||||||
return genericResp;
|
|
||||||
} else if (messageType == MessageTypeConstant.RealTimeData) {
|
|
||||||
final TalkHangup talkHangup = TalkHangup.fromBuffer(byte);
|
|
||||||
return talkHangup;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
print('❌未知的payloadType类型,按照字符串解析');
|
|
||||||
String payload = utf8.decode(byte);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
} catch (e, stackTrace) {
|
} catch (e, stackTrace) {
|
||||||
// 打印异常信息
|
throw StartChartMessageException('❌反序列化udp数据时遇到错误----》$e \n$stackTrace');
|
||||||
_log(text: '❌反序列化udp数据时遇到错误----》$e');
|
|
||||||
// 打印堆栈跟踪信息
|
|
||||||
_log(text: '堆栈跟踪:\n$stackTrace');
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,49 +313,4 @@ class ScpMessage {
|
|||||||
static void _log({required String text}) {
|
static void _log({required String text}) {
|
||||||
AppLog.log('=====${text}');
|
AppLog.log('=====${text}');
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 处理分包逻辑
|
|
||||||
/// 如果没有收到所有包则返回null
|
|
||||||
static dynamic _handleFragmentedPayload({
|
|
||||||
required int messageId,
|
|
||||||
required int spTotal,
|
|
||||||
required int spIndex,
|
|
||||||
required List<int> byte,
|
|
||||||
required int payloadType,
|
|
||||||
}) {
|
|
||||||
// 初始化分包列表
|
|
||||||
if (!_packetBuffer.containsKey(messageId)) {
|
|
||||||
_packetBuffer[messageId] = List.filled(spTotal, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查分包索引是否在合法范围内
|
|
||||||
if (spIndex < 1 || spIndex > spTotal) {
|
|
||||||
print('Invalid spIndex: $spIndex for messageId: $messageId');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 存储当前分包
|
|
||||||
_packetBuffer[messageId]![spIndex - 1] = byte;
|
|
||||||
|
|
||||||
// 检查是否接收到所有分包
|
|
||||||
if (_packetBuffer[messageId]!.every((packet) => packet.isNotEmpty)) {
|
|
||||||
// 重组所有分包
|
|
||||||
List<int> completePayload = _packetBuffer[messageId]!.expand((packet) => packet).toList();
|
|
||||||
|
|
||||||
// 清除已重组的分包数据
|
|
||||||
_packetBuffer.remove(messageId);
|
|
||||||
|
|
||||||
// 解析完整的 payload
|
|
||||||
if (payloadType == PayloadTypeConstant.talkData) {
|
|
||||||
final TalkData talkData = TalkData.fromBuffer(completePayload);
|
|
||||||
return talkData;
|
|
||||||
} else {
|
|
||||||
String payload = utf8.decode(completePayload);
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 如果分包尚未接收完全,返回 null 或其他指示符
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
import 'package:star_lock/talk/startChart/start_chart_talk_status.dart';
|
|
||||||
|
|
||||||
class TalkStatusChangeEvent {
|
|
||||||
final TalkStatus oldStatus;
|
|
||||||
final TalkStatus newStatus;
|
|
||||||
|
|
||||||
TalkStatusChangeEvent(this.oldStatus, this.newStatus);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return "TalkStatusChangeEvent: ${oldStatus.name} -> ${newStatus.name}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
class StartChartMessageException implements Exception {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
StartChartMessageException(this.message);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'StartChartMessageException{message: $message}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
class StartChartTalkStatusException implements Exception {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
StartChartTalkStatusException(this.message);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'StartChartTalkStatusException{message: $message}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/appRouters.dart';
|
import 'package:star_lock/appRouters.dart';
|
||||||
@ -28,4 +30,19 @@ class UdpBlePassThroughHandler extends ScpMessageBaseHandle
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {}
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
final BleResp bleResp = BleResp();
|
||||||
|
bleResp.mergeFromBuffer(byte);
|
||||||
|
return bleResp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
@ -10,15 +13,11 @@ import '../../start_chart_manage.dart';
|
|||||||
class UdpEchoTestHandler extends ScpMessageBaseHandle
|
class UdpEchoTestHandler extends ScpMessageBaseHandle
|
||||||
implements ScpMessageHandler {
|
implements ScpMessageHandler {
|
||||||
@override
|
@override
|
||||||
void handleReq(ScpMessage scpMessage) {
|
void handleReq(ScpMessage scpMessage) {}
|
||||||
// TODO: 收到回声测试请求
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleResp(ScpMessage scpMessage) {
|
void handleResp(ScpMessage scpMessage) {
|
||||||
// TODO: 收到回声测试回复
|
|
||||||
final List<int> payload = scpMessage.Payload;
|
final List<int> payload = scpMessage.Payload;
|
||||||
|
|
||||||
if (payload is String) {
|
if (payload is String) {
|
||||||
EasyLoading.showToast(scpMessage.Payload, duration: 2000.milliseconds);
|
EasyLoading.showToast(scpMessage.Payload, duration: 2000.milliseconds);
|
||||||
} else {
|
} else {
|
||||||
@ -32,4 +31,34 @@ class UdpEchoTestHandler extends ScpMessageBaseHandle
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {}
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
// 回声测试
|
||||||
|
if (spTotal != null &&
|
||||||
|
spTotal > 1 &&
|
||||||
|
messageId != null &&
|
||||||
|
spIndex != null) {
|
||||||
|
// 分包处理
|
||||||
|
return handleFragmentedPayload(
|
||||||
|
messageId: messageId,
|
||||||
|
spTotal: spTotal,
|
||||||
|
spIndex: spIndex,
|
||||||
|
byte: byte,
|
||||||
|
payloadType: payloadType,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// 如果 spTotal 为 1 或者没有分包信息,直接处理 byte 数据
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
@ -7,17 +11,14 @@ import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
|||||||
|
|
||||||
import '../../start_chart_manage.dart';
|
import '../../start_chart_manage.dart';
|
||||||
|
|
||||||
class UdpGateWayResetHandler extends ScpMessageBaseHandle implements ScpMessageHandler {
|
class UdpGateWayResetHandler extends ScpMessageBaseHandle
|
||||||
|
implements ScpMessageHandler {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleReq(ScpMessage scpMessage) {
|
void handleReq(ScpMessage scpMessage) {
|
||||||
// TODO: 收到网关初始化请求
|
// TODO: 收到网关初始化请求
|
||||||
final GatewayResetResp gatewayResetResp = scpMessage.Payload;
|
final GatewayResetResp gatewayResetResp = scpMessage.Payload;
|
||||||
final status = gatewayResetResp.status;
|
final status = gatewayResetResp.status;
|
||||||
if (status != null && status == GatewayResetResp_StatusE.OK) {
|
if (status != null && status == GatewayResetResp_StatusE.OK) {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -26,12 +27,33 @@ class UdpGateWayResetHandler extends ScpMessageBaseHandle implements ScpMessageH
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleInvalidReq(ScpMessage scpMessage) {
|
void handleInvalidReq(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
// 初始化网关
|
||||||
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
|
final GatewayResetResp gatewayResetResp =
|
||||||
|
GatewayResetResp.fromBuffer(byte);
|
||||||
|
return gatewayResetResp;
|
||||||
|
} else if (messageType == MessageTypeConstant.Req) {
|
||||||
|
final GatewayResetReq gatewayResetReq = GatewayResetReq();
|
||||||
|
gatewayResetReq.mergeFromBuffer(byte);
|
||||||
|
return gatewayResetReq;
|
||||||
|
} else {
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/proto/gateway_transfer.pb.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||||
|
|
||||||
import '../../start_chart_manage.dart';
|
import '../../start_chart_manage.dart';
|
||||||
@ -29,4 +34,28 @@ class UdpGateWayTransferHandler extends ScpMessageBaseHandle
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {}
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
|
final GenericResp genericResp = GenericResp();
|
||||||
|
genericResp.mergeFromBuffer(byte);
|
||||||
|
return genericResp;
|
||||||
|
} else if (messageType == MessageTypeConstant.Req) {
|
||||||
|
final GatewayTransferReq gatewayTransferReq = GatewayTransferReq();
|
||||||
|
gatewayTransferReq.mergeFromBuffer(byte);
|
||||||
|
return gatewayTransferReq;
|
||||||
|
} else {
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart';
|
import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/login_response.dart';
|
import 'package:star_lock/talk/startChart/entity/login_response.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
@ -35,4 +37,19 @@ class UdpGoOnlineHandler extends ScpMessageBaseHandle
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {}
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
// 上线
|
||||||
|
LoginResponse loginResp = LoginResponse.fromBytes(byte);
|
||||||
|
return loginResp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart';
|
import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/heartbeat_response.dart';
|
import 'package:star_lock/talk/startChart/entity/heartbeat_response.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/login_response.dart';
|
import 'package:star_lock/talk/startChart/entity/login_response.dart';
|
||||||
@ -39,4 +41,19 @@ class UdpHeartBeatHandler extends ScpMessageBaseHandle
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {}
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
// 心跳
|
||||||
|
HeartbeatResponse heartbeatResponse = HeartbeatResponse.fromBytes(byte);
|
||||||
|
return heartbeatResponse;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/appRouters.dart';
|
import 'package:star_lock/appRouters.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
@ -32,4 +36,20 @@ class UdpRemoteUnLockHandler extends ScpMessageBaseHandle implements ScpMessageH
|
|||||||
void handleRealTimeData(ScpMessage scpMessage) {
|
void handleRealTimeData(ScpMessage scpMessage) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload({required int payloadType, required int messageType, required List<int> byte, int? offset, int? PayloadLength, int? spTotal, int? spIndex, int? messageId}) {
|
||||||
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
|
final GenericResp genericResp = GenericResp();
|
||||||
|
genericResp.mergeFromBuffer(byte);
|
||||||
|
return genericResp;
|
||||||
|
} else if (messageType == MessageTypeConstant.Req) {
|
||||||
|
final RemoteUnlockResp remoteUnlockResp = RemoteUnlockResp();
|
||||||
|
remoteUnlockResp.mergeFromBuffer(byte);
|
||||||
|
return remoteUnlockResp;
|
||||||
|
} else {
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,16 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
|
import 'package:flutter_pcm_sound/flutter_pcm_sound.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/proto/talk_accept.pb.dart';
|
||||||
|
|
||||||
import '../../start_chart_manage.dart';
|
import '../../start_chart_manage.dart';
|
||||||
|
|
||||||
@ -12,22 +18,16 @@ class UdpTalkAcceptHandler extends ScpMessageBaseHandle
|
|||||||
implements ScpMessageHandler {
|
implements ScpMessageHandler {
|
||||||
@override
|
@override
|
||||||
void handleReq(ScpMessage scpMessage) {
|
void handleReq(ScpMessage scpMessage) {
|
||||||
print('收到同意接听请求');
|
|
||||||
// 回复同意接听消息
|
// 回复同意接听消息
|
||||||
startChartManage.sendGenericRespSuccessMessage(
|
replySuccessMessage(scpMessage);
|
||||||
ToPeerId: scpMessage.FromPeerId!,
|
|
||||||
FromPeerId: scpMessage.ToPeerId!,
|
|
||||||
PayloadType: scpMessage.PayloadType!,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleResp(ScpMessage scpMessage) {
|
void handleResp(ScpMessage scpMessage) {
|
||||||
// 收到同意接听回复
|
// 收到同意接听回复
|
||||||
final GenericResp genericResp = scpMessage.Payload;
|
final GenericResp genericResp = scpMessage.Payload;
|
||||||
if (checkGenericRespSuccess(genericResp)) {
|
if (checkGenericRespSuccess(genericResp)) {
|
||||||
// 延迟2秒后启动监听
|
Future.delayed(Duration(seconds: 1), () {
|
||||||
Future.delayed(Duration(seconds: 4), () {
|
|
||||||
// 启动通话保持定时器
|
// 启动通话保持定时器
|
||||||
_handleStartTalkPing();
|
_handleStartTalkPing();
|
||||||
// 启动发送预期数据请求
|
// 启动发送预期数据请求
|
||||||
@ -37,9 +37,11 @@ class UdpTalkAcceptHandler extends ScpMessageBaseHandle
|
|||||||
});
|
});
|
||||||
// 停止播放铃声
|
// 停止播放铃声
|
||||||
stopRingtone();
|
stopRingtone();
|
||||||
// 设置状态为接听中
|
// 设置状态为接听成功
|
||||||
talkStatus.setAnsweredSuccessfully();
|
talkStatus.setAnsweredSuccessfully();
|
||||||
talkStatus.setDuringCall();
|
// 同意接听之后,停止对讲请求超时监听定时器
|
||||||
|
talkeRequestOverTimeTimerManager.receiveMessage();
|
||||||
|
talkeRequestOverTimeTimerManager.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +51,31 @@ class UdpTalkAcceptHandler extends ScpMessageBaseHandle
|
|||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {}
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
// 启动通话保持
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
|
final GenericResp genericResp = GenericResp();
|
||||||
|
genericResp.mergeFromBuffer(byte);
|
||||||
|
return genericResp;
|
||||||
|
} else if (messageType == MessageTypeConstant.Req) {
|
||||||
|
final TalkAcceptReq talkAccept = TalkAcceptReq();
|
||||||
|
talkAccept.mergeFromBuffer(byte);
|
||||||
|
return talkAccept;
|
||||||
|
} else {
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动通话保持,判断x秒内是否收到通话保持
|
||||||
void _handleStartTalkPing() {
|
void _handleStartTalkPing() {
|
||||||
// 启动通话保持
|
// 启动通话保持
|
||||||
startChartManage.startTalkPingMessageTimer();
|
startChartManage.startTalkPingMessageTimer();
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:star_lock/app_settings/app_settings.dart';
|
||||||
|
import 'package:star_lock/talk/call/g711.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
@ -23,16 +29,61 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {
|
void handleRealTimeData(ScpMessage scpMessage) {
|
||||||
|
// 收到数据后调用更新,防止定时器超时
|
||||||
|
talkDataOverTimeTimerManager.receiveMessage();
|
||||||
if (scpMessage.Payload != null) {
|
if (scpMessage.Payload != null) {
|
||||||
final TalkData talkData = scpMessage.Payload;
|
final TalkData talkData = scpMessage.Payload;
|
||||||
// 处理音视频数据
|
// 处理音视频数据
|
||||||
_handleTalkData(talkData: talkData);
|
_handleTalkData(talkData: talkData);
|
||||||
print('talkData:$talkData');
|
|
||||||
// 收到数据后调用更新,防止定时器超时
|
|
||||||
talkDataOverTimeTimerManager.receiveMessage();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String bufferToHexString(List<int> buffer) {
|
||||||
|
return buffer.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
// AppLog.log(
|
||||||
|
// '没有组包之前的每一个包的数据:${byte.length} messageId:$messageId spTotal:$spTotal spIndex:$spIndex PayloadLength:$PayloadLength,byte:${bufferToHexString(byte)}');
|
||||||
|
if (messageType == MessageTypeConstant.RealTimeData) {
|
||||||
|
// 回声测试
|
||||||
|
if (spTotal != null &&
|
||||||
|
spTotal > 1 &&
|
||||||
|
messageId != null &&
|
||||||
|
spIndex != null) {
|
||||||
|
// 分包处理
|
||||||
|
return handleFragmentedPayload(
|
||||||
|
messageId: messageId,
|
||||||
|
spTotal: spTotal,
|
||||||
|
spIndex: spIndex,
|
||||||
|
byte: byte,
|
||||||
|
payloadType: payloadType,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// 没有分包直接解析
|
||||||
|
final TalkData talkData = TalkData();
|
||||||
|
talkData.mergeFromBuffer(byte);
|
||||||
|
return talkData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String listToHexString(List<int> intList) {
|
||||||
|
// 将整数列表转换为十六进制字符串列表
|
||||||
|
List<String> hexList = intList.map((num) => num.toRadixString(16)).toList();
|
||||||
|
// 将十六进制字符串列表连接成一个字符串,没有空格
|
||||||
|
return hexList.join('');
|
||||||
|
}
|
||||||
|
|
||||||
void _handleTalkData({required TalkData talkData}) {
|
void _handleTalkData({required TalkData talkData}) {
|
||||||
if (talkData == null) return;
|
if (talkData == null) return;
|
||||||
final contentType = talkData.contentType;
|
final contentType = talkData.contentType;
|
||||||
@ -58,8 +109,65 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 处理图片数据
|
/// 处理图片数据
|
||||||
void _handleVideoImage(TalkData talkData) {}
|
void _handleVideoImage(TalkData talkData) async {
|
||||||
|
final List<Uint8List> processCompletePayload =
|
||||||
|
await _processCompletePayload(Uint8List.fromList(talkData.content));
|
||||||
|
// AppLog.log('得到完整的帧:${processCompletePayload.length}'); // 循环发送每一帧的数据
|
||||||
|
processCompletePayload.forEach((element) {
|
||||||
|
talkData.content = element;
|
||||||
|
talkDataRepository.addTalkData(talkData);
|
||||||
|
// 设置状态为接听中
|
||||||
|
talkStatus.setDuringCall();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// 处理g711音频数据
|
/// 处理g711音频数据
|
||||||
void _handleVideoG711(TalkData talkData) {}
|
void _handleVideoG711(TalkData talkData) {
|
||||||
|
try {
|
||||||
|
final g711Data = talkData.content;
|
||||||
|
// 转pcm数据
|
||||||
|
List<int> pcmBytes = G711().convertList(g711Data);
|
||||||
|
talkData.content = pcmBytes;
|
||||||
|
talkDataRepository.addTalkData(talkData);
|
||||||
|
// 设置状态为接听中
|
||||||
|
talkStatus.setDuringCall();
|
||||||
|
} catch (e) {
|
||||||
|
print('Error decoding G.711 to PCM: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<Uint8List>> _processCompletePayload(Uint8List payload) async {
|
||||||
|
// 存储找到的所有完整帧
|
||||||
|
List<Uint8List> frames = [];
|
||||||
|
|
||||||
|
// 寻找完整帧 (0xFFD8 开始, 0xFFD9 结束)
|
||||||
|
int startIdx = 0;
|
||||||
|
while (startIdx < payload.length - 1) {
|
||||||
|
// 找到帧的起始标志 0xFFD8
|
||||||
|
startIdx = payload.indexOf(0xFF, startIdx);
|
||||||
|
if (startIdx == -1 || startIdx + 1 >= payload.length) break;
|
||||||
|
if (payload[startIdx + 1] == 0xD8) {
|
||||||
|
// 找到帧的起始标志 0xFFD8
|
||||||
|
int endIdx = startIdx + 2;
|
||||||
|
while (endIdx < payload.length - 1) {
|
||||||
|
endIdx = payload.indexOf(0xFF, endIdx);
|
||||||
|
if (endIdx == -1 || endIdx + 1 >= payload.length) break;
|
||||||
|
if (payload[endIdx + 1] == 0xD9) {
|
||||||
|
// 找到帧的结束标志 0xFFD9
|
||||||
|
Uint8List frame = payload.sublist(startIdx, endIdx + 2);
|
||||||
|
frames.add(frame);
|
||||||
|
startIdx = endIdx + 2; // 继续寻找下一个帧
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
endIdx += 1; // 继续寻找结束标志
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
startIdx += 1; // 继续寻找下一个起始标志
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回找到的所有完整帧
|
||||||
|
return frames;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
|
import 'dart:convert';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
@ -18,7 +20,7 @@ class UdpTalkExpectHandler extends ScpMessageBaseHandle
|
|||||||
@override
|
@override
|
||||||
void handleReq(ScpMessage scpMessage) {
|
void handleReq(ScpMessage scpMessage) {
|
||||||
// 收到预期音视频数据请求
|
// 收到预期音视频数据请求
|
||||||
final TalkExpect talkExpect = scpMessage.Payload;
|
final TalkExpectReq talkExpect = scpMessage.Payload;
|
||||||
print('收到预期音视频数据请求:$talkExpect');
|
print('收到预期音视频数据请求:$talkExpect');
|
||||||
|
|
||||||
// 回复请求
|
// 回复请求
|
||||||
@ -42,4 +44,31 @@ class UdpTalkExpectHandler extends ScpMessageBaseHandle
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {}
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
|
// final TalkExpectResp talkExpectResp = TalkExpectResp();
|
||||||
|
// talkExpectResp.mergeFromBuffer(byte);
|
||||||
|
// return talkExpectResp;
|
||||||
|
final GenericResp genericResp = GenericResp();
|
||||||
|
genericResp.mergeFromBuffer(byte);
|
||||||
|
return genericResp;
|
||||||
|
} else if (messageType == MessageTypeConstant.Req) {
|
||||||
|
final TalkExpectReq talkExpect = TalkExpectReq();
|
||||||
|
talkExpect.mergeFromBuffer(byte);
|
||||||
|
return talkExpect;
|
||||||
|
} else {
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'dart:convert';
|
||||||
import 'package:get/get.dart';
|
|
||||||
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/talk_status.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
|
||||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/proto/talk_hangup.pb.dart';
|
||||||
|
|
||||||
|
|
||||||
import '../../start_chart_manage.dart';
|
import '../../start_chart_manage.dart';
|
||||||
|
|
||||||
@ -12,8 +16,10 @@ class UdpTalkHangUpHandler extends ScpMessageBaseHandle
|
|||||||
implements ScpMessageHandler {
|
implements ScpMessageHandler {
|
||||||
@override
|
@override
|
||||||
void handleReq(ScpMessage scpMessage) {
|
void handleReq(ScpMessage scpMessage) {
|
||||||
// 通话中挂断请求
|
if (talkStatus.status != TalkStatus.duringCall) {
|
||||||
print('收到通话中挂断请求');
|
// 如果不是接听中,不处理通话中挂断请求
|
||||||
|
return;
|
||||||
|
}
|
||||||
startChartManage.sendGenericRespSuccessMessage(
|
startChartManage.sendGenericRespSuccessMessage(
|
||||||
ToPeerId: scpMessage.FromPeerId!,
|
ToPeerId: scpMessage.FromPeerId!,
|
||||||
FromPeerId: scpMessage.ToPeerId!,
|
FromPeerId: scpMessage.ToPeerId!,
|
||||||
@ -23,28 +29,49 @@ class UdpTalkHangUpHandler extends ScpMessageBaseHandle
|
|||||||
startChartManage.stopTalkPingMessageTimer();
|
startChartManage.stopTalkPingMessageTimer();
|
||||||
startChartManage.stopTalkExpectMessageTimer();
|
startChartManage.stopTalkExpectMessageTimer();
|
||||||
talkStatus.setHangingUpDuring();
|
talkStatus.setHangingUpDuring();
|
||||||
talkStatus.setEnd();
|
|
||||||
stopRingtone();
|
stopRingtone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleResp(ScpMessage scpMessage) {
|
void handleResp(ScpMessage scpMessage) {
|
||||||
print('收到通话中挂断回复');
|
|
||||||
// 停止发送通话保持的命令
|
// 停止发送通话保持的命令
|
||||||
startChartManage.stopTalkPingMessageTimer();
|
startChartManage.stopTalkPingMessageTimer();
|
||||||
startChartManage.stopTalkExpectMessageTimer();
|
startChartManage.stopTalkExpectMessageTimer();
|
||||||
talkStatus.setHangingUpDuring();
|
talkStatus.setHangingUpDuring();
|
||||||
talkStatus.setEnd();
|
|
||||||
stopRingtone();
|
stopRingtone();
|
||||||
|
|
||||||
|
// 拒绝接听之后,停止对讲请求超时监听定时器
|
||||||
|
talkeRequestOverTimeTimerManager.receiveMessage();
|
||||||
|
talkeRequestOverTimeTimerManager.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleInvalidReq(ScpMessage scpMessage) {
|
void handleInvalidReq(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
|
final GenericResp genericResp = GenericResp();
|
||||||
|
genericResp.mergeFromBuffer(byte);
|
||||||
|
return genericResp;
|
||||||
|
} else if (messageType == MessageTypeConstant.RealTimeData) {
|
||||||
|
final TalkHangup talkHangup = TalkHangup();
|
||||||
|
talkHangup.mergeFromBuffer(byte);
|
||||||
|
return talkHangup;
|
||||||
|
} else {
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,13 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
|
|
||||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/proto/talk_ping.pb.dart';
|
||||||
|
|
||||||
class UdpTalkPingHandler extends ScpMessageBaseHandle
|
class UdpTalkPingHandler extends ScpMessageBaseHandle
|
||||||
implements ScpMessageHandler {
|
implements ScpMessageHandler {
|
||||||
@ -26,4 +31,28 @@ class UdpTalkPingHandler extends ScpMessageBaseHandle
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {}
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
|
final GenericResp genericResp = GenericResp();
|
||||||
|
genericResp.mergeFromBuffer(byte);
|
||||||
|
return genericResp;
|
||||||
|
} else if (messageType == MessageTypeConstant.Req) {
|
||||||
|
final TalkPing talkPing = TalkPing();
|
||||||
|
talkPing.mergeFromBuffer(byte);
|
||||||
|
return talkPing;
|
||||||
|
} else {
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/proto/talk_push.pb.dart';
|
||||||
|
|
||||||
import '../../start_chart_manage.dart';
|
import '../../start_chart_manage.dart';
|
||||||
|
|
||||||
@ -27,4 +32,28 @@ class UdpTalkPushHandler extends ScpMessageBaseHandle
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {}
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
|
final GenericResp genericResp = GenericResp();
|
||||||
|
genericResp.mergeFromBuffer(byte);
|
||||||
|
return genericResp;
|
||||||
|
} else if (messageType == MessageTypeConstant.Req) {
|
||||||
|
final TalkPush talkPush = TalkPush();
|
||||||
|
talkPush.mergeFromBuffer(byte);
|
||||||
|
return talkPush;
|
||||||
|
} else {
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,20 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/proto/talk_receiver_transfer.pb.dart';
|
||||||
|
|
||||||
import '../../start_chart_manage.dart';
|
import '../../start_chart_manage.dart';
|
||||||
|
|
||||||
class UdpTalkReceiverTransferHandler extends ScpMessageBaseHandle
|
class UdpTalkReceiverTransferHandler extends ScpMessageBaseHandle
|
||||||
implements ScpMessageHandler {
|
implements ScpMessageHandler {
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleReq(ScpMessage scpMessage) {
|
void handleReq(ScpMessage scpMessage) {
|
||||||
// TODO: 对讲接听者转移请求
|
// TODO: 对讲接听者转移请求
|
||||||
@ -23,12 +26,32 @@ class UdpTalkReceiverTransferHandler extends ScpMessageBaseHandle
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleInvalidReq(ScpMessage scpMessage) {
|
void handleInvalidReq(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
|
final GenericResp genericResp = GenericResp();
|
||||||
|
genericResp.mergeFromBuffer(byte);
|
||||||
|
return genericResp;
|
||||||
|
} else if (messageType == MessageTypeConstant.Req) {
|
||||||
|
final TalkReceiverTransfer talkReceiverTransfer = TalkReceiverTransfer();
|
||||||
|
talkReceiverTransfer.mergeFromBuffer(byte);
|
||||||
|
return talkReceiverTransfer;
|
||||||
|
} else {
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/proto/talk_reject.pb.dart';
|
||||||
|
|
||||||
import '../../start_chart_manage.dart';
|
import '../../start_chart_manage.dart';
|
||||||
|
|
||||||
@ -13,35 +18,54 @@ class UdpTalkRejectHandler extends ScpMessageBaseHandle
|
|||||||
@override
|
@override
|
||||||
void handleReq(ScpMessage scpMessage) {
|
void handleReq(ScpMessage scpMessage) {
|
||||||
// 收到接听拒绝请求
|
// 收到接听拒绝请求
|
||||||
startChartManage.sendGenericRespSuccessMessage(
|
// 回复成功消息
|
||||||
ToPeerId: scpMessage.FromPeerId!,
|
replySuccessMessage(scpMessage);
|
||||||
FromPeerId: scpMessage.ToPeerId!,
|
// 停止铃声
|
||||||
PayloadType: scpMessage.PayloadType!,
|
|
||||||
);
|
|
||||||
startChartManage.stopTalkPingMessageTimer();
|
|
||||||
startChartManage.stopTalkExpectMessageTimer();
|
|
||||||
talkStatus.setRejected();
|
|
||||||
stopRingtone();
|
stopRingtone();
|
||||||
talkStatus.setEnd();
|
// 收到接听拒绝回复
|
||||||
|
talkStatus.setRejected();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleResp(ScpMessage scpMessage) {
|
void handleResp(ScpMessage scpMessage) {
|
||||||
// 收到接听拒绝回复
|
|
||||||
talkStatus.setRejected();
|
|
||||||
startChartManage.stopTalkPingMessageTimer();
|
startChartManage.stopTalkPingMessageTimer();
|
||||||
startChartManage.stopTalkExpectMessageTimer();
|
startChartManage.stopTalkExpectMessageTimer();
|
||||||
stopRingtone();
|
stopRingtone();
|
||||||
talkStatus.setEnd();
|
|
||||||
|
|
||||||
|
// 拒绝接听之后,停止对讲请求超时监听定时器
|
||||||
|
talkeRequestOverTimeTimerManager.receiveMessage();
|
||||||
|
talkeRequestOverTimeTimerManager.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleInvalidReq(ScpMessage scpMessage) {
|
void handleInvalidReq(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void handleRealTimeData(ScpMessage scpMessage) {
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
|
final GenericResp genericResp = GenericResp();
|
||||||
|
genericResp.mergeFromBuffer(byte);
|
||||||
|
return genericResp;
|
||||||
|
} else if (messageType == MessageTypeConstant.Req) {
|
||||||
|
final TalkReject talkReject = TalkReject();
|
||||||
|
talkReject.mergeFromBuffer(byte);
|
||||||
|
return talkReject;
|
||||||
|
} else {
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +1,27 @@
|
|||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/appRouters.dart';
|
import 'package:star_lock/appRouters.dart';
|
||||||
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/talk_status.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||||
import 'package:star_lock/talk/startChart/proto/talk_request.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/talk_request.pb.dart';
|
||||||
import 'package:star_lock/tools/storage.dart';
|
|
||||||
|
|
||||||
import '../../start_chart_manage.dart';
|
|
||||||
|
|
||||||
class UdpTalkRequestHandler extends ScpMessageBaseHandle
|
class UdpTalkRequestHandler extends ScpMessageBaseHandle
|
||||||
implements ScpMessageHandler {
|
implements ScpMessageHandler {
|
||||||
@override
|
@override
|
||||||
void handleReq(ScpMessage scpMessage) {
|
void handleReq(ScpMessage scpMessage) {
|
||||||
|
if (talkStatus == TalkStatus.waitingAnswer) {
|
||||||
|
// 如果已经是等待接听了,就不在处理剩下的请求
|
||||||
|
return;
|
||||||
|
}
|
||||||
// 收到对讲请求
|
// 收到对讲请求
|
||||||
final TalkReq talkReq = scpMessage.Payload;
|
final TalkReq talkReq = scpMessage.Payload;
|
||||||
// 回复收到对讲成功的消息
|
// 回复收到对讲成功的消息
|
||||||
@ -29,6 +34,16 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle
|
|||||||
startChartManage.ToPeerId = scpMessage.FromPeerId!;
|
startChartManage.ToPeerId = scpMessage.FromPeerId!;
|
||||||
// 处理收到接听请求后的事件
|
// 处理收到接听请求后的事件
|
||||||
_talkRequestEvent(talkObjectName: talkReq.callerName);
|
_talkRequestEvent(talkObjectName: talkReq.callerName);
|
||||||
|
|
||||||
|
// 启动对讲请求超时定时器
|
||||||
|
talkeRequestOverTimeTimerManager.startTimer();
|
||||||
|
talkeRequestOverTimeTimerManager.setOnTimeout(() {
|
||||||
|
if (talkStatus.status == TalkStatus.waitingAnswer) {
|
||||||
|
// 超时未接听,发送挂断请求
|
||||||
|
startChartManage.sendTalkRejectMessage();
|
||||||
|
Get.back();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -52,9 +67,12 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle
|
|||||||
_showTalkRequestNotification(talkObjectName: talkObjectName);
|
_showTalkRequestNotification(talkObjectName: talkObjectName);
|
||||||
// 收到呼叫请求,跳转到接听页面
|
// 收到呼叫请求,跳转到接听页面
|
||||||
Get.toNamed(
|
Get.toNamed(
|
||||||
Routers.starChartPage,
|
Routers.starChartTalkView,
|
||||||
arguments: <String, String>{'lockId': '111'},
|
|
||||||
);
|
);
|
||||||
|
// 触发震动反馈
|
||||||
|
HapticFeedback.vibrate();
|
||||||
|
// 设置为等待接听状态
|
||||||
|
talkStatus.setWaitingAnswer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收到来电请求时进行本地通知
|
// 收到来电请求时进行本地通知
|
||||||
@ -77,4 +95,28 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle
|
|||||||
'${'收到来自'.tr}($talkObjectName)${'锁的呼叫'.tr}。', platformChannelSpecifics,
|
'${'收到来自'.tr}($talkObjectName)${'锁的呼叫'.tr}。', platformChannelSpecifics,
|
||||||
payload: 'item x');
|
payload: 'item x');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
|
final GenericResp genericResp = GenericResp();
|
||||||
|
genericResp.mergeFromBuffer(byte);
|
||||||
|
return genericResp;
|
||||||
|
} else if (messageType == MessageTypeConstant.Req) {
|
||||||
|
final TalkReq talkReq = TalkReq();
|
||||||
|
talkReq.mergeFromBuffer(byte);
|
||||||
|
return talkReq;
|
||||||
|
} else {
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:star_lock/app_settings/app_settings.dart';
|
import 'package:star_lock/app_settings/app_settings.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||||
@ -27,4 +29,17 @@ class UnKnowPayloadTypeHandler extends ScpMessageBaseHandle
|
|||||||
void handleRealTimeData(ScpMessage scpMessage) {
|
void handleRealTimeData(ScpMessage scpMessage) {
|
||||||
AppLog.log('❌未知的payloadType类型---》${scpMessage}');
|
AppLog.log('❌未知的payloadType类型---》${scpMessage}');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserializePayload(
|
||||||
|
{required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId}) {
|
||||||
|
AppLog.log('❌未知的payloadType类型---》');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,9 +12,6 @@ class OverTimeTimerManager {
|
|||||||
// 超时时间(以秒为单位),是 final 的,因此必须在构造函数中初始化
|
// 超时时间(以秒为单位),是 final 的,因此必须在构造函数中初始化
|
||||||
final int timeoutInSeconds;
|
final int timeoutInSeconds;
|
||||||
|
|
||||||
// 默认超时时间(以秒为单位)
|
|
||||||
static const int defaultTimeoutInSeconds = 5;
|
|
||||||
|
|
||||||
// 超时回调函数
|
// 超时回调函数
|
||||||
TimeoutCallback? _onTimeout;
|
TimeoutCallback? _onTimeout;
|
||||||
|
|
||||||
@ -24,7 +21,7 @@ class OverTimeTimerManager {
|
|||||||
_timer = Timer(Duration(seconds: timeoutInSeconds), () {
|
_timer = Timer(Duration(seconds: timeoutInSeconds), () {
|
||||||
// 超时回调方法
|
// 超时回调方法
|
||||||
_onTimeout?.call();
|
_onTimeout?.call();
|
||||||
// 清楚定时器
|
// 清除定时器
|
||||||
_cancelTimer();
|
_cancelTimer();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ class TalkDataRepository {
|
|||||||
Stream<TalkData> get talkDataStream => _talkDataStreamController.stream;
|
Stream<TalkData> get talkDataStream => _talkDataStreamController.stream;
|
||||||
|
|
||||||
// 提供一个方法来添加 TalkData 到 Stream
|
// 提供一个方法来添加 TalkData 到 Stream
|
||||||
void addTalkData(TalkData talkData) {
|
void addTalkData(TalkData talkData) async {
|
||||||
_talkDataStreamController.add(talkData);
|
_talkDataStreamController.add(talkData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,37 +1,58 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:audioplayers/audioplayers.dart';
|
import 'package:audioplayers/audioplayers.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
|
|
||||||
import 'package:star_lock/app_settings/app_settings.dart';
|
import 'package:star_lock/app_settings/app_settings.dart';
|
||||||
import 'package:star_lock/talk/other/audio_player_manager.dart';
|
import 'package:star_lock/talk/other/audio_player_manager.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/constant/udp_constant.dart';
|
import 'package:star_lock/talk/startChart/constant/udp_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/other/overtime_timer_manger.dart';
|
import 'package:star_lock/talk/startChart/handle/other/overtime_timer_manger.dart';
|
||||||
import 'package:star_lock/talk/startChart/handle/other/talk_data_repository.dart';
|
import 'package:star_lock/talk/startChart/handle/other/talk_data_repository.dart';
|
||||||
|
|
||||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||||
|
import 'package:star_lock/talk/startChart/proto/talk_data.pb.dart';
|
||||||
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
|
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
|
||||||
import 'package:star_lock/talk/startChart/start_chart_talk_status.dart';
|
import 'package:star_lock/talk/startChart/start_chart_talk_status.dart';
|
||||||
|
|
||||||
class ScpMessageBaseHandle {
|
class ScpMessageBaseHandle {
|
||||||
final startChartManage = StartChartManage();
|
final startChartManage = StartChartManage();
|
||||||
|
final List<int> _buffer = [];
|
||||||
|
|
||||||
|
/// 分包缓冲区
|
||||||
|
// 存储每个 messageId 对应的分包数据
|
||||||
|
static Map<String, List<List<int>>> _packetBuffer = {};
|
||||||
|
final Map<String, Timer> _packetTimers = {};
|
||||||
|
final Duration _timeoutDuration = Duration(seconds: 10); // 分包组包最大超时时间
|
||||||
|
|
||||||
// 通话数据流的单例流数据处理类
|
// 通话数据流的单例流数据处理类
|
||||||
final TalkDataRepository talkDataRepository = TalkDataRepository.instance;
|
final TalkDataRepository talkDataRepository = TalkDataRepository.instance;
|
||||||
|
|
||||||
|
// 获取 StartChartTalkStatus 的唯一实例
|
||||||
|
final StartChartTalkStatus talkStatus = StartChartTalkStatus.instance;
|
||||||
|
|
||||||
final audioManager = AudioPlayerManager();
|
final audioManager = AudioPlayerManager();
|
||||||
|
|
||||||
|
// 通话请求超时未处理监听定时器管理
|
||||||
|
final talkeRequestOverTimeTimerManager = OverTimeTimerManager(
|
||||||
|
timeoutInSeconds: 30,
|
||||||
|
);
|
||||||
|
|
||||||
// 通话保持超时监听定时器管理
|
// 通话保持超时监听定时器管理
|
||||||
final talkePingOverTimeTimerManager = OverTimeTimerManager(
|
final talkePingOverTimeTimerManager = OverTimeTimerManager(
|
||||||
timeoutInSeconds: 5,
|
timeoutInSeconds: 260,
|
||||||
);
|
);
|
||||||
|
|
||||||
// 通话数据超时定时器
|
// 通话数据超时定时器
|
||||||
final talkDataOverTimeTimerManager = OverTimeTimerManager(
|
final talkDataOverTimeTimerManager = OverTimeTimerManager(
|
||||||
timeoutInSeconds: 3,
|
timeoutInSeconds: 260,
|
||||||
);
|
);
|
||||||
|
|
||||||
// 回复成功消息
|
// 回复成功消息
|
||||||
void replySuccessMessage(ScpMessage scpMessage){
|
void replySuccessMessage(ScpMessage scpMessage) {
|
||||||
startChartManage.sendGenericRespSuccessMessage(
|
startChartManage.sendGenericRespSuccessMessage(
|
||||||
ToPeerId: scpMessage.FromPeerId!,
|
ToPeerId: scpMessage.FromPeerId!,
|
||||||
FromPeerId: scpMessage.ToPeerId!,
|
FromPeerId: scpMessage.ToPeerId!,
|
||||||
@ -39,9 +60,6 @@ class ScpMessageBaseHandle {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取 StartChartTalkStatus 的唯一实例
|
|
||||||
StartChartTalkStatus talkStatus = StartChartTalkStatus.instance;
|
|
||||||
|
|
||||||
bool checkGenericRespSuccess(GenericResp genericResp) {
|
bool checkGenericRespSuccess(GenericResp genericResp) {
|
||||||
if (genericResp == null) return false;
|
if (genericResp == null) return false;
|
||||||
final code = genericResp.code;
|
final code = genericResp.code;
|
||||||
@ -63,4 +81,64 @@ class ScpMessageBaseHandle {
|
|||||||
void stopRingtone() async {
|
void stopRingtone() async {
|
||||||
await audioManager.stopRingtone();
|
await audioManager.stopRingtone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 处理分包逻辑
|
||||||
|
/// 如果没有收到所有包则返回null
|
||||||
|
dynamic handleFragmentedPayload({
|
||||||
|
required int messageId,
|
||||||
|
required int spTotal,
|
||||||
|
required int spIndex,
|
||||||
|
required List<int> byte,
|
||||||
|
required int payloadType,
|
||||||
|
}) {
|
||||||
|
// 初始化分包列表
|
||||||
|
String key = '$messageId-$payloadType';
|
||||||
|
if (!_packetBuffer.containsKey(key)) {
|
||||||
|
_packetBuffer[key] = List.filled(spTotal, []);
|
||||||
|
_startTimer(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查分包索引是否在合法范围内
|
||||||
|
if (spIndex < 1 || spIndex > spTotal) {
|
||||||
|
// print(
|
||||||
|
// 'Invalid spTotal: $spTotal spIndex: $spIndex for messageId: $messageId');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 存储当前分包
|
||||||
|
_packetBuffer[key]![spIndex - 1] = byte;
|
||||||
|
|
||||||
|
// 检查是否接收到所有分包
|
||||||
|
if (_packetBuffer[key]!.every((packet) => packet.isNotEmpty)) {
|
||||||
|
// 重组所有分包
|
||||||
|
Uint8List completePayload = Uint8List.fromList(
|
||||||
|
_packetBuffer[key]!.expand((packet) => packet).toList());
|
||||||
|
// 清除已重组和超时的分包数据
|
||||||
|
_clearPacketData(key);
|
||||||
|
|
||||||
|
// 使用重组的包构造成TalkData
|
||||||
|
if (payloadType == PayloadTypeConstant.talkData) {
|
||||||
|
final talkData = TalkData();
|
||||||
|
talkData.mergeFromBuffer(completePayload);
|
||||||
|
return talkData;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果分包尚未接收完全,返回 null 或其他指示符
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动定时器
|
||||||
|
void _startTimer(String key) {
|
||||||
|
_packetTimers[key]?.cancel();
|
||||||
|
_packetTimers[key] = Timer(_timeoutDuration, () {
|
||||||
|
_clearPacketData(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除分包数据和定时器
|
||||||
|
void _clearPacketData(String key) {
|
||||||
|
_packetBuffer.remove(key);
|
||||||
|
_packetTimers.remove(key)?.cancel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
|
|
||||||
abstract class ScpMessageHandler {
|
abstract class ScpMessageHandler {
|
||||||
@ -12,4 +14,16 @@ abstract class ScpMessageHandler {
|
|||||||
|
|
||||||
// 无效请求
|
// 无效请求
|
||||||
void handleInvalidReq(ScpMessage scpMessage);
|
void handleInvalidReq(ScpMessage scpMessage);
|
||||||
|
|
||||||
|
// 处理荷载
|
||||||
|
dynamic deserializePayload({
|
||||||
|
required int payloadType,
|
||||||
|
required int messageType,
|
||||||
|
required List<int> byte,
|
||||||
|
int? offset,
|
||||||
|
int? PayloadLength,
|
||||||
|
int? spTotal,
|
||||||
|
int? spIndex,
|
||||||
|
int? messageId,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,12 +17,13 @@ import 'talk_data.pbenum.dart';
|
|||||||
|
|
||||||
export 'talk_data.pbenum.dart';
|
export 'talk_data.pbenum.dart';
|
||||||
|
|
||||||
/// 注意这个包不应该使用Req,而应该只用单向发送类型,不等待响应。
|
/// 注意这个包不应该使用请求响应(Req/Resp),应该用单向发送类型(RealTimeData),不等待响应。
|
||||||
/// 在未收到对方的Ping,或者其他情况,即停止发送。
|
/// 在未收到对方的Ping,或者其他情况,即停止发送。
|
||||||
class TalkData extends $pb.GeneratedMessage {
|
class TalkData extends $pb.GeneratedMessage {
|
||||||
factory TalkData({
|
factory TalkData({
|
||||||
TalkData_ContentTypeE? contentType,
|
TalkData_ContentTypeE? contentType,
|
||||||
$core.List<$core.int>? content,
|
$core.List<$core.int>? content,
|
||||||
|
$core.int? durationMs,
|
||||||
}) {
|
}) {
|
||||||
final $result = create();
|
final $result = create();
|
||||||
if (contentType != null) {
|
if (contentType != null) {
|
||||||
@ -31,6 +32,9 @@ class TalkData extends $pb.GeneratedMessage {
|
|||||||
if (content != null) {
|
if (content != null) {
|
||||||
$result.content = content;
|
$result.content = content;
|
||||||
}
|
}
|
||||||
|
if (durationMs != null) {
|
||||||
|
$result.durationMs = durationMs;
|
||||||
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
TalkData._() : super();
|
TalkData._() : super();
|
||||||
@ -40,6 +44,7 @@ class TalkData extends $pb.GeneratedMessage {
|
|||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'TalkData', package: const $pb.PackageName(_omitMessageNames ? '' : 'main'), createEmptyInstance: create)
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'TalkData', package: const $pb.PackageName(_omitMessageNames ? '' : 'main'), createEmptyInstance: create)
|
||||||
..e<TalkData_ContentTypeE>(1, _omitFieldNames ? '' : 'ContentType', $pb.PbFieldType.OE, protoName: 'ContentType', defaultOrMaker: TalkData_ContentTypeE.Image, valueOf: TalkData_ContentTypeE.valueOf, enumValues: TalkData_ContentTypeE.values)
|
..e<TalkData_ContentTypeE>(1, _omitFieldNames ? '' : 'ContentType', $pb.PbFieldType.OE, protoName: 'ContentType', defaultOrMaker: TalkData_ContentTypeE.Image, valueOf: TalkData_ContentTypeE.valueOf, enumValues: TalkData_ContentTypeE.values)
|
||||||
..a<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'Content', $pb.PbFieldType.OY, protoName: 'Content')
|
..a<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'Content', $pb.PbFieldType.OY, protoName: 'Content')
|
||||||
|
..a<$core.int>(3, _omitFieldNames ? '' : 'DurationMs', $pb.PbFieldType.OU3, protoName: 'DurationMs')
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -73,6 +78,7 @@ class TalkData extends $pb.GeneratedMessage {
|
|||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
void clearContentType() => clearField(1);
|
void clearContentType() => clearField(1);
|
||||||
|
|
||||||
|
/// 音视频数据,例如PCM的字节,或者H264的字节,或者图片的字节
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
$core.List<$core.int> get content => $_getN(1);
|
$core.List<$core.int> get content => $_getN(1);
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
@ -81,6 +87,18 @@ class TalkData extends $pb.GeneratedMessage {
|
|||||||
$core.bool hasContent() => $_has(1);
|
$core.bool hasContent() => $_has(1);
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
void clearContent() => clearField(2);
|
void clearContent() => clearField(2);
|
||||||
|
|
||||||
|
/// 时间 毫秒,例如第一帧视频,就是0ms,第2秒的第一帧,就是1000ms
|
||||||
|
/// 该字段仅用于协调音视频同步,而不是用于影响音视频播放时机
|
||||||
|
/// 对于对讲场景,应该根据网络延迟和设备性能自行决定缓冲时长,在满足播放条件时立即进行渲染。
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.int get durationMs => $_getIZ(2);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
set durationMs($core.int v) { $_setUnsignedInt32(2, v); }
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.bool hasDurationMs() => $_has(2);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
void clearDurationMs() => clearField(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user