Flutter蓝牙外设管理插件flutter_ble_peripheral的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter蓝牙外设管理插件flutter_ble_peripheral的使用

插件简介

pub package Join the chat Workflow style: lint sponsor me

FlutterBlePeripheral 是一个Flutter插件,允许设备以外围设备模式运行,并通过BLE向中心设备广播数据。

开发贡献

如果您想为这个插件做贡献,欢迎提交问题和拉取请求。

注意事项

由于该插件仍在开发中,部分功能可能尚未完全实现。请查阅发布页面获取最新版本信息。

功能 Android iOS 描述
广播UUID 设置并广播自定义UUID
广播制造商数据 设置并广播自定义数据(iOS不支持)
广播自定义服务 广播自定义服务(iOS不支持)

使用方法

请参考示例应用程序了解如何广播数据。注意,iOS对许多选项的支持有限,请参阅AdvertiseData查看iOS和Android支持的选项。

示例代码

以下是完整的示例代码,展示了如何使用flutter_ble_peripheral插件:

/*
 * Copyright (c) 2020. Julian Steenbakker.
 * All rights reserved. Use of this source code is governed by a
 * BSD-style license that can be found in the LICENSE file.
 */

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_ble_peripheral/flutter_ble_peripheral.dart';

void main() => runApp(const FlutterBlePeripheralExample());

class FlutterBlePeripheralExample extends StatefulWidget {
  const FlutterBlePeripheralExample({Key? key}) : super(key: key);

  @override
  FlutterBlePeripheralExampleState createState() => FlutterBlePeripheralExampleState();
}

class FlutterBlePeripheralExampleState extends State<FlutterBlePeripheralExample> {
  final AdvertiseData advertiseData = AdvertiseData(
    serviceUuid: 'bf27730d-860a-4e09-889c-2d8b6a9e0fe7',
    localName: 'test',
    manufacturerId: 1234,
    manufacturerData: Uint8List.fromList([1, 2, 3, 4, 5, 6]),
  );

  final AdvertiseSetParameters advertiseSetParameters = AdvertiseSetParameters();

  bool _isSupported = false;

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  Future<void> initPlatformState() async {
    final isSupported = await FlutterBlePeripheral().isSupported;
    setState(() {
      _isSupported = isSupported;
    });
  }

  Future<void> _toggleAdvertise() async {
    if (await FlutterBlePeripheral().isAdvertising) {
      await FlutterBlePeripheral().stop();
    } else {
      await FlutterBlePeripheral().start(advertiseData: advertiseData);
    }
  }

  Future<void> _toggleAdvertiseSet() async {
    if (await FlutterBlePeripheral().isAdvertising) {
      await FlutterBlePeripheral().stop();
    } else {
      await FlutterBlePeripheral().start(
        advertiseData: advertiseData,
        advertiseSetParameters: advertiseSetParameters,
      );
    }
  }

  Future<void> _requestPermissions() async {
    final hasPermission = await FlutterBlePeripheral().hasPermission();
    switch (hasPermission) {
      case BluetoothPeripheralState.denied:
        _messangerKey.currentState?.showSnackBar(
          const SnackBar(
            backgroundColor: Colors.red,
            content: Text("We don't have permissions, requesting now!"),
          ),
        );
        await _requestPermissions();
        break;
      default:
        _messangerKey.currentState?.showSnackBar(
          SnackBar(
            backgroundColor: Colors.green,
            content: Text('State: $hasPermission!'),
          ),
        );
        break;
    }
  }

  Future<void> _hasPermissions() async {
    final hasPermissions = await FlutterBlePeripheral().hasPermission();
    _messangerKey.currentState?.showSnackBar(
      SnackBar(
        content: Text('Has permission: $hasPermissions'),
        backgroundColor: hasPermissions == BluetoothPeripheralState.granted ? Colors.green : Colors.red,
      ),
    );
  }

  final _messangerKey = GlobalKey<ScaffoldMessengerState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      scaffoldMessengerKey: _messangerKey,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter BLE Peripheral'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Is supported: $_isSupported'),
              StreamBuilder(
                stream: FlutterBlePeripheral().onPeripheralStateChanged,
                initialData: PeripheralState.unknown,
                builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
                  return Text('State: ${(snapshot.data as PeripheralState).name}');
                },
              ),
              Text('Current UUID: ${advertiseData.serviceUuid}'),
              MaterialButton(
                onPressed: _toggleAdvertise,
                child: Text(
                  'Toggle advertising',
                  style: Theme.of(context).primaryTextTheme.labelLarge!.copyWith(color: Colors.blue),
                ),
              ),
              MaterialButton(
                onPressed: () async {
                  await FlutterBlePeripheral().start(
                    advertiseData: advertiseData,
                    advertiseSetParameters: advertiseSetParameters,
                  );
                },
                child: Text(
                  'Start advertising',
                  style: Theme.of(context).primaryTextTheme.labelLarge!.copyWith(color: Colors.blue),
                ),
              ),
              MaterialButton(
                onPressed: () async {
                  await FlutterBlePeripheral().stop();
                },
                child: Text(
                  'Stop advertising',
                  style: Theme.of(context).primaryTextTheme.labelLarge!.copyWith(color: Colors.blue),
                ),
              ),
              MaterialButton(
                onPressed: _toggleAdvertiseSet,
                child: Text(
                  'Toggle advertising set for 1 second',
                  style: Theme.of(context).primaryTextTheme.labelLarge!.copyWith(color: Colors.blue),
                ),
              ),
              StreamBuilder(
                stream: FlutterBlePeripheral().onPeripheralStateChanged,
                initialData: PeripheralState.unknown,
                builder: (BuildContext context, AsyncSnapshot<PeripheralState> snapshot) {
                  return MaterialButton(
                    onPressed: () async {
                      final bool enabled = await FlutterBlePeripheral().enableBluetooth(askUser: false);
                      if (enabled) {
                        _messangerKey.currentState!.showSnackBar(
                          const SnackBar(
                            content: Text('Bluetooth enabled!'),
                            backgroundColor: Colors.green,
                          ),
                        );
                      } else {
                        _messangerKey.currentState!.showSnackBar(
                          const SnackBar(
                            content: Text('Bluetooth not enabled!'),
                            backgroundColor: Colors.red,
                          ),
                        );
                      }
                    },
                    child: Text(
                      'Enable Bluetooth (ANDROID)',
                      style: Theme.of(context).primaryTextTheme.labelLarge!.copyWith(color: Colors.blue),
                    ),
                  );
                },
              ),
              MaterialButton(
                onPressed: () async {
                  final bool enabled = await FlutterBlePeripheral().enableBluetooth();
                  if (enabled) {
                    _messangerKey.currentState!.showSnackBar(
                      const SnackBar(
                        content: Text('Bluetooth enabled!'),
                        backgroundColor: Colors.green,
                      ),
                    );
                  } else {
                    _messangerKey.currentState!.showSnackBar(
                      const SnackBar(
                        content: Text('Bluetooth not enabled!'),
                        backgroundColor: Colors.red,
                      ),
                    );
                  }
                },
                child: Text(
                  'Ask if enable Bluetooth (ANDROID)',
                  style: Theme.of(context).primaryTextTheme.labelLarge!.copyWith(color: Colors.blue),
                ),
              ),
              MaterialButton(
                onPressed: _requestPermissions,
                child: Text(
                  'Request Permissions',
                  style: Theme.of(context).primaryTextTheme.labelLarge!.copyWith(color: Colors.blue),
                ),
              ),
              MaterialButton(
                onPressed: _hasPermissions,
                child: Text(
                  'Has permissions',
                  style: Theme.of(context).primaryTextTheme.labelLarge!.copyWith(color: Colors.blue),
                ),
              ),
              MaterialButton(
                onPressed: () => FlutterBlePeripheral().openBluetoothSettings(),
                child: Text(
                  'Open bluetooth settings',
                  style: Theme.of(context).primaryTextTheme.labelLarge!.copyWith(color: Colors.blue),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

关键点说明

  1. 初始化平台状态:在initState中调用initPlatformState方法来检查设备是否支持BLE外围设备模式。
  2. 切换广播:通过_toggleAdvertise方法来启动或停止广播。
  3. 权限处理:通过_requestPermissions方法请求必要的权限,并通过_hasPermissions方法检查当前权限状态。
  4. UI交互:提供了多个按钮用于启动、停止广播,启用蓝牙,打开蓝牙设置等操作。

希望这些信息能帮助您更好地理解和使用flutter_ble_peripheral插件。如果有任何问题或需要进一步的帮助,请随时联系我!


更多关于Flutter蓝牙外设管理插件flutter_ble_peripheral的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter蓝牙外设管理插件flutter_ble_peripheral的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何使用Flutter蓝牙外设管理插件flutter_ble_peripheral的示例代码案例。这个插件允许你的Flutter应用充当一个蓝牙外设,并发布服务和特征值,以便其他蓝牙设备可以连接和交互。

首先,确保你已经在你的pubspec.yaml文件中添加了flutter_ble_peripheral依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_ble_peripheral: ^x.y.z  # 请使用最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter应用中,你可以按照以下步骤来设置蓝牙外设:

  1. 初始化插件并设置服务和特征值
import 'package:flutter/material.dart';
import 'package:flutter_ble_peripheral/flutter_ble_peripheral.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlePeripheralPage(),
    );
  }
}

class BlePeripheralPage extends StatefulWidget {
  @override
  _BlePeripheralPageState createState() => _BlePeripheralPageState();
}

class _BlePeripheralPageState extends State<BlePeripheralPage> {
  FlutterBlePeripheral? _flutterBlePeripheral;
  String? _deviceName;

  @override
  void initState() {
    super.initState();
    _initBlePeripheral();
  }

  void _initBlePeripheral() async {
    _flutterBlePeripheral = FlutterBlePeripheral();

    // 设置设备名称
    _deviceName = "MyFlutterDevice";

    // 添加服务和特征值
    await _flutterBlePeripheral?.addService(
      FlutterBlePeripheralService(
        uuid: "0000180d-0000-1000-8000-00805f9b34fb", // 设备信息服务的UUID
        characteristics: [
          FlutterBlePeripheralCharacteristic(
            uuid: "00002a27-0000-1000-8000-00805f9b34fb", // 制造名称的UUID
            properties: [
              FlutterBleCharacteristicProperty.read,
              FlutterBleCharacteristicProperty.notify,
            ],
            value: Uint8List.fromList("MyManufacturer".codeUnits),
          ),
          FlutterBlePeripheralCharacteristic(
            uuid: "00002a28-0000-1000-8000-00805f9b34fb", // 模型号码的UUID
            properties: [
              FlutterBleCharacteristicProperty.read,
            ],
            value: Uint8List.fromList("MyModelNumber".codeUnits),
          ),
        ],
      ),
    );

    // 开始广播
    await _flutterBlePeripheral?.startAdvertising(
      name: _deviceName!,
      includeDeviceName: true,
      manufacturerId: 0x0059, // 示例制造商ID
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Flutter BLE Peripheral Example"),
      ),
      body: Center(
        child: Text("BLE Peripheral is advertising"),
      ),
    );
  }

  @override
  void dispose() {
    _flutterBlePeripheral?.stopAdvertising();
    super.dispose();
  }
}
  1. 处理连接和通知

虽然上面的示例代码已经开始了广播,但在实际应用中,你可能还需要处理设备连接和特征值通知。这里是如何处理这些事件的简单示例:

class _BlePeripheralPageState extends State<BlePeripheralPage> with WidgetsBindingObserver {
  // ... 其他代码

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance?.addObserver(this);
    _initBlePeripheral();

    // 监听连接状态变化
    _flutterBlePeripheral?.onConnected?.listen((device) {
      print("Device connected: ${device.id}");
    });

    // 监听断开连接
    _flutterBlePeripheral?.onDisconnected?.listen((device) {
      print("Device disconnected: ${device.id}");
    });

    // 监听特征值写入
    _flutterBlePeripheral?.onCharacteristicValueWritten?.listen((event) {
      print("Characteristic written: ${event.characteristic.uuid}, value: ${event.value}");
    });

    // 监听特征值读取请求
    _flutterBlePeripheral?.onCharacteristicValueReadRequest?.listen((request) {
      request.respondWithValue(Uint8List.fromList("ResponseValue".codeUnits));
    });

    // 监听通知订阅
    _flutterBlePeripheral?.onNotifySubscriptionChanged?.listen((event) {
      if (event.isSubscribed) {
        print("Characteristic ${event.characteristic.uuid} subscribed");
      } else {
        print("Characteristic ${event.characteristic.uuid} unsubscribed");
      }
    });
  }

  @override
  void dispose() {
    WidgetsBinding.instance?.removeObserver(this);
    _flutterBlePeripheral?.stopAdvertising();
    super.dispose();
  }

  // 其他代码 ...
}

请注意,flutter_ble_peripheral插件主要用于将Flutter应用作为蓝牙外设,因此它不支持作为中央设备(Client)来扫描和连接其他蓝牙设备。如果你需要这种功能,你可能需要使用flutter_blue等其他插件。

这个示例展示了如何初始化一个蓝牙外设,添加服务和特征值,并开始广播。同时,它还展示了如何监听连接状态、特征值写入、读取请求和通知订阅的变化。根据你的需求,你可以进一步扩展这些功能。

回到顶部