设备重启后 iBeacon 监控/测距

Posted

技术标签:

【中文标题】设备重启后 iBeacon 监控/测距【英文标题】:iBeacon monitoring/ranging after device restarts 【发布时间】:2015-01-19 15:45:44 【问题描述】:

我使用 IBeacon 构建了一个简单的 ios 应用程序,当应用程序处于前台或后台时,它可以正常工作,但重启手机后,我的应用程序停止获取 CoreLocation 委托回调。这是我的 AppDelegate.m 代码。

#import "AppDelegate.h"
#import <CoreLocation/CoreLocation.h>
#import "ViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

   if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) 
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound
                                                                                                              categories:nil]];
    


    if(launchOptions != nil)
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"alerta"
                                                        message:[launchOptions[UIApplicationLaunchOptionsLocalNotificationKey] description]
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
    


    NSUUID *beaconUUID = [[NSUUID alloc] initWithUUIDString:@"B39ED98FF-2900-441A-802F-9C398FC199D2"];
    NSString *regionIdentifier = @"iBeacons region 1";
    CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID: beaconUUID identifier: regionIdentifier ];
    beaconRegion.notifyEntryStateOnDisplay = YES;
    self.locationManager = [[CLLocationManager alloc]init];



    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
        [self.locationManager requestAlwaysAuthorization];
    

    self.locationManager.delegate = self;
    //self.locationManager.pausesLocationUpdatesAutomatically = NO;

    [self.locationManager startMonitoringForRegion:beaconRegion];
    [self.locationManager startRangingBeaconsInRegion:beaconRegion];
    [self.locationManager startUpdatingLocation];


    return YES;


-(void)sendLocalNotificationWithMessage:(NSString*)message 
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody = message;
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];



- (void) locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region

    ViewController *viewController = (ViewController*) self.window.rootViewController;
    viewController.beacons = beacons;
    [viewController.tableView reloadData];

    NSString *message = @"";

    if(beacons.count > 0)
        CLBeacon *nearestBeacon = beacons.firstObject;
        if(nearestBeacon.proximity == self.lastProximity || nearestBeacon.proximity == CLProximityUnknown)
            return;
        
        self.lastProximity = nearestBeacon.proximity;

        switch (nearestBeacon.proximity) 
            case CLProximityFar:
                message = @"CLProximityFar";
                break;
            case CLProximityNear:
                message= @"CLProximityNear";
                break;
            case CLProximityImmediate:
                message= @"CLProximityImmediate";
                break;
            case CLProximityUnknown:
                return;
      

    else 
        message = @"No BEACONS";
    

    NSLog(@"%@", message);
    [self sendLocalNotificationWithMessage:message];



- (void) locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
    [manager startRangingBeaconsInRegion:(CLBeaconRegion*) region];
    [self.locationManager startUpdatingLocation];

    NSLog(@"INSIDE REGION");
    [self sendLocalNotificationWithMessage:@"INSIDE REGION"];


- (void) locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
    [manager stopRangingBeaconsInRegion:(CLBeaconRegion*) region];
   [self.locationManager stopUpdatingLocation];

    NSLog(@"OUTSIDE REGION");
    [self sendLocalNotificationWithMessage:@"OUTSIDE REGION"];


- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region

    if (state == CLRegionStateInside) 


        //Start Ranging
        [manager startRangingBeaconsInRegion:(CLBeaconRegion*) region];
        [self.locationManager startUpdatingLocation];

        NSLog(@"INSIDE REGION");
        [self sendLocalNotificationWithMessage:@"INSIDE REGION"];
    

    else

        //Stop Ranging
        [manager stopRangingBeaconsInRegion:(CLBeaconRegion*) region];
        [self.locationManager stopUpdatingLocation];

        NSLog(@"OUTSIDE REGION");
        [self sendLocalNotificationWithMessage:@"OUTSIDE REGION"];
    




-(void)application:(UIApplication *)application didReceiveLocalNotification:(NSDictionary *)userInfo 

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"ALERT"
                                                    message:@"didReceiveLocalNotification"
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];




- (void)applicationWillResignActive:(UIApplication *)application 
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.


- (void)applicationDidEnterBackground:(UIApplication *)application 
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.


- (void)applicationWillEnterForeground:(UIApplication *)application 
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.


- (void)applicationDidBecomeActive:(UIApplication *)application 
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.


- (void)applicationWillTerminate:(UIApplication *)application 
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.


@end

我找不到问题所在,我需要你的帮助!

【问题讨论】:

【参考方案1】:

代码看起来没问题。测试时,我建议您执行以下操作:

    启动您的应用 打开您的信标 验证您是否收到了 didEnterRegion 回调。 关闭您的信标 验证您是否收到了 didExitRegion 回调。 重启手机 至少等待 2 分钟(CoreLocation 在重新启动后完全启动需要一点时间。) 打开您的信标 等待几分钟,看看是否收到 didEnterRegion 回调。

【讨论】:

谢谢,但我仍然有同样的问题,应用程序正常工作,直到我重新启动设备。我在 iPad 4 上进行测试。 您可以尝试的另一件事:在第 9 步之后,启动一个现成的信标扫描仪,例如 Locate。 itunes.apple.com/us/app/locate-beacon/id738709014?mt=8 在单独的应用程序中执行前台信标扫描将强制硬件寻找信标,并可能触发您的应用程序的检测。如果这解决了问题,则表明您的设备存在问题,在重新启动后它没有像应有的那样自动寻找信标。有些人报告说这在 iPhone 5 上最多需要 1 小时,但我没有听说它从未检测到。 问题仍然存在,Locate Beacon 应用程序会查找信标并检测到其中一些,但我的应用程序没有重新启动服务。 这不是预期的行为。抱歉,我无法解释您所看到的。我很想知道您是否可以在其他 iOS 设备上重现。 我在 iphone 5 上试用过,该应用程序运行正常。我不知道这是一般错误还是这个错误只发生在我的 ipad 4 上。

以上是关于设备重启后 iBeacon 监控/测距的主要内容,如果未能解决你的问题,请参考以下文章

手机重启后 iBeacon 监控/测距

在蓝牙重置之前,蓝牙设备在测距和监控 iBeacons 后无法连接

在对iBeacons进行测距和监控之后,蓝牙设备无法连接,直到重置蓝牙

iOS 在后台监控/测距信标会消耗大量电池

iBeacon 监控无法正常工作

Estimote iBeacons 监控无法在 iOS 9.0.2 上运行