// // LocationTracker.m // Location // // Created by Rick // Copyright (c) 2014 Location All rights reserved. // #import "LocationTracker.h" #define LATITUDE @"latitude" #define LONGITUDE @"longitude" #define ACCURACY @"theAccuracy" #define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) @implementation LocationTracker + (CLLocationManager *)sharedLocationManager { static CLLocationManager *_locationManager; @synchronized(self) { if (_locationManager == nil) { _locationManager = [[CLLocationManager alloc] init]; _locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; _locationManager.pausesLocationUpdatesAutomatically = NO; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) { //[_locationManager requestWhenInUseAuthorization];//?只在前台开启定位 [_locationManager requestAlwaysAuthorization];//?在后台也可定位 } // 5.iOS9新特性:将允许出现这种场景:同一app中多个location manager:一些只能在前台定位,另一些可在后台定位(并可随时禁止其后台定位)。 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) { _locationManager.allowsBackgroundLocationUpdates = YES; } } } return _locationManager; } - (id)init { if (self = [super init]) { //Get the share model and also initialize myLocationArray self.shareModel = [LocationShareModel sharedModel]; self.shareModel.myLocationArray = [NSMutableArray array]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil]; } return self; } -(void)applicationEnterBackground{ CLLocationManager *locationManager = [LocationTracker sharedLocationManager]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; locationManager.distanceFilter = kCLDistanceFilterNone;//不需要移动都可以刷新 if(IS_OS_8_OR_LATER) { [locationManager requestAlwaysAuthorization]; } [locationManager startUpdatingLocation]; //Use the BackgroundTaskManager to manage all the background Task self.shareModel.bgTask = [BackgroundTaskManager sharedBackgroundTaskManager]; [self.shareModel.bgTask beginNewBackgroundTask]; } - (void) restartLocationUpdates { //NSLog(@"restartLocationUpdates"); if (self.shareModel.timer) { [self.shareModel.timer invalidate]; self.shareModel.timer = nil; } CLLocationManager *locationManager = [LocationTracker sharedLocationManager]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; locationManager.distanceFilter = kCLDistanceFilterNone;//不需要移动都可以刷新 if(IS_OS_8_OR_LATER) { [locationManager requestAlwaysAuthorization]; } [locationManager startUpdatingLocation]; } - (void)startLocationTracking { //NSLog(@"startLocationTracking"); if ([CLLocationManager locationServicesEnabled] == NO) { //NSLog(@"locationServicesEnabled false"); [RQ_SHARE_FUNCTION showAlertWithTitle:@"启用位置服务" message:@"您必须启用位置服务(设置-隐私-定位服务-极速驾培-始终)" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"确定" otherButtonTitles:nil otherButtonStyles:nil showInWindow:NO completion:nil]; } else { CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus]; if(authorizationStatus == kCLAuthorizationStatusDenied || authorizationStatus == kCLAuthorizationStatusRestricted){ //NSLog(@"authorizationStatus failed"); } else { //NSLog(@"authorizationStatus authorized"); CLLocationManager *locationManager = [LocationTracker sharedLocationManager]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; locationManager.distanceFilter = kCLDistanceFilterNone;//不需要移动都可以刷新 if(IS_OS_8_OR_LATER) { [locationManager requestAlwaysAuthorization]; } [locationManager startUpdatingLocation]; } } } - (void)stopLocationTracking { //NSLog(@"stopLocationTracking"); if (self.shareModel.timer) { [self.shareModel.timer invalidate]; self.shareModel.timer = nil; } CLLocationManager *locationManager = [LocationTracker sharedLocationManager]; [locationManager stopUpdatingLocation]; } #pragma mark - CLLocationManagerDelegate Methods -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ //NSLog(@"locationManager didUpdateLocations"); for(int i=0;i 30.0) { continue; } //Select only valid location and also location with good accuracy if(newLocation!=nil&&theAccuracy>0 &&theAccuracy<2000 &&(!(theLocation.latitude==0.0&&theLocation.longitude==0.0))){ self.myLastLocation = theLocation; self.myLastLocationAccuracy= theAccuracy; NSMutableDictionary * dict = [[NSMutableDictionary alloc]init]; [dict setObject:[NSNumber numberWithFloat:theLocation.latitude] forKey:@"latitude"]; [dict setObject:[NSNumber numberWithFloat:theLocation.longitude] forKey:@"longitude"]; [dict setObject:[NSNumber numberWithFloat:theAccuracy] forKey:@"theAccuracy"]; //Add the vallid location with good accuracy into an array //Every 1 minute, I will select the best location based on accuracy and send to server [self.shareModel.myLocationArray addObject:dict]; } } //If the timer still valid, return it (Will not run the code below) if (self.shareModel.timer) { return; } self.shareModel.bgTask = [BackgroundTaskManager sharedBackgroundTaskManager]; [self.shareModel.bgTask beginNewBackgroundTask]; //Restart the locationMaanger after 1 minute self.shareModel.timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(restartLocationUpdates) userInfo:nil repeats:NO]; //Will only stop the locationManager after 10 seconds, so that we can get some accurate locations //The location manager will only operate for 10 seconds to save battery if (self.shareModel.delay10Seconds) { [self.shareModel.delay10Seconds invalidate]; self.shareModel.delay10Seconds = nil; } self.shareModel.delay10Seconds = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(stopLocationDelayBy10Seconds) userInfo:nil repeats:NO]; } //Stop the locationManager -(void)stopLocationDelayBy10Seconds{ CLLocationManager *locationManager = [LocationTracker sharedLocationManager]; [locationManager stopUpdatingLocation]; //NSLog(@"locationManager stop Updating after 10 seconds"); } - (void)locationManager: (CLLocationManager *)manager didFailWithError: (NSError *)error { // NSLog(@"locationManager error:%@",error); switch([error code]) { case kCLErrorNetwork: // general, network-related error { [RQ_SHARE_FUNCTION showAlertWithTitle:@"网络错误" message:@"请检查网络连接" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"确定" otherButtonTitles:nil otherButtonStyles:nil showInWindow:NO completion:nil]; } break; case kCLErrorDenied:{ [RQ_SHARE_FUNCTION showAlertWithTitle:@"启用位置服务" message:@"您必须启用位置服务(设置-隐私-定位服务-极速驾培-始终)" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"确定" otherButtonTitles:nil otherButtonStyles:nil showInWindow:NO completion:nil]; } break; default: { } break; } } //Send the location to Server - (void)updateLocationToServer { //NSLog(@"updateLocationToServer"); // Find the best location from the array based on accuracy NSMutableDictionary * myBestLocation = [[NSMutableDictionary alloc]init]; for(int i=0;i