iOS的定时定位,利用了类似于歌曲后台播放时,只用你不主动切断程序,程序就会一直运行。
首先、导入AVFoundation.framework库。AVFoundation是一个可以用来使用和创建基于时间的视听媒体的框架,它提供了一个能使用基于时间的视听数据的详细级别的Objective-C接口。
//在AppDelegate中导入头文件。当进入后台后可调用。
#import <AVFoundation/AVFoundation.h> //可以就行类似于音乐播放的操作。
#import <CoreLocation/CoreLocation.h> //必须使用系统的地图定位功能
在info.plist 加入如下:
info.plist.png
//声明全局属性,方便操作。
@property (strong, nonatomic)CLLocationManager *locationManager; //
@property (assign, nonatomic)BOOL isLogation; //判断是否定位
@property (assign, nonatomic) CGFloat deviceLevel; //记录电量
@property (strong, nonatomic) NSTimer *myTimer; //定时器
利用懒加载,可防止多次的初始化
#pragma mark --------懒加载----------
- (CLLocationManager *)locationManager {
if (!_locationManager) {
_locationManager = [[CLLocationManager alloc] init];
//取得用户授权 不管应用是否在前台运行,都可以获取用户授权;
[_locationManager requestAlwaysAuthorization];
//定位服务,每隔多少米定位一次;
_locationManager.distanceFilter = 100;
//定位的精确度,越高越耗电
_locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
//指定代理
_locationManager.delegate = self;
_locationManager.pausesLocationUpdatesAutomatically = NO; //该模式是抵抗ios在后台杀死程序设置,iOS会根据当前手机使用状况会自动关闭某些应用程序的后台刷新,该语句申明不能够被暂停,但是不一定iOS系统在性能不佳的情况下强制结束应用刷新
}
return _locationManager;
}
在didFinishLaunchingWithOptions就行定位与定时器的初始化。
//确保后台运行
NSError *error1 = nil;
NSError *error2 = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error1];
[[AVAudioSession sharedInstance] setActive:YES error:&error2];
self.isLogation = [CLLocationManager locationServicesEnabled];
NSLog(@"%.2f",[self getCurrentBatteryLevel]);
//是否可定位
if (self.isLogation) {
_myTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(startLocation) userInfo:nil repeats:YES];
[self.myTimer setFireDate:[NSDate distantFuture]]; //先暂停定时器,当应用程序进入后台后再打开。这可根据需求进行修改。
}else {
NSLog(@"洗洗睡吧");
}
在程序进入后台后可进行后台定位操作applicationDidEnterBackground
//开启不停歇定位
UIApplication *app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier identifier;
identifier = [app beginBackgroundTaskWithExpirationHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
if (identifier != UIBackgroundTaskInvalid) {
identifier = UIBackgroundTaskInvalid;
}
});
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
if (identifier != UIBackgroundTaskInvalid) {
identifier = UIBackgroundTaskInvalid;
}
});
});
if (self.isLogation) {
[self.myTimer setFireDate:[NSDate distantPast]];
}else { //用过未开启定位服务;
NSLog(@"洗洗睡吧");
}
需要如下方法
#pragma mark -------定时器代理方法------
- (void)startLocation {
if ([self getCurrentBatteryLevel]>0.4f) {
//开始定位
[self.locationManager startUpdatingLocation];
}else {
[self.myTimer invalidate];
self.myTimer = nil; }
}
#pragma mark -------地图代理方法--------
//实时获取的定位信息 代理方法会被多次执行
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray*)locations {
if (locations.count) {
//获取最新位置
CLLocation *location = locations.lastObject;
NSString *str = [NSString stringWithFormat:@"%.2f:%.2f",location.coordinate.latitude,location.coordinate.longitude];
NSLog(@"%@",str);
[self.locationManager stopUpdatingLocation];
}
}
//定位失败
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
if ([error code] == kCLErrorDenied) {
NSLog(@"定位被拒绝");
}
if ([error code] == kCLErrorLocationUnknown) {
NSLog(@"定位失败 = %@", error);
}
}
#pragma mark -------判断电量------------
- (CGFloat)getCurrentBatteryLevel {
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
return [UIDevice currentDevice].batteryLevel;
}
网友评论