SensorPlugin.m 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. #import "SensorPlugin.h"
  2. #import <sys/utsname.h>
  3. #import "AppEventChannel.h"
  4. #import<CoreMotion/CoreMotion.h>
  5. #import <CoreBluetooth/CoreBluetooth.h>
  6. #import <CoreLocation/CoreLocation.h>
  7. #import <CoreLocation/CLLocationManager.h>
  8. @interface SensorPlugin()<FLTSensorApi, CLLocationManagerDelegate, CBCentralManagerDelegate, BLEManagerDelegate, BLEDeviceDelegate> {
  9. FlutterEventSink flutterEventSink;
  10. FlutterEventChannel* flutterEventChannel;
  11. // CBCM对象
  12. CBCentralManager* CM;
  13. // 位置服务对象
  14. CLLocationManager * locationManager;
  15. UInt64 isOpenLastTime;
  16. bool isOpen;
  17. // 当前位置
  18. FLTPosition *fltPosition;
  19. // 陀螺仪传感器
  20. CMMotionManager *motionManager;
  21. // 返回的陀螺仪数据
  22. FLTOrientation *newOriention;
  23. // 蓝牙是否打开
  24. bool isBLOpen;
  25. // bleManager 对象
  26. HeartBLEManager *bleManager;
  27. // 扫描出的设备
  28. NSArray *ListPeripheral;
  29. // 当前连接设备
  30. HeartBLEDevice *BleDevice;
  31. // 心率交换池数组
  32. NSMutableArray *ListFLTHr;
  33. AppEventChannel *channelLocation;
  34. AppEventChannel *channelOriention;
  35. }
  36. @property (nonatomic, strong) FlutterEventSink eventSink;
  37. @property (nonatomic, strong) FlutterEventChannel *eventChannel ;
  38. @end
  39. @implementation SensorPlugin
  40. + (instancetype)sharedInstance {
  41. static SensorPlugin *instance = nil;
  42. static dispatch_once_t onceToken;
  43. dispatch_once(&onceToken, ^{
  44. instance = [[self alloc] init];
  45. });
  46. return instance;
  47. }
  48. + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  49. //注册methodChannel
  50. FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:@"sensor" binaryMessenger:[registrar messenger]];
  51. [registrar addMethodCallDelegate:SensorPlugin.sharedInstance channel:channel];
  52. //初始化streamChannel
  53. AppEventChannel *evenChannal = [[AppEventChannel alloc]initWithNameMessge:registrar :@"com.beswell.sensor.event/location"];
  54. SensorPlugin.sharedInstance -> channelLocation = evenChannal;
  55. AppEventChannel *channelOri = [[AppEventChannel alloc]initWithNameMessge:registrar :@"com.beswell.sensor.event/orientation"];
  56. SensorPlugin.sharedInstance -> channelOriention = channelOri;
  57. AppEventChannel *channelHrm = [[AppEventChannel alloc]initWithNameMessge:registrar :@"com.beswell.sensor.event/HRM"];
  58. AppEventChannel *channelWearScan = [[AppEventChannel alloc]initWithNameMessge:registrar :@"com.beswell.sensor.event/SportWearScanResult"];
  59. AppEventChannel *channelWearConn = [[AppEventChannel alloc]initWithNameMessge:registrar :@"com.beswell.sensor.event/SportWearConnected"];
  60. //初始化SensorApi
  61. FLTSensorApiSetup(registrar.messenger, SensorPlugin.sharedInstance);
  62. }
  63. // 构造函数,初始化一些变量
  64. -(id) init {
  65. NSLog(@"init struct");
  66. if (self=[super init]) {
  67. NSLog(@"init page obj");
  68. //初始化
  69. motionManager = [[CMMotionManager alloc] init];
  70. //设置更新间隔每秒60次
  71. motionManager.deviceMotionUpdateInterval = 1.0 / 60.0;
  72. //开启陀螺仪
  73. if (motionManager.isDeviceMotionAvailable) {
  74. [motionManager startDeviceMotionUpdates];
  75. }
  76. [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {
  77. if(self->newOriention == nil){
  78. self->newOriention = [[FLTOrientation alloc]init];
  79. }
  80. // Gravity 获取手机的重力值在各个方向上的分量,根据这个就可以获得手机的空间位置,倾斜角度等
  81. double gravityX = motion.gravity.x;
  82. double gravityY = motion.gravity.y;
  83. double gravityZ = motion.gravity.z;
  84. // 获取手机的倾斜角度(zTheta是手机与水平面的夹角, xyTheta是手机绕自身旋转的角度):
  85. double zTheta = atan2(gravityZ,sqrtf(gravityX * gravityX + gravityY * gravityY)) / M_PI * 180.0;
  86. double xyTheta = atan2(gravityX, gravityY) / M_PI * 180.0;
  87. // NSLog(@"手机与水平面的夹角 --- %.4f, 手机绕自身旋转的角度为 --- %.4f", zTheta, xyTheta);
  88. [self->newOriention setX:[[NSNumber alloc] initWithDouble:motion.gravity.x]];
  89. [self->newOriention setY:[[NSNumber alloc] initWithDouble:motion.gravity.y]];
  90. if(self->channelOriention != nil){
  91. [self->channelOriention success: @[
  92. (self->newOriention.x ?: [NSNull null]),
  93. (self->newOriention.y ?: [NSNull null]),
  94. (self->newOriention.z ?: [NSNull null]),
  95. ]
  96. ];
  97. }
  98. }];
  99. // 实例化bleManager
  100. bleManager = [HeartBLEManager sharedInstance];
  101. // 设置蓝牙代理
  102. [bleManager setDelegate:self];
  103. // 初始化心率数组
  104. ListFLTHr = [[NSMutableArray alloc]initWithCapacity:64];
  105. // 初始化蓝牙协议对象
  106. CM = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
  107. // 初始化位置对象
  108. fltPosition = [[FLTPosition alloc]init];
  109. }
  110. return self;
  111. }
  112. //StreamLocation
  113. /**
  114. */
  115. - (void)locationStartMinTimeMs:(NSNumber *)minTimeMs minDistanceM:(NSNumber *)minDistanceM error:(FlutterError * _Nullable __autoreleasing *)error{
  116. int isOpenTime = [[NSDate date] timeIntervalSince1970];
  117. if(isOpenTime - isOpenLastTime > 5){
  118. // NSLog(@"isLocationServiceOpenWithError%llu",(isOpenTime - isOpenLastTime));
  119. if ([CLLocationManager locationServicesEnabled]) {
  120. isOpen = true;
  121. if (locationManager == nil) {
  122. locationManager = [[CLLocationManager alloc] init];
  123. locationManager.delegate = self;
  124. [locationManager startUpdatingHeading];// 请求方向
  125. [locationManager requestAlwaysAuthorization];// 请求前台和后台定位权限 ios >= 8.0
  126. // [locationManager startUpdatingLocation];// 请求前台定位权限
  127. NSLog(@"init locationManager");
  128. }
  129. }else {
  130. isOpen = false;
  131. }
  132. isOpenLastTime = isOpenTime;
  133. }
  134. }
  135. - (void)locationStopWithError:(FlutterError * _Nullable __autoreleasing *)error{
  136. // 停止更新
  137. [ locationManager stopUpdatingLocation];
  138. }
  139. //
  140. - (void)toGenAllClassOrientation:(FLTOrientation *)orientation hrm:(FLTHeartRateMeasurement *)hrm position:(FLTPosition *)position error:(FlutterError *_Nullable *_Nonnull)error{
  141. }
  142. // 获取屏幕x向DPI
  143. - (nullable NSNumber *)getXDPIWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
  144. // NSLog(@"getXDPIWithError %@",[self getDpiOnPhone]);
  145. return [self getDpiOnPhone];
  146. }
  147. // 获取屏幕y向DPI
  148. - (nullable NSNumber *)getYDPIWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
  149. // NSLog(@"getYDPIWithError");
  150. return [self getDpiOnPhone];
  151. }
  152. // 获取设备当前朝向
  153. - (nullable FLTOrientation *)getOrientationWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
  154. // NSLog(@"getOrientationWithError%@ - %@ - %@",newOriention.x,newOriention.y,newOriention.z);
  155. return newOriention;
  156. }
  157. // 位置服务是否开启
  158. - (nullable NSNumber *)isLocationServiceOpenWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
  159. NSNumber *isLocationOpen = [[NSNumber alloc]initWithBool:isOpen];
  160. return isLocationOpen;
  161. }
  162. // 强制获取当前位置
  163. - (void)getCurrentPositionForce:(nonnull NSNumber *)force completion:(nonnull void (^)(FLTPosition * _Nullable, FlutterError * _Nullable))completion {
  164. // NSLog(@"getCurrentPositionForce");
  165. if (locationManager == nil) {
  166. locationManager = [[CLLocationManager alloc] init];
  167. locationManager.delegate = self;
  168. [locationManager startUpdatingHeading];// 请求方向
  169. [locationManager requestAlwaysAuthorization];// 请求前台和后台定位权限 ios >= 8.0
  170. // [locationManager startUpdatingLocation];// 请求前台定位权限
  171. }
  172. completion(fltPosition,NULL);
  173. }
  174. // 询问蓝牙是否开启
  175. - (void)askEnableBluetoothWithCompletion:(void (^)(NSNumber * _Nullable, FlutterError * _Nullable))completion{
  176. // NSLog(@"askEnableBluetoothWithCompletion");
  177. NSNumber *blueToothOpen = [[NSNumber alloc]initWithBool:isBLOpen];
  178. completion(blueToothOpen,NULL);
  179. }
  180. // 开始扫描心率带
  181. - (void)sportWearScanStartWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
  182. NSLog(@"sportWearScanStartWithError");
  183. [bleManager StartScanDevice];
  184. }
  185. // 停止扫描心率带
  186. - (void)sportWearScanStopWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
  187. NSLog(@"sportWearScanStopWithError");
  188. [bleManager stopScan];
  189. }
  190. // 获取心率带扫描结果
  191. - (nullable NSArray<FLTSportWear *> *)getSportWearScanResultWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
  192. NSMutableArray *resultArr = [[NSMutableArray alloc]initWithCapacity:ListPeripheral.count];
  193. for(int i =0;i<ListPeripheral.count;i++){
  194. HeartBLEDevice *tempDev = ListPeripheral[i];
  195. FLTSportWear *bandWear = [FLTSportWear new];
  196. bandWear.name = tempDev.DeviceName;
  197. bandWear.address = tempDev.UUIDStr;
  198. bandWear.rssi = [[NSNumber alloc]initWithInt:[tempDev.RSSI intValue]];
  199. [resultArr addObject:bandWear];
  200. }
  201. NSArray *resultFLT = [resultArr mutableCopy];
  202. return resultFLT;
  203. }
  204. // 连接心率带
  205. - (void)sportWearConnectWear:(nonnull FLTSportWear *)wear completion:(nonnull void (^)(FlutterError * _Nullable))completion {
  206. NSLog(@"sportWearConnectWear");
  207. for(int i =0;i<ListPeripheral.count;i++){
  208. HeartBLEDevice *tempDev = ListPeripheral[i];
  209. if([tempDev.UUIDStr isEqual:wear.address]){
  210. NSLog(@"尝试连接%@",BleDevice.UUIDStr);
  211. [tempDev connect];
  212. break;
  213. }
  214. }
  215. // 填充回调
  216. completion(NULL);
  217. }
  218. // 断开心率带
  219. - (void)sportWearDisconnectWear:(nonnull FLTSportWear *)wear completion:(nonnull void (^)(FlutterError * _Nullable))completion {
  220. NSLog(@"sportWearDisconnectWear");
  221. for(int i =0;i<ListPeripheral.count;i++){
  222. HeartBLEDevice *tempDev = ListPeripheral[i];
  223. NSLog(@"%@ - %@",tempDev.UUIDStr,BleDevice.UUIDStr);
  224. if([tempDev.UUIDStr isEqual:wear.address]){
  225. NSLog(@"尝试断开%@",BleDevice.UUIDStr);
  226. [tempDev disconncet];
  227. BleDevice = tempDev;
  228. }
  229. }
  230. // 填充回调
  231. completion(NULL);
  232. }
  233. // 获取已连接心率带信息
  234. - (nullable NSArray<FLTSportWear *> *)getSportWearConnectedWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
  235. NSArray *bandArr;
  236. if(BleDevice){
  237. FLTSportWear *bandWear = [FLTSportWear new];
  238. bandWear.name = BleDevice.DeviceName;
  239. bandWear.address = BleDevice.UUIDStr;
  240. bandWear.rssi = [[NSNumber alloc]initWithInt:[BleDevice.RSSI intValue]];
  241. bandArr = [[NSArray alloc] initWithObjects:bandWear, nil];
  242. }else{
  243. bandArr = [[NSArray alloc] init];
  244. }
  245. return bandArr;
  246. }
  247. // 获取心率
  248. - (nullable NSArray<FLTHeartRateMeasurement *> *)getSportWearHeartRateMeasurementWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
  249. NSArray *hrArr = [NSArray arrayWithArray:ListFLTHr];
  250. [ListFLTHr removeAllObjects];
  251. return hrArr;
  252. }
  253. /**
  254. 屏幕相关
  255. */
  256. - (NSNumber *)getDpiOnPhone {
  257. //需要导入头文件:#import <sys/utsname.h>
  258. struct utsname systemInfo;
  259. uname(&systemInfo);
  260. NSString *platform = [NSString stringWithCString: systemInfo.machine encoding:NSASCIIStringEncoding];
  261. // iPhone 6 Plus
  262. if([platform isEqualToString:@"iPhone7,1"]) return [[NSNumber alloc]initWithDouble:401];
  263. // iPhone 6
  264. if([platform isEqualToString:@"iPhone7,2"]) return [[NSNumber alloc]initWithDouble:326];
  265. // iPhone 6s
  266. if([platform isEqualToString:@"iPhone8,1"]) return [[NSNumber alloc]initWithDouble:326];
  267. // iPhone 6s Plus
  268. if([platform isEqualToString:@"iPhone8,2"]) return [[NSNumber alloc]initWithDouble:401];
  269. // iPhone SE
  270. if([platform isEqualToString:@"iPhone8,4"]) return [[NSNumber alloc]initWithDouble:401];
  271. // iPhone 7
  272. if([platform isEqualToString:@"iPhone9,1"]) return [[NSNumber alloc]initWithDouble:326];
  273. // iPhone 7 Plus
  274. if([platform isEqualToString:@"iPhone9,2"]) return [[NSNumber alloc]initWithDouble:401];
  275. // iPhone 8
  276. if([platform isEqualToString:@"iPhone10,1"])return [[NSNumber alloc]initWithDouble:326];
  277. // iPhone 8
  278. if([platform isEqualToString:@"iPhone10,4"])return [[NSNumber alloc]initWithDouble:326];
  279. // iPhone 8 Plus
  280. if([platform isEqualToString:@"iPhone10,2"])return [[NSNumber alloc]initWithDouble:401];
  281. // iPhone 8 Plus
  282. if([platform isEqualToString:@"iPhone10,5"])return [[NSNumber alloc]initWithDouble:401];
  283. // iPhone X
  284. if([platform isEqualToString:@"iPhone10,3"])return [[NSNumber alloc]initWithDouble:458];
  285. // iPhone X
  286. if([platform isEqualToString:@"iPhone10,6"])return [[NSNumber alloc]initWithDouble:458];
  287. // iPhone XS
  288. if([platform isEqualToString:@"iPhone11,2"])return [[NSNumber alloc]initWithDouble:458];
  289. // iPhone XS Max
  290. if([platform isEqualToString:@"iPhone11,4"])return [[NSNumber alloc]initWithDouble:458];
  291. // iPhone XS Max
  292. if([platform isEqualToString:@"iPhone11,6"])return [[NSNumber alloc]initWithDouble:458];
  293. // iPhone XR
  294. if([platform isEqualToString:@"iPhone11,8"])return [[NSNumber alloc]initWithDouble:326];
  295. // iPhone 11
  296. if([platform isEqualToString:@"iPhone12,1"])return [[NSNumber alloc]initWithDouble:326];
  297. // iPhone 11 Pro Max
  298. if([platform isEqualToString:@"iPhone12,3"])return [[NSNumber alloc]initWithDouble:458];
  299. // iPhone 11
  300. if([platform isEqualToString:@"iPhone12,5"])return [[NSNumber alloc]initWithDouble:326];
  301. // iPhone SE 2
  302. if([platform isEqualToString:@"iPhone12,8"])return [[NSNumber alloc]initWithDouble:326];
  303. // iPhone 12 mini
  304. if([platform isEqualToString:@"iPhone13,1"])return [[NSNumber alloc]initWithDouble:476];
  305. // iPhone 12
  306. if([platform isEqualToString:@"iPhone13,2"])return [[NSNumber alloc]initWithDouble:460];
  307. // iPhone 12 Pro
  308. if([platform isEqualToString:@"iPhone13,3"])return [[NSNumber alloc]initWithDouble:460];
  309. // iPhone 12 Pro Max
  310. if([platform isEqualToString:@"iPhone13,4"])return [[NSNumber alloc]initWithDouble:458];
  311. //2021年新款iPhone 13 mini、13、13 Pro、13 Pro Max发布
  312. // iPhone 13 mini
  313. if([platform isEqualToString:@"iPhone14,4"])return [[NSNumber alloc]initWithDouble:476];
  314. // iPhone 13
  315. if([platform isEqualToString:@"iPhone14,5"])return [[NSNumber alloc]initWithDouble:460];
  316. // iPhone 13 Pro
  317. if([platform isEqualToString:@"iPhone14,2"])return [[NSNumber alloc]initWithDouble:460];
  318. // iPhone 13 Pro Max
  319. if([platform isEqualToString:@"iPhone14,3"])return [[NSNumber alloc]initWithDouble:458];
  320. //2022年新款iPhone 14、14Plus、14 Pro、14 Pro Max发布
  321. // iPhone 14
  322. if([platform isEqualToString:@"iPhone14,7"])return [[NSNumber alloc]initWithDouble:460];
  323. // iPhone 14 Plus
  324. if([platform isEqualToString:@"iPhone14,8"])return [[NSNumber alloc]initWithDouble:458];
  325. // iPhone 14 Pro
  326. if([platform isEqualToString:@"iPhone15,2"])return [[NSNumber alloc]initWithDouble:460];
  327. // iPhone 14 Pro Max
  328. if([platform isEqualToString:@"iPhone15,3"])return [[NSNumber alloc]initWithDouble:460];
  329. return [[NSNumber alloc]initWithDouble:460];
  330. }
  331. /**
  332. locationManager相关
  333. */
  334. // 当获取到用户方向时就会调用
  335. - (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
  336. {
  337. // NSLog(@"%s", __func__);
  338. /*
  339. magneticHeading 设备与磁北的相对角度
  340. trueHeading 设置与真北的相对角度, 必须和定位一起使用, iOS需要设置的位置来计算真北
  341. 真北始终指向地理北极点
  342. */
  343. // NSLog(@"%f", newHeading.magneticHeading);
  344. // 1.将获取到的角度转为弧度 = (角度 * π) / 180;
  345. CGFloat angle = newHeading.magneticHeading * M_PI / 180;
  346. [self->newOriention setZ:[[NSNumber alloc] initWithFloat:angle]];
  347. [self->channelOriention success: @[
  348. (newOriention.x ?: [NSNull null]),
  349. (newOriention.y ?: [NSNull null]),
  350. (newOriention.z ?: [NSNull null]),
  351. ]
  352. ];
  353. // NSLog(@"locationManager %f - newHeading.magneticHeading %f",angle,newHeading.magneticHeading);
  354. // 2.旋转图片
  355. /*
  356. 顺时针 正
  357. 逆时针 负数
  358. */
  359. // self.compasspointer.transform = CGAffineTransformIdentity;
  360. // self.compasspointer.transform = CGAffineTransformMakeRotation(-angle);
  361. }
  362. -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
  363. // CLAuthorizationStatus
  364. /*
  365. 用户从未选择过权限
  366. kCLAuthorizationStatusNotDetermined
  367. 无法使用定位服务,该状态用户无法改变
  368. kCLAuthorizationStatusRestricted
  369. 用户拒绝该应用使用定位服务,或是定位服务总开关处于关闭状态
  370. kCLAuthorizationStatusDenied
  371. 已经授权(废弃)
  372. kCLAuthorizationStatusAuthorized
  373. 用户允许该程序无论何时都可以使用地理信息
  374. kCLAuthorizationStatusAuthorizedAlways
  375. 用户同意程序在可见时使用地理位置
  376. kCLAuthorizationStatusAuthorizedWhenInUse*/
  377. // 允许授权
  378. if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse) {
  379. NSLog(@"授权成功");
  380. [locationManager startUpdatingLocation];
  381. } else if(status == kCLAuthorizationStatusNotDetermined) { // 用户从未选择过权限
  382. NSLog(@"等待用户授权");
  383. }
  384. else{
  385. NSLog(@"授权失败");
  386. }
  387. }
  388. /**
  389. * 获取到位置信息之后就会去调用(如果不做控制会频繁调用,浪费电量)
  390. *
  391. * @param manager 调用者
  392. * @param locations 获取到的地理位置信息
  393. */
  394. - ( void ) locationManager: ( CLLocationManager * ) manager didUpdateToLocation: ( CLLocation * ) newLocation fromLocation: ( CLLocation * ) oldLocation
  395. {
  396. //打印经纬度
  397. // NSLog(@"latitude:%f - longitude:%f - altitude:%f",newLocation.coordinate.latitude,newLocation.coordinate.longitude, newLocation.altitude);
  398. [fltPosition setAltitude:[[NSNumber alloc] initWithFloat:newLocation.altitude]];
  399. [fltPosition setLatitude:[[NSNumber alloc] initWithFloat:newLocation.coordinate.latitude]];
  400. [fltPosition setLongitude:[[NSNumber alloc] initWithFloat:newLocation.coordinate.longitude]];
  401. //发送数据 @[ result ?: [NSNull null] ]
  402. [channelLocation success:@[
  403. (fltPosition.latitude ?: [NSNull null]),
  404. (fltPosition.longitude ?: [NSNull null]),
  405. (fltPosition.altitude ?: [NSNull null]),
  406. (fltPosition.bearing ?: [NSNull null]),
  407. (fltPosition.accuracy ?: [NSNull null]),
  408. (fltPosition.speed ?: [NSNull null]),
  409. ]];
  410. }
  411. /**
  412. CoreBluetooth协议
  413. */
  414. - (void)centralManagerDidUpdateState:(CBCentralManager *)central {
  415. NSString *message = nil;
  416. switch (central.state) {
  417. case 1:
  418. message = @"该设备不支持蓝牙功能,请检查系统设置";
  419. break;
  420. case 2:
  421. message = @"该设备蓝牙未授权,请检查系统设置";
  422. break;
  423. case 3:
  424. message = @"该设备蓝牙未授权,请检查系统设置";
  425. break;
  426. case 4:
  427. isBLOpen = false;
  428. message = @"该设备尚未打开蓝牙,请在设置中打开";
  429. break;
  430. case 5:
  431. isBLOpen = true;
  432. message = @"蓝牙已经成功开启,请稍后再试";
  433. break;
  434. default:
  435. break;
  436. }
  437. if(message!=nil&&message.length!=0) {
  438. NSLog(@"message == %@",message);
  439. }
  440. }
  441. /**
  442. 心率SDK相关 PROTOCAL
  443. */
  444. // 心率带是否连接
  445. - (void)isConnected:(BOOL)isConnected withDevice:(nonnull HeartBLEDevice *)device {
  446. // NSLog(@"isConnected%@ ",device.DeviceName);
  447. // 给连接成功的心率带设置代理
  448. [device setDelegate:self];
  449. // 赋值BLEDevice引用
  450. BleDevice = device;
  451. }
  452. // 断开心率带
  453. - (void)disconnected:(nonnull HeartBLEDevice *)device {
  454. // NSLog(@"disconnected");
  455. BleDevice = NULL;
  456. }
  457. // 设备扫描回调
  458. - (void)onDeviceFound:(nonnull NSArray *)deviceArray {
  459. // NSLog(@"onDeviceFound:%lu",(unsigned long)deviceArray.count);
  460. ListPeripheral = [NSArray arrayWithArray:deviceArray];
  461. for(int i =0;i<ListPeripheral.count;i++){
  462. HeartBLEDevice *tempDev = ListPeripheral[i];
  463. // NSLog(@"onDeviceFound%@ - %@",tempDev.UUIDStr,tempDev.DeviceName);
  464. }
  465. }
  466. // HeartStr:实时心率值 RRIs:对应的RRI值,Array存储的NSNumber类型
  467. - (void)SDKFitHeartParamter:(NSString *)HeartStr RRIs:(NSArray *)RRIs {
  468. // HeartStr = [NSString stringWithFormat:@"%d", (arc4random() % 80) + 85];//开启随机心率
  469. UInt64 recordTime = [[NSDate date] timeIntervalSince1970]*1000;
  470. // NSLog(@"时间戳:%llu",recordTime);
  471. // NSLog(@"心率值:%@",HeartStr);
  472. FLTHeartRateMeasurement *realHr = [[FLTHeartRateMeasurement alloc]init];
  473. realHr.timestampMill = [[NSNumber alloc]initWithLong:recordTime];
  474. realHr.heartRate = [[NSNumber alloc]initWithInt:[HeartStr intValue]];
  475. realHr.rrIntervals = RRIs;
  476. realHr.deviceMac = BleDevice.UUIDStr;
  477. // NSLog(@"心率池数据容量:%lu",ListFLTHr.count);
  478. // 缓存达一定数量后清空心率池
  479. if(ListFLTHr.count > 10){
  480. [ListFLTHr removeAllObjects];
  481. }
  482. [ListFLTHr addObject:realHr];
  483. }
  484. //设备电量回调
  485. - (void)SDKDianciStr:(NSString *_Nullable)DianStr {
  486. // NSLog(@"SDKDianciStr:%@",[[NSString alloc] initWithFormat:@"%@已连接 电量 %@%%", BleDevice.DeviceName,DianStr]);
  487. BleDevice.PowerLevel = DianStr;
  488. }
  489. @end