调试蓝牙协议及蓝牙协议适配安卓

This commit is contained in:
魏少阳 2023-10-12 11:24:41 +08:00
parent d6fa4edd2e
commit cf0df90ae1
13 changed files with 426 additions and 110 deletions

View File

@ -28,10 +28,12 @@ class BlueManage{
String connectDeviceMacAddress = ""; String connectDeviceMacAddress = "";
String connectDeviceName = ""; String connectDeviceName = "";
final int _limitLen = 20; // final int _limitLen = 20;
// //
StreamSubscription<EventSendModel>? _sendStreamSubscription; StreamSubscription<EventSendModel>? _sendStreamSubscription;
StreamSubscription? _scanSubscription;
// //
DeviceConnectionState? deviceConnectionState = DeviceConnectionState.disconnected; DeviceConnectionState? deviceConnectionState = DeviceConnectionState.disconnected;
@ -64,25 +66,41 @@ class BlueManage{
} }
/// ///
void startScan(ScanResultCallBack scanResultCallBack) { void startScan(bool isScanAll, ScanResultCallBack scanResultCallBack) {
_scanDevices.clear(); _scanDevices.clear();
_flutterReactiveBle!.scanForDevices(withServices: []).listen((device) { _scanSubscription = _flutterReactiveBle!.scanForDevices(withServices: []).listen((device) {
// //
if(device.name.isEmpty){ if(device.name.isEmpty){
return; return;
} }
// print("startScanDevice:${device}"); print("startScanDevice:${device}");
if (((device.serviceUuids.isNotEmpty ? device.serviceUuids[0] : "").toString().contains("758824")) && ((device.serviceUuids.isNotEmpty ? device.serviceUuids[0] : "").toString()[31] != "1") && (device.rssi >= -100)) { //
final knownDeviceIndex = _scanDevices.indexWhere((d) => d.id == device.id); if(isScanAll == true){
if (((device.serviceUuids.isNotEmpty ? device.serviceUuids[0] : "").toString().contains("758824"))&& (device.rssi >= -100)) {
if (knownDeviceIndex >= 0) { // id相同的元素
_scanDevices[knownDeviceIndex] = device; final knownDeviceIndex = _scanDevices.indexWhere((d) => d.id == device.id);
} else { // -1
_scanDevices.add(device); if (knownDeviceIndex >= 0) {
_scanDevices[knownDeviceIndex] = device;
} else {
_scanDevices.add(device);
}
scanResultCallBack(_scanDevices);
}
}else{
if (((device.serviceUuids.isNotEmpty ? device.serviceUuids[0] : "").toString().contains("758824")) && ((device.serviceUuids.isNotEmpty ? device.serviceUuids[0] : "").toString()[31] != "1") && (device.rssi >= -100)) {
// id相同的元素
final knownDeviceIndex = _scanDevices.indexWhere((d) => d.id == device.id);
// -1
if (knownDeviceIndex >= 0) {
_scanDevices[knownDeviceIndex] = device;
} else {
_scanDevices.add(device);
}
scanResultCallBack(_scanDevices);
} }
scanResultCallBack(_scanDevices);
} }
// _pushState();
}, onError: (Object e) { }, onError: (Object e) {
print('Device scan fails with error: $e'); print('Device scan fails with error: $e');
}); });
@ -161,7 +179,7 @@ class BlueManage{
IoSenderManage.getPublicKey(lockId: deviceName); IoSenderManage.getPublicKey(lockId: deviceName);
// } // }
} }
connectStateCallBack!(connectionStateUpdate.connectionState); // connectStateCallBack!(connectionStateUpdate.connectionState);
} on Exception catch (e) { } on Exception catch (e) {
EasyLoading.dismiss(); EasyLoading.dismiss();
print('Error occurred when discovering services: $e'); print('Error occurred when discovering services: $e');
@ -175,6 +193,12 @@ class BlueManage{
); );
} }
///
Future<void> stopScan() async {
await _scanSubscription?.cancel();
_scanSubscription = null;
}
// //
Future<void> disconnect(String deviceMAC) async { Future<void> disconnect(String deviceMAC) async {
try { try {
@ -263,24 +287,34 @@ class BlueManage{
// code to handle incoming data // code to handle incoming data
print("subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data"); print("subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data");
var dataLen = 0;// 16 var dataLen = 0;// 16
if((data[0] != 0xEF)&&(data[1] != 0x01)&&(data[2] != 0xEE)&&(data[3] != 0x02)){
// if((data[0] == 0xEF)&&(data[1] == 0x01)&&(data[2] == 0xEE)&&(data[3] == 0x02)){
allData.addAll(data); //
}else{ //
dataLen = data[8] * 256 + data[9]; dataLen = data[8] * 256 + data[9];
allData = <int>[]; print("dataLen1111:$dataLen getDataLength:${data.length}");
// if(dataLen + 12 > data.length){
if(dataLen > (data.length - 12)){ //
// ,
allData.addAll(data); allData.addAll(data);
return;
}else{ }else{
// //
allData = data; allData.addAll(data);
CommandReciverManager.appDataReceive(allData);
//
allData = <int>[];
}
}else{
//
allData.addAll(data);
// var len = allData[8] * 256 + allData[9];
print("dataLen222:$dataLen");
if(dataLen <= (allData.length - 14)){
//
CommandReciverManager.appDataReceive(allData);
//
allData = <int>[];
} }
} }
CommandReciverManager.appDataReceive(allData);
}, onError: (dynamic error) { }, onError: (dynamic error) {
EasyLoading.dismiss(); EasyLoading.dismiss();
print("subscribeToCharacteristic error:$error"); print("subscribeToCharacteristic error:$error");
@ -291,11 +325,11 @@ class BlueManage{
Future<void> writeCharacteristicWithResponse(List<int> value) async { Future<void> writeCharacteristicWithResponse(List<int> value) async {
QualifiedCharacteristic characteristic = QualifiedCharacteristic(characteristicId: characteristicIdWrite, serviceId: serviceId, deviceId: connectDeviceMacAddress); QualifiedCharacteristic characteristic = QualifiedCharacteristic(characteristicId: characteristicIdWrite, serviceId: serviceId, deviceId: connectDeviceMacAddress);
print('Write with characteristicId${characteristic.characteristicId} serviceId${characteristic.serviceId} deviceId${characteristic.deviceId} value : $value \nhexStr:${radixHex16String(value)}'); print('Write with characteristicId${characteristic.characteristicId} serviceId${characteristic.serviceId} deviceId${characteristic.deviceId} value : $value \nhexStr:${radixHex16String(value)}');
int mtuLength = await _flutterReactiveBle!.requestMtu(deviceId: characteristic.deviceId, mtu: 512); int mtuLength = await _flutterReactiveBle!.requestMtu(deviceId: characteristic.deviceId, mtu: 250);
print("mtuLength:$mtuLength"); print("mtuLength:$mtuLength");
try { try {
List<int> valueList = value; List<int> valueList = value;
List subData = splitList(valueList, _limitLen); List subData = splitList(valueList, mtuLength);
print('得到的分割数据:$subData'); print('得到的分割数据:$subData');
for (int i = 0; i < subData.length; i++) { for (int i = 0; i < subData.length; i++) {

View File

@ -65,11 +65,11 @@ class GetPrivateKeyCommand extends SenderProtocol {
//NowTime 4 //NowTime 4
// DateTime now = DateTime.now(); // DateTime now = DateTime.now();
// int timestamp = now.millisecondsSinceEpoch; // int timestamp = now.millisecondsSinceEpoch;
var d1 = 0x11223344; // var d1 = 0x11223344;
data.add((d1 & 0xff000000) >> 24); data.add((nowTime! & 0xff000000) >> 24);
data.add((d1 & 0xff0000) >> 16); data.add((nowTime! & 0xff0000) >> 16);
data.add((d1 & 0xff00) >> 8); data.add((nowTime! & 0xff00) >> 8);
data.add((d1 & 0xff)); data.add((nowTime! & 0xff));
if (needAuthor == 0) { if (needAuthor == 0) {
data.add(0); data.add(0);
@ -85,11 +85,11 @@ class GetPrivateKeyCommand extends SenderProtocol {
//NowTime 4 //NowTime 4
// DateTime now = DateTime.now(); // DateTime now = DateTime.now();
// int timestamp = now.millisecondsSinceEpoch; // int timestamp = now.millisecondsSinceEpoch;
var d1 = 0x11223344; // var d1 = 0x11223344;
authCodeData.add((d1 & 0xff000000) >> 24); authCodeData.add((nowTime! & 0xff000000) >> 24);
authCodeData.add((d1 & 0xff0000) >> 16); authCodeData.add((nowTime! & 0xff0000) >> 16);
authCodeData.add((d1 & 0xff00) >> 8); authCodeData.add((nowTime! & 0xff00) >> 8);
authCodeData.add((d1 & 0xff)); authCodeData.add((nowTime! & 0xff));
authCodeData.addAll(publicKeyData!); authCodeData.addAll(publicKeyData!);

View File

@ -256,17 +256,25 @@ List<int> intToByte2ListLow(int value) => [value >> 8, value];
String radixHex16String(List<int> codeUnits) { String radixHex16String(List<int> codeUnits) {
String result = ''; String result = '';
codeUnits.forEach((value) { for (var value in codeUnits) {
result += value.toRadixString(16).padLeft(2, '0'); result += value.toRadixString(16).padLeft(2, '0');
}
return result;
}
String radixHex16StringTo2String(List<int> codeUnits) {
String result = '';
codeUnits.forEach((value) {
result += int.parse(value.toRadixString(16).padLeft(2, '0'),radix: 16).toRadixString(2);
}); });
return result; return result;
} }
String asciiString(List<int> codeUnits) { String asciiString(List<int> codeUnits) {
String result = ''; String result = '';
codeUnits.forEach((value) { for (var value in codeUnits) {
result += String.fromCharCode(value); result += String.fromCharCode(value);
}); }
return result; return result;
} }

View File

@ -15,6 +15,8 @@ import 'appRouters.dart';
import 'baseWidget.dart'; import 'baseWidget.dart';
import 'tools/appRouteObserver.dart'; import 'tools/appRouteObserver.dart';
import 'tools/store_service.dart'; import 'tools/store_service.dart';
import 'dart:io';
import 'package:flutter/services.dart';
void main() async { void main() async {
@ -24,6 +26,11 @@ void main() async {
await _initTranslation(); await _initTranslation();
runApp(MyApp()); runApp(MyApp());
if (Platform.isAndroid) {
SystemUiOverlayStyle systemUiOverlayStyle = const SystemUiOverlayStyle(statusBarColor: Colors.transparent);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
}
} }
class MyApp extends StatefulWidget { class MyApp extends StatefulWidget {

View File

@ -394,7 +394,7 @@ class LockDetailLogic extends BaseGetXController{
// //
Future<void> openDoorAction() async { Future<void> openDoorAction() async {
BlueManage().judgeReconnect(state.keyInfos.value.bluetooth!.bluetoothDeviceId!, state.keyInfos.value.bluetooth!.bluetoothDeviceName!, (DeviceConnectionState state) async { BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, state.keyInfos.value.bluetooth!.bluetoothDeviceName!, (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected){ if (state == DeviceConnectionState.connected){
var privateKey = await Storage.getStringList(saveBluePrivateKey); var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!); List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
@ -483,9 +483,9 @@ class LockDetailLogic extends BaseGetXController{
} }
// //
Future<void> connectBlue() async { Future<void> connectBlue(String bluetoothDeviceId, String bluetoothDeviceName) async {
// //
BlueManage().connect(state.keyInfos.value.bluetooth!.bluetoothDeviceId!, state.keyInfos.value.bluetooth!.bluetoothDeviceName!, connectStateCallBack: (DeviceConnectionState state) async { BlueManage().connect(bluetoothDeviceId, bluetoothDeviceName, connectStateCallBack: (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected){ if (state == DeviceConnectionState.connected){
var privateKey = await Storage.getStringList(saveBluePrivateKey); var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!); List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
@ -503,6 +503,18 @@ class LockDetailLogic extends BaseGetXController{
}, isShowLoading: false); }, isShowLoading: false);
} }
void startScanAction(){
BlueManage().startScan(true, (v){
// print("startScanAllDevice:${v}");
final knownDeviceIndex = v.indexWhere((d) => d.name == state.keyInfos.value.bluetooth!.bluetoothDeviceName!);
//
if (knownDeviceIndex >= 0) {
connectBlue(v[knownDeviceIndex].id, state.keyInfos.value.bluetooth!.bluetoothDeviceName!);
BlueManage().connectDeviceMacAddress = v[knownDeviceIndex].id;
}
});
}
@override @override
void onReady() { void onReady() {
// TODO: implement onReady // TODO: implement onReady
@ -510,9 +522,7 @@ class LockDetailLogic extends BaseGetXController{
print("onReady()"); print("onReady()");
_initReplySubscription(); _initReplySubscription();
// BlueManage().startScan((v){ startScanAction();
//
// });
} }
@override @override

View File

@ -42,8 +42,8 @@ class _LockDetailPageState extends State<LockDetailPage> with RouteAware {
state.keyInfos.value = widget.keyInfo; state.keyInfos.value = widget.keyInfo;
BlueManage().connectDeviceName = BlueManage().connectDeviceName =
state.keyInfos.value.bluetooth!.bluetoothDeviceName!; state.keyInfos.value.bluetooth!.bluetoothDeviceName!;
BlueManage().connectDeviceMacAddress = // BlueManage().connectDeviceMacAddress =
state.keyInfos.value.bluetooth!.bluetoothDeviceId!; // state.keyInfos.value.bluetooth!.bluetoothDeviceId!;
List<int> publicKeyData = List<int> publicKeyData =
state.keyInfos.value.bluetooth!.publicKey!.cast<int>(); state.keyInfos.value.bluetooth!.publicKey!.cast<int>();
@ -63,7 +63,7 @@ class _LockDetailPageState extends State<LockDetailPage> with RouteAware {
Storage.setStringList(saveBlueSignKey, saveSignKeyList); Storage.setStringList(saveBlueSignKey, saveSignKeyList);
// print("publicKeyData:$publicKeyData saveStrList:$saveStrList privateKeyData:$privateKeyData savePrivateKeyList:$savePrivateKeyList"); // print("publicKeyData:$publicKeyData saveStrList:$saveStrList privateKeyData:$privateKeyData savePrivateKeyList:$savePrivateKeyList");
logic.connectBlue(); // logic.startScanAction();
} }
@override @override
@ -338,6 +338,7 @@ class _LockDetailPageState extends State<LockDetailPage> with RouteAware {
bottomItem( bottomItem(
'images/main/icon_main_set.png', TranslationLoader.lanKeys!.set!.tr, 'images/main/icon_main_set.png', TranslationLoader.lanKeys!.set!.tr,
() { () {
BlueManage().stopScan();
Get.toNamed(Routers.lockSetPage, arguments: widget.keyInfo); Get.toNamed(Routers.lockSetPage, arguments: widget.keyInfo);
}), }),
]; ];

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../../appRouters.dart'; import '../../../appRouters.dart';
import '../../../app_settings/app_colors.dart'; import '../../../app_settings/app_colors.dart';
@ -70,13 +71,41 @@ class _AddLockPageState extends State<AddLockPage> with BaseWidget {
btnName: TranslationLoader.lanKeys!.next!.tr, btnName: TranslationLoader.lanKeys!.next!.tr,
borderRadius: 20.w, borderRadius: 20.w,
onClick: () { onClick: () {
Navigator.pushNamed(context, Routers.nearbyLockPage); getMicrophonePermission()
.then((value) {
if (value) {
//
Navigator.pushNamed(context, Routers.nearbyLockPage);
}else{
//
openAppSettings();//app系统设置
}
});
}), }),
], ],
), ),
); );
} }
///
Future<bool> getMicrophonePermission() async {
// You can request multiple permissions at once.
Map<Permission, PermissionStatus> statuses = await [
Permission.bluetoothScan,
Permission.bluetoothConnect,
Permission.location,
].request();
//granted denied permanentlyDenied
if (statuses[Permission.bluetoothScan]!.isGranted &&
statuses[Permission.bluetoothConnect]!.isGranted &&
statuses[Permission.location]!.isGranted) {
return true;
}
return false;
}
void onShow() {} void onShow() {}
void onHide() {} void onHide() {}

View File

@ -16,11 +16,9 @@ import '../../../../app_settings/app_colors.dart';
import '../../../../tools/titleAppBar.dart'; import '../../../../tools/titleAppBar.dart';
import '../../../../tools/toast.dart'; import '../../../../tools/toast.dart';
import '../../../../translations/trans_lib.dart'; import '../../../../translations/trans_lib.dart';
import 'lockAddressGaoDe_logic.dart';
// typedef BlockAddressMapCallback = void Function(dynamic addressMap);
class LockAddressGaoDePage extends StatefulWidget { class LockAddressGaoDePage extends StatefulWidget {
// BlockAddressMapCallback callback;
const LockAddressGaoDePage({Key? key}) : super(key: key); const LockAddressGaoDePage({Key? key}) : super(key: key);
@ -29,11 +27,14 @@ class LockAddressGaoDePage extends StatefulWidget {
} }
class _LockAddressGaoDePageState extends State<LockAddressGaoDePage>{ class _LockAddressGaoDePageState extends State<LockAddressGaoDePage>{
final logic = Get.put(LockAddressGaoDeLogic());
final state = Get.find<LockAddressGaoDeLogic>().state;
// //
static const AMapApiKey amapApiKeys = AMapApiKey(iosKey: '883a3355d2d77c2fdc2667030dc97ffe', androidKey: '11d49b3f4fc09c04a02bbb7500925ba2'); static const AMapApiKey amapApiKeys = AMapApiKey(iosKey: '883a3355d2d77c2fdc2667030dc97ffe', androidKey: '11d49b3f4fc09c04a02bbb7500925ba2');
AMapController? mapController; AMapController? mapController;
AMapFlutterLocation? location; AMapFlutterLocation location = AMapFlutterLocation();
PermissionStatus? permissionStatus; PermissionStatus? permissionStatus;
Map<String, Object>? addressInfo; Map<String, Object>? addressInfo;
@ -44,9 +45,12 @@ class _LockAddressGaoDePageState extends State<LockAddressGaoDePage>{
AMapFlutterLocation.updatePrivacyAgree(true); AMapFlutterLocation.updatePrivacyAgree(true);
AMapFlutterLocation.updatePrivacyShow(true, true); AMapFlutterLocation.updatePrivacyShow(true, true);
AMapFlutterLocation.setApiKey("11d49b3f4fc09c04a02bbb7500925ba2", "883a3355d2d77c2fdc2667030dc97ffe");
requestPermission(); requestPermission();
AMapFlutterLocation.setApiKey("11d49b3f4fc09c04a02bbb7500925ba2", "883a3355d2d77c2fdc2667030dc97ffe");
requestLocation();
} }
Future<void> requestPermission() async { Future<void> requestPermission() async {
@ -58,37 +62,29 @@ class _LockAddressGaoDePageState extends State<LockAddressGaoDePage>{
print("拒绝"); print("拒绝");
break; break;
case PermissionStatus.granted: case PermissionStatus.granted:
requestLocation(); _setLocationOption();
location.startLocation();
break; break;
case PermissionStatus.limited: case PermissionStatus.limited:
print("限制"); print("限制");
break; break;
default: default:
print("其他状态"); print("其他状态");
requestLocation(); // requestLocation();
break; break;
} }
} }
Future<void> requestLocation() async { Future<void> requestLocation() async {
location = AMapFlutterLocation() location.onLocationChanged().listen((event) {
..setLocationOption(AMapLocationOption())
..onLocationChanged().listen((event) {
print("listenLocationChanged$event"); print("listenLocationChanged$event");
// double? latitude = double.parse(event['latitude']);
// double? longitude = double.parse(event['longitude'] as String);
if (event.isNotEmpty) { if (event.isNotEmpty) {
// widget.callback(event);
setState(() { setState(() {
addressInfo = event; addressInfo = event;
// currentLocation = CameraPosition(
// target: LatLng(latitude, longitude),
// zoom: 10,
// );
}); });
location.stopLocation();
} }
}) });
..startLocation();
} }
@override @override
@ -110,7 +106,10 @@ class _LockAddressGaoDePageState extends State<LockAddressGaoDePage>{
Toast.show(msg:"还未获取到位置信息哦,请耐心等待一下!"); Toast.show(msg:"还未获取到位置信息哦,请耐心等待一下!");
return; return;
} }
Get.toNamed(Routers.saveLockPage, arguments: addressInfo); Get.toNamed(Routers.saveLockPage, arguments: {
"addressInfo": addressInfo,
"pwdTimestamp": state.pwdTimestamp.value,
});
// Navigator.pushNamed(context, Routers.saveLockPage); // Navigator.pushNamed(context, Routers.saveLockPage);
}, },
), ),
@ -133,7 +132,7 @@ class _LockAddressGaoDePageState extends State<LockAddressGaoDePage>{
// //
initialCameraPosition: ( initialCameraPosition: (
CameraPosition( CameraPosition(
target: LatLng(double.parse(addressInfo!['latitude'] as String), double.parse(addressInfo!['longitude'] as String)), target: LatLng(double.parse(addressInfo!['latitude'].toString()), double.parse(addressInfo!['longitude'].toString())),
zoom: 10.0, zoom: 10.0,
) )
), ),
@ -202,11 +201,58 @@ class _LockAddressGaoDePageState extends State<LockAddressGaoDePage>{
} }
///
void _setLocationOption() {
AMapLocationOption locationOption = AMapLocationOption();
///
locationOption.onceLocation = true;
///
locationOption.needAddress = true;
///
locationOption.geoLanguage = GeoLanguage.DEFAULT;
locationOption.desiredLocationAccuracyAuthorizationMode = AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;
locationOption.fullAccuracyPurposeKey = "AMapLocationScene";
///Android端连续定位的定位间隔
locationOption.locationInterval = 2000;
///Android端的定位模式<br>
///<br>
///<li>[AMapLocationMode.Battery_Saving]</li>
///<li>[AMapLocationMode.Device_Sensors]</li>
///<li>[AMapLocationMode.Hight_Accuracy]</li>
locationOption.locationMode = AMapLocationMode.Battery_Saving;
///iOS端的定位最小更新距离<br>
locationOption.distanceFilter = -1;
///iOS端期望的定位精度
/// <br>
/// <li>[DesiredAccuracy.Best] </li>
/// <li>[DesiredAccuracy.BestForNavigation] </li>
/// <li>[DesiredAccuracy.NearestTenMeters] 10 </li>
/// <li>[DesiredAccuracy.Kilometer] 1000</li>
/// <li>[DesiredAccuracy.ThreeKilometers] 3000</li>
locationOption.desiredAccuracy = DesiredAccuracy.BestForNavigation;
///iOS端是否允许系统暂停定位
locationOption.pausesLocationUpdatesAutomatically = false;
///
location.setLocationOption(locationOption);
}
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
location?.destroy(); location.destroy();
print("地图界面销毁了"); print("地图界面销毁了");
} }
} }

View File

@ -7,11 +7,9 @@ import 'package:permission_handler/permission_handler.dart';
class LockAddressGaoDeState{ class LockAddressGaoDeState{
// AMapController? mapController; var pwdTimestamp= 0.obs;
// AMapFlutterLocation? location; LockAddressGaoDeState() {
// // PermissionStatus? permissionStatus; Map map = Get.arguments;
// pwdTimestamp.value = map["pwdTimestamp"];
// final addressInfo = {}.obs; }
// final latitude = 39.909187.obs;
// final longitude = 116.397451.obs;
} }

View File

@ -18,6 +18,7 @@ import '../../../blue/io_tool/io_model.dart';
import '../../../blue/io_tool/io_tool.dart'; import '../../../blue/io_tool/io_tool.dart';
import '../../../blue/io_tool/manager_event_bus.dart'; import '../../../blue/io_tool/manager_event_bus.dart';
import '../../../blue/sender_manage.dart'; import '../../../blue/sender_manage.dart';
import '../../../tools/dateTool.dart';
import '../../../tools/storage.dart'; import '../../../tools/storage.dart';
import 'nearbyLock_state.dart'; import 'nearbyLock_state.dart';
@ -27,7 +28,8 @@ class NearbyLockLogic extends BaseGetXController{
// //
void connect(String lockId, String deviceName){ void connect(String lockId, String deviceName){
BlueManage().connect(lockId, deviceName, isFrist: true); // BlueManage().stopScan();
BlueManage().connect(lockId, deviceName, isFrist: true, isShowLoading: true);
} }
// //
@ -44,7 +46,7 @@ class NearbyLockLogic extends BaseGetXController{
}); });
} }
void _replyGetPublicKey(Reply reply){ Future<void> _replyGetPublicKey(Reply reply) async {
// //
switch(reply.status){ switch(reply.status){
case 0x00: case 0x00:
@ -58,8 +60,8 @@ class NearbyLockLogic extends BaseGetXController{
IoSenderManage.getPrivateKey( IoSenderManage.getPrivateKey(
lockId:BlueManage().connectDeviceName, lockId:BlueManage().connectDeviceName,
keyID:"1", keyID:"1",
authUserID:"1", authUserID:await Storage.getUid(),
nowTime:1, nowTime:DateTime.now().millisecondsSinceEpoch~/1000,
publicKeyData:publicKey, publicKeyData:publicKey,
needAuthor:1); needAuthor:1);
break; break;
@ -84,18 +86,33 @@ class NearbyLockLogic extends BaseGetXController{
// //
print('获取私钥成功'); print('获取私钥成功');
reply.data.removeAt(0); reply.data.removeAt(0);
print("reply.data:${reply.data}");
// //
List<int> privateKey = reply.data.sublist(0, 16); List<int> privateKey = reply.data.sublist(0, 16);
print("privateKey:$privateKey");
var savePrivateKeyList = changeIntListToStringList(privateKey); var savePrivateKeyList = changeIntListToStringList(privateKey);
Storage.setStringList(saveBluePrivateKey, savePrivateKeyList); Storage.setStringList(saveBluePrivateKey, savePrivateKeyList);
// signKey // signKey
List<int> signKey = reply.data.sublist(16, 32); List<int> signKey = reply.data.sublist(16, 32);
print("signKey:$signKey");
var saveSignKeyList = changeIntListToStringList(signKey); var saveSignKeyList = changeIntListToStringList(signKey);
Storage.setStringList(saveBlueSignKey, saveSignKeyList); Storage.setStringList(saveBlueSignKey, saveSignKeyList);
Get.toNamed(Routers.lockAddressGaoDePage); //
List<int> timestamp = reply.data.sublist(32, 36);
int timestampValue = (
(0xff & timestamp[(0)]) << 24 |
(0xff & timestamp[1]) << 16 |
(0xff & timestamp[2]) << 8 |
(0xFF & timestamp[3]));
String timestampValueStr = DateTool().dateToYMDHNSString(timestampValue.toString());
print("timestamp:$timestamp timestampValue:$timestampValue timestampValueStr:$timestampValueStr");
Get.toNamed(Routers.lockAddressGaoDePage, arguments: {
"pwdTimestamp": timestampValue*1000,
});
break; break;
case 0x07: case 0x07:
// //
@ -129,7 +146,7 @@ class NearbyLockLogic extends BaseGetXController{
print("NearbyLockLogic onInit()"); print("NearbyLockLogic onInit()");
// //
BlueManage().startScan((v){ BlueManage().startScan(false ,(v){
state.devices.clear(); state.devices.clear();
state.devices.addAll(v); state.devices.addAll(v);
}); });
@ -140,6 +157,7 @@ class NearbyLockLogic extends BaseGetXController{
// TODO: implement onClose // TODO: implement onClose
super.onClose(); super.onClose();
_replySubscription.cancel(); _replySubscription.cancel();
BlueManage().stopScan();
} }
} }

View File

@ -17,6 +17,7 @@ import '../../../blue/io_tool/manager_event_bus.dart';
import '../../../blue/sender_manage.dart'; import '../../../blue/sender_manage.dart';
import '../../../network/api_repository.dart'; import '../../../network/api_repository.dart';
import '../../../tools/baseGetXController.dart'; import '../../../tools/baseGetXController.dart';
import '../../../tools/dateTool.dart';
import '../../../tools/eventBusEventManage.dart'; import '../../../tools/eventBusEventManage.dart';
import '../../../tools/storage.dart'; import '../../../tools/storage.dart';
import 'saveLock_state.dart'; import 'saveLock_state.dart';
@ -192,7 +193,8 @@ class SaveLockLogic extends BaseGetXController {
print("${reply.commandType}数据解析成功"); print("${reply.commandType}数据解析成功");
// //
var vendor = reply.data.sublist(3, 23); var vendor = reply.data.sublist(3, 23);
print("softVersion:$vendor"); var vendorStr = utf8String(vendor);
print("softVersion:$vendor vendorStr:$vendorStr");
// //
var product = reply.data[23]; var product = reply.data[23];
@ -200,11 +202,13 @@ class SaveLockLogic extends BaseGetXController {
// //
var model = reply.data.sublist(24, 44); var model = reply.data.sublist(24, 44);
print("model:$model"); var modelStr = utf8String(model);
print("model:$model modelStr:$modelStr");
// //
var fwVersion = reply.data.sublist(44, 64); var fwVersion = reply.data.sublist(44, 64);
print("fwVersion:$fwVersion"); var fwVersionStr = utf8String(fwVersion);
print("fwVersion:$fwVersion fwVersionStr:$fwVersionStr");
// //
var hwVersion = reply.data.sublist(64, 84); var hwVersion = reply.data.sublist(64, 84);
@ -220,27 +224,54 @@ class SaveLockLogic extends BaseGetXController {
// //
var btDeviceName = reply.data.sublist(116, 132); var btDeviceName = reply.data.sublist(116, 132);
print("btDeviceName:$btDeviceName"); var btDeviceNameStr = utf8String(btDeviceName);
print("btDeviceName:$btDeviceName btDeviceNameStr:$btDeviceNameStr");
// //
var battRemCap = reply.data[132]; var battRemCap = reply.data[132];
print("battRemCap:$battRemCap"); print("battRemCap:$battRemCap");
// //
var restoreCounter = reply.data.sublist(133, 134); var restoreCounter = reply.data.sublist(133, 135);
print("restoreCounter:$restoreCounter"); print("restoreCounter:$restoreCounter");
// //
var restoreDate = reply.data.sublist(134, 138); var restoreDate = reply.data.sublist(135, 139);
print("restoreDate:$restoreDate"); int restoreDateValue = ((0xff & restoreDate[(0)]) << 24 | (0xff & restoreDate[1]) << 16 | (0xff & restoreDate[2]) << 8 | (0xFF & restoreDate[3]));
String restoreDateStr = DateTool().dateToYMDHNSString(restoreDateValue.toString());
print("restoreDate:$restoreDate restoreDateStr:$restoreDateStr");
// //
var icPartNo = reply.data.sublist(138, 148); var icPartNo = reply.data.sublist(139, 149);
print("icPartNo:$icPartNo"); var icPartNoStr = utf8String(icPartNo);
print("icPartNo:$icPartNo icPartNoStr:$icPartNoStr");
// //
var indate = reply.data.sublist(148, 152); var indate = reply.data.sublist(149, 153);
print("indate:$indate"); int indateValue = ((0xff & restoreDate[(0)]) << 24 | (0xff & restoreDate[1]) << 16 | (0xff & restoreDate[2]) << 8 | (0xFF & restoreDate[3]));
String indateStr = DateTool().dateToYMDHNSString(indateValue.toString());
print("indate:$indate indateStr:$indateStr");
var index = 153;
//
var featureValueLength = reply.data[153];
// ()
//
var featureValue = reply.data.sublist(index+1, index + featureValueLength+1);
List allFeatureValueTwoList = charListChangeIntList(featureValue);
// print("featureValueLength:$featureValueLength featureValue:$featureValue \n allFeatureValueTwoList:$allFeatureValueTwoList");
index = index + featureValueLength + 1;
// 使
var featureEnValLength = reply.data[index];
// 使()
var featureEnVal = reply.data.sublist(index+1, index + featureEnValLength+1);
List allFeatureEnValTwoList = charListChangeIntList(featureEnVal);
// print("featureEnValLength:$featureEnValLength featureEnVal:$featureEnVal \n allFeatureEnValTwoList:$allFeatureEnValTwoList");
index = index + featureEnValLength + 1;
//
var featureParaTotal = reply.data[index];
break; break;
case 0x06: case 0x06:
@ -266,6 +297,20 @@ class SaveLockLogic extends BaseGetXController {
} }
} }
List charListChangeIntList(List<int> featureValue){
// 16
String featureValueStr = asciiString(featureValue);
// 162 0 57 60
String featureValueTwoStr = int.parse(featureValueStr,radix: 16).toRadixString(2);
List<int> featureValueTwoList = [];
for(int i = 0;i<featureValueTwoStr.length;i++){
featureValueTwoList.add(int.parse(featureValueTwoStr[i]));
}
featureValueTwoList = featureValueTwoList.reversed.toList();
List allFeatureValueTwoList = getFixedLengthList(featureValueTwoList, 60 - featureValueTwoList.length);
return allFeatureValueTwoList;
}
// //
saveLockAction(){ saveLockAction(){
addUserConnectBlue(); addUserConnectBlue();
@ -312,18 +357,18 @@ class SaveLockLogic extends BaseGetXController {
void bindBlueAdmin() async{ void bindBlueAdmin() async{
var lockDataMap = {}; var lockDataMap = {};
lockDataMap['lockName'] = BlueManage().connectDeviceName; lockDataMap['lockName'] = BlueManage().connectDeviceName;
lockDataMap['lockMac'] = "AB:C1:40:61:54:61"; lockDataMap['lockMac'] = BlueManage().connectDeviceMacAddress;
// lockDataMap['lockMac'] = BlueManage().connectDeviceMacAddress; // lockDataMap['lockMac'] = BlueManage().connectDeviceMacAddress;
var positionMap = {}; var positionMap = {};
positionMap['longitude'] = state.addressMap["longitude"]; positionMap['longitude'] = state.addressInfo["longitude"];
positionMap['latitude'] = state.addressMap["latitude"]; positionMap['latitude'] = state.addressInfo["latitude"];
positionMap['country'] = state.addressMap["country"]; positionMap['country'] = state.addressInfo["country"];
positionMap['province'] = state.addressMap["province"]; positionMap['province'] = state.addressInfo["province"];
positionMap['city'] = state.addressMap["city"]; positionMap['city'] = state.addressInfo["city"];
positionMap['district'] = state.addressMap["district"]; positionMap['district'] = state.addressInfo["district"];
positionMap['township'] = state.addressMap["street"]; positionMap['township'] = state.addressInfo["street"];
positionMap['address'] = state.addressMap["address"]; positionMap['address'] = state.addressInfo["address"];
var bluetooth = {}; var bluetooth = {};
bluetooth['bluetoothDeviceId'] = BlueManage().connectDeviceMacAddress; bluetooth['bluetoothDeviceId'] = BlueManage().connectDeviceMacAddress;
@ -354,7 +399,7 @@ class SaveLockLogic extends BaseGetXController {
deviceNo:"123456", deviceNo:"123456",
// lockUserNo:userNo.toString(), // lockUserNo:userNo.toString(),
lockUserNo:"1234", lockUserNo:"1234",
pwdTimestamp:DateTime.now().millisecondsSinceEpoch.toString() pwdTimestamp:state.pwdTimestamp.value.toString()
); );
if(entity.errorCode!.codeIsSuccessful){ if(entity.errorCode!.codeIsSuccessful){
eventBus.fire(RefreshLockListInfoDataEvent()); eventBus.fire(RefreshLockListInfoDataEvent());

View File

@ -7,13 +7,17 @@ import '../../../blue/blue_manage.dart';
class SaveLockState { class SaveLockState {
var aliName = ''.obs; var aliName = ''.obs;
var addressMap = {}.obs; var pwdTimestamp= 0.obs;
var addressInfo = {}.obs;
TextEditingController aliNameController = TextEditingController(); TextEditingController aliNameController = TextEditingController();
SaveLockState() { SaveLockState() {
aliName.value = BlueManage().connectDeviceName; aliName.value = BlueManage().connectDeviceName;
aliNameController.text = aliName.value; aliNameController.text = aliName.value;
addressMap.value = Get.arguments as Map;
Map map = Get.arguments;
pwdTimestamp.value = map["pwdTimestamp"];
addressInfo.value = map["addressInfo"];
} }
void onClose() { void onClose() {

View File

@ -0,0 +1,116 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
/// @ClassName ${NAME}
/// : szj
/// : ${DATE} ${TIME}
/// CSDN:https://blog.csdn.net/weixin_44819566
/// :
typedef BlockScuessStatus = void Function();
class PermissionUtil {
PermissionUtil(this._context);
final List<String> _list = [
"为了更好地应用体验,请确定权限",
"您第一次拒绝权限,请确定权限",
"您第二次拒绝权限,请去应用设置开启权限"
];
final BuildContext _context ;
void checkPermission({PermissionStatus? status, BlockScuessStatus? blockScuessStatus}) async {
// permission_handler: ^5.0.1+1
//
Permission permission = Permission.location;
status ??= await permission.status;
print("statusstatusstatus:$status");
if (status.isDenied) {
//
showPermissionDialog(_list[0], "同意", permission);
} else if (status.isDenied) {
//
showPermissionDialog(_list[1], "重试", permission);
} else if (status.isPermanentlyDenied) {
//
showPermissionDialog(_list[2], "去应用市场", permission,isUndetermined: true);
} else if (status.isGranted) {
//
blockScuessStatus!();
} else {
//
}
}
///
bool isGoAppSetteng = false;
///msg
///rightMsg
///
/// isUndetermined ,
void showPermissionDialog(
String msg, String rightMsg, Permission permission,{bool isUndetermined = false}) {
//使dialog
showCupertinoDialog(
builder: (BuildContext context) {
return CupertinoAlertDialog(
title: Text("温馨提示"),
content: Container(
child: Text(msg),
),
actions: [
//
CupertinoDialogAction(
child: Text("关闭应用"),
onPressed: (){
//
closeAPP();
},
),
//
CupertinoDialogAction(
child: Text(rightMsg),
onPressed: () {
//
Navigator.pop(context);
if(isUndetermined){
isGoAppSetteng = true;
//
openAppSettings();
}else{
//
isGoAppSetteng = false;
requestPermission(context,permission);
}
},
),
],
);
},
context: _context);
}
void requestPermission(BuildContext context,Permission permission) async {
//
PermissionStatus status = await permission.request();
//
checkPermission(status: status);
}
//
void closeAPP() {
SystemChannels.platform.invokeMethod("SystemNavigator.pop");
}
}