FlutterBleLib
Flutter中所有低功耗蓝牙需求的库。内部利用Polidea的
MultiPlatformBleAdapter,
其运行在RxAndroidBle
和RxBluetoothKit。
蓝牙模拟器
此库支持BLEmulator,即蓝牙模拟器。
模拟允许在没有物理智能手机或蓝牙外设的情况下进行开发,并在自动化测试中使用产品的蓝牙相关代码。
安装
要使用此插件,请在您的pubspec.yaml文件中添加flutter_ble_lib作为依赖项。
Android
在[project]/android/app/build.gradle文件中将minSDKVersion设置为18。
defaultConfig {
...
minSdkVersion 18
...
}
API 18中已添加对低功耗蓝牙的支持,因此该库要求将minSDKVersion设置为18。如果蓝牙不是您应用程序的核心,您可以覆盖它并在代码中处理支持检测。
注意:您无需将任何与蓝牙相关的权限添加到AndroidManifest.xml,因为它们已在库的本机模块中声明。但是,您仍然需要运行时请求ACCESS_FINE_LOCATION权限才能扫描外设。请参阅示例代码和示例的pubspec。
iOS
转到[project]/ios目录并运行pod install。
将Privacy – Bluetooth Always Usage Description键添加到[project]/ios/Runner/Info.plist文件。
...
<key>NSBluetoothAlwaysUsageDescription</key>
<string>Your own description of the purpose.</string>
...
后台模式
要支持后台功能,请将bluetooth-central后台执行模式键添加到[project]/ios/Runner/Info.plist文件。
...
<key>UIBackgroundModes</key>
<array>
<string>bluetooth-central</string>
</array>
...
用法
该库围绕几个基本实体组织,它们是
- BleManager
- Peripheral
- Service
- Characteristic
- Descriptor
您必须创建一个BleManager实例并初始化底层的原生资源。
使用该实例,然后获取Peripheral的实例,
该实例可用于在相应的外设上运行操作。
所有通过Dart-原生桥传递的操作都是异步的,
因此插件中的所有操作都返回Future或Stream。
有关更多信息,请参阅REFERENCE。
注意:此库不会为您处理任何权限。要在Android上扫描外设,根据Android开发者指南,您需要ACCESS_FINE_LOCATION。
初始化
BleManager bleManager = BleManager();
await bleManager.createClient(); //ready to go!
// your peripheral logic
bleManager.destroyClient(); //remember to release native resources when you're done!
以下代码段假定库已初始化。
处理蓝牙适配器状态
enum BluetoothState {
UNKNOWN,
UNSUPPORTED,
UNAUTHORIZED,
POWERED_ON,
POWERED_OFF,
RESETTING,
}
bleManager.enableRadio(); //ANDROID-ONLY turns on BT. NOTE: doesn't check permissions
bleManager.disableRadio() //ANDROID-ONLY turns off BT. NOTE: doesn't check permissions
BluetoothState currentState = await bleManager.bluetoothState();
bleManager.observeBluetoothState().listen((btState) {
print(btState);
//do your BT logic, open different screen, etc.
});
扫描外设
bleManager.startPeripheralScan(
uuids: [
"F000AA00-0451-4000-B000-000000000000",
],
).listen((scanResult) {
//Scan one peripheral and stop scanning
print("Scanned Peripheral ${scanResult.peripheral.name}, RSSI ${scanResult.rssi}");
bleManager.stopPeripheralScan();
});
上面的代码段启动外设扫描,并在收到第一个结果后停止它。
它会过滤扫描结果,只选择广告具有指定UUID的服务。
注意:ScanResult的isConnectable和overflowServiceUuids字段仅在iOS上可用,在Android上则为null。
连接到已保存的外设
您可以尝试连接具有已知ID的外设,无论是iOS上先前扫描的UUID还是Android上的MAC地址,从而避免应用程序中的整个扫描操作。要做到这一点,您需要使用
Peripheral myPeripheral = bleManager.createUnsafePeripheral("< known id >");
获取Peripheral的实例。一旦有了外设的实例,您就可以继续连接。但请记住,
Android可能仍然在未先扫描的情况下找不到外设。
连接到外设
首先,您必须从BleManager.startPeripheralScan()获取一个ScanResult。
Peripheral peripheral = scanResult.peripheral;
peripheral.observeConnectionState(emitCurrentValue: true, completeOnDisconnect: true)
.listen((connectionState) {
print("Peripheral ${scanResult.peripheral.identifier} connection state is $connectionState");
});
await peripheral.connect();
bool connected = await peripheral.isConnected();
await peripheral.disconnectOrCancelConnection();
上面的代码段开始观察与外设连接的状态,
连接到它,检查它是否已连接,然后断开连接。
事务
没有相反效果的对应方法且是异步的方法接受
String transactionId作为可选参数,允许用户取消此类操作。
返回Dart的Future将以BleError(BleErrorCode.operationCancelled…)结束,
但这只会丢弃操作结果,操作本身仍将执行.
例如,如果我决定不再对选定的外设进行发现
//assuming peripheral is connected
peripheral.discoverAllServicesAndCharacteristics(transactionId: "discovery");
//will return operation cancelled error after calling the below
bleManager.cancelTransaction("discovery");
具有相同transactionId的每个新操作都会导致上一个操作被取消并出错,如果它尚未完成。
如果transactionId设置为null或根本未指定,则该库会为此操作设置唯一的整数transactionId。
注意
请勿将整数设置为transactionId,因为它们由库使用。
获取特征
要对该外设进行操作,必须先运行其服务和特征的发现。
//assuming peripheral is connected
await peripheral.discoverAllServicesAndCharacteristics();
List<Service> services = await peripheral.services(); //getting all services
List<Characteristic> characteristics1 = await peripheral.characteristics("F000AA00-0451-4000-B000-000000000000");
List<Characteristic> characteristics2 = await services.firstWhere(
(service) => service.uuid == "F000AA00-0451-4000-B000-000000000000").characteristics();
//characteristics1 and characteristics2 have the same contents
代表特征的对象具有唯一的标识符,因此它们指向一个特定的特征,
即使存在多个服务/特征UUID匹配。
操作特征
以下是写入特征的3种方法,它们都产生相同的效果,前提是
只有一个具有指定UUID的服务和一个具有指定UUID的特征。
peripheral.writeCharacteristic(
"F000AA00-0451-4000-B000-000000000000",
"F000AA02-0451-4000-B000-000000000000",
Uint8List.fromList([0]),
false); //returns Characteristic to chain operations more easily
service.writeCharacteristic(
"F000AA02-0451-4000-B000-000000000000",
Uint8List.fromList([0]),
false); //returns Characteristic to chain operations more easily
characteristic.write(Uint8List.fromList([0]), false); //returns void
从Peripheral/Service级别监视或读取特征
返回CharacteristicWithValue对象,该对象是Characteristic,并带有附加的Uint8List value属性。
描述符操作
单个特征的描述符列表可以与服务中的特征列表类似地获得,无论是从Peripheral、Service还是Characteristic对象。描述符可以
通过提供必要的UUID,从Peripheral、Service或Characteristic中读取/写入描述符,或者直接从Descriptor对象读取/写入。
注意:要启用特征监视,您应该使用characteristic.monitor()或(peripheral/service).monitorCharacteristic(),而不是自己更改底层描述符的值。
由Frontside促进
Frontside代表Resideo为此库提供了架构建议和财务支持。
维护者
此库由Polidea维护
维护人员
待办
许可证
版权所有 2019 Polidea Sp. z o.o
根据Apache许可证2.0版(“许可证”)获得许可;
除非符合许可证规定,否则不得使用此文件。
您可以在以下网址获取许可证副本:
https://apache.ac.cn/licenses/LICENSE-2.0
除非适用法律要求或书面同意,否则
根据许可证分发的软件按“原样”分发,
不附带任何明示或暗示的保证。
有关管辖权限和的特定语言,请参阅许可证
许可证下的限制。
更多来自Polidea
查看Polidea的其他蓝牙库
