关注公众号: 微信搜索 前端工具人 ; 收货更多的干货
一、项目场景
地下车库无网路的情况下需要使用蓝牙对小区门禁进行开门
二、遇到的坑:
2.1 坑一
安卓端引入flutter_blue运行项目报错
- 原因: 安卓sdk版本需要28以上
- 解决:
android/build.gradle下修改compileSdkVersionminSdkVersion为28minSdkVersion修改为19
android {
.............
compileSdkVersion 28
.............
defaultConfig {
minSdkVersion 19
targetSdkVersion 28
}
.............
}
2.1 坑二
ios引入flutter_blue运行项目报错
- 原因:
windows创建的flutterswift语言, 而ios要的是objc - 解决: 新建空目录使用
flutter create -i objc my-flutter-app创建新项目, 在把原项目下lib文件夹下的所有文件替换新创建的lib文件夹, 这就可以了;Android\ios端都没问题
附上实际项目的源码; 其他的坑暂时就没想起来了,反正坑蛮多,初期运行时也是控制台各种报错
三、需求简介:
- 执行完一次蓝牙开门之后,就断开连接蓝牙,以降低手机耗能;
20s扫码一次蓝牙,扫描时长为10s,以便根据距离搜索新的及强度高的蓝牙设备- 初始化项目即执行一次蓝牙扫描
import 'package:flutter_blue/flutter_blue.dart';
FlutterBlue flutterBlue = FlutterBlue.instance;
// 蓝牙开门
void _blueOpenDoor (Map list) async {
var isFirstScan = true;
var isConnect = false;
_delayed?.cancel();
// 自定义loading
cancel = BotToast.showCustomLoading(
ignoreContentClick: true,
toastBuilder: (cancelFunc) {
return Loading();
}
);
blueList.forEach((scanResult) async {
// if (scanResult.device.name == '201901012212') {
if (scanResult.device.name == list["macAddress"]) {
print('蓝牙设备门禁正在连接~~~~~~~~~');
await scanResult.device.disconnect();
await scanResult.device.connect();
isConnect = true;
print('蓝牙设备门禁连接成功~~~~~~~~~');
// List<BluetoothDevice> connectedDevices = await flutterBlue.connectedDevices;
// if(connectedDevices.contains(scanResult.device)) {
// // TO DO
// }
List<BluetoothService> services = await scanResult.device.discoverServices();
//遍历蓝牙设备对列表
services.forEach((service) async {
if (service.uuid.toString().toUpperCase().substring(4, 8) == 'FFF0') {
var characteristics = service.characteristics;
for(BluetoothCharacteristic c in characteristics) {
if (c.uuid.toString().toUpperCase().substring(4, 8) == 'FFF1') {
// 开门指令
print('蓝牙设备门禁服务匹配成功~~~~~~~~~');
await c.write([0x30, 0x10, 0x02, 0x03 ...........]);
print('蓝牙设备门禁指令发送成功~~~~~~~~~');
// 开门声音
cancel();
_delayed?.cancel();
showOpenDoorDialog(1, list['doorControlName']);
await _audioPlayer.play("https://qinlin-resource.oss-cn-zhangjiakou.aliyuncs.com/wechat/opendoor.mp3");
await scanResult.device.disconnect();
}
// 监听门禁返回 并断开连接
if (c.uuid.toString().toUpperCase().substring(4, 8) == 'FFF2') {
// List<int> value = await c.read();
// print('88888888888888888888888$value');
await c.setNotifyValue(true);
notifySubscription = c.value.listen((value) async {
print('88888888888888888888888$value');
cancel();
await scanResult.device.disconnect();
notifySubscription.cancel();
});
}
}
}
});
// 获取设备连接状态
stateSubscription = scanResult.device.state.listen((s) async {
print('连接状态连接状态$s');
switch (s) {
// 蓝牙连接成功
case BluetoothDeviceState.connected:
isFirstScan = true;
break;
case BluetoothDeviceState.disconnected:
if (!isFirstScan){
cancel();
_delayed?.cancel();
print('蓝牙设备门禁连接失败~~~~~~~~~');
BotToast.showText(
text: '蓝牙设备连接失败,请稍后再试',
align: Alignment(0, 0.1),
onlyOne: true,
duration: Duration(milliseconds: 2000),
contentPadding: const EdgeInsets.all(15.0),
);
}
break;
default:
cancel();
_delayed?.cancel();
print('蓝牙设备门禁连接失败~~~~~~~~~');
BotToast.showText(
text: '蓝牙设备连接失败,请稍后再试',
align: Alignment(0, 0.1),
onlyOne: true,
duration: Duration(milliseconds: 2000),
contentPadding: const EdgeInsets.all(15.0),
);
break;
}
});
}
});
_delayed = Timer.periodic(new Duration(seconds: 15), (timer) {
cancel();
if (!isConnect) {
BotToast.showText(
text: '该门禁蓝牙信号较弱,请稍后再试',
align: Alignment(0, 0.1),
onlyOne: true,
duration: Duration(milliseconds: 2000),
contentPadding: const EdgeInsets.all(15.0),
);
}
_delayed?.cancel();
});
}
// 15s 定时扫描蓝牙
Future<dynamic> _scanBlue () async {
flutterBlue.state.listen((s) {
if (s == BluetoothState.on) {
setState(() {
_isOpenBlue = true;
});
FlutterBlue.instance.stopScan();
// 立即执行一次
_initScan();
_timer = Timer.periodic(new Duration(seconds: 20), (timer) {
setState(() {
blueList = [];
});
scanSubscription = flutterBlue.scan().listen((scanResult) async {
if (!blueList.contains(scanResult)) {
setState(() {
blueList.add(scanResult);
});
}
});
Future.delayed(Duration(seconds: 10), () {
FlutterBlue.instance.stopScan();
scanSubscription?.cancel();
});
});
} else {
_timer?.cancel();
if (!_isOpenBlue) {
final snackBar = new SnackBar(
content: new Text('如需要蓝牙开门,请先前往手机设置开启蓝牙'),
backgroundColor: Colors.red,
duration: Duration(seconds: 3),
action: SnackBarAction(
textColor: Colors.white,
label: '关闭',
onPressed: () {},
),
);
_scaffoldkey.currentState.showSnackBar(snackBar);
}
}
});
}
// 初始执行扫描
void _initScan () {
setState(() {
blueList = [];
});
scanSubscription = flutterBlue.scan().listen((scanResult) async {
if (!blueList.contains(scanResult)) {
setState(() {
blueList.add(scanResult);
});
}
});
Future.delayed(Duration(seconds: 10), () {
FlutterBlue.instance.stopScan();
scanSubscription?.cancel();
});
}
四、结尾
原文链接: 本人博客园文章