我正在使用CLLocationManager的“startMonitoringSignificantLocationChanges”方法。此方法在后台状态和活动状态下运行良好,但在应用程序终止时则无法运行。上述方法的文档说:
“如果您启动此服务并且您的应用程序随后终止,则系统会在新事件到来时自动将应用程序重新启动到后台。”
但我无法在我的代码中实现它。我在Stack Overflow中经历了很多QnA,并且尝试了一些解决方案,但还没有成功。 我的iOS版本是7.1。
我的代码:
ViewController.m
//Created sharedInstance of my class
+(ViewController *)sharedInstance { <br/><br/>
static ViewController *sharedViewController = nil; <br/>
@synchronized(self) { <br/>
if (sharedViewController == nil) { <br/>
sharedViewController = [[self alloc] init]; <br/>
} <br/>
} <br/>
return sharedViewController; <br/>
}
//按钮单击启动startMonitoringSignificantLocationChanges方法
- (IBAction)clickedGetCurrentLocation:(id)sender { <br/>
locationManager.delegate = self; <br/>
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self startMonitoringSignificantLocationChanges]; <br/>
}
- (void) startMonitoringSignificantLocationChanges
{ <br/>
[locationManager startMonitoringSignificantLocationChanges]; <br/>
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{ <br/>
NSLog(@"didFailWithError: %@", error); <br/>
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; <br/>
[errorAlert show];
[locationManager stopUpdatingLocation]; <br/>
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *currentLocation = locations[0];
if (currentLocation != nil) { <br/>
longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude]; <br/>
latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude]; <br/>
}
// Reverse Geocoding <br/>
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) { <br/>
if (error == nil && [placemarks count] > 0) { <br/>
placemark = [placemarks lastObject]; <br/>
addressLabel.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@",
placemark.subThoroughfare, placemark.thoroughfare,
placemark.postalCode, placemark.locality,
placemark.administrativeArea,
placemark.country]; <br/>
} else { <br/>
NSLog(@"%@", error.debugDescription); <br/>
} <br/>
} ];
UILocalNotification* localNotification = [[UILocalNotification alloc] init]; <br/>
NSString *message = [NSString stringWithFormat:@"Location Changed To (%@, %@)", [latitudeLabel text], [longitudeLabel text]]; <br/>
localNotification.alertBody = message; <br/>
localNotification.fireDate = [NSDate date]; <br/>
localNotification.alertAction = @"Location Change Detected"; <br/>
localNotification.timeZone = [NSTimeZone timeZoneWithName:@"Asia/India"]; <br/>
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self];
}
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ <br/>
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) { <br/>
[[ViewController sharedInstance] startMonitoringSignificantLocationChanges]; <br/>
} <br/>
UILocalNotification *locationNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (locationNotification) { <br/>
application.applicationIconBadgeNumber = 0; <br/>
}
return YES; <br/>
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{ <br/>
UIApplicationState state = [application applicationState]; <br/>
if (state == UIApplicationStateActive) { <br/>
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location"
message:notification.alertBody
delegate:self cancelButtonTitle:@"OK"
otherButtonTitles:nil]; <br/>
[alert show]; <br/>
}
// Set icon badge number to zero <br/><br/>
application.applicationIconBadgeNumber = 0;
}
答案 0 :(得分:0)
当IOS收到位置更新,并在终止应用后重新生成您的应用时,让它知道由于位置服务而重新生成。那么你需要在diddidFinishLaunchingWithOptions方法中重新启动后台位置服务,如下所示:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {
[[LocationController sharedInstance] startMonitoringSignificantLocationChanges];
}
return YES;
}
答案 1 :(得分:0)
根据我的经验,由于重要的位置更改,应用程序无法从终止启动,但GeoFencing可以解决问题。 如果设置用户进入/退出的围栏,您将从终止启动到响应事件〜30秒的后台时间(取决于设备类型)。