如何将智能手表连接到Flutter应用并获取步数数据、控制功能?
Flutter 与智能手表连接:步数追踪与功能控制方案
核心思路
Flutter本身没有跨平台的智能手表原生连接API,需基于Android Wear(Android)和watchOS(iOS)的原生能力,通过Flutter插件或平台通道对接。优先选择**BLE(蓝牙低功耗)**协议,这是绝大多数消费级智能手表的标准通信方式;若开发自有生态的手表应用,可使用平台专属的通信框架。
平台适配方案与代码示例
Android 平台(适配Wear OS/第三方BLE手表)
推荐使用 flutter_blue_plus 插件,它是Flutter生态中维护活跃的BLE通信库,支持扫描、连接、读写特征值等核心功能。
步骤1:配置权限与依赖
在 android/app/src/main/AndroidManifest.xml 中添加蓝牙权限:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
在 pubspec.yaml 中添加依赖:
dependencies: flutter_blue_plus: ^1.13.16
步骤2:核心代码示例
import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'dart:convert'; // 初始化蓝牙并请求权限 Future<void> initBluetooth() async { if (!await FlutterBluePlus.isAvailable) { print("蓝牙硬件不可用"); return; } final status = await FlutterBluePlus.requestPermissions(); if (status != BluetoothPermissionStatus.granted) { print("蓝牙权限未授予"); return; } await FlutterBluePlus.turnOn(); } // 扫描并连接目标智能手表 void connectToWatch() { FlutterBluePlus.scanResults.listen((results) { for (final result in results) { // 匹配你的手表设备名称或MAC地址 if (result.device.name == "MySmartWatch") { result.device.connect().then((_) { _discoverServices(result.device); }); FlutterBluePlus.stopScan(); break; } } }); FlutterBluePlus.startScan(timeout: const Duration(seconds: 10)); } // 发现服务并读写数据(需提前获取手表的服务/特征UUID) void _discoverServices(BluetoothDevice device) { device.discoverServices().then((services) { for (final service in services) { // 匹配步数服务UUID(需参考手表的开发文档) if (service.uuid.toString() == "0000ffe0-0000-1000-8000-00805f9b34fb") { for (final characteristic in service.characteristics) { // 匹配步数特征UUID if (characteristic.uuid.toString() == "0000ffe1-0000-1000-8000-00805f9b34fb") { // 读取当前步数 characteristic.read().then((value) { final steps = int.parse(utf8.decode(value)); print("当前步数:$steps"); }); // 监听步数实时更新 characteristic.setNotifyValue(true); characteristic.value.listen((value) { final steps = int.parse(utf8.decode(value)); print("步数更新:$steps"); }); // 发送控制指令(如启动/停止追踪) characteristic.write(utf8.encode("START_TRACKING")); } } } } }); }
iOS 平台(适配watchOS/第三方BLE手表)
- 若对接第三方BLE手表:同样使用
flutter_blue_plus,配置方式与Android类似,需在Info.plist中添加蓝牙权限描述:<key>NSBluetoothAlwaysUsageDescription</key> <string>需要蓝牙权限连接智能手表</string> - 若开发自有watchOS应用:推荐使用
watch_connectivity插件,实现iOS主App与watchOS App的双向通信。
watch_connectivity 代码示例(主App端)
import 'package:watch_connectivity/watch_connectivity.dart'; class WatchCommunicator { final _watchConnectivity = WatchConnectivity(); bool _isReachable = false; Future<void> init() async { await _watchConnectivity.activate(); // 监听手表可达状态 _watchConnectivity.isReachable.listen((isReachable) { _isReachable = isReachable; print("手表是否可达:$isReachable"); }); // 监听来自手表的消息 _watchConnectivity.messageStream.listen((message) { if (message.containsKey('steps')) { final steps = message['steps'] as int; print("收到手表步数:$steps"); } }); } // 请求手表步数数据 Future<void> requestSteps() async { if (_isReachable) { await _watchConnectivity.sendMessage({'action': 'request_steps'}); } } // 发送控制指令到手表 Future<void> sendControlCommand(String command) async { if (_isReachable) { await _watchConnectivity.sendMessage({'command': command}); } } }
watchOS 端配套代码(Swift)
需在watchOS Extension中实现WCSession代理:
import WatchConnectivity import HealthKit class ExtensionDelegate: NSObject, WKExtensionDelegate, WCSessionDelegate { private let healthStore = HKHealthStore() private var session: WCSession? func applicationDidFinishLaunching() { guard WCSession.isSupported() else { return } session = WCSession.default session?.delegate = self session?.activate() } func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) { if message["action"] as? String == "request_steps" { // 从HealthKit读取步数(需提前申请HealthKit权限) fetchSteps { steps in replyHandler(["steps": steps]) } } else if let command = message["command"] as? String { handleControlCommand(command) } } private func fetchSteps(completion: @escaping (Int) -> Void) { let stepType = HKObjectType.quantityType(forIdentifier: .stepCount)! let predicate = HKQuery.predicateForSamples(withStart: Date().startOfDay, end: Date(), options: .strictStartDate) let query = HKStatisticsQuery(quantityType: stepType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, error in guard let result = result, let sum = result.sumQuantity() else { completion(0) return } let steps = sum.doubleValue(for: HKUnit.count()) completion(Int(steps)) } healthStore.execute(query) } private func handleControlCommand(_ command: String) { switch command { case "START_TRACKING": // 启动步数追踪逻辑 break case "STOP_TRACKING": // 停止步数追踪逻辑 break default: break } } }
关键建议
- 确认设备协议:优先选择支持BLE的智能手表,若为自有生态设备,使用平台专属框架(Wear OS的
wear插件、watchOS的watch_connectivity)更高效。 - 权限处理:Android 12+需动态申请
BLUETOOTH_SCAN和BLUETOOTH_CONNECT权限;iOS需在Info.plist中添加蓝牙权限描述,若使用HealthKit还需申请健康数据权限。 - 测试注意事项:必须使用真实设备测试,模拟器不支持BLE或手表连接功能。
- 稳定性处理:实现连接断开的自动重连逻辑,添加异常捕获(如连接超时、权限拒绝)。
- 数据解析:严格按照手表的通信协议解析数据,部分设备使用二进制格式,需参考官方文档转换。
内容的提问来源于stack exchange,提问作者Nehil Koshiya
相关产品推荐
相关产品推荐

