You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter检测Android/iOS蓝牙开关状态问题求助

解决Flutter检测蓝牙开关状态无响应问题(基于flutter_blue_plus)

你的代码核心问题在于蓝牙状态的监听逻辑没有被加入到Widget树中,导致页面加载后无法响应蓝牙状态变化。以下是修正后的完整实现,完全支持空安全:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:app_settings/app_settings.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:qbit/routes/index_routes.dart';

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

  @override
  State<BleEnabled> createState() => _BleEnabledState();
}

class _BleEnabledState extends State<BleEnabled> with WidgetsBindingObserver {
  bool _openedSettings = false;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    // 主动检查一次蓝牙初始状态
    _checkBluetoothStatus();
  }

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

  void _checkBluetoothStatus() async {
    final currentState = await FlutterBluePlus.instance.state.first;
    if (currentState == BluetoothState.on) {
      _navigateToConnectionPage();
    } else {
      _showEnableBluetoothDialog();
    }
  }

  void _navigateToConnectionPage() {
    if (!Get.currentRoute.contains(AppRoutes.connection)) {
      Get.toNamed(AppRoutes.connection);
    }
  }

  void _showEnableBluetoothDialog() {
    Get.dialog(
      AlertDialog(
        title: const Text("需要开启蓝牙"),
        content: const Text("请开启蓝牙以继续使用功能"),
        actions: [
          ElevatedButton(
            onPressed: () {
              _openedSettings = true;
              AppSettings.openBluetoothSettings();
              Get.back();
            },
            child: const Text("打开设置"),
          ),
        ],
      ),
      barrierDismissible: false,
    );
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.resumed && _openedSettings) {
      _openedSettings = false;
      // 从设置返回后重新检查蓝牙状态
      _checkBluetoothStatus();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        // 用StreamBuilder实时监听蓝牙状态变化
        child: StreamBuilder<BluetoothState>(
          stream: FlutterBluePlus.instance.state,
          initialData: BluetoothState.unknown,
          builder: (context, snapshot) {
            final state = snapshot.data;
            if (state == BluetoothState.on) {
              WidgetsBinding.instance.addPostFrameCallback((_) {
                _navigateToConnectionPage();
              });
            }
            // 加载状态提示,可根据需求自定义
            return const Center(child: CircularProgressIndicator());
          },
        ),
      ),
    );
  }
}

关键修改说明:

  1. Widget树整合监听逻辑:将StreamBuilder移到build方法中,确保蓝牙状态变化能实时触发UI和逻辑更新
  2. 简化页面跳转逻辑:移除冗余的ChangePage组件,直接在状态判断中处理页面跳转,避免不必要的组件嵌套
  3. 优化生命周期监听:在应用从设置返回后,主动重新检查蓝牙状态,而非重新创建组件
  4. 避免重复跳转:添加路由判断,防止多次触发页面跳转

额外配置要求:

  • 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" />
    <!-- Android 12+ 需额外添加 -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    
  • iOS:在Info.plist中添加权限描述
    <key>NSBluetoothAlwaysUsageDescription</key>
    <string>需要蓝牙权限以连接设备</string>
    <key>NSBluetoothPeripheralUsageDescription</key>
    <string>需要蓝牙权限以连接设备</string>
    

内容的提问来源于stack exchange,提问作者Luca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 09:15:43