提交蓝牙插件及封装
This commit is contained in:
parent
681ed316bc
commit
32b7f4cb52
@ -1,5 +1,6 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.star_lock">
|
package="com.example.star_lock"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!-- The INTERNET permission is required for development. Specifically,
|
<!-- The INTERNET permission is required for development. Specifically,
|
||||||
the Flutter tool needs it to communicate with the running application
|
the Flutter tool needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
@ -8,4 +9,12 @@
|
|||||||
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
|
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
|
||||||
|
tools:remove="android:usesPermissionFlags"
|
||||||
|
tools:targetApi="s" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
# Uncomment this line to define a global platform for your project
|
# Uncomment this line to define a global platform for your project
|
||||||
# platform :ios, '11.0'
|
# platform :ios, '11.0'
|
||||||
|
#use_modular_headers!
|
||||||
|
use_frameworks! :linkage => :static
|
||||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,12 @@ PODS:
|
|||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- Protobuf (3.23.4)
|
||||||
|
- reactive_ble_mobile (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- Protobuf (~> 3.5)
|
||||||
|
- SwiftProtobuf (~> 1.0)
|
||||||
|
- SwiftProtobuf (1.22.0)
|
||||||
- url_launcher_ios (0.0.1):
|
- url_launcher_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
|
||||||
@ -21,8 +27,14 @@ DEPENDENCIES:
|
|||||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
|
- reactive_ble_mobile (from `.symlinks/plugins/reactive_ble_mobile/ios`)
|
||||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
|
|
||||||
|
SPEC REPOS:
|
||||||
|
trunk:
|
||||||
|
- Protobuf
|
||||||
|
- SwiftProtobuf
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||||
@ -36,6 +48,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||||
|
reactive_ble_mobile:
|
||||||
|
:path: ".symlinks/plugins/reactive_ble_mobile/ios"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
|
|
||||||
@ -45,9 +59,12 @@ SPEC CHECKSUMS:
|
|||||||
flutter_native_contact_picker: bd430ba0fbf82768bb50c2c52a69a65759a8f907
|
flutter_native_contact_picker: bd430ba0fbf82768bb50c2c52a69a65759a8f907
|
||||||
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
|
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
|
||||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||||
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
|
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
|
||||||
|
Protobuf: c6bc59bbab3d38a71c67f62d7cb7ca8f8ea4eca1
|
||||||
|
reactive_ble_mobile: 9ce6723d37ccf701dbffd202d487f23f5de03b4c
|
||||||
|
SwiftProtobuf: 40bd808372cb8706108f22d28f8ab4a6b9bc6989
|
||||||
url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
|
url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
|
||||||
|
|
||||||
PODFILE CHECKSUM: 663715e941f9adb426e33bf9376914006f9ea95b
|
PODFILE CHECKSUM: 2f695eae20a86ca77f41095e9bd74ba52bd6304c
|
||||||
|
|
||||||
COCOAPODS: 1.12.1
|
COCOAPODS: 1.12.1
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
3ED61D98CC08F93BC18EEFD0 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B7537A79A618D0BBB434A17B /* libPods-Runner.a */; };
|
3EF1E85D6F1EE0C0DCF8449F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09D8B2FA2B26BA5BFF31AB2A /* Pods_Runner.framework */; };
|
||||||
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
|
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
|
||||||
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
|
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
|
||||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||||
@ -31,6 +31,7 @@
|
|||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
09D8B2FA2B26BA5BFF31AB2A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||||
@ -46,7 +47,6 @@
|
|||||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
99F6494C6B1A24363CCC6D32 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
99F6494C6B1A24363CCC6D32 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
B7537A79A618D0BBB434A17B /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
BDB5B400176768766E85D5EB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
BDB5B400176768766E85D5EB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
DC20461C9C4624BEB2DCD779 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
DC20461C9C4624BEB2DCD779 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
@ -56,7 +56,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
3ED61D98CC08F93BC18EEFD0 /* libPods-Runner.a in Frameworks */,
|
3EF1E85D6F1EE0C0DCF8449F /* Pods_Runner.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -76,7 +76,7 @@
|
|||||||
9304F75C378DB3447BB2408C /* Frameworks */ = {
|
9304F75C378DB3447BB2408C /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
B7537A79A618D0BBB434A17B /* libPods-Runner.a */,
|
09D8B2FA2B26BA5BFF31AB2A /* Pods_Runner.framework */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -349,6 +349,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
||||||
@ -475,6 +476,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
||||||
@ -494,6 +496,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
DEVELOPMENT_TEAM = 7NLFRKNVY3;
|
||||||
|
|||||||
@ -14,6 +14,10 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>NSContactsUsageDescription</key>
|
<key>NSContactsUsageDescription</key>
|
||||||
<string>Reason we need access to the contact list</string>
|
<string>Reason we need access to the contact list</string>
|
||||||
|
<key>NSBluetoothAlwaysUsageDescription</key>
|
||||||
|
<string>The app uses bluetooth to find, connect and transfer data between different devices</string>
|
||||||
|
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||||
|
<string>The app uses bluetooth to find, connect and transfer data between different devices</string>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
|
|||||||
@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.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_core/src/get_main.dart';
|
|
||||||
import 'package:star_lock/tools/app_manager.dart';
|
import 'package:star_lock/tools/app_manager.dart';
|
||||||
import 'package:star_lock/tools/device_info_service.dart';
|
import 'package:star_lock/tools/device_info_service.dart';
|
||||||
import 'package:star_lock/tools/platform_info_services.dart';
|
import 'package:star_lock/tools/platform_info_services.dart';
|
||||||
|
import 'package:star_lock/tools/reactiveBlueTool/getx_ble.dart';
|
||||||
import 'package:star_lock/tools/store_service.dart';
|
import 'package:star_lock/tools/store_service.dart';
|
||||||
import 'package:star_lock/translations/app_dept.dart';
|
import 'package:star_lock/translations/app_dept.dart';
|
||||||
import 'package:star_lock/translations/trans_lib.dart';
|
import 'package:star_lock/translations/trans_lib.dart';
|
||||||
@ -19,6 +19,8 @@ void main() async {
|
|||||||
// 设置国际化信息
|
// 设置国际化信息
|
||||||
await _initTranslation();
|
await _initTranslation();
|
||||||
|
|
||||||
|
GetxBle();
|
||||||
|
|
||||||
runApp(MyApp());
|
runApp(MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,8 @@ class _UnlockQRCodePageState extends State<UnlockQRCodePage> {
|
|||||||
// data:'二维码',
|
// data:'二维码',
|
||||||
// size:300,
|
// size:300,
|
||||||
// ),
|
// ),
|
||||||
QrImage(data: 'www.baidu.com', size: 300.w),
|
// QrImage(data: 'www.baidu.com', size: 300.w),
|
||||||
|
QrImageView(data: 'www.baidu.com', size: 300.w),
|
||||||
SizedBox(height: 50.w,),
|
SizedBox(height: 50.w,),
|
||||||
SubmitBtn(btnName: TranslationLoader.lanKeys!.share!.tr,
|
SubmitBtn(btnName: TranslationLoader.lanKeys!.share!.tr,
|
||||||
borderRadius: 20.w,
|
borderRadius: 20.w,
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_reactive_ble/flutter_reactive_ble.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:star_lock/app_settings/app_colors.dart';
|
import 'package:star_lock/app_settings/app_colors.dart';
|
||||||
@ -7,6 +10,7 @@ import 'package:star_lock/mine/mineSet/mineSet_page.dart';
|
|||||||
import '../../appRouters.dart';
|
import '../../appRouters.dart';
|
||||||
import '../../baseWidget.dart';
|
import '../../baseWidget.dart';
|
||||||
import '../../mine/mine_page.dart';
|
import '../../mine/mine_page.dart';
|
||||||
|
import '../../tools/reactiveBlueTool/getx_ble.dart';
|
||||||
import '../../tools/titleAppBar.dart';
|
import '../../tools/titleAppBar.dart';
|
||||||
import '../../translations/trans_lib.dart';
|
import '../../translations/trans_lib.dart';
|
||||||
|
|
||||||
@ -18,6 +22,26 @@ class StarLockMain extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _StarLockMainState extends State<StarLockMain> with BaseWidget{
|
class _StarLockMainState extends State<StarLockMain> with BaseWidget{
|
||||||
|
// final logic = Get.put(GetxBle());
|
||||||
|
|
||||||
|
StreamSubscription<DiscoveredDevice>? _streamSubscription;
|
||||||
|
StreamSubscription<ConnectionStateUpdate>? _connectionStreamSubscription;
|
||||||
|
final flutterReactiveBle = FlutterReactiveBle();
|
||||||
|
List<DiscoveredDevice> deviceList = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void setState(VoidCallback fn) {
|
||||||
|
// TODO: implement setState
|
||||||
|
super.setState(fn);
|
||||||
|
|
||||||
|
// BleScanner.to.startScan([
|
||||||
|
//
|
||||||
|
// ]);
|
||||||
|
|
||||||
|
GetxBle.call.scanner.startScan([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
|||||||
@ -0,0 +1,65 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class BleDeviceConnector extends GetxController {
|
||||||
|
BleDeviceConnector({
|
||||||
|
required FlutterReactiveBle ble,
|
||||||
|
required void Function(String message) logMessage,
|
||||||
|
}) : _ble = ble,
|
||||||
|
_logMessage = logMessage {
|
||||||
|
rxBleConnectionState.bindStream(_deviceConnectionController.stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
final FlutterReactiveBle _ble;
|
||||||
|
|
||||||
|
final void Function(String message) _logMessage;
|
||||||
|
|
||||||
|
final rxBleConnectionState = Rx<ConnectionStateUpdate>(
|
||||||
|
const ConnectionStateUpdate(
|
||||||
|
deviceId: "",
|
||||||
|
connectionState: DeviceConnectionState.disconnected,
|
||||||
|
failure: null));
|
||||||
|
|
||||||
|
final _deviceConnectionController = StreamController<ConnectionStateUpdate>();
|
||||||
|
|
||||||
|
late StreamSubscription<ConnectionStateUpdate> _connection;
|
||||||
|
|
||||||
|
Future<void> connect(String deviceMAC) async {
|
||||||
|
_logMessage('Start connecting to $deviceMAC');
|
||||||
|
_connection = _ble.connectToDevice(id: deviceMAC).listen(
|
||||||
|
(update) {
|
||||||
|
_logMessage(
|
||||||
|
'ConnectionState for device $deviceMAC : ${update.connectionState}');
|
||||||
|
_deviceConnectionController.add(update);
|
||||||
|
},
|
||||||
|
onError: (Object e) =>
|
||||||
|
_logMessage('Connecting to device $deviceMAC resulted in error $e'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> disconnect(String deviceMAC) async {
|
||||||
|
try {
|
||||||
|
_logMessage('disconnecting to device: $deviceMAC');
|
||||||
|
await _connection.cancel();
|
||||||
|
} on Exception catch (e, _) {
|
||||||
|
_logMessage("Error disconnecting from a device: $e");
|
||||||
|
} finally {
|
||||||
|
// Since [_connection] subscription is terminated, the "disconnected" state cannot be received and propagated
|
||||||
|
_deviceConnectionController.add(
|
||||||
|
ConnectionStateUpdate(
|
||||||
|
deviceId: deviceMAC,
|
||||||
|
connectionState: DeviceConnectionState.disconnected,
|
||||||
|
failure: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onClose() async {
|
||||||
|
rxBleConnectionState.close();
|
||||||
|
await _deviceConnectionController.close();
|
||||||
|
super.onClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class BleDeviceInteractor extends GetxController {
|
||||||
|
BleDeviceInteractor({
|
||||||
|
required FlutterReactiveBle ble,
|
||||||
|
required void Function(String message) logMessage,
|
||||||
|
}) : _ble = ble,
|
||||||
|
_logMessage = logMessage;
|
||||||
|
|
||||||
|
final FlutterReactiveBle _ble;
|
||||||
|
|
||||||
|
final void Function(String message) _logMessage;
|
||||||
|
|
||||||
|
Future<List<DiscoveredService>> discoverServices(String deviceId) async {
|
||||||
|
try {
|
||||||
|
_logMessage('Start discovering services for: $deviceId');
|
||||||
|
final result = await _ble.discoverServices(deviceId);
|
||||||
|
_logMessage('Discovering services finished');
|
||||||
|
return result;
|
||||||
|
} on Exception catch (e) {
|
||||||
|
_logMessage('Error occurred when discovering services: $e');
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<int>> readCharacteristic(
|
||||||
|
QualifiedCharacteristic characteristic) async {
|
||||||
|
try {
|
||||||
|
final result = await _ble.readCharacteristic(characteristic);
|
||||||
|
_logMessage('Read ${characteristic.characteristicId}: value = $result');
|
||||||
|
return result;
|
||||||
|
} on Exception catch (e, s) {
|
||||||
|
_logMessage(
|
||||||
|
'Error occurred when reading ${characteristic.characteristicId} : $e',
|
||||||
|
);
|
||||||
|
// ignore: avoid_print
|
||||||
|
print(s);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> writeCharacteristicWithResponse(
|
||||||
|
QualifiedCharacteristic characteristic, List<int> value) async {
|
||||||
|
try {
|
||||||
|
_logMessage(
|
||||||
|
'Write with response value : $value to ${characteristic.characteristicId}');
|
||||||
|
await _ble.writeCharacteristicWithResponse(characteristic, value: value);
|
||||||
|
} on Exception catch (e, s) {
|
||||||
|
_logMessage(
|
||||||
|
'Error occurred when writing ${characteristic.characteristicId} : $e',
|
||||||
|
);
|
||||||
|
// ignore: avoid_print
|
||||||
|
print(s);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> writeCharacteristicWithoutResponse(
|
||||||
|
QualifiedCharacteristic characteristic, List<int> value) async {
|
||||||
|
try {
|
||||||
|
await _ble.writeCharacteristicWithoutResponse(characteristic,
|
||||||
|
value: value);
|
||||||
|
_logMessage(
|
||||||
|
'Write without response value: $value to ${characteristic.characteristicId}');
|
||||||
|
} on Exception catch (e, s) {
|
||||||
|
_logMessage(
|
||||||
|
'Error occurred when writing ${characteristic.characteristicId} : $e',
|
||||||
|
);
|
||||||
|
// ignore: avoid_print
|
||||||
|
print(s);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<List<int>> subScribeToCharacteristic(
|
||||||
|
QualifiedCharacteristic characteristic) {
|
||||||
|
_logMessage('Subscribing to: ${characteristic.characteristicId} ');
|
||||||
|
return _ble.subscribeToCharacteristic(characteristic);
|
||||||
|
}
|
||||||
|
}
|
||||||
28
star_lock/lib/tools/reactiveBlueTool/ble_logger.dart
Normal file
28
star_lock/lib/tools/reactiveBlueTool/ble_logger.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class BleLogger extends GetxController {
|
||||||
|
BleLogger({
|
||||||
|
required FlutterReactiveBle ble,
|
||||||
|
}) : _ble = ble;
|
||||||
|
|
||||||
|
final FlutterReactiveBle _ble;
|
||||||
|
final Rx<List<String>> rxMessages = Rx<List<String>>([]);
|
||||||
|
final RxBool rxVerboseLogging = false.obs;
|
||||||
|
|
||||||
|
void addToLog(String message) {
|
||||||
|
final now = DateTime.now();
|
||||||
|
final formattedDate = '${now.year}-${now.month}-${now.day} ${now.hour}:${now.minute}:${now.second}';
|
||||||
|
rxMessages.value.add('$formattedDate - $message');
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearLogs() => rxMessages.value.clear();
|
||||||
|
|
||||||
|
void verboseLoggingUpdate() {
|
||||||
|
if (rxVerboseLogging.value) {
|
||||||
|
_ble.logLevel = LogLevel.verbose;
|
||||||
|
} else {
|
||||||
|
_ble.logLevel = LogLevel.none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
114
star_lock/lib/tools/reactiveBlueTool/ble_scanner.dart
Normal file
114
star_lock/lib/tools/reactiveBlueTool/ble_scanner.dart
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
/// 这个类负责开启和关闭蓝牙扫描器并输出扫描结果
|
||||||
|
class BleScanner extends GetxController {
|
||||||
|
BleScanner({
|
||||||
|
required FlutterReactiveBle ble,
|
||||||
|
required void Function(String message) logMessage,
|
||||||
|
}) : _ble = ble,
|
||||||
|
_logMessage = logMessage {
|
||||||
|
rxBleScannerState.bindStream(_stateStreamController.stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static BleScanner get to => Get.find<BleScanner>();
|
||||||
|
|
||||||
|
|
||||||
|
final FlutterReactiveBle _ble;
|
||||||
|
|
||||||
|
/// 输入 FlutterReactiveBle 来获取结果及功能
|
||||||
|
final void Function(String message) _logMessage;
|
||||||
|
|
||||||
|
/// 输入日志函数来输出日志
|
||||||
|
final StreamController<BleScannerState> _stateStreamController =
|
||||||
|
StreamController();
|
||||||
|
|
||||||
|
StreamSubscription? _subscription;
|
||||||
|
|
||||||
|
/// 使用 Getx 的 Rx 来监听扫描结果
|
||||||
|
final rxBleScannerState = Rx<BleScannerState>(
|
||||||
|
const BleScannerState(discoveredDevices: [], scanIsInProgress: false));
|
||||||
|
|
||||||
|
final _devices = <DiscoveredDevice>[];
|
||||||
|
|
||||||
|
/// 开始扫描蓝牙设备
|
||||||
|
void startScan(List<Uuid> serviceIds) {
|
||||||
|
_logMessage('Start ble discovery');
|
||||||
|
_devices.clear();
|
||||||
|
_subscription?.cancel();
|
||||||
|
_subscription = _ble.scanForDevices(withServices: serviceIds).listen((device) {
|
||||||
|
final knownDeviceIndex = _devices.indexWhere((d) => d.id == device.id);
|
||||||
|
|
||||||
|
if (knownDeviceIndex >= 0) {
|
||||||
|
_devices[knownDeviceIndex] = device;
|
||||||
|
} else {
|
||||||
|
// if (device.name.toLowerCase().contains((filter.name ?? "".toLowerCase()))) {
|
||||||
|
// if (device.id.contains((filter.mac ?? ""))) {
|
||||||
|
// if (device.rssi >= (filter.rssi ?? -100)) {
|
||||||
|
_devices.add(device);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
_pushState();
|
||||||
|
}, onError: (Object e) => _logMessage('Device scan fails with error: $e'));
|
||||||
|
_pushState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 更新扫描结果
|
||||||
|
void _pushState() {
|
||||||
|
_stateStreamController.add(
|
||||||
|
BleScannerState(
|
||||||
|
discoveredDevices: _devices,
|
||||||
|
scanIsInProgress: _subscription != null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 停止扫描蓝牙设备
|
||||||
|
Future<void> stopScan() async {
|
||||||
|
_logMessage('Stop ble discovery');
|
||||||
|
|
||||||
|
await _subscription?.cancel();
|
||||||
|
_subscription = null;
|
||||||
|
_pushState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// GetxController 的生命周期函数,当页面关闭时,关闭扫描器
|
||||||
|
@override
|
||||||
|
Future<void> onClose() async {
|
||||||
|
rxBleScannerState.close();
|
||||||
|
await _stateStreamController.close();
|
||||||
|
super.onClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 这个类用来存储扫描到的蓝牙设备以及扫描器状态
|
||||||
|
@immutable
|
||||||
|
class BleScannerState {
|
||||||
|
const BleScannerState({
|
||||||
|
required this.discoveredDevices,
|
||||||
|
required this.scanIsInProgress,
|
||||||
|
});
|
||||||
|
|
||||||
|
final List<DiscoveredDevice> discoveredDevices;
|
||||||
|
final bool scanIsInProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 这个类用来存储扫描器的过滤器
|
||||||
|
class BleScannerFilter {
|
||||||
|
String? name;
|
||||||
|
String? mac;
|
||||||
|
List<Uuid>? serviceId;
|
||||||
|
int? rssi;
|
||||||
|
|
||||||
|
BleScannerFilter({
|
||||||
|
this.name,
|
||||||
|
this.mac,
|
||||||
|
this.serviceId,
|
||||||
|
this.rssi,
|
||||||
|
});
|
||||||
|
}
|
||||||
485
star_lock/lib/tools/reactiveBlueTool/ble_sig_gatt_uuids.dart
Normal file
485
star_lock/lib/tools/reactiveBlueTool/ble_sig_gatt_uuids.dart
Normal file
@ -0,0 +1,485 @@
|
|||||||
|
class BleSigGattUuids {
|
||||||
|
static const Map serviceUuids = {
|
||||||
|
"1800": "Generic Access",
|
||||||
|
"1811": "Alert Notification Service",
|
||||||
|
"1815": "Automation IO",
|
||||||
|
"180F": "Battery Service",
|
||||||
|
"1810": "Blood Pressure",
|
||||||
|
"181B": "Body Composition",
|
||||||
|
"181E": "Bond Management Service",
|
||||||
|
"181F": "Continuous Glucose Monitoring",
|
||||||
|
"1805": "Current Time Service",
|
||||||
|
"1818": "Cycling Power",
|
||||||
|
"1816": "Cycling Speed and Cadence",
|
||||||
|
"180A": "Device Information",
|
||||||
|
"181A": "Environmental Sensing",
|
||||||
|
"1826": "Fitness Machine",
|
||||||
|
"1801": "Generic Attribute",
|
||||||
|
"1808": "Glucose",
|
||||||
|
"1809": "Health Thermometer",
|
||||||
|
"180D": "Heart Rate",
|
||||||
|
"1823": "HTTP Proxy",
|
||||||
|
"1812": "Human Interface Device",
|
||||||
|
"1802": "Immediate Alert",
|
||||||
|
"1821": "Indoor Positioning",
|
||||||
|
"183A": "Insulin Delivery",
|
||||||
|
"1820": "Internet Protocol Support Service",
|
||||||
|
"1803": "Link Loss",
|
||||||
|
"1819": "Location and Navigation",
|
||||||
|
"1827": "Mesh Provisioning Service",
|
||||||
|
"1828": "Mesh Proxy Service",
|
||||||
|
"1807": "Next DST Change Service",
|
||||||
|
"1825": "Object Transfer Service",
|
||||||
|
"180E": "Phone Alert Status Service",
|
||||||
|
"1822": "Pulse Oximeter Service",
|
||||||
|
"1829": "Reconnection Configuration",
|
||||||
|
"1806": "Reference Time Update Service",
|
||||||
|
"1814": "Running Speed and Cadence",
|
||||||
|
"1813": "Scan Parameters",
|
||||||
|
"1824": "Transport Discovery",
|
||||||
|
"1804": "Tx Power",
|
||||||
|
"181C": "User Data",
|
||||||
|
"181D": "Weight Scale",
|
||||||
|
"183B": "Binary Sensor",
|
||||||
|
"183C": "Emergency Configuration",
|
||||||
|
"183E": "Physical Activity Monitor",
|
||||||
|
"1843": "Audio Input Control",
|
||||||
|
"1844": "Volume Control",
|
||||||
|
"1845": "Volume Offset Control",
|
||||||
|
"1846": "Coordinated Set Identification",
|
||||||
|
"1847": "Device Time",
|
||||||
|
"1848": "Media Control",
|
||||||
|
"1849": "Generic Media Control",
|
||||||
|
"184A": "Constant Tone Extension",
|
||||||
|
"184B": "Telephone Bearer",
|
||||||
|
"184C": "Generic Telephone Bearer",
|
||||||
|
"184D": "Microphone Control",
|
||||||
|
"184E": "Audio Stream Control",
|
||||||
|
"184F": "Broadcast Audio Scan",
|
||||||
|
"1850": "Published Audio Capabilities",
|
||||||
|
"1851": "Published Audio Data",
|
||||||
|
"1852": "Broadcast Audio Announcement",
|
||||||
|
"1853": "Common Audio",
|
||||||
|
"1854": "Hearing Access",
|
||||||
|
"1855": "TMAS"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Map characteristicUuids = {
|
||||||
|
"2A7E": "Aerobic Heart Rate Lower Limit",
|
||||||
|
"2A84": "Aerobic Heart Rate Upper Limit",
|
||||||
|
"2A7F": "Aerobic Threshold",
|
||||||
|
"2A80": "Age",
|
||||||
|
"2A5A": "Aggregate",
|
||||||
|
"2A43": "Alert Category ID",
|
||||||
|
"2A42": "Alert Category ID Bit Mask",
|
||||||
|
"2A06": "Alert Level",
|
||||||
|
"2A44": "Alert Notification Control Point",
|
||||||
|
"2A3F": "Alert Status",
|
||||||
|
"2AB3": "Altitude",
|
||||||
|
"2A81": "Anaerobic Heart Rate Lower Limit",
|
||||||
|
"2A82": "Anaerobic Heart Rate Upper Limit",
|
||||||
|
"2A83": "Anaerobic Threshold",
|
||||||
|
"2A58": "Analog",
|
||||||
|
"2A59": "Analog Output",
|
||||||
|
"2A73": "Apparent Wind Direction",
|
||||||
|
"2A72": "Apparent Wind Speed",
|
||||||
|
"2A01": "Appearance",
|
||||||
|
"2AA3": "Barometric Pressure Trend",
|
||||||
|
"2A19": "Battery Level",
|
||||||
|
"2A1B": "Battery Level State",
|
||||||
|
"2A1A": "Battery Power State",
|
||||||
|
"2A49": "Blood Pressure Feature",
|
||||||
|
"2A35": "Blood Pressure Measurement",
|
||||||
|
"2A9B": "Body Composition Feature",
|
||||||
|
"2A9C": "Body Composition Measurement",
|
||||||
|
"2A38": "Body Sensor Location",
|
||||||
|
"2AA4": "Bond Management Control Point",
|
||||||
|
"2AA5": "Bond Management Features",
|
||||||
|
"2A22": "Boot Keyboard Input Report",
|
||||||
|
"2A32": "Boot Keyboard Output Report",
|
||||||
|
"2A33": "Boot Mouse Input Report",
|
||||||
|
"2AA6": "Central Address Resolution",
|
||||||
|
"2AA8": "CGM Feature",
|
||||||
|
"2AA7": "CGM Measurement",
|
||||||
|
"2AAB": "CGM Session Run Time",
|
||||||
|
"2AAA": "CGM Session Start Time",
|
||||||
|
"2AAC": "CGM Specific Ops Control Point",
|
||||||
|
"2AA9": "CGM Status",
|
||||||
|
"2ACE": "Cross Trainer Data",
|
||||||
|
"2A5C": "CSC Feature",
|
||||||
|
"2A5B": "CSC Measurement",
|
||||||
|
"2A2B": "Current Time",
|
||||||
|
"2A66": "Cycling Power Control Point",
|
||||||
|
"2A65": "Cycling Power Feature",
|
||||||
|
"2A63": "Cycling Power Measurement",
|
||||||
|
"2A64": "Cycling Power Vector",
|
||||||
|
"2A99": "Database Change Increment",
|
||||||
|
"2A85": "Date of Birth",
|
||||||
|
"2A86": "Date of Threshold Assessment",
|
||||||
|
"2A08": "Date Time",
|
||||||
|
"2A0A": "Day Date Time",
|
||||||
|
"2A09": "Day of Week",
|
||||||
|
"2A7D": "Descriptor Value Changed",
|
||||||
|
"2A00": "Device Name",
|
||||||
|
"2A7B": "Dew Point",
|
||||||
|
"2A56": "Digital",
|
||||||
|
"2A57": "Digital Output",
|
||||||
|
"2A0D": "DST Offset",
|
||||||
|
"2A6C": "Elevation",
|
||||||
|
"2A87": "Email Address",
|
||||||
|
"2A0B": "Exact Time 100",
|
||||||
|
"2A0C": "Exact Time 256",
|
||||||
|
"2A88": "Fat Burn Heart Rate Lower Limit",
|
||||||
|
"2A89": "Fat Burn Heart Rate Upper Limit",
|
||||||
|
"2A26": "Firmware Revision String",
|
||||||
|
"2A8A": "First Name",
|
||||||
|
"2AD9": "Fitness Machine Control Point",
|
||||||
|
"2ACC": "Fitness Machine Feature",
|
||||||
|
"2ADA": "Fitness Machine Status",
|
||||||
|
"2A8B": "Five Zone Heart Rate Limits",
|
||||||
|
"2AB2": "Floor Number",
|
||||||
|
"2A8C": "Gender",
|
||||||
|
"2A51": "Glucose Feature",
|
||||||
|
"2A18": "Glucose Measurement",
|
||||||
|
"2A34": "Glucose Measurement Context",
|
||||||
|
"2A74": "Gust Factor",
|
||||||
|
"2A27": "Hardware Revision String",
|
||||||
|
"2A39": "Heart Rate Control Point",
|
||||||
|
"2A8D": "Heart Rate Max",
|
||||||
|
"2A37": "Heart Rate Measurement",
|
||||||
|
"2A7A": "Heat Index",
|
||||||
|
"2A8E": "Height",
|
||||||
|
"2A4C": "HID Control Point",
|
||||||
|
"2A4A": "HID Information",
|
||||||
|
"2A8F": "Hip Circumference",
|
||||||
|
"2ABA": "HTTP Control Point",
|
||||||
|
"2AB9": "HTTP Entity Body",
|
||||||
|
"2AB7": "HTTP Headers",
|
||||||
|
"2AB8": "HTTP Status Code",
|
||||||
|
"2ABB": "HTTPS Security",
|
||||||
|
"2A6F": "Humidity",
|
||||||
|
"2B22": "IDD Annunciation Status",
|
||||||
|
"2B25": "IDD Command Control Point",
|
||||||
|
"2B26": "IDD Command Data",
|
||||||
|
"2B23": "IDD Features",
|
||||||
|
"2B28": "IDD History Data",
|
||||||
|
"2B27": "IDD Record Access Control Point",
|
||||||
|
"2B21": "IDD Status",
|
||||||
|
"2B20": "IDD Status Changed",
|
||||||
|
"2B24": "IDD Status Reader Control Point",
|
||||||
|
"2A2A": "IEEE 11073-20601 Regulatory Certification Data List",
|
||||||
|
"2AD2": "Indoor Bike Data",
|
||||||
|
"2AAD": "Indoor Positioning Configuration",
|
||||||
|
"2A36": "Intermediate Cuff Pressure",
|
||||||
|
"2A1E": "Intermediate Temperature",
|
||||||
|
"2A77": "Irradiance",
|
||||||
|
"2AA2": "Language",
|
||||||
|
"2A90": "Last Name",
|
||||||
|
"2AAE": "Latitude",
|
||||||
|
"2A6B": "LN Control Point",
|
||||||
|
"2A6A": "LN Feature",
|
||||||
|
"2AB1": "Local East Coordinate",
|
||||||
|
"2AB0": "Local North Coordinate",
|
||||||
|
"2A0F": "Local Time Information",
|
||||||
|
"2A67": "Location and Speed Characteristic",
|
||||||
|
"2AB5": "Location Name",
|
||||||
|
"2AAF": "Longitude",
|
||||||
|
"2A2C": "Magnetic Declination",
|
||||||
|
"2AA0": "Magnetic Flux Density - 2D",
|
||||||
|
"2AA1": "Magnetic Flux Density - 3D",
|
||||||
|
"2A29": "Manufacturer Name String",
|
||||||
|
"2A91": "Maximum Recommended Heart Rate",
|
||||||
|
"2A21": "Measurement Interval",
|
||||||
|
"2A24": "Model Number String",
|
||||||
|
"2A68": "Navigation",
|
||||||
|
"2A3E": "Network Availability",
|
||||||
|
"2A46": "New Alert",
|
||||||
|
"2AC5": "Object Action Control Point",
|
||||||
|
"2AC8": "Object Changed",
|
||||||
|
"2AC1": "Object First-Created",
|
||||||
|
"2AC3": "Object ID",
|
||||||
|
"2AC2": "Object Last-Modified",
|
||||||
|
"2AC6": "Object List Control Point",
|
||||||
|
"2AC7": "Object List Filter",
|
||||||
|
"2ABE": "Object Name",
|
||||||
|
"2AC4": "Object Properties",
|
||||||
|
"2AC0": "Object Size",
|
||||||
|
"2ABF": "Object Type",
|
||||||
|
"2ABD": "OTS Feature",
|
||||||
|
"2A04": "Peripheral Preferred Connection Parameters",
|
||||||
|
"2A02": "Peripheral Privacy Flag",
|
||||||
|
"2A5F": "PLX Continuous Measurement Characteristic",
|
||||||
|
"2A60": "PLX Features",
|
||||||
|
"2A5E": "PLX Spot-Check Measurement",
|
||||||
|
"2A50": "PnP ID",
|
||||||
|
"2A75": "Pollen Concentration",
|
||||||
|
"2A2F": "Position 2D",
|
||||||
|
"2A30": "Position 3D",
|
||||||
|
"2A69": "Position Quality",
|
||||||
|
"2A6D": "Pressure",
|
||||||
|
"2A4E": "Protocol Mode",
|
||||||
|
"2A62": "Pulse Oximetry Control Point",
|
||||||
|
"2A78": "Rainfall",
|
||||||
|
"2B1D": "RC Feature",
|
||||||
|
"2B1E": "RC Settings",
|
||||||
|
"2A03": "Reconnection Address",
|
||||||
|
"2B1F": "Reconnection Configuration Control Point",
|
||||||
|
"2A52": "Record Access Control Point",
|
||||||
|
"2A14": "Reference Time Information",
|
||||||
|
"2A3A": "Removable",
|
||||||
|
"2A4D": "Report",
|
||||||
|
"2A4B": "Report Map",
|
||||||
|
"2AC9": "Resolvable Private Address Only",
|
||||||
|
"2A92": "Resting Heart Rate",
|
||||||
|
"2A40": "Ringer Control point",
|
||||||
|
"2A41": "Ringer Setting",
|
||||||
|
"2AD1": "Rower Data",
|
||||||
|
"2A54": "RSC Feature",
|
||||||
|
"2A53": "RSC Measurement",
|
||||||
|
"2A55": "SC Control Point",
|
||||||
|
"2A4F": "Scan Interval Window",
|
||||||
|
"2A31": "Scan Refresh",
|
||||||
|
"2A3C": "Scientific Temperature Celsius",
|
||||||
|
"2A10": "Secondary Time Zone",
|
||||||
|
"2A5D": "Sensor Location",
|
||||||
|
"2A05": "Service Changed",
|
||||||
|
"2A0E": "Time Zone",
|
||||||
|
"2A11": "Time with DST",
|
||||||
|
"2A12": "Time Accuracy",
|
||||||
|
"2A13": "Time Source",
|
||||||
|
"2A15": "Time Broadcast",
|
||||||
|
"2A16": "Time Update Control Point",
|
||||||
|
"2A17": "Time Update State",
|
||||||
|
"2A25": "Serial Number String",
|
||||||
|
"2A3B": "Service Required",
|
||||||
|
"2A28": "Software Revision String",
|
||||||
|
"2A93": "Sport Type for Aerobic and Anaerobic Thresholds",
|
||||||
|
"2AD0": "Stair Climber Data",
|
||||||
|
"2ACF": "Step Climber Data",
|
||||||
|
"2A3D": "String",
|
||||||
|
"2AD7": "Supported Heart Rate Range",
|
||||||
|
"2AD5": "Supported Inclination Range",
|
||||||
|
"2A47": "Supported New Alert Category",
|
||||||
|
"2AD8": "Supported Power Range",
|
||||||
|
"2AD6": "Supported Resistance Level Range",
|
||||||
|
"2AD4": "Supported Speed Range",
|
||||||
|
"2A48": "Supported Unread Alert Category",
|
||||||
|
"2A23": "System ID",
|
||||||
|
"2ABC": "TDS Control Point",
|
||||||
|
"2A6E": "Temperature",
|
||||||
|
"2A1F": "Temperature Celsius",
|
||||||
|
"2A20": "Temperature Fahrenheit",
|
||||||
|
"2A1C": "Temperature Measurement",
|
||||||
|
"2A1D": "Temperature Type",
|
||||||
|
"2A94": "Three Zone Heart Rate Limits",
|
||||||
|
"2A70": "True Wind Speed",
|
||||||
|
"2A71": "True Wind Direction",
|
||||||
|
"2A95": "Two Zone Heart Rate Limit",
|
||||||
|
"2A07": "Tx Power Level",
|
||||||
|
"2AB4": "Uncertainty",
|
||||||
|
"2A45": "Unread Alert Status",
|
||||||
|
"2AB6": "URI",
|
||||||
|
"2A9F": "User Control Point",
|
||||||
|
"2A9A": "User Index",
|
||||||
|
"2A76": "UV Index",
|
||||||
|
"2A79": "Wind Chill",
|
||||||
|
"2A96": "VO2 Max",
|
||||||
|
"2A97": "Waist Circumference",
|
||||||
|
"2A98": "Weight",
|
||||||
|
"2A9D": "Weight Measurement",
|
||||||
|
"2A9E": "Weight Scale Feature",
|
||||||
|
"2ACD": "Treadmill Data",
|
||||||
|
"2AD3": "Training Status",
|
||||||
|
"2AE0": "Average Current",
|
||||||
|
"2AE1": "Average Voltage",
|
||||||
|
"2AE2": "Boolean",
|
||||||
|
"2AE3": "Chromatic Distance From Planckian",
|
||||||
|
"2AE4": "Chromaticity Coordinates",
|
||||||
|
"2AE5": "Chromaticity In CCT And Duv Values",
|
||||||
|
"2AE6": "Chromaticity Tolerance",
|
||||||
|
"2AE7": "CIE 13.3-1995 Color Rendering Index",
|
||||||
|
"2AE8": "Coefficient",
|
||||||
|
"2AE9": "Correlated Color Temperature",
|
||||||
|
"2AEA": "Count 16",
|
||||||
|
"2AEB": "Count 24",
|
||||||
|
"2AEC": "Country Code",
|
||||||
|
"2AED": "Date UTC",
|
||||||
|
"2AEE": "Electric Current",
|
||||||
|
"2AEF": "Electric Current Range",
|
||||||
|
"2AF0": "Electric Current Specification",
|
||||||
|
"2AF1": "Electric Current Statistics",
|
||||||
|
"2AF2": "Energy",
|
||||||
|
"2AF3": "Energy In A Period Of Day",
|
||||||
|
"2AF4": "Event Statistics",
|
||||||
|
"2AF5": "Fixed String 16",
|
||||||
|
"2AF6": "Fixed String 24",
|
||||||
|
"2AF7": "Fixed String 36",
|
||||||
|
"2AF8": "Fixed String 8",
|
||||||
|
"2AF9": "Generic Level",
|
||||||
|
"2AFA": "Global Trade Item Number",
|
||||||
|
"2AFB": "Illuminance",
|
||||||
|
"2AFC": "Luminous Efficacy",
|
||||||
|
"2AFD": "Luminous Energy",
|
||||||
|
"2AFE": "Luminous Exposure",
|
||||||
|
"2AFF": "Luminous Flux",
|
||||||
|
"2B00": "Luminous Flux Range",
|
||||||
|
"2B01": "Luminous Intensity",
|
||||||
|
"2B02": "B02 Mass Flow",
|
||||||
|
"2B03": "Perceived Lightness",
|
||||||
|
"2B04": "Percentage 8",
|
||||||
|
"2B05": "Power",
|
||||||
|
"2B06": "Power Specification",
|
||||||
|
"2B07": "Relative Runtime In A Current Range",
|
||||||
|
"2B08": "Relative Runtime In A Generic Level Range",
|
||||||
|
"2B09": "Relative Value In A Voltage Range",
|
||||||
|
"2B0A": "Relative Value In An Illuminance Range",
|
||||||
|
"2B0B": "Relative Value In A Period Of Day",
|
||||||
|
"2B0C": "Relative Value In A Temperature Range",
|
||||||
|
"2B0D": "Temperature 8",
|
||||||
|
"2B0E": "Temperature 8 In A Period Of Day",
|
||||||
|
"2B0F": "Temperature 8 Statistics",
|
||||||
|
"2B10": "Temperature Range",
|
||||||
|
"2B11": "Temperature Statistics",
|
||||||
|
"2B12": "Time Decihour 8",
|
||||||
|
"2B13": "Time Exponential 8",
|
||||||
|
"2B14": "Time Hour 24",
|
||||||
|
"2B15": "Time Millisecond 24",
|
||||||
|
"2B16": "Time Second 16",
|
||||||
|
"2B17": "Time Second 8",
|
||||||
|
"2B18": "Voltage",
|
||||||
|
"2B19": "Voltage Specification",
|
||||||
|
"2B1A": "Volume Flow",
|
||||||
|
"2B1B": "Volume Flow",
|
||||||
|
"2B1C": "Volume Flow In A Period Of Day",
|
||||||
|
"2B29": "Client Supported Features",
|
||||||
|
"2B2A": "Database Hash",
|
||||||
|
"2B2B": "BSS Control Point",
|
||||||
|
"2B2C": "BSS Response",
|
||||||
|
"2B2D": "Emergency ID",
|
||||||
|
"2B2E": "Emergency Text",
|
||||||
|
"2B34": "Enhanced Blood Pressure Measurement",
|
||||||
|
"2B35": "Enhanced Intermediate Cuff Pressure",
|
||||||
|
"2B36": "Blood Pressure Record",
|
||||||
|
"2B38": "BR-EDR Handover Data",
|
||||||
|
"2B39": "Bluetooth SIG Data",
|
||||||
|
"2B3A": "Server Supported Features",
|
||||||
|
"2B3B": "Physical Activity Monitor Features",
|
||||||
|
"2B3C": "General Activity Instantaneous Data",
|
||||||
|
"2B3D": "General Activity Summary Data",
|
||||||
|
"2B3E": "CardioRespiratory Activity Instantaneous Data",
|
||||||
|
"2B3F": "CardioRespiratory Activity Summary Data",
|
||||||
|
"2B40": "Step Counter Activity Summary Data",
|
||||||
|
"2B41": "Sleep Activity Instantaneous Data",
|
||||||
|
"2B42": "Sleep Activity Summary Data",
|
||||||
|
"2B43": "Physical Activity Monitor Control Point",
|
||||||
|
"2B44": "Activity Current Session",
|
||||||
|
"2B45": "Physical Activity Session Descriptor",
|
||||||
|
"2B46": "Preferred Units",
|
||||||
|
"2B47": "High Resolution Height",
|
||||||
|
"2B48": "Middle Name",
|
||||||
|
"2B49": "Stride Length",
|
||||||
|
"2B4A": "Handedness",
|
||||||
|
"2B4B": "Device Wearing Position",
|
||||||
|
"2B4C": "Four Zone Heart Rate Limits",
|
||||||
|
"2B4D": "High Intensity Exercise Threshold",
|
||||||
|
"2B4E": "Activity Goal",
|
||||||
|
"2B4F": "Sedentary Interval Notification",
|
||||||
|
"2B50": "Caloric Intake",
|
||||||
|
"2B51": "TMAP Role",
|
||||||
|
"2B77": "Audio Input State",
|
||||||
|
"2B78": "Audio Input Control Point",
|
||||||
|
"2B79": "Audio Input Type",
|
||||||
|
"2B7A": "Audio Input Status",
|
||||||
|
"2B7B": "Audio Input Control Point",
|
||||||
|
"2B7C": "Audio Input Description",
|
||||||
|
"2B7D": "Volume State",
|
||||||
|
"2B7E": "Volume Control Point",
|
||||||
|
"2B7F": "Volume Flags",
|
||||||
|
"2B80": "Volume Offset State",
|
||||||
|
"2B81": "Audio Location",
|
||||||
|
"2B82": "Volume Offset Control Point",
|
||||||
|
"2B83": "Audio Output State",
|
||||||
|
"2B84": "Set Identity Resolving Key",
|
||||||
|
"2B85": "Coordinated Set Size",
|
||||||
|
"2B86": "Set Member Lock",
|
||||||
|
"2B87": "Set Member Rank",
|
||||||
|
"2B8E": "Device Time Feature",
|
||||||
|
"2B8F": "Device Time Parameters",
|
||||||
|
"2B90": "Device Time",
|
||||||
|
"2B91": "Device Time Control Point",
|
||||||
|
"2B92": "Time Change Log Data",
|
||||||
|
"2B93": "Media Player Name",
|
||||||
|
"2B94": "Media Player Icon Object ID",
|
||||||
|
"2B95": "Media Player Icon URL",
|
||||||
|
"2B96": "Track Changed",
|
||||||
|
"2B97": "Track Title",
|
||||||
|
"2B98": "Track Duration",
|
||||||
|
"2B99": "Track Position",
|
||||||
|
"2B9A": "Playback Speed",
|
||||||
|
"2B9B": "Seeking Speed",
|
||||||
|
"2B9C": "Current Track Segments Object ID",
|
||||||
|
"2B9D": "Current Track Object ID",
|
||||||
|
"2B9E": "Next Track Object ID",
|
||||||
|
"2B9F": "Parent Group Object ID",
|
||||||
|
"2BA0": "Current Group Object ID",
|
||||||
|
"2BA1": "Playing Order",
|
||||||
|
"2BA2": "Playing Orders Supported",
|
||||||
|
"2BA3": "Media State",
|
||||||
|
"2BA4": "Media Control Point",
|
||||||
|
"2BA5": "Media Control Point Opcodes Supported",
|
||||||
|
"2BA6": "Search Results Object ID",
|
||||||
|
"2BA7": "Search Control Point",
|
||||||
|
"2BA9": "Media Player Icon Object Type",
|
||||||
|
"2BAA": "Track Segments Object Type",
|
||||||
|
"2BAB": "Track Object Type",
|
||||||
|
"2BAC": "Group Object Type",
|
||||||
|
"2BAD": "Constant Tone Extension Enable",
|
||||||
|
"2BAE": "Advertising Constant Tone Extension Minimum Length",
|
||||||
|
"2BAF": "Advertising Constant Tone Extension Minimum Transmit Count",
|
||||||
|
"2BB0": "Advertising Constant Tone Extension Transmit Duration",
|
||||||
|
"2BB1": "Advertising Constant Tone Extension Interval",
|
||||||
|
"2BB2": "Advertising Constant Tone Extension PHY",
|
||||||
|
"2BB3": "Bearer Provider Name",
|
||||||
|
"2BB4": "Bearer UCI",
|
||||||
|
"2BB5": "Bearer Technology",
|
||||||
|
"2BB6": "Bearer URI Schemes Supported List",
|
||||||
|
"2BB7": "Bearer Signal Strength",
|
||||||
|
"2BB8": "Bearer Signal Strength Reporting Interval",
|
||||||
|
"2BB9": "Bearer List Current Calls",
|
||||||
|
"2BBA": "Content Control ID",
|
||||||
|
"2BBB": "Status Flags",
|
||||||
|
"2BBC": "Incoming Call Target Bearer URI",
|
||||||
|
"2BBD": "Call State",
|
||||||
|
"2BBE": "Call Control Point",
|
||||||
|
"2BBF": "Call Control Point Optional Opcodes",
|
||||||
|
"2BC0": "Termination Reason",
|
||||||
|
"2BC1": "Incoming Call",
|
||||||
|
"2BC2": "Call Friendly Name",
|
||||||
|
"2BC3": "Mute",
|
||||||
|
"2BC4": "Sink ASE",
|
||||||
|
"2BC5": "Source ASE",
|
||||||
|
"2BC6": "ASE Control Point",
|
||||||
|
"2BC7": "Broadcast Audio Scan Control Point",
|
||||||
|
"2BC8": "Broadcast Receive State",
|
||||||
|
"2BC9": "Sink PAC",
|
||||||
|
"2BCA": "Sink Audio Locations",
|
||||||
|
"2BCB": "Source PAC",
|
||||||
|
"2BCC": "Source Audio Locations",
|
||||||
|
"2BCD": "Available Audio Contexts",
|
||||||
|
"2BCE": "Supported Audio Contexts",
|
||||||
|
"2BCF": "Ammonia Concentration",
|
||||||
|
"2BD0": "Carbon Monoxide Concentration",
|
||||||
|
"2BD1": "Nitrogen Dioxide Concentration",
|
||||||
|
"2BD2": "Nitrogen Dioxide Concentration",
|
||||||
|
"2BD3": "Non-Methane Volatile Organic Compounds Concentration",
|
||||||
|
"2BD4": "Ozone Concentration",
|
||||||
|
"2BD5": "Particulate Matter - PM1 Concentration",
|
||||||
|
"2BD6": "Particulate Matter - PM2.5 Concentration",
|
||||||
|
"2BD7": "Particulate Matter - PM10 Concentration",
|
||||||
|
"2BD8": "Sulfur Dioxide Concentration",
|
||||||
|
"2BD9": "Sulfur Hexafluoride Concentration",
|
||||||
|
"2BDA": "Hearing Aid Features",
|
||||||
|
"2BDB": "Hearing Aid Preset Control Point",
|
||||||
|
"2BDC": "Hearing Aid Preset",
|
||||||
|
};
|
||||||
|
}
|
||||||
12
star_lock/lib/tools/reactiveBlueTool/ble_status_monitor.dart
Normal file
12
star_lock/lib/tools/reactiveBlueTool/ble_status_monitor.dart
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class BleStatusMonitor extends GetxController {
|
||||||
|
BleStatusMonitor(this._ble) {
|
||||||
|
rxBleStatus.bindStream(_ble.statusStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
final FlutterReactiveBle _ble;
|
||||||
|
|
||||||
|
final Rx<BleStatus> rxBleStatus = BleStatus.unknown.obs;
|
||||||
|
}
|
||||||
34
star_lock/lib/tools/reactiveBlueTool/getx_ble.dart
Normal file
34
star_lock/lib/tools/reactiveBlueTool/getx_ble.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
library getx_ble;
|
||||||
|
|
||||||
|
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||||
|
import 'ble_device_connector.dart';
|
||||||
|
import 'ble_device_interactor.dart';
|
||||||
|
import 'ble_logger.dart';
|
||||||
|
import 'ble_scanner.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'ble_status_monitor.dart';
|
||||||
|
|
||||||
|
export 'ble_device_connector.dart';
|
||||||
|
export 'ble_device_interactor.dart';
|
||||||
|
export 'ble_logger.dart';
|
||||||
|
export 'ble_scanner.dart';
|
||||||
|
export 'ble_status_monitor.dart';
|
||||||
|
|
||||||
|
class GetxBle extends GetxController {
|
||||||
|
static GetxBle get call => Get.find<GetxBle>();
|
||||||
|
|
||||||
|
final ble = FlutterReactiveBle();
|
||||||
|
late final BleLogger bleLogger;
|
||||||
|
late final BleStatusMonitor bleStatusMonitor;
|
||||||
|
late final BleScanner scanner;
|
||||||
|
late final BleDeviceConnector connector;
|
||||||
|
late final BleDeviceInteractor interactor;
|
||||||
|
|
||||||
|
GetxBle() {
|
||||||
|
bleLogger = BleLogger(ble: ble);
|
||||||
|
bleStatusMonitor = BleStatusMonitor(ble);
|
||||||
|
scanner = BleScanner(ble: ble, logMessage: bleLogger.addToLog);
|
||||||
|
connector = BleDeviceConnector(ble: ble, logMessage: bleLogger.addToLog);
|
||||||
|
interactor = BleDeviceInteractor(ble: ble, logMessage: bleLogger.addToLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -57,7 +57,7 @@ dependencies:
|
|||||||
#底部弹出选择器
|
#底部弹出选择器
|
||||||
flutter_picker: ^2.1.0
|
flutter_picker: ^2.1.0
|
||||||
#生成二维码
|
#生成二维码
|
||||||
qr_flutter: ^4.0.0
|
qr_flutter: ^4.1.0
|
||||||
#底部选择
|
#底部选择
|
||||||
flutter_pickers: ^2.1.9
|
flutter_pickers: ^2.1.9
|
||||||
#万年历
|
#万年历
|
||||||
@ -66,6 +66,10 @@ dependencies:
|
|||||||
image_picker: ^1.0.1
|
image_picker: ^1.0.1
|
||||||
#跳转到外部
|
#跳转到外部
|
||||||
url_launcher: ^6.1.12
|
url_launcher: ^6.1.12
|
||||||
|
#蓝牙
|
||||||
|
flutter_reactive_ble: ^5.1.1
|
||||||
|
# flutter_blue_plus: ^1.10.5
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user