调试蓝牙协议及蓝牙协议适配安卓
This commit is contained in:
parent
d6fa4edd2e
commit
cf0df90ae1
@ -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++) {
|
||||||
|
|||||||
@ -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!);
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|||||||
@ -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() {}
|
||||||
|
|||||||
@ -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("地图界面销毁了");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
}
|
||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
// 16进制字符串转化为2进制的字符串 获取的是逆序的需要倒序 前面有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());
|
||||||
|
|||||||
@ -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() {
|
||||||
|
|||||||
116
star_lock/lib/tools/permissionUtil.dart
Normal file
116
star_lock/lib/tools/permissionUtil.dart
Normal 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user