前言
在生活中钧舌,使用到藍牙的場景很多,如共享單車涎跨,智能手環(huán)洼冻,藍牙打印機,藍牙萬用表隅很,藍牙門鎖等
今天我們討論在flutter中如何開發(fā)與藍牙相關(guān)的app撞牢。
小伙伴們對藍牙使用流程不是很了解的情況,建議去惡補一下叔营。我這里也只是簡單提到
0.打開藍牙屋彪,藍牙權(quán)限判斷等
1.掃描設備,找到目標設備
2.連接設備
3.掃描已連接設備下的服務绒尊,可能有多個服務(fff0,fff1,fff2,fff3,fff4,fff5等)
4.針對某一個服務畜挥,掃描它的特征,可能有多個特征
5.有些特征是可讀婴谱,可寫蟹但,有的特征只能讀操作躯泰,有的只能寫操作,有的特征只通知
6.根據(jù)不同的特征华糖,做相應的處理麦向,可以對下位機發(fā)命令,也可以讀取下位機的相關(guān)信息等
正題
下面將從零開始客叉,在flutter里面寫一個關(guān)于藍牙萬用表的app
一.創(chuàng)建工程
1.創(chuàng)建一個項目诵竭,如下圖
2.然后就是下一步,下一步兼搏,直到最后一步卵慰,要勾選支持swift,kotlin的選項向族,因為現(xiàn)在很多第三方庫都要支持swift呵燕,要不然在后面引入第三方庫時,會有很多報錯件相!
3.創(chuàng)建完工程后,點擊到pubspec.yaml文件氧苍,點擊右上角的Pub get夜矗,獲取一下依賴,然后點擊運行让虐,看能不能正常跑起來
4.如果沒有報錯紊撕,跳過此步驟,如果報錯了赡突,去原生工程里面配置一下
4.1 點擊工程文件对扶,右鍵一下,如下圖
4.2 配置一下iOS 開發(fā)者團隊惭缰,如果沒有話浪南,就去申請開發(fā)都賬號吧
5.再回到flutter工程,把工程跑起來
二.選擇第三方庫漱受,封裝一個藍牙工具络凿,方便使用及后期的維護工作
我這里選擇了https://pub.dev/packages/flutter_blue,flutter_blue這個藍牙庫昂羡,他適配了iOS Android,也支持了空安全絮记。
有了第三方庫,我們需要對flutter_blue進行簡單封裝一下虐先,ble_tool,具體代碼如下:
import 'dart:async';
import 'package:flutter_blue/flutter_blue.dart';
import 'dart:developer';
import 'dart:core';
typedef ScanResultHandler = void Function(List<ScanResult>? datas);
typedef CharacteristicHandler = void Function(List<int>? datas);
class BleManager {
FlutterBlue? _flutterBlue;
factory BleManager() => _getInstance();
static BleManager get instance => _getInstance();
static BleManager? _instance;
BleManager._internal() {
_flutterBlue = FlutterBlue.instance;
}
static BleManager _getInstance() {
if (_instance == null) {
_instance = BleManager._internal();
}
return _instance!;
}
startScan(ScanResultHandler dataHandler, {int timeout = 60}) {
log("_scan");
// _flutterBlue?.startScan(timeout: Duration(seconds: timeout));
_flutterBlue?.startScan(timeout: Duration(seconds: timeout),withServices: [Guid("0000fff0-0000-1000-XXXX-XXXXXXXXXXX")]);
_flutterBlue?.scanResults.listen(dataHandler);
}
stopScan() {
log("_stopScan");
_flutterBlue?.stopScan();
}
Future<void> connectDevice(BluetoothDevice device) async {
log("_connect");
await device.connect(autoConnect: false);
}
Future<List<BluetoothService>> deviceToDiscoverServices(
BluetoothDevice device) async {
return await device.discoverServices();
}
Future<bool> characteristicToSetNotifyValue(
BluetoothCharacteristic characteristic) async {
return await characteristic.setNotifyValue(true);
}
listenCharacteristicValue(BluetoothCharacteristic characteristic,
CharacteristicHandler characteristicHandler) {
characteristic.value.listen(characteristicHandler);
}
Future<Null> characteristicToWriteValue(
BluetoothCharacteristic characteristic, List<int> list,{bool withoutResponse = false}) async {
log("_write withoutResponse = $withoutResponse",);
return await characteristic.write(list,withoutResponse: withoutResponse);
}
Future<List<int>> characteristicToReadValue(
BluetoothCharacteristic characteristic) async {
log("_read");
return await characteristic.read();
}
Future<List<BluetoothDevice>>? getConnectedDevices() {
return _flutterBlue?.connectedDevices;
}
Future<dynamic> disconnectDevice(BluetoothDevice device) async {
log("_disconnect");
return await device.disconnect();
}
}
三.使用封裝好的藍牙工具類ble_tool
使用之前需要對iOS工程怨愤,Android工程加一些權(quán)限
iOS 如下圖
android如下圖
開始掃描
BleManager.instance.startScan(scanResultHandler, timeout: 10);
掃描結(jié)果監(jiān)聽
void scanResultHandler(List<ScanResult>? results) {
print('results ====> $results');
for (ScanResult r in results!) {
print('${r.device.name} found! rssi: ${r.rssi}');
}
}
停止掃描
BleManager.instance.stopScan();
連接設備并且去掃描設備的服務services
BleManager.instance.connectDevice(widget.device).then((e) {
_discoverServices();
});
掃描設備服務,過濾服務0000fff0-0000-1000-XXXX-XXXXXXXXXXX蛹批,簡稱fff0撰洗, 并且掃描fff0服務下的所有特征
(_characteristicForFFF1膀息,_characteristicForFFF2等)
_discoverServices() async {
List<BluetoothService> services =
await BleManager.instance.deviceToDiscoverServices(widget.device);
print("+++++++$services");
if (services == null) return;
services.forEach((service) {
// do something with service
print("uuid=${service.uuid} deviceId=${service.deviceId}");
if (service.uuid.toString() == "0000fff0-0000-1000-XXXX-XXXXXXXXXXX") {
print("---service is fff0---");
var characteristics = service.characteristics;
for (BluetoothCharacteristic c in characteristics) {
// log("----BluetoothCharacteristic-->$c");
print("----BluetoothCharacteristicUUID-->${c.uuid}");
if (c.uuid.toString().contains("fff1")) {
print("is fff1");
_characteristicForFFF1 = c;
} else if (c.uuid.toString().contains("fff2")) {
print("is fff2");
_characteristicForFFF2 = c;
_readDeviceBasicInfo();
} else if (c.uuid.toString().contains("fff3")) {
print("is fff3");
_characteristicForFFF3 = c;
} else if (c.uuid.toString().contains("fff4")) {
print("is fff4");
_characteristicForFFF4 = c;
_characteristicFFF4SetNotify();//fff4這個特征是只通知的,所以要設置通知setNotify了赵,后面可以監(jiān)聽特征值上報
} else if (c.uuid.toString().contains("fff5")) {
print("is fff5");
}
}
}
});
}
斷開藍牙連接
BleManager.instance
.disconnectDevice(widget.device)
.then((value) => print("disconnected !!"));
監(jiān)聽特征值上報,主要的數(shù)據(jù)來自這里
_characteristicFFF4SetNotify() async {
await _characteristicForFFF4!.setNotifyValue(true);
// ignore: missing_return
BleManager.instance.listenCharacteristicValue(_characteristicForFFF4!,
(data) {
print("object=>>>>>>$data");
if (data == null) {
print("data=null>>>>>>");
return;
}
}
}
對設備設置命令潜支,發(fā)送請求(寫操作)
BleManager.instance
.characteristicToWriteValue(_characteristicForFFF3!, list)
.then((value) => print("write result:$value"));
讀取設備的信息(讀操作)
BleManager.instance
.characteristicToReadValue(_characteristicForFFF2!)
.then((value) {
print("fff2 value=$value");
});
這樣藍牙的相關(guān)操作,基本全部結(jié)束了柿汛,最后來看一下效果吧
結(jié)尾
藍牙其他相關(guān)文章
flutter 實戰(zhàn)App 之 提詞器app
flutter 藍牙ble(blue tooth),同時連接多臺/多個設備
iOS 解決藍牙配對彈框的問題冗酿,解決ANCS帶來的問題,獲取已配對(已綁定)設備列表
flutter的藍牙還是挺方便的络断, 做一般的藍牙應用還是可以的哦裁替,小伴們,覺得有點用的話,或者已經(jīng)看到這里面來的請點個贊吧~~ 后續(xù)分享更多有關(guān)flutter的文章貌笨。如果有疑問的話弱判,請在下方留言~