博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS后台运行延长时间
阅读量:4288 次
发布时间:2019-05-27

本文共 6294 字,大约阅读时间需要 20 分钟。

后台长时间运行除了官方的音乐,下载,定位,可以通过推送。

//============================

- (void)applicationDidEnterBackground:(UIApplication *)application {

    
    UIApplication* app = [UIApplication sharedApplication];
    __block
    UIBackgroundTaskIdentifier bgTask;
    bgTask= [app beginBackgroundTaskWithExpirationHandler:^{
        
        dispatch_async(dispatch_get_main_queue(),^{
            if(bgTask != UIBackgroundTaskInvalid){
                
                bgTask = UIBackgroundTaskInvalid;
                
            }
            
        });
        
    }];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
        
        dispatch_async(dispatch_get_main_queue(),
                       ^{
                           
                           if(bgTask != UIBackgroundTaskInvalid){
                               bgTask= UIBackgroundTaskInvalid;
                           }
                           
                       });
        
    });
}

以上的方法似乎只有连接电脑测试时,能运行10分钟以上,如果不连接电脑在手机上运行则只能运行三分钟;

//=====================

下面是用定位的方法,把用时定位(需要设置info.plist),持续定位(需要设置info.plist),后台定位(需要设置self.locationManager.allowsBackgroundLocationUpdates=YES,也需要

同时还需要打开后台定位模式 -->点击项目-->Capabilitys-->Background Modes-->勾选Location update

)

程序进入后台有5秒中的缓冲时间来做一些事情,比如申请执行后台任务;

@interface AppDelegate () <LoginDelegate,CLLocationManagerDelegate>

@property(nonatomic,assign)UIBackgroundTaskIdentifier bgTask;//用于申请后台时间

@end

@implementation AppDelegate

//后台时间设置

-(void)backGroundTime{

    UIApplication *appl=[UIApplication sharedApplication];

    self.bgTask = [appl beginBackgroundTaskWithExpirationHandler:^{//注册一个后台任务,如果超过10分钟,就会执行这个block中的方法,而且这个block中必须要加上endBackgroundTask:方法,否则会crash;

        只要调用了beginBackgroundTaskWithExpirationHandler:方法,就必须在handler里相应地调用endBackgroundTask:方法。

//        //后执行这里,应该进行一些清理工作,如断开和服务器的连接等

        [appl endBackgroundTask:self.bgTask];

        self.bgTask =UIBackgroundTaskInvalid;

     

    }];

    

}

//10分钟没到又打开app,结束后台任务

-(void)endBackGroundTask{

    // 如果没到10分钟又打开了app,结束后台任务

    if (self.bgTask!=UIBackgroundTaskInvalid) {

        [[UIApplication sharedApplication]endBackgroundTask:self.bgTask];

        self.bgTask =UIBackgroundTaskInvalid;

    }

}

//定时器到一定时间,关闭之前后台任务,开启新的后台任务

-(void)counst{

    if (self.count %160 == 0) {

        NSLog(@"结束之前的任务,又开启一个新任务");

        [selfbackGroundTime];//又一次执行后台任务

   }

    NSLog(@"后台定时器-%tu--",self.count++);

}

//程序进入后台

- (void)applicationDidEnterBackground:(UIApplication *)application {

    [selfbackGroundTime];

    _time=[NSTimerscheduledTimerWithTimeInterval:1target:self

selector:@selector(counst)userInfo:nilrepeats:YES];

    [[NSRunLoopcurrentRunLoop]addTimer:_timeforMode:NSRunLoopCommonModes];

    

}

//程序将要进入前台

- (void)applicationWillEnterForeground:(UIApplication *)application {

    发送开启socket重连的通知

    [[NSNotificationCenterdefaultCenter]postNotificationName:@"initSocket"

object:nil];

    [selfendBackGroundTask];//结束后台任务

}

//程序变的活跃

- (void)applicationDidBecomeActive:(UIApplication *)application {

    [_timeinvalidate];//停止定时器

}

//应用程序将要变成不活跃状态

- (void)applicationWillResignActive:(UIApplication *)application {

    NSLog(@"程序将要变的不活跃");

}

//程序进入后台

- (void)applicationDidEnterBackground:(UIApplication *)application {

    [selfbackGroundTime];//开启后台任务

    

//==============================

    NSLog(@"程序进入后台");

}

//程序将要进入前台

- (void)applicationWillEnterForeground:(UIApplication *)application {

    发送开启socket重连的通知

    [[NSNotificationCenterdefaultCenter]postNotificationName:@"initSocket"object:nil];

  [selfendBackGroundTask];//结束后台任务

    

 //程序进入前台,角标清零

[UIApplicationsharedApplication].applicationIconBadgeNumber=0;

    NSLog(@"程序将要进入前台");

}

//程序变的活跃

- (void)applicationDidBecomeActive:(UIApplication *)application {

    NSLog(@"程序变的活跃");

}

//程序将要终止

- (void)applicationWillTerminate:(UIApplication *)application {

    

//    [self gotoLogin];//程序将要终止的时候调用登录按钮,这时候长时间锁屏后再打开程序会自动登录。

    NSLog(@"程序将要终止");

}

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{

    

    returnUIInterfaceOrientationMaskAll;

    

}

//==============使用后台定位保持后台在线

//定位城市

-(void)locationCity{

    if(![CLLocationManagerlocationServicesEnabled] || ([CLLocationManagerauthorizationStatus] ==kCLAuthorizationStatusDenied))//判断定位服务是否打开

    {

        UIAlertController *alertController=[UIAlertControlleralertControllerWithTitle:@""message:@"请打开定位服务"preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction *sure=[UIAlertActionactionWithTitle:@"确定"style:UIAlertActionStyleCancelhandler:^(UIAlertAction *_Nonnull action) {

            

        }];

        [alertController addAction:sure];

        [[UIApplicationsharedApplication].keyWindow.rootViewControllerpresentViewController:alertControlleranimated:YEScompletion:nil];

        return;

    }

    //1. 创建一个CLLocationManager对象

    self.locationManager = [CLLocationManagernew];

    

    //2. 请求授权 --> iOS8以后需要授权并配置plist键值

    if ([UIDevicecurrentDevice].systemVersion.floatValue >=8.0) {

    if ([self.locationManagerrespondsToSelector:@selector(requestWhenInUseAuthorization)]) {

        [self.locationManagerrequestWhenInUseAuthorization];

        NSLog(@"使用时定位");

    }

 }

    

//    //ios8持续定位

//        if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {

//    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){

//        [self.locationManager requestAlwaysAuthorization];

//        NSLog(@"持续定位");

//        }

//  }

    self.locationManager.pausesLocationUpdatesAutomatically=NO;//不自动停止定位

    //iOS9后台定位

    if ([UIDevicecurrentDevice].systemVersion.floatValue >=9.0) {

        //allowsBackgroundLocationUpdates :允许后台位置更新

        self.locationManager.allowsBackgroundLocationUpdates = YES;

        NSLog(@"后台定位");

    }

    //3. 设置代理-->来获取用户定位的数据

    self.locationManager.delegate = self;

    

    self.locationManager.distanceFilter = kCLDistanceFilterNone;//距离选择器,设置任何情况下都定位

    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;//预期精度kCLLocationAccuracyBest//kCLLocationAccuracyKilometer

    //4. 开始定位

    [self.locationManagerstartUpdatingLocation];

    NSLog(@"开始定位");

}

//定位的代理方法-

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations

{

    //locations : 包含了经纬度,速度等信息

    NSLog(@"locations: %@", locations);

    // CLLocation: 位置对象

    CLLocation *location = locations.lastObject;

    NSLog(@"location: %@", location);

    

    /反地理编码

    [selfgeocodeWithLocation:location];

}

//反地理编码

-(void)geocodeWithLocation:(CLLocation *)location{

    //1. 创建Geocoder对象

    CLGeocoder *geocoder = [CLGeocodernew];

    //2.2 调用反地理编码方法

    [geocoder reverseGeocodeLocation:locationcompletionHandler:^(NSArray<CLPlacemark *> *_Nullable placemarks,NSError *_Nullable error) {

        

        //3.1 防错处理

        if (placemarks.count ==0 || error) {

            return;

        }

        

        //3.2 解析数据反地理编码,只会对应一个唯一的地址,所以不需要for循环

        CLPlacemark *placemark = placemarks.lastObject;

        

        //locality: 城市

        if (placemark.locality) {

            NSLog(@"---city----%@", placemark.locality);

            self.cityName=placemark.locality;

        } else {

            //administrativeArea:行政区域

            

            self.cityName=placemark.administrativeArea;

            

        }

    }];

}

转载地址:http://ewmgi.baihongyu.com/

你可能感兴趣的文章
Java笔试题及答案
查看>>
这是一个挺有意思的Java讨论话题
查看>>
没错!java中private字段也是可以访问D!
查看>>
安卓:文本框TextView/EditText的开源库清单
查看>>
Android中Xposed框架篇---利用Xposed框架实现拦截系统方法
查看>>
腾讯老司机的RecyclerView局部刷新爬坑之路
查看>>
JavaScript null 和 undefined
查看>>
JavaScript 里的splice()与slice()
查看>>
Javascript替代eval方法
查看>>
Android开发UI布局必备基础知识
查看>>
程序员面试以及工作中真实问题汇编!
查看>>
浅谈java中的数学运算
查看>>
用大白话聊聊JavaSE
查看>>
Android 手把手带你玩转自定义相机
查看>>
仿墨迹天气的折线图控件,效果杠杠滴
查看>>
移动端防止被抓包
查看>>
Android异步批量压缩图片
查看>>
仿主流APP功能实现
查看>>
Java读取文件夹大小的6种方法及代码
查看>>
Java多线程中的10个面试要点
查看>>