如何实现Flutter应用永久连接BLE按键信标,支持系统重启自动重连
Flutter 连接BLE物理按键并全生命周期监听实现方案
针对你需要在Flutter应用中连接BLE物理按键、按键触发发邮件,且要求前台/后台/终止状态下持续监听、系统重启后自动重连的需求,结合Android和iOS的平台特性,给出以下实现方案:
核心依赖选择
放弃flutter_blue,改用flutter_blue_plus(flutter_blue的维护分支,更稳定,对平台后台支持更好);邮件发送使用mailer插件;Android前台服务用flutter_foreground_task。
Android 端实现
1. 权限与配置
在AndroidManifest.xml中添加以下权限和配置:
<!-- BLE基础权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 后台BLE监听权限 --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <!-- 开机自启权限 --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <!-- 前台服务声明 --> <service android:name="com.pravera.flutter_foreground_task.service.ForegroundService" /> <!-- 开机广播接收器 --> <receiver android:name=".BootCompletedReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
2. 后台保活与BLE监听
- 使用
flutter_foreground_task创建前台服务,将BLE连接、监听逻辑放在服务中运行,避免后台进程被系统杀死。 - 在BLE管理类中实现自动重连逻辑:监听设备断开事件,一旦断开立即发起扫描并重新连接目标设备。
3. 开机自启
创建原生BootCompletedReceiver类,收到开机广播后启动前台服务,触发BLE扫描与重连:
class BootCompletedReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if (intent?.action == Intent.ACTION_BOOT_COMPLETED) { val serviceIntent = Intent(context, ForegroundService::class.java) ContextCompat.startForegroundService(context!!, serviceIntent) } } }
iOS 端实现
1. 后台模式配置
在Xcode中开启后台模式:
- 打开项目
Capabilities->Background Modes - 勾选
Uses Bluetooth LE accessories和Acts as a Bluetooth LE accessory
同时在Info.plist中添加:
<key>UIBackgroundModes</key> <array> <string>bluetooth-central</string> </array>
2. BLE后台与终止状态监听
- iOS系统会自动维护已配对BLE设备的连接,当设备断开后会尝试自动重连;若应用处于终止状态,当BLE设备发送Notify特征值时,系统会短暂唤醒应用。
- 在Flutter的
main函数中,通过WidgetsBindingObserver监听应用生命周期,在didFinishLaunchingWithOptions中处理BLE唤醒事件,触发邮件发送逻辑。
3. 系统重启后重连
iOS没有开机自启API,但只要应用之前连接过目标BLE设备,系统重启后检测到设备广播时,会自动唤醒应用并尝试重连(需确保后台BLE权限已开启)。
跨平台通用逻辑
1. BLE管理封装
创建单例类BleManager,统一处理:
- 扫描目标BLE设备(通过设备UUID过滤)
- 连接设备并订阅按键对应的特征值Notify
- 监听特征值变化,触发邮件发送
- 设备断开时自动发起重连
2. 邮件发送
使用mailer插件配置SMTP信息,当检测到按键按下的特征值时,异步发送邮件:
Future<void> sendEmail() async { final smtpServer = SmtpServer('smtp.example.com', username: 'your_email', password: 'your_password'); final message = Message() ..from = Address('your_email', 'App Name') ..recipients.add('target_email') ..subject = 'BLE按键触发通知' ..text = 'BLE物理按键已被按下'; try { await send(message, smtpServer); } catch (e) { // 处理发送失败逻辑 } }
关键注意事项
- Android 12+需动态申请
BLUETOOTH_SCAN、BLUETOOTH_CONNECT和后台定位权限,否则无法正常扫描BLE设备。 - iOS后台唤醒应用后仅能运行数秒,邮件发送逻辑需轻量化,必要时使用
URLSession后台任务延长执行时间。 - 所有功能需在真实设备上测试,模拟器对BLE和后台进程支持有限。
内容的提问来源于stack exchange,提问作者Florian Marcu
相关产品推荐
相关产品推荐

