boskokg / flutter_blue_plus

Flutter plugin for connecting and communicationg with Bluetooth Low Energy devices, on Android and iOS
Other
659 stars 416 forks source link

[Help]: RedMi k60 cannot detect Bluetooth devices when using the latest version of the plugin. #786

Closed guduqiucai closed 5 months ago

guduqiucai commented 5 months ago

Requirements

Have you checked this problem on the example app?

No

FlutterBluePlus Version

1.31.13

Flutter Version

3.16.9

What OS?

Android

OS Version

unknown

Bluetooth Module

unknown

What is your problem?

The RedMi k60 phone can detect Bluetooth devices using plugin version 1.10.4, but subsequent plugin versions, including 1.31.13, are unable to detect Bluetooth devices.Other Android phones can normally scan for Bluetooth.

Logs

Launching lib/main.dart on 22041211AC in debug mode...
Running Gradle task 'assembleDebug'...
注: 某些输入文件使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
注: /Users/coco/.pub-cache/hosted/pub.flutter-io.cn/scan-1.6.0/android/src/main/java/com/chavesgu/scan/ScanViewFactory.java使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
✓  Built build/app/outputs/flutter-apk/app-debug.apk.
Debug service listening on ws://127.0.0.1:51533/VlqJNIdwXqc=/ws
Syncing files to device 22041211AC...
I/flutter (28100): MyNavObserver:didPush: _CustomTransitionPageRoute<dynamic>(NoTransitionPage<dynamic>("null", null, null), animation: AnimationController#4228e(⏭ 1.000; paused; for _CustomTransitionPageRoute<dynamic>)), previousRoute= null
D/permissions_handler(28100): Bluetooth permission missing in manifest
I/flutter (28100): 蓝牙权限请求失败
D/[FBP-Android](28100): [FBP] onMethodCall: flutterHotRestart
D/[FBP-Android](28100): [FBP] initializing BluetoothAdapter
I/flutter (28100): 位置权限已开启1
D/[FBP-Android](28100): [FBP] disconnectAllDevices(flutterHotRestart)
D/[FBP-Android](28100): [FBP] connectedPeripherals: 0
D/[FBP-Android](28100): [FBP] onMethodCall: isSupported
I/flutter (28100): 蓝牙是否可用,true
D/[FBP-Android](28100): [FBP] onMethodCall: getAdapterState
D/[FBP-Android](28100): [FBP] onMethodCall: getAdapterState
I/flutter (28100): 蓝牙状态已经开启,true
I/flutter (28100): 蓝牙状态为开启
D/[FBP-Android](28100): [FBP] onMethodCall: stopScan
D/BluetoothAdapter(28100): isLeEnabled(): ON
D/BluetoothLeScanner(28100): could not find callback wrapper
I/flutter (28100): blue is stop
I/flutter (28100): start scan
D/[FBP-Android](28100): [FBP] onMethodCall: startScan
D/BluetoothAdapter(28100): isLeEnabled(): ON
D/BluetoothLeScanner(28100): onScannerRegistered() - status=0 scannerId=14 mScannerId=0
E/OpenGLRenderer(28100): fbcNotifyFrameComplete error: undefined symbol: fbcNotifyFrameComplete
E/OpenGLRenderer(28100): fbcNotifyNoRender error: undefined symbol: fbcNotifyNoRender
D/DecorView[](28100): onWindowFocusChanged hasWindowFocus true
D/[FBP-Android](28100): [FBP] onMethodCall: stopScan
D/BluetoothAdapter(28100): isLeEnabled(): ON
I/flutter (28100): blue is stop
I/flutter (28100): start scan
D/[FBP-Android](28100): [FBP] onMethodCall: startScan
D/BluetoothAdapter(28100): isLeEnabled(): ON
D/BluetoothLeScanner(28100): onScannerRegistered() - status=0 scannerId=14 mScannerId=0
D/DecorView[](28100): onWindowFocusChanged hasWindowFocus false
D/AppScoutStateMachine(28100): 28100-ScoutStateMachinecreated
D/DecorView[](28100): onWindowFocusChanged hasWindowFocus true
I/OpenGLRenderer(28100): Davey! duration=18775ms; Flags=1, FrameTimelineVsyncId=119107, IntendedVsync=2747897342397, Vsync=2747897342397, InputEventId=0, HandleInputStart=2747897629470, AnimationStart=2747897630624, PerformTraversalsStart=2747897631009, DrawStart=2747898013470, FrameDeadline=2747917342397, FrameInterval=2747897612547, FrameStartTime=16666667, SyncQueued=2747899088855, SyncStart=2747899143855, IssueDrawCommandsStart=2747899370086, SwapBuffers=2747904574086, FrameCompleted=2766672692241, DequeueBufferDuration=707077, QueueBufferDuration=549308, GpuCompleted=2766672692241, SwapBuffersCompleted=2747906267547, DisplayPresentTime=476466408098, 
D/DecorView[](28100): onWindowFocusChanged hasWindowFocus false
D/[FBP-Android](28100): [FBP] onMethodCall: stopScan
D/BluetoothAdapter(28100): isLeEnabled(): ON
Lost connection to device.
the Dart compiler exited unexpectedly.
chipweinberger commented 5 months ago

try example app

guduqiucai commented 5 months ago

example app is OK,but my app is wrong, this is my

main.dart:
class TestBluePage extends StatefulWidget {
  TestBluePage({Key? key}) : super(key: key);

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

class TestBlueState extends State<TestBluePage> {
  bool isDebug = false;
  bool isBleOn = false;
  bool isConnecting = false;
  List<ScanResult> _blueDevice = [];
  late BluetoothService currentService;
  late BluetoothCharacteristic writeChar;
  late BluetoothCharacteristic readChar;
  List<String> receiveData = [];
  List<String> blueName = [];
  bool isAutoConnect = false;
  Timer? authTimer;
  var subscription = null;

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

    reuestBlue();

    requestLocation();

    /// 监听蓝牙扫描结果
    scanLister();
  }

  @override
  void dispose() {
    EasyLoading.dismiss();
    authTimer?.cancel();
    super.dispose();
    subscription.cancel();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(S.current.bluetoothPageTitle, style: TextStyle(color: Colors.white),),
          backgroundColor: Colors.blue,
          leading: Padding(
            padding: EdgeInsets.only(top: 3),
            child: IconButton(
              tooltip: S.current.returnPrePage,
              icon: Icon(
                CupertinoIcons.left_chevron,
                color: Colors.white,
              ),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ),
        ),
        body: ListView(
            children: [
              Platform.isAndroid ? Text(
            S.current.androidTips,
            style: TextStyle(
                fontWeight: FontWeight.normal,
                color: Colors.black54,
                backgroundColor: Colors.white
            ),
          ): Container(),
              SingleChildScrollView(
                child: Column(
                  children: <Widget>[
                    ListView.separated(
                        itemBuilder: _buildBlueDevice,
                        physics: NeverScrollableScrollPhysics(),
                        shrinkWrap: true,
                        itemCount: _blueDevice.length,
                        separatorBuilder: (BuildContext context, int index) =>
                            Divider(
                              height: 1,
                              color: Colors.grey,
                            )),
                  ],
                ),
              ),
            ],
          ),
        // ],),

        floatingActionButton: Stack(
          children: [
            Align(
              alignment: Alignment.bottomRight,
              child: FloatingActionButton(
                backgroundColor: Colors.blue,
                onPressed: searchBlueClick,
                heroTag: S.current.scan,
                tooltip: S.current.scanBluetoothDevices,
                child: Icon(Icons.bluetooth_searching_outlined, color: Colors.white,),
              ),
            ),
          ],
        ));
  }

  reuestBlue() async {
    if (await Permission.bluetooth.request().isGranted) {
      print('蓝牙权限已开启');
    } else {
      print('蓝牙权限请求失败');
    }

    FlutterBluePlus.isSupported.then((value) {
      print('蓝牙是否可用,$value');
    });

    FlutterBluePlus.isOn.then((value) {
      print('蓝牙状态已经开启,$value');
      isBleOn = value;
    });

    FlutterBluePlus.adapterState.listen((state) {
      if (state == BluetoothAdapterState.on) {
        print('蓝牙状态为开启');
        isBleOn = true;

        searchBlue();
      } else if (state == BluetoothAdapterState.off) {
        print('蓝牙状态为关闭');
        isBleOn = false;
      }
    });
  }

  requestLocation() async {
    if (await Permission.location.isGranted) {
      print('位置权限已开启1');
    } else {
      print('蓝牙搜索需要开启位置权限');
      if (await Permission.location.request().isGranted) {
        print('位置权限已开启2');
        searchBlue();
      } else {
        print('位置权限请求失败');
      }
    }
  }

  Widget _buildBlueDevice(BuildContext context, int index) {
    ScanResult model = _blueDevice[index];
    print(model);
    return Padding(
      padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 10),
      child: Row(
        children: <Widget>[
          model.device.connectionState != BluetoothConnectionState.connected
              ? IconButton(
                  onPressed: null,
                  icon: Icon(
                    Icons.bluetooth,
                    color: green,
                  ),
                )
              : IconButton(
                  onPressed: () => model.device.disconnect(),
                  icon: Icon(Icons.bluetooth_connected),
                ),
          Container(
            width: 200,
            child: Tooltip(
              child: Text(
                breakWord(Platform.isAndroid ?  model.device.platformName : model.advertisementData.advName),
                // breakWord(Platform.isAndroid ?  model.device.localName : model.advertisementData.advName),
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
                style: TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                ),
              ),
              message: model.device.platformName,
            ),
          ),
          Expanded(
            child: Text(''),
          ),
          ElevatedButton(
            // 赋值为null,就是disable状态
            onPressed: model.advertisementData.connectable
                ? () {
                    isAutoConnect = false;
                    beforeConnectDeal(model);
                  }
                : null,
            style: ElevatedButton.styleFrom(
                backgroundColor: green,
                disabledBackgroundColor: Colors.green[300],
                fixedSize: const Size(100, 10),
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(5))),
            child: Text(
              S.current.connect,
              style: TextStyle(color: Colors.white, fontSize: 16),
            ),
          ),
        ],
      ),
    );
  }

  // 自动扫描蓝牙设备
  void searchBlue() {
    if (!isBleOn) {
      showWarnToast(S.current.bluetoothOffMessage);
      return;
    }
    FlutterBluePlus.stopScan().then((value) {
      print('blue is stop');
      print('start scan');
      setState(() {
        this.blueName.clear();
        this._blueDevice.clear();
      });
      // Listen to scan results
      if (FlutterBluePlus.isScanningNow == false) {
        FlutterBluePlus.startScan(timeout: const Duration(seconds: 15));
      }
      // FlutterBluePlus.startScan(timeout: Duration(seconds: 3));
    });
  }
  // 手动扫描:安卓规定30s内只能扫描5次,因为进入该界面自动扫描了1次,所以30s内只能扫描4次
  int startTime = DateTime.now().millisecondsSinceEpoch;
  void searchBlueClick() {
    if (!isBleOn) {
      showWarnToast(S.current.bluetoothOffMessage);
      return;
    }
    int curTime = DateTime.now().millisecondsSinceEpoch;
    if (curTime - startTime < 8000) {
      return;
    } else {
      startTime = curTime;
    }
    FlutterBluePlus.stopScan().then((value) {
      print('blue is stop');
      print('start scan');

      scanLister();
      setState(() {
        this.blueName.clear();
        this._blueDevice.clear();
      });
      if (FlutterBluePlus.isScanningNow == false) {
        FlutterBluePlus.startScan(timeout: Duration(seconds: 15));
      }
    });
  }

  void scanLister() {
    subscription = FlutterBluePlus.scanResults.listen((results) {
      if (results.isNotEmpty) {
        // ScanResult res = results.last; // the most recently found device
        for (ScanResult r in results) {
          if (Platform.isAndroid) {
            if (r.device.platformName != '' &&
                !blueName.contains(r.device.platformName)) {
              blueName.add(r.device.platformName);
              if (mounted) {
                setState(() {
                  this._blueDevice.add(r);
                });
              }
            }
          } else {
            if (r.advertisementData.advName != '' &&
                !blueName.contains(r.advertisementData.advName)) {
              blueName.add(r.advertisementData.advName);
              if (mounted) {
                setState(() {
                  this._blueDevice.add(r);
                });
              }
            }
          }
        }
      }
    },
      onError: (e) => print(e),
    );
  }
}
chipweinberger commented 5 months ago

im not sure, your code is pretty confusing. look at the example app code