我开发了一个应用程序,它能够在应用程序处于后台和前台时更新服务器上的位置。我使用了 Timer,它以 1 分钟的时间间隔连续更新位置,因为如果间隔超过 1 分钟,则会iOS
在后台暂停应用程序。
问题在于 iOS 9,当应用程序在后台时,有时它会停止位置更新,并在一段时间后再次启动。
这些是我从设备日志中找到的崩溃日志。
Exception Type: 00000020
Exception Codes: 0x000000008badf00d
Exception Note: SIMULATED (this is NOT a crash)
Highlighted by Thread: 2
Application Specific Information:
<BKNewProcess: 0x15646220; com.com.com; pid: 1168; hostpid: -1> has active assertions beyond permitted time:
{(
<BKProcessAssertion: 0x15537b80> id: 1168-1B744B09-0EB7-4B01-A6FE-F167669E4439 name: Called by UIKit, from <redacted> process: <BKNewProcess: 0x15646220; com.com.com; pid: 1168; hostpid: -1> permittedBackgroundDuration: 180.000000 reason: finishTask owner pid:1168 preventSuspend preventIdleSleep preventSuspendOnSleep ,
<BKProcessAssertion: 0x15643480> id: 1168-59515322-D982-46F8-94A5-0DD259406664 name: Called by UIKit, from <redacted> process: <BKNewProcess: 0x15646220; com.com.com; pid: 1168; hostpid: -1> permittedBackgroundDuration: 180.000000 reason: finishTask owner pid:1168 preventSuspend preventIdleSleep preventSuspendOnSleep
)}
Elapsed total CPU time (seconds): 6.880 (user 6.880, system 0.000), 9% CPU
Elapsed application CPU time (seconds): 0.081, 0% CPU
注意:在 iOS 7 和 iOS 8 中一切正常。
我已经尝试了 stackoverflow 上可用的几个解决方案,但我无法找出可以解决问题的确切解决方案。
我还发现,如果我不锁定设备,则位置更新和 Web 服务调用工作正常,但如果设备被锁定,它会停止更新位置并调用 Web 服务。
任何帮助将不胜感激。
先感谢您。
更新
AppDelegate.h
@property (nonatomic, retain) CLLocation *currentLocation;
@property (nonatomic, strong) NSTimer* locationUpdateTimer;
-(void)updateUsersLocation;
-(void)distroyTimer;
AppDelegate.m
-(void)callLocationManager
{
@autoreleasepool
{
UIAlertView * alert;
//We have to make sure that the Background App Refresh is enable for the Location updates to work in the background.
if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusDenied)
{
alert = [[UIAlertView alloc]initWithTitle:ALERTTITLE
message:@"The app doesn't work without the Background App Refresh enabled. To turn it on, go to Settings > General > Background App Refresh"
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil, nil];
[alert show];
return;
}
else if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusRestricted)
{
alert = [[UIAlertView alloc]initWithTitle:ALERTTITLE
message:@"The functions of this app are limited because the Background App Refresh is disable."
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil, nil];
[alert show];
return;
}
else if(![CLLocationManager locationServicesEnabled])
{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@""
message:@"Please enable GPS service for HiHo Mobile From settings"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
return;
}
else
{
if (!self.locationManager)
{
self.locationManager = [[CLLocationManager alloc] init];
}
self.locationManager.delegate = self;
// self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = 10.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;
}
if([self.locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)])
{
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}
[self.locationManager stopMonitoringSignificantLocationChanges];
[self.locationManager startUpdatingLocation];
if ([USERDEFAULTS boolForKey:@"someFlag"]==YES)
{
[self distroyTimer];
self.locationUpdateTimer =
[NSTimer scheduledTimerWithTimeInterval:180
target:self
selector:@selector(updateUsersLocation)
userInfo:nil
repeats:YES];
[[NSRunLoop mainRunLoop]addTimer:self.locationUpdateTimer forMode:NSRunLoopCommonModes];
}
else
{
[self.locationManager stopUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
}
}
}
}
-(void)distroyTimer
{
if ([self.locationUpdateTimer isValid])
{
[self.locationUpdateTimer invalidate];
self.locationUpdateTimer = nil;
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(@"latitude: %f, longitude: %f",newLocation.coordinate.latitude, newLocation.coordinate.longitude);
self.currentLocation = newLocation;
}
// 编写代码以更新服务器上的位置
-(void)updateUsersLocation
{
// Your code goes here.
}
注意:位置服务的持续更新将极大地消耗您的 iOS 设备的电池。因此,一旦您没有使用更新的位置,您就可以使用significant locations
.