Flutter教程实现蓝牙设备搜索

在Flutter中如何实现蓝牙设备的搜索功能?我尝试使用flutter_blue插件,但扫描不到周围的蓝牙设备。已经确认手机蓝牙已开启且设备可见,但扫描结果列表始终为空。请问正确的实现流程是什么?是否需要额外的权限配置?在Android和iOS平台上是否有不同的设置要求?能否提供一个完整的设备搜索代码示例?

3 回复

首先在pubspec.yaml中添加权限依赖:flutter_blue: ^0.8.0。接着在AndroidManifest.xml中添加蓝牙权限和系统功能:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

代码实现如下:

  1. 初始化FlutterBlue实例:
final FlutterBlue flutterBlue = FlutterBlue.instance;
  1. 开始扫描蓝牙设备:
flutterBlue.startScan(timeout: Duration(seconds: 4));
  1. 监听扫描结果:
StreamSubscription subscription = flutterBlue.scanResults.listen((results) {
  for (ScanResult r in results) {
    print('${r.device.name} found! rssi: ${r.rssi}');
  }
});
  1. 停止扫描:
flutterBlue.stopScan();

注意:从Android 6.0开始,使用蓝牙需要获取位置权限,确保用户已开启定位服务。同时在iOS上还需要配置Info.plist添加描述字段。

更多关于Flutter教程实现蓝牙设备搜索的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


以下是一个简单的 Flutter 蓝牙设备搜索示例:

  1. 添加依赖:
dependencies:
  flutter_blue: ^0.8.0
  1. 导入库并初始化:
import 'package:flutter_blue/flutter_blue.dart';

void main() {
  FlutterBlue flutterBlue = FlutterBlue.instance;
}
  1. 开始扫描设备:
flutterBlue.startScan(timeout: Duration(seconds: 4));
  1. 监听扫描结果:
StreamSubscription scanSubscription = flutterBlue.scan().listen((scanResult) {
  print('发现设备: ${scanResult.device.name},地址: ${scanResult.device.id}');
});
  1. 停止扫描:
scanSubscription.cancel();
flutterBlue.stopScan();

完整代码:

import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';

void main() => runApp(MyApp());

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

class BluetoothPage extends StatefulWidget {
  @override
  _BluetoothPageState createState() => _BluetoothPageState();
}

class _BluetoothPageState extends State<BluetoothPage> {
  final FlutterBlue flutterBlue = FlutterBlue.instance;
  List<ScanResult> devices = [];

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

  void startScan() async {
    flutterBlue.startScan(timeout: Duration(seconds: 4));
    flutterBlue.scan().listen((scanResult) {
      setState(() {
        devices.add(scanResult);
      });
    }, onDone: stopScan);
  }

  void stopScan() {
    flutterBlue.stopScan();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('蓝牙设备搜索')),
      body: ListView.builder(
        itemCount: devices.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(devices[index].device.name.isEmpty ? '未知设备' : devices[index].device.name),
            subtitle: Text(devices[index].device.id.toString()),
          );
        },
      ),
    );
  }
}

运行此代码后,应用程序会自动搜索蓝牙设备并在列表中显示设备名称和地址。

Flutter 蓝牙设备搜索实现

下面是一个使用 Flutter 进行蓝牙设备搜索的基本教程,我们将使用flutter_blue_plus这个流行的蓝牙插件。

1. 添加依赖

首先在 pubspec.yaml 中添加依赖:

dependencies:
  flutter_blue_plus: ^1.10.0

然后运行 flutter pub get

2. 基本实现代码

import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';

class BluetoothScreen extends StatefulWidget {
  @override
  _BluetoothScreenState createState() => _BluetoothScreenState();
}

class _BluetoothScreenState extends State<BluetoothScreen> {
  FlutterBluePlus flutterBlue = FlutterBluePlus.instance;
  List<BluetoothDevice> devicesList = [];
  bool isScanning = false;

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

  // 检查蓝牙状态
  _checkBluetoothState() async {
    bool isAvailable = await flutterBlue.isAvailable;
    if (!isAvailable) {
      print("蓝牙不可用");
      return;
    }
  }

  // 开始扫描
  _startScan() async {
    setState(() => isScanning = true);
    devicesList.clear();
    
    // 监听扫描结果
    flutterBlue.scanResults.listen((results) {
      for (ScanResult result in results) {
        if (!devicesList.any((device) => device.id == result.device.id)) {
          setState(() {
            devicesList.add(result.device);
          });
        }
      }
    });
    
    await flutterBlue.startScan(timeout: Duration(seconds: 15));
    setState(() => isScanning = false);
  }

  // 停止扫描
  _stopScan() async {
    await flutterBlue.stopScan();
    setState(() => isScanning = false);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('蓝牙设备搜索')),
      body: Column(
        children: [
          ElevatedButton(
            child: Text(isScanning ? '停止扫描' : '开始扫描'),
            onPressed: isScanning ? _stopScan : _startScan,
          ),
          Expanded(
            child: ListView.builder(
              itemCount: devicesList.length,
              itemBuilder: (context, index) {
                BluetoothDevice device = devicesList[index];
                return ListTile(
                  title: Text(device.name.isEmpty ? '未知设备' : device.name),
                  subtitle: Text(device.id.toString()),
                  trailing: ElevatedButton(
                    child: Text('连接'),
                    onPressed: () {
                      // 连接设备逻辑
                    },
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

3. 权限设置

对于Android,需要在 AndroidManifest.xml 中添加以下权限:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

对于iOS,需要在 Info.plist 中添加:

<dict>
    <key>NSBluetoothAlwaysUsageDescription</key>
    <string>需要蓝牙权限来搜索设备</string>
    <key>NSBluetoothPeripheralUsageDescription</key>
    <string>需要蓝牙权限来连接设备</string>
</dict>

注意事项

  1. 在真机上测试,模拟器不支持蓝牙功能
  2. 安卓6.0以上需要动态请求位置权限
  3. 扫描到的设备名称可能为空,需要使用设备ID作为唯一标识

如果需要更详细的功能如连接设备、读取服务等,可以进一步扩展此代码。

回到顶部