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

Flutter iOS:无第三方包,通过Method Channel结合AppDelegate.swift检查蓝牙状态

解决Flutter iOS端通过Method Channel结合AppDelegate检查蓝牙状态的问题

原代码存在的问题

  • centralManager是方法内的局部变量,创建后立即判断状态时,CBCentralManager可能还未完成初始化,此时状态大概率是unknown,导致判断不准确
  • 未正确实现CBCentralManagerDelegate的centralManagerDidUpdateState方法,无法接收蓝牙状态的异步更新
  • 未保留centralManager的类级实例,方法执行完毕后局部变量被释放,代理回调无法触发
  • 使用了已废弃的CBCentralManagerState枚举,应替换为CBManagerState

修正后的AppDelegate.swift代码

import UIKit
import Flutter
import CoreBluetooth

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, CBCentralManagerDelegate {
    // 将centralManager设为类属性,避免被释放
    private var centralManager: CBCentralManager!
    // 保存Flutter回调,用于状态更新后返回结果
    private var bluetoothStateResult: FlutterResult?
    
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // 初始化CBCentralManager,确保代理生效
        centralManager = CBCentralManager(delegate: self, queue: nil, options: [CBCentralManagerOptionShowPowerAlertKey: false])
        
        // 注册Method Channel
        let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
        let bluetoothChannel = FlutterMethodChannel(name: "app/bleState", binaryMessenger: controller.binaryMessenger)
        
        bluetoothChannel.setMethodCallHandler { [weak self] call, result in
            guard let self = self else { return }
            switch call.method {
            case "getBluetoothState":
                // 先检查当前状态,如果不是unknown直接返回
                if self.centralManager.state != .unknown {
                    result(self.centralManager.state == .poweredOn)
                } else {
                    // 状态未确定,保存回调,等待代理返回
                    self.bluetoothStateResult = result
                }
            default:
                result(FlutterMethodNotImplemented)
            }
        }
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    
    // 实现代理方法,处理蓝牙状态更新
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        // 如果有等待的回调,返回当前状态
        if let result = bluetoothStateResult {
            result(central.state == .poweredOn)
            bluetoothStateResult = nil // 清空回调,避免重复调用
        }
    }
}

Flutter端调用代码示例

import 'package:flutter/services.dart';

class BluetoothChecker {
  static const MethodChannel _channel = MethodChannel('app/bleState');

  static Future<bool> get isBluetoothEnabled async {
    try {
      final bool result = await _channel.invokeMethod('getBluetoothState');
      return result;
    } on PlatformException catch (e) {
      print('获取蓝牙状态失败: ${e.message}');
      return false;
    }
  }
}

// 使用示例
// bool enabled = await BluetoothChecker.isBluetoothEnabled;

关键说明

  • 类级别的centralManager确保实例不会被释放,代理回调能正常触发
  • 处理getBluetoothState调用时,先判断当前状态,若未初始化完成则保存回调,等待代理方法返回后再响应
  • 使用最新的CBManagerState枚举替代废弃的CBCentralManagerState
  • 增加[weak self]避免循环引用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:08:31