import 'dart:async'; import 'package:flutter/services.dart'; import 'package:permission_handler/permission_handler.dart'; import 'messages.dart' as msg; class Sensor { static final msg.SensorApi api = msg.SensorApi(); static const _eventChannelLocation = EventChannel("com.beswell.sensor.event/location"); static const _eventChannelOrientation = EventChannel("com.beswell.sensor.event/orientation"); static const _eventChannelHRM = EventChannel("com.beswell.sensor.event/HRM"); /// 类型List>,每个Map中包括 /// String address; /// String name; /// int rssi; static const _eventChannelSportWearScanResult = EventChannel("com.beswell.sensor.event/SportWearScanResult"); /// 类型List>,每个Map中包括 /// String address; /// String name; /// int rssi; static const _eventChannelSportWearConnected = EventChannel("com.beswell.sensor.event/SportWearConnected"); static Stream? _locationStream; static Stream get locationStream { _locationStream ??= _eventChannelLocation.receiveBroadcastStream(); return _locationStream!.map((event) { final p0 = msg.Position.decode(event); return Position() ..longitude=p0.longitude??0 ..latitude=p0.latitude??0 ..altitude=p0.altitude??0 ..speed=p0.speed??0 ..accuracy=p0.accuracy??0 ..bearing=p0.bearing??0 ..tsMs=p0.timeMs??0 ; } ); } static Stream? _orientationStream; static Stream get orientationStream { _orientationStream??=_eventChannelOrientation.receiveBroadcastStream(); return _orientationStream!.map((event) { final r = msg.Orientation.decode(event); return Orientation() ..x = r.x ?? 0 ..y = r.y ?? 0 ..z = r.z ?? 0; } ); } static Future getCurrentPosition({bool force = false}) async { final r = await api.getCurrentPosition(force); return Position() ..longitude = r.longitude ?? 0 ..latitude = r.latitude ?? 0 ..altitude = r.altitude ?? 0; } static Future isLocationServiceOpen()async { return api.isLocationServiceOpen(); } static Stream> get sportWearScanResultStream { return _eventChannelSportWearScanResult.receiveBroadcastStream().map((event) { final l = event as List; return l.map((e){ final m = e as Map; return SportWear() ..name=m['name'] ..address=m['address'] ..rssi=m['rssi'] ; } ).toList(); } ); } static Future sportWearScanStart() async{ var status = await Permission.bluetoothScan.status ; if (status.isDenied){ if(await Permission.bluetoothScan.request().isDenied){ throw Exception('无扫描权限'); } } status = await Permission.bluetooth.status ; if (status.isDenied){ if(await Permission.bluetooth.request().isDenied){ throw Exception('无蓝牙权限'); } } status = await Permission.bluetoothConnect.status ; if (status.isDenied){ if(await Permission.bluetoothConnect.request().isDenied){ throw Exception('无蓝牙权限'); } } status = await Permission.location.status ; if (status.isDenied){ if(await Permission.location.request().isDenied){ throw Exception('无定位权限'); } } if (await api.askEnableBluetooth()){ api.sportWearScanStart(); }else{ throw Exception('未开启蓝牙'); } } static Future sportWearScanStop() async{ await api.sportWearScanStop(); } static Future sportWearConnect(SportWear wear)async{ await api.sportWearConnect(msg.SportWear()..address=wear.address); } static Future sportWearDisconnect(SportWear wear)async{ await api.sportWearDisconnect(msg.SportWear()..address=wear.address); } static Stream> get sportWearConnectedStream { return _eventChannelSportWearConnected.receiveBroadcastStream().map((event) { final l = event as List; return l.map((e){ final m = e as Map; return SportWear() ..name=m.containsKey('name')?m['name']:'' ..address=m['address'] ..rssi=m.containsKey('rssi')?m['rssi']:0 ; } ).toList(); }); } static Stream get sportWearHeartRateMeasurementStream { return _eventChannelHRM.receiveBroadcastStream().map((event) { try{ final e = msg.HeartRateMeasurement.decode(event); return HeartRateMeasurement() ..sportWearAddress=e.deviceMac ??'' ..heartRate=e.heartRate??0 ..contactDetected=e.contactDetected??true ..rrIntervals=e.rrIntervals?.map((rr) => rr??0).toList()??List.empty() ..timestamp= DateTime.fromMillisecondsSinceEpoch( e.timestampMill?? DateTime.now().millisecondsSinceEpoch); }catch(e){ print('心率接收错误:$e'); return HeartRateMeasurement(); } } ); } static Future locationStart(Duration minTime, double minDistanceM) async { var status = await Permission.location.status ; if (status.isDenied){ if(await Permission.location.request().isDenied){ throw Exception('无定位权限'); } } await api.locationStart(minTime.inMilliseconds, minDistanceM); } } class Orientation { double x = 0; double y = 0; double z = 0; } class Position { double latitude = 0; double longitude = 0; double altitude = 0; double speed=0; double accuracy=0; double bearing=0; int tsMs=0; } class SportWear{ String address=''; String name=''; int rssi=0; } class HeartRateMeasurement{ String sportWearAddress=''; int heartRate=0; /// 是否已检测到传感器接触信息 bool contactDetected=false; /// RR间隔的可选列表,每个间隔为1/1024秒 List rrIntervals=List.empty(); DateTime timestamp=DateTime.now(); }