在地理围栏中多次调用区域监控方法
Posted
技术标签:
【中文标题】在地理围栏中多次调用区域监控方法【英文标题】:Region Monitoring method getting called multiple times in Geo-Fencing 【发布时间】:2016-04-23 05:33:11 【问题描述】:我创建了多个地理围栏来监控区域进入/退出事件。
我在AppDelegate.h
文件中创建了一个位置管理器。
@interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
@property (strong, nonatomic) UIWindow *window;
@property(nonatomic,retain)CLLocationManager *locationManager;
@property(nonatomic,retain)CLLocation *currentLocation;
+(AppDelegate *)sharedDelegate;
AppDelegate.m
文件
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notification)
NSLog(@"AppDelegate didFinishLaunchingWithOptions");
application.applicationIconBadgeNumber = 0;
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:settings];
else // ios 7 or earlier
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
if (!self.locationManager)
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
//locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.distanceFilter = 2.0f;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
[self.locationManager requestAlwaysAuthorization];
if ([self.locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)])
self.locationManager.allowsBackgroundLocationUpdates = YES;
if ([self.locationManager respondsToSelector:@selector(pausesLocationUpdatesAutomatically)])
self.locationManager.pausesLocationUpdatesAutomatically= NO;
[self.locationManager stopMonitoringSignificantLocationChanges];
if ([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] != kCLAuthorizationStatusDenied)
[self.locationManager startUpdatingLocation];
// Override point for customization after application launch.
return YES;
-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
NSLog(@"Started monitoring %@ region",region.identifier);
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
NSLog(@"%@",[locations description]);
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
dispatch_async(dispatch_get_main_queue(), ^
if ([[UIApplication sharedApplication] applicationState]==UIApplicationStateBackground || [[UIApplication sharedApplication] applicationState]==UIApplicationStateInactive)
UILocalNotification *localnotification = [[UILocalNotification alloc]init];
localnotification.fireDate=[NSDate dateWithTimeIntervalSinceNow:1];
localnotification.alertBody=@"You are enter in region.";
localnotification.timeZone=[NSTimeZone defaultTimeZone];
localnotification.repeatInterval = 0;
localnotification.hasAction=YES;
[[UIApplication sharedApplication]scheduleLocalNotification:localnotification];
else
[[[UIAlertView alloc]initWithTitle:@"message" message:@"Enter into region." delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok ", nil] show];
);
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
dispatch_async(dispatch_get_main_queue(), ^
if ([[UIApplication sharedApplication] applicationState]==UIApplicationStateBackground || [[UIApplication sharedApplication] applicationState]==UIApplicationStateInactive)
UILocalNotification *localnotificationExit = [[UILocalNotification alloc]init];
localnotificationExit.fireDate=[NSDate dateWithTimeIntervalSinceNow:1];
localnotificationExit.alertBody=@"You are exit from region.";
NSLog(@"Exit from region.");
localnotificationExit.timeZone=[NSTimeZone defaultTimeZone];
localnotificationExit.repeatInterval = 0;
localnotificationExit.hasAction=YES;
[[UIApplication sharedApplication]scheduleLocalNotification:localnotificationExit];
else
[[[UIAlertView alloc]initWithTitle:@"message" message:@"Exit from region." delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok ", nil] show];
);
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
NSLog(@"didFailWithError: %@", error);
[[[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
这个东西是管理区域监控的。
现在我的视图控制器正在添加要监控的区域。
-(void)AddRegionsInGeoFence
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
//----1
CLLocationCoordinate2D centerCoordinate1 = CLLocationCoordinate2DMake(23.046518, 72.543337);
CLCircularRegion *region1 =[[CLCircularRegion alloc] initWithCenter:centerCoordinate1 radius:200 identifier:@"Location First"];
NSLog(@"%@",[region1 description]);
region1.notifyOnEntry=YES;
region1.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region1];
NSLog(@"Started Monitoring- %@", [region1 description]);
[self.mapview setShowsUserLocation:YES];
[self.mapview setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
//----2
CLLocationCoordinate2D centercoordinate2=CLLocationCoordinate2DMake(23.064381, 72.531181);
CLCircularRegion *region2=[[CLCircularRegion alloc]initWithCenter:centercoordinate2 radius:200 identifier:@"Location Second"];
NSLog(@"%@",[region2 description]);
region2.notifyOnEntry=YES;
region2.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region2];
NSLog(@"Started Monitoring- %@", [region2 description]);
//----3
CLLocationCoordinate2D centercoordinate3=CLLocationCoordinate2DMake(23.083583,72.546441);
CLCircularRegion *region3=[[CLCircularRegion alloc]initWithCenter:centercoordinate3 radius:200 identifier:@"Location Third"];
NSLog(@"%@",[region3 description]);
region3.notifyOnEntry=YES;
region3.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region3];
NSLog(@"Started Monitoring- %@", [region3 description]);
//4
CLLocationCoordinate2D centercoordinate4=CLLocationCoordinate2DMake(23.122255, 72.584499);
CLCircularRegion *region4=[[CLCircularRegion alloc]initWithCenter:centercoordinate4 radius:500 identifier:@"Location Fourth"];
NSLog(@"%@",[region4 description]);
region4.notifyOnEntry=YES;
region4.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region4];
NSLog(@"Started Monitoring- %@", [region4 description]);
[standardDefaults setBool:YES forKey:@"EnterRegion"];
[standardDefaults synchronize];
我的问题是区域监控方法被多次调用,即使我没有进入区域本身。其他一切工作正常,Accuracy buffer 在 50-80 meters
附近,这对我来说很好。
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
此外,如果我关闭 Wi-Fi,那么它会背靠背调用这些方法,说退出区域并进入区域。据我所知,GPS 精度取决于 Wi-Fi。
任何帮助将不胜感激。
【问题讨论】:
我的代码中也有同样的问题。当我还在地理围栏中时,多次调用区域监控方法。这里是my code @Merry 是的,我已经浏览了此链接,但您的问题有所不同。我的代码被多次调用,你甚至没有被调用。 是的,你说得对,我的问题标题与不调用任何委托方法有关,但现在成功调用了 Enter 和 exit 方法,但是当用户已经在区域中时它会调用多次。它多次显示**进入或退出**通知。 【参考方案1】:在修复苹果错误期间,可能的临时解决方法是限制回调的速率;因此不会作用于所有回调,而是限制回调可以被处理的速率。
在时间段到期之前发生的回调执行部分将被忽略。
以下是可以提供帮助的示例代码,未测试: 速率限制为 2 秒。
-(void)methodRateLimit
@synchronized(self)
// rate limit begin
static NSDate *lastTimeExit = nil;
if (!lastTimeExit)
lastTimeExit = [NSDate distantPast]; // way back in time
NSDate *now = [NSDate date];
if ([now timeIntervalSinceDate:lastTimeExit] > 2)
// do work here
NSLog(@"Executing");
lastTimeExit = now;
else
NSLog(@"Limiting");
【讨论】:
以上是关于在地理围栏中多次调用区域监控方法的主要内容,如果未能解决你的问题,请参考以下文章