Flutter 蓝牙:无法在 flutter 列表视图上显示蓝牙扫描到的设备

问题描述 投票:0回答:3

我一直在尝试将 Fluter_blue_plus 插件集成到我的 flutter 应用程序中,但在扫描可用设备时,我得到一个空列表,没有任何可用设备可配对。

在这里,我附上了屏幕截图和日志,以便完成同样的操作。我很震惊,你能帮我解决这个问题吗?

控制器类文件:

`import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';

class BluetoothController extends GetxController {

  FlutterBluePlus flutterBlue = FlutterBluePlus.instance;

  Future scanDevices() async {
    flutterBlue.startScan(timeout: const Duration(seconds: 5));

    print("_________________________________________________________");
    print(flutterBlue.scanResults);
    print("_________________________________________________________");

    flutterBlue.stopScan();
  }

  Stream<List<ScanResult>> get scanResults => flutterBlue.scanResults;

}`

我调用控制器来扫描并在列表视图中显示可用设备的小部件:

`Widget _buildPopupDialog(BuildContext context) {
    return new AlertDialog(
      title: const Text('List of available devices'),
      content: GetBuilder<BluetoothController>(
          init: BluetoothController(),
          builder: (controller) {
            return Container(
              height: MediaQuery.of(context).size.height/1.3,
              width: MediaQuery.of(context).size.width,
              child: SingleChildScrollView(
                child: Column(
                  mainAxisSize: MainAxisSize.max,
                  children: [
                    GestureDetector(
                      onTap: () {
                        controller.scanDevices();
                      },
                      child: Container(
                        height: MediaQuery.of(context).size.height / 20,
                        width: MediaQuery.of(context).size.width / 3,
                        decoration: BoxDecoration(
                          color: Colors.blueAccent,
                          border: Border.all(
                            color: Colors.black,
                            width: 1,
                          ),
                          borderRadius: BorderRadius.circular(10.0),
//gradient: LinearGradient(
//colors: [Colors.indigo, Colors.blueAccent]),
                          boxShadow: const [
                            BoxShadow(
                                color: Colors.white,
                                blurRadius: 1.0,
                                offset: Offset(1.0, 1.0))
                          ],
                        ),
                        child: Center(
                          child: Text(
                            "Scan Devices!!!",
                            style: TextStyle(
                                fontSize: MediaQuery.of(context).size.width/40,
                                letterSpacing: 1,
                                fontWeight: FontWeight.w400,
                                color: Colors.black),
                          ),
                        ),
                      ),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    StreamBuilder<List<ScanResult>>(
                      stream: controller.scanResults,
                        builder: (context, snapshot){
                        if(snapshot.hasData)
                          {
                            return ListView.builder(
                                shrinkWrap: true,
                                itemCount: snapshot.data!.length,
                                itemBuilder: (context,index){
                                  final data = snapshot.data![index];
                                  return Card(
                                    elevation: 2,
                                      child: ListTile(
                                        title: Text(data.device.name,
                                        selectionColor: Colors.black,),
                                        subtitle: Text(data.device.id.id),
                                        trailing: Text(data.rssi.toString()),
                                      ),
                                  );
                                });
                          }
                        else
                        {
                          return const Center(
                            child: Text("No devices found!!!"),
                          );
                        }
                        }
                    )
                  ],
                ),
              ),
            );
          }),
      actions: <Widget>[
        new GestureDetector(
          onTap: () {
            Navigator.of(context).pop();
          },
          child: const Text('Close'),
        ),
      ],
    );
  }`

Log output when i call the function:

/ViewRootImpl@7b87c05[MainActivity](13581): ViewPostIme pointer 0
I/ViewRootImpl@7b87c05[MainActivity](13581): ViewPostIme pointer 1
I/flutter (13581): _________________________________________________________
I/flutter (13581): Instance of '_BroadcastStream<List<ScanResult>>'
I/flutter (13581): _________________________________________________________
I/BluetoothAdapter(13581): STATE_ON
I/BluetoothAdapter(13581): STATE_ON
D/BluetoothLeScanner(13581): could not find callback wrapper
I/BluetoothAdapter(13581): STATE_ON
I/BluetoothAdapter(13581): STATE_ON
I/BluetoothAdapter(13581): STATE_ON
I/BluetoothAdapter(13581): STATE_ON
D/BluetoothLeScanner(13581): Start Scan with callback
D/BluetoothLeScanner(13581): onScannerRegistered() - status=0 scannerId=11 mScannerId=0
I/BluetoothAdapter(13581): STATE_ON
I/BluetoothAdapter(13581): STATE_ON
D/BluetoothLeScanner(13581): Stop Scan with callback

我的 Android 清单文件:

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

我已尝试在运行 Android 版本 13 和一个 ui 版本 5.1 的 Android 手机的设置中向应用程序授予所有权限。

但仍然没有在列表视图中显示扫描到的设备。

我已经为移动应用程序授予了手机中的所有位置权限。

我附上下面空列表的手机UI截图: enter image description here

flutter bluetooth bluetooth-lowenergy flutter-dependencies
3个回答
0
投票

查看您的代码,似乎您从未真正监听过扫描结果。 flutter_blue_plus 的使用部分展示了一个示例:

// Start scanning
flutterBlue.startScan(timeout: Duration(seconds: 4));

// Listen to scan results
var subscription = flutterBlue.scanResults.listen((results) {
    // do something with scan results
    for (ScanResult r in results) {
        print('${r.device.name} found! rssi: ${r.rssi}');
    }
});

// Stop scanning
flutterBlue.stopScan();

这可能已经解决了您的问题。


0
投票

我评论“flutterBlue.stopScan();”解决了问题

不确定这是如何工作的,“flutterBlue.stopScan();”的代码相同没有对其他项目发表评论,在该项目中一切都很完美

这是“flutterBlue.stopScan();”的示例没有评论,扫描有效 https://github.com/tusharhow/flutter-bluetooth-app

对我有用的代码->

import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';

class BluetoothController extends GetxController {
  FlutterBluePlus flutterBlue = FlutterBluePlus.instance;

  Future scanDevices() async {
    // Start scanning
    flutterBlue.startScan(timeout: const Duration(seconds: 5));

// Listen to scan results
    var subscription = flutterBlue.scanResults.listen((results) {
      print('scanResults: ${results}');
      // do something with scan results
      for (ScanResult r in results) {
        print('${r.device.name} found! rssi: ${r.rssi}');
      }
    });
    print('subscription: $subscription');
    // Stop scanning
    //flutterBlue.stopScan();
  }

  // scan result stream
  Stream<List<ScanResult>> get scanResults => flutterBlue.scanResults;

  // connect to device
  Future<void> connectToDevice(BluetoothDevice device) async {
    await device.connect();
  }

}

0
投票

我遇到了同样的问题,在 android 13 上工作。我无法获取可用设备的列表。

解决方案是将 android:usesPermissionFlags="neverForLocation" 标志添加到 AndroidManifest.xml: 中的 BLUETOH_SCAN

之前:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

之后(就像魅力一样):

<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />

应用程序权限请求可能如下所示(您需要添加对Android的支持< API 31):

Future<bool> requestBluetoothAccess() async {
  Future<bool> permStatus;
  if (Platform.isAndroid && await getAndroidSdk() > 30) {
    Map<Permission, PermissionStatus> statuses = await [
      Permission.bluetoothScan,
      Permission.bluetoothConnect,
    ].request();

    if (statuses[Permission.bluetoothScan] == PermissionStatus.granted &&
        statuses[Permission.bluetoothConnect] == PermissionStatus.granted) {
      return true;
    }
    return false;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.