iOS后台定时定位

作者: 山水域 | 来源:发表于2016-08-02 16:54 被阅读128次

    听说了一些比较流氓的的需求,其中就有iOS的定时定位。可以实现任意时间对用户的定位,只有用户不主动杀死该程序。利用了类似于歌曲后台播放时,只用你不主动切断程序,程序就会一直运行。

    首先、导入AVFoundation.framework库。AVFoundation是一个可以用来使用和创建基于时间的视听媒体的框架,它提供了一个能使用基于时间的视听数据的详细级别的Objective-C接口。

    
    //在AppDelegate中导入头文件。当进入后台后可调用。
    
    #import <AVFoundation/AVFoundation.h>  //可以就行类似于音乐播放的操作。
    
    #import <CoreLocation/CoreLocation.h> //必须使用系统的地图定位功能
    
    

    在info.plist 加入如下:


    1866197-7459b3f3819662f6.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;
    
    }
    
    

    demo下载https://github.com/ChineseMao/backstageLocation1.git

    点击链接,参考方法2

    点我点我点我哦.png

    扫描


    微信图片.jpg

    相关文章

      网友评论

        本文标题:iOS后台定时定位

        本文链接:https://www.haomeiwen.com/subject/bjofsttx.html