| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- 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, dynamic>>,每个Map中包括
- /// String address;
- /// String name;
- /// int rssi;
- static const _eventChannelSportWearScanResult = EventChannel("com.beswell.sensor.event/SportWearScanResult");
- /// 类型List<Map<String, dynamic>>,每个Map中包括
- /// String address;
- /// String name;
- /// int rssi;
- static const _eventChannelSportWearConnected = EventChannel("com.beswell.sensor.event/SportWearConnected");
- static Stream<dynamic>? _locationStream;
- static Stream<Position> 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<dynamic>? _orientationStream;
- static Stream<Orientation> 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<Position> 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<bool> isLocationServiceOpen()async {
- return api.isLocationServiceOpen();
- }
- static Stream<List<SportWear>> get sportWearScanResultStream {
- return _eventChannelSportWearScanResult.receiveBroadcastStream().map((event) {
- final l = event as List<dynamic>;
- return l.map((e){
- final m = e as Map<dynamic, dynamic>;
- return SportWear()
- ..name=m['name']
- ..address=m['address']
- ..rssi=m['rssi']
- ;
- }
- ).toList();
- } );
- }
- static Future<void> 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<void> sportWearScanStop() async{
- await api.sportWearScanStop();
- }
- static Future<void> sportWearConnect(SportWear wear)async{
- await api.sportWearConnect(msg.SportWear()..address=wear.address);
- }
- static Future<void> sportWearDisconnect(SportWear wear)async{
- await api.sportWearDisconnect(msg.SportWear()..address=wear.address);
- }
- static Stream<List<SportWear>> get sportWearConnectedStream {
- return _eventChannelSportWearConnected.receiveBroadcastStream().map((event) {
- final l = event as List<dynamic>;
- return l.map((e){
- final m = e as Map<dynamic, dynamic>;
- return SportWear()
- ..name=m.containsKey('name')?m['name']:''
- ..address=m['address']
- ..rssi=m.containsKey('rssi')?m['rssi']:0
- ;
- }
- ).toList();
- });
- }
- static Stream<HeartRateMeasurement> 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<void> 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<int> rrIntervals=List.empty();
- DateTime timestamp=DateTime.now();
- }
|