<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          聊聊 Apple 的 iBeacon 技術(shù)

          共 21561字,需瀏覽 44分鐘

           ·

          2021-09-01 03:01

          ????關(guān)注后回復 “進群” ,拉你進程序員交流群????


          轉(zhuǎn)自:掘金 阿華12年

          https://juejin.cn/post/6995857698747056142



          前言

          網(wǎng)上查資料說蘋果在13年的WWDC上發(fā)布iOS7上配備的新功能。之前,利用iBeacon設(shè)備做了下定位的算法研究,故此來總結(jié)下,也希望能和大家交流下。

          什么是iBeacon

          首先,iBeacon 的標志是下面這張圖片

          下面進入正題,iBeacon這項技術(shù)是蘋果建立在低功耗藍牙的技術(shù)上做出來的東西。具體來說是利用BLE中名為"通告幀"的廣播幀。

          通告幀是由配備BLE的設(shè)備定期發(fā)出,只要是支持BLE的終端,都可以接受到信號。通告幀的有效載荷部分,寫入了蘋果定義的數(shù)據(jù)。

          一個iBeacon基站的數(shù)據(jù)大致由四部分信息組成:

          • 1 、UUID(universally unique identifier):一個128位的唯一標識一個或多個Beacon基站為特定類型或特定的組織。
          • 2、 Major:一個16位的無符號整數(shù),可以將具有相同proximity UUID的Beacon基站組織聯(lián)系起來。(用戶可以自定義)
          • 3、 Minor:同上。
          • 4、Measured Power :是iBeacon發(fā)送模塊與接收器之間距離為1米時的信號強度(RSSI)參照值。

          通過藍牙低功耗技術(shù)(BLE)發(fā)送特定的識別信息,來確定Beacon基站和設(shè)備之間的相對距離。而這個距離并不是精密推算的,而是將其分為三級:

          • 約10厘米(immediate)
          • 1米以內(nèi)(near)
          • 1米以外(far)

          這是因為,發(fā)送和接受設(shè)備之間的距離在1米之內(nèi)時,RSSI值基本是按照理論值減少的,而在1米外,收到發(fā)射波的影響,RSSI不會明顯的隨距離增加減少,而是會上下波動。也就是說,1米外的距離無法非常精密推測,可以用far來概括。

          接下來,進入重點:

          既然,用一個iBeacon我們可以測出Beacon設(shè)備和掃描Beacon設(shè)備之間的距離(Apple的API中已給出距離值)。那么,猜想下,有三個Beacon,然后知道他們的坐標信息,那么我們拿著手機去不斷的掃描這三個Beacon的RSSI信息就可以利用定位算法來進行定位了。

          下面,上代碼

          關(guān)于開始定位的部分

          在這,我設(shè)置了三個基準點作為坐標點固定,用來探測手持設(shè)備的位置。


              UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
              [[UIApplication sharedApplication] registerUserNotificationSettings:settings];

              self.locationManager            = [[CLLocationManager alloc] init];
              self.locationManager.delegate   = self;
              
              NSArray *myBeacon = @[UUID_BEACON_O, UUID_BEACON_T, UUID_BEACON_H];
              
              for (NSString *uuid in myBeacon) {

                  NSString *identifier = @"";
                  if ([uuid isEqualToString:UUID_BEACON_O]) {
                      
                      identifier = @"左后";
                  }else if ([uuid isEqualToString:UUID_BEACON_T]) {
                  
                      identifier = @"右后";
                  }else if ([uuid isEqualToString:UUID_BEACON_H]) {
                  
                      identifier = @"左前";
                  }
                  
                  CLBeaconRegion *beacon = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:uuid]
                                                                              identifier:identifier];
                  beacon.notifyOnExit              = YES;
                  beacon.notifyOnEntry             = YES;
                  beacon.notifyEntryStateOnDisplay = YES;
                  
                  [self.locationManager startMonitoringForRegion:beacon];
                  [self.locationManager startRangingBeaconsInRegion:beacon];
              }
              
              [self.locationManager requestAlwaysAuthorization];

          關(guān)于位置的Delegate部分

          處理收到的系統(tǒng)發(fā)給的信號, 在這里主要是做了本地消息的推送。在持續(xù)探測信號強度的時候,可以按照最后的參考文章,實現(xiàn)三角定位原理,來實現(xiàn)設(shè)備的定位。

          - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {

              if ([region isKindOfClass:[CLBeaconRegion class]]) {
                  
                  UILocalNotification *notification = [[UILocalNotification alloc] init];
                  notification.alertBody = [NSString stringWithFormat:@"你已進入到 %@ 范圍內(nèi)", region.identifier];
                  notification.soundName = @"Default";
                  [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
                  
                  NSLog(@"%@", [NSString stringWithFormat:@"你已進入到 %@ 范圍內(nèi)", region.identifier]);
              }
          }

          - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {

              if ([region isKindOfClass:[CLBeaconRegion class]]) {
                  
                  UILocalNotification *notification = [[UILocalNotification alloc] init];
                  notification.alertBody = [NSString stringWithFormat:@"你已離開 %@ 的范圍", region.identifier];
                  notification.soundName = @"Default";
                  [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
                  
                  NSLog(@"%@", [NSString stringWithFormat:@"你已離開 %@ 的范圍", region.identifier]);
              }
          }

          - (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region {

                  for (CLBeacon *beacon in beacons) {
                      
              //        NSLog(@"beacon Info : rssi is %ld, major is %@, minor is %@, accuracy is %f, proximity is %ld.", beacon.rssi, beacon.major, beacon.minor, beacon.accuracy, beacon.proximity);
                      
                      if (self.beaconDataSource.count == 3) {
                          
                          if ([[beacon.proximityUUID UUIDString] isEqualToString:UUID_BEACON_O]) {
                              [self.beaconDataSource replaceObjectAtIndex:0 withObject:beacon];
                              
                              [self.wait1 addObject:beacon];      //采集數(shù)據(jù)  左后
                          }
                          if ([[beacon.proximityUUID UUIDString]isEqualToString:UUID_BEACON_T]) {
                              
                              [self.beaconDataSource replaceObjectAtIndex:1 withObject:beacon];
                              
                              [self.wait2 addObject:beacon];      //采集數(shù)據(jù)  右后
                          }
                          if ([[beacon.proximityUUID UUIDString]isEqualToString:UUID_BEACON_H]) {
                              
                              [self.beaconDataSource replaceObjectAtIndex:2 withObject:beacon];
                              
                              [self.wait3 addObject:beacon];      //采集數(shù)據(jù)  左前
                          }
                          
                          if (!self.testButton.selected) {   //測試按鈕沒有選中
                             //實時刷新位置信息
                              if (self.wait1.count == 20 && self.wait2.count == 20 && self.wait3.count == 20) {
                                  
                                  //                    NSArray *result = [DealModel dealWithBaseData:@[@[@"0", @"0"], @[@"220", @"0"], @[@"110", @"110"]] andThreeAuxData:@[self.wait1, self.wait2, self.wait3] andReal:@[self.textX.text, self.textY.text]];
                                  DataProcessing *data = [[DataProcessing alloc] init];
                                  NSArray *result2 = [data dealWithBaseData:@[@[@"0", @"0"], @[@"220", @"0"], @[@"110", @"110"]] andThreeAuxData:@[self.wait1, self.wait2, self.wait3] andReal:@[@"",@""]];
                                  
                                  self.result1.text = self.result2.text;
                                  self.result2.text = [NSString stringWithFormat:@"X : %@\nY : %@", result2[0], result2[1]];
                                  
                                  NSLog(@"%@", data);
                                  //                self.xyView.center = CGPointMake([result[0] floatValue], [result[1] floatValue]);
                                  
                                  [self.wait1 removeAllObjects];
                                  [self.wait2 removeAllObjects];
                                  [self.wait3 removeAllObjects];
                                  self.sureButton.selected = NO;
                                  self.sureButton.backgroundColor = [UIColor blackColor];
                                  
                              }
                              

                          }else {
                              //開始測試單個設(shè)備誤差
                              if (self.wait1.count == 20) {
                                  
                                  if (![self.textX.text isEqualToString:@""])
                                      [DataProcessing testErrorWithUUID:UUID_BEACON_O andRealValue:self.textX.text andTestArray:self.wait1];
                                  
                                  
                                  [self.wait1 removeAllObjects];
                                  [self.wait2 removeAllObjects];
                                  [self.wait3 removeAllObjects];
                              }else if (self.wait2.count == 20) {
                              
                                  if (![self.textX.text isEqualToString:@""])
                                      [DataProcessing testErrorWithUUID:UUID_BEACON_T andRealValue:self.textX.text andTestArray:self.wait2];

                                  [self.wait1 removeAllObjects];
                                  [self.wait2 removeAllObjects];
                                  [self.wait3 removeAllObjects];
                              }else if (self.wait3.count == 20) {
                                  
                                  if (![self.textX.text isEqualToString:@""])
                                      [DataProcessing testErrorWithUUID:UUID_BEACON_H andRealValue:self.textX.text andTestArray:self.wait3];

                                  [self.wait1 removeAllObjects];
                                  [self.wait2 removeAllObjects];
                                  [self.wait3 removeAllObjects];
                              }
                          }
                          
                          [self.localView refreshWithArray:self.beaconDataSource];
                      }else {
                          
                          if ([[beacon.proximityUUID UUIDString] isEqualToString:UUID_BEACON_O] || [[beacon.proximityUUID UUIDString]isEqualToString:UUID_BEACON_T] || [[beacon.proximityUUID UUIDString]isEqualToString:UUID_BEACON_H]) {
                              
                              [self.beaconDataSource addObject:beacon];
                          }
                      }
                  }
                  
                  [self.beaconTableView reloadData];
             
          }

          總結(jié)

          iOS設(shè)備不僅可以探測周圍iBeacon信號,也可以把自身作為一個iBeacon來向外界發(fā)送信號內(nèi)容(具體實現(xiàn)很簡單,大家自行查閱資料)。

          最后在實際的使用中,參照最后的那片文章實現(xiàn)了三角定位的算法,但是,信號的波動還是很大的,并不符合理想,就沒有在繼續(xù)研究下去。如果大家有興趣可以一起研究討論。

          參考文獻

          基于iBeacon基站的室內(nèi)定位技術(shù)研究[1]

          參考資料

          [1]

          https://github.com/wangjianhuajoysuccess/iOSCoreLib/blob/main/6%E5%9F%BA%E4%BA%8EiBeacon%E5%9F%BA%E7%AB%99%E7%9A%84%E5%AE%A4%E5%86%85%E5%AE%9A%E4%BD%8D%E6%8A%80%E6%9C%AF%E7%A0%94%E7%A9%B6.pdf

          -End-

          最近有一些小伙伴,讓我?guī)兔φ乙恍?nbsp;面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網(wǎng)盤了,歡迎下載!

          點擊??卡片,關(guān)注后回復【面試題】即可獲取

          在看點這里好文分享給更多人↓↓

          瀏覽 25
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  仓井空无码一区 | 欧美操熟女 | 色色无码 | 九九影院精品 | 极品人妻3p一人一次DVD |