app持续定位 ios
2015-12-11 17:27:00 weixin_34032779 阅读数 27

继之前的后台播放音频,后台下载,再来一发后台持续定位的实现。流程差不多:
1.开去后台模式:

937405-f6389f976cba668e.png
后台模式勾选

2.在plist中加入NSLocationAlwaysUsageDescription这个键,对应的值为Boolean型,YES (总是使用定位)。
并在程序中加入如下代码,获取持续定位的许可。
<pre>if([_manager respondsToSelector:@selector(requestAlwaysAuthorization)])
{
[_manager requestAlwaysAuthorization];
}</pre>
其中的manager是CLLocationManager对象。

3.在applicationDidEnterBackground:方法中,加入如下代码:
<pre>- (void)applicationDidEnterBackground:(UIApplication )application {
if([CLLocationManager significantLocationChangeMonitoringAvailable])
{
ViewController
vc=(ViewController *)self.window.rootViewController;
[vc.manager stopUpdatingLocation];
[vc.manager startMonitoringSignificantLocationChanges];
}
else
{
NSLog(@"significant Location Change not Available");
}
}</pre>
4.在applicationDidBecomeActive:方法中,加入如下代码:
<pre>

  • (void)applicationDidBecomeActive:(UIApplication )application {
    if([CLLocationManager significantLocationChangeMonitoringAvailable])
    {
    ViewController
    vc=(ViewController *)self.window.rootViewController;

      [vc.manager stopMonitoringSignificantLocationChanges];
      [vc.manager startUpdatingLocation];
    

    }
    else
    {
    NSLog(@"significant Location Change not Available");
    }
    }</pre>

5.至此,后台持续定位功能成功实现。最后附上部分代码,供参考:
AppDelegate.m
<pre>

import "AppDelegate.h"

import <CoreLocation/CoreLocation.h>

import "ViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window.rootViewController=[ViewController new];
    return YES;
    }

  • (void)applicationDidEnterBackground:(UIApplication )application {
    if([CLLocationManager significantLocationChangeMonitoringAvailable])
    {
    ViewController
    vc=(ViewController *)self.window.rootViewController;
    [vc.manager stopUpdatingLocation];
    [vc.manager startMonitoringSignificantLocationChanges];
    }
    else
    {
    NSLog(@"significant Location Change not Available");
    }
    }

  • (void)applicationDidBecomeActive:(UIApplication )application {
    if([CLLocationManager significantLocationChangeMonitoringAvailable])
    {
    ViewController
    vc=(ViewController *)self.window.rootViewController;

      [vc.manager stopMonitoringSignificantLocationChanges];
      [vc.manager startUpdatingLocation];
    

    }
    else
    {
    NSLog(@"significant Location Change not Available");
    }
    }

@end
</pre>
ViewController.h
<pre>

import <UIKit/UIKit.h>

import <CoreLocation/CoreLocation.h>

@interface ViewController : UIViewController<CLLocationManagerDelegate>

//定位管理对象
@property(nonatomic,strong)CLLocationManager *manager;

@end
</pre>
ViewController.m
<pre>

import "ViewController.h"

import <Photos/Photos.h>

import <CoreLocation/CoreLocation.h>

@interface ViewController ()<CLLocationManagerDelegate>
{
// 定位管理对象
CLLocationManager *_manager;
CLGeocoder *_coder;
// 存储上一次的位置
}
@end

@implementation ViewController

  • (void)viewDidLoad
    {
    [super viewDidLoad];
    PHFetchResult *result=[PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    for(PHAssetCollection *collection in result)
    {
    if ([collection.localizedTitle isEqualToString:@"FGG"]) {
    NSLog(@"%@",collection);
    }
    }

    //1.创建定位管理对象
    _manager=[[CLLocationManager alloc]init];
    _coder=[[CLGeocoder alloc]init];
    //2.设置属性 distanceFilter、desiredAccuracy
    _manager.distanceFilter=kCLDistanceFilterNone;//实时更新定位位置
    _manager.desiredAccuracy=kCLLocationAccuracyBest;//定位精确度

    //iOS8之后需要设置Info.plist,NSLocationAlwaysUsageDescription=YES以开启总是使用定位
    if([_manager respondsToSelector:@selector(requestAlwaysAuthorization)])
    {
    [_manager requestAlwaysAuthorization];
    }
    //该模式是抵抗程序在后台被杀,申明不能够被暂停
    _manager.pausesLocationUpdatesAutomatically=NO;
    //3.设置代理
    _manager.delegate=self;
    //4.开始定位
    [_manager startUpdatingLocation];
    //5.获取朝向
    [_manager startUpdatingHeading];

}

pragma mark-CLLocationManager代理方法

//定位失败时调用的方法
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"%@",error);
}
//定位成功调用的的方法
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
if(locations.count>0)
{
//获取位置信息
CLLocation *loc=[locations lastObject];
//海拔
CGFloat altitute=loc.altitude;
CGFloat altituteAcuracy=loc.verticalAccuracy;

    NSLog(@"海拔高度:%.0fm 精度:%.0fm",altitute,altituteAcuracy);
    //获取经纬度的结构体
    CLLocationCoordinate2D coor=loc.coordinate;
    
    CLLocation *location=[[CLLocation alloc]initWithLatitude:coor.latitude longitude:coor.longitude];
    
    [_coder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        CLPlacemark *pmark=[placemarks firstObject];
        NSLog(@"%@",pmark.addressDictionary);
        NSString *city=pmark.addressDictionary[@"City"];
        if([city hasSuffix:@"市辖区"])
            city=[city substringToIndex:city.length-3];
        if([city hasSuffix:@"市"])
            city=[city substringToIndex:city.length-1];
        NSLog(@"%@",city);
    }];
}

}
//返回定位的朝向
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
// 相对地理北极的方向
// newHeading.trueHeading;
// 相对地磁北极的方向
// newHeading.magneticHeading;
}

@end
</pre>

937405-3ca930be4b1730f3.JPG
2017-02-07 16:30:00 weixin_33725126 阅读数 28

环境: xcode8.2.1
1.Target->Capabilities->Background modes,勾选Location updates


2198165-7813cf9884405ec2.png
后台定位

2.请求权限 在info.plist添加
NSLocationWhenInUseUsageDescription、NSLocationAlwaysUsageDescription

2198165-9c842ead8600a100.png
权限请求

3.导入系统库

import <CoreLocation/CoreLocation.h>

4.代理

2198165-10596c8b73ed9603.png
Paste_Image.png

5.locationManager初始化

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//若不设置 app会在进入后台20分钟后停止
    self.locationManager.pausesLocationUpdatesAutomatically = NO;
    [self findMe];  
}

6.实现

- (void)findMe
{
    
    if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        NSLog(@"requestAlwaysAuthorization");
        [self.locationManager requestAlwaysAuthorization];
    }
    
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
        self.locationManager.allowsBackgroundLocationUpdates = YES;
    }
    
    [self.locationManager startUpdatingLocation];
    NSLog(@"start location");
}

7.获取位置信息

- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations
{
    // 1.获取用户位置的对象
    CLLocation *location = [locations lastObject];
    CLLocationCoordinate2D coordinate = location.coordinate;
        NSLog(@"%@纬度:%f 经度:%f",[NSDate date],coordinate.latitude, coordinate.longitude);

}

8.源码:
https://github.com/Liangjianghao/backgroudLocation.git

2018-11-30 09:24:00 weixin_34242331 阅读数 41

在日常的工作开发中,有时会遇到需要在后台持续运行的需求。对于这个需求,安卓实现起来比较简单,而iOS来说就比较复杂了。我们公司就有后台持续定位并且上传上传地理坐标的需求, 现在总结一下

实现方式一

因为项目用的百度定位SDK,而百度定位就自带后台定位功能所以可以直接用。

这里说明一下为什么要用百度SDK,因为项目要用定位获取的经纬度、城市信息请接口,而CLLocationManager返回的经纬度和百度是有差别的需要转换,有可能同一位置百度和苹果定位返回的定位信息有差别。为了统一iOS和Android都统一使用百度。

百度SDK后台定位

1.引入头文件

在调用定位功能的类中引入 BMKLocationComponent.h 这个头文件。

#import <BMKLocationkit/BMKLocationComponent.h>
2.配置AK

在调用定位时,需要添加AK,需要注意的是请在 SDK 任何类的初始化以及方法调用之前设置正确的 AK。设置AK的方式如下:

[[BMKLocationAuth sharedInstance] checkPermisionWithKey:@"输入AK" authDelegate:self];
3.设置期望定位精度

由于苹果系统的首次定位结果为粗定位,其可能无法满足需要高精度定位的场景。
百度提供了 kCLLocationAccuracyBest 参数,设置该参数可以获取到精度在10m左右的定位结果,但是相应的需要付出比较长的时间(10s左右),越高的精度需要持续定位时间越长。

推荐使用kCLLocationAccuracyHundredMeters,一次还不错的定位,偏差在百米左右,超时时间设置在2s-3s左右即可。

//初始化实例
_locationManager = [[BMKLocationManager alloc] init];
//设置delegate
_locationManager.delegate = self;
//设置返回位置的坐标系类型
_locationManager.coordinateType = BMKLocationCoordinateTypeBMK09LL;
//设置距离过滤参数
_locationManager.distanceFilter = kCLDistanceFilterNone;
//设置预期精度参数
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//设置应用位置类型
_locationManager.activityType = CLActivityTypeAutomotiveNavigation;
//设置是否自动停止位置更新
_locationManager.pausesLocationUpdatesAutomatically = NO;
//设置是否允许后台定位
_locationManager.allowsBackgroundLocationUpdates = YES;
//设置位置获取超时时间
_locationManager.locationTimeout = 10;
//设置获取地址信息超时时间
_locationManager.reGeocodeTimeout = 10;

更多详细介绍及其余精度阈值说明,请查看参考手册。

4.开启持续定位

调用BMKLocationManager提供的startUpdatingLocation方法实现。代码如下:

[self.locationManager startUpdatingLocation];

如果需要持续定位返回地址信息(需要联网),请设置如下:

[self.locationManager setLocatingWithReGeocode:YES];
[self.locationManager startUpdatingLocation];
5.接收位置更新

实现BMKLocationManagerDelegate代理的BMKLocationManager: didUpdateLocation: orError:方法,处理位置更新。代码如下:

- (void)BMKLocationManager:(BMKLocationManager * _Nonnull)manager didUpdateLocation:(BMKLocation * _Nullable)location orError:(NSError * _Nullable)error

{
    if (error)
    {
        NSLog(@"locError:{%ld - %@};", (long)error.code, error.localizedDescription);  
    } if (location) {//得到定位信息,添加annotation
        if (location.location) {
            NSLog(@"LOC = %@",location.location);
        }
        if (location.rgcData) {
            NSLog(@"rgc = %@",[location.rgcData description]);
        }   
    }
}
6.停止持续定位

当不再需要定位时,调用BMKLocationManager提供的stopUpdatingLocation方法停止定位。代码如下:

[self.locationManager stopUpdatingLocation];
7.更改info.plist

将info.plist的字段改成NSLocationWhenInUseUsageDescription,NSLocationAlwaysUsageDescription,NSLocationAlwaysAndWhenInUseUsageDescription三项。

在左侧目录中选中工程名,开启 TARGETS->Capabilities->Background Modes
在Background Modes中勾选 Location updates,如下图所示:


2416132-7bb23b8102cb2e9e.png
屏幕快照 2018-11-30 09.21.59.png
实现方式二

使用CLLocationManager 定位

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    [self keepBackgroundTask];
}
- (void)keepBackgroundTask
{
     [self startBgTask];
    
    if (!self.locationManager) {
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
        [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
        [self.locationManager requestAlwaysAuthorization];
        self.locationManager.allowsBackgroundLocationUpdates = YES;
        self.locationManager.pausesLocationUpdatesAutomatically = NO;
    }
    
     [self.locationManager startUpdatingLocation];  
}

- (void)startBgTask
{
    UIApplication *application = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier bgTask;
    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        
    }];
    
}
2416132-7bb23b8102cb2e9e.png
屏幕快照 2018-11-30 09.21.59.png

开启后台定位审核被拒参考:
IOS开启后台定位之审核被拒

2015-07-29 19:49:20 u013958441 阅读数 351
http://www.cnblogs.com/oshushu/articles/4569252.html  一个支持后台持续定位的小型第三方库,大家可以get一下


<iframe width='738' height='523' class='preview-iframe' scrolling='no' frameborder='0' src='http://download.csdn.net/source/preview/8223983/b6b592e26fc46720d6181a9c20e3954e' ></iframe>
2015-08-18 14:49:50 love_Coders 阅读数 451
项目需要,加了长时间后台定位(计时器控制后台运行时间),现在把代码发给大家哈
本人只测试了定时一小时控制后台获取位置信息,肯定可以更长时间的运行,不过耗电那是当然的了,所以做类似软件一定要先提醒用户,避免被拒和被用户差评!




一、首先。在Info.plist里面添加Key:Required background modes 
Value:App registers for location updates








二、初始化



#define RUNTIME 60*60//当然是控制在一小时以内


- (void)viewDidLoad
{
[superviewDidLoad];
    [self initData];

//响应后台
[[NSNotificationCenterdefaultCenteraddObserver:selfselector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotificationobject:nil];
}






//初始化数据
-(void)initData{
backgroundUpdateIntervalRUNTIME;//设置计时器时间


    self._saveLocations = [[NSMutableArray allocinit];
self._locationManager= [[CLLocationManagerallocinit];
self._locationManager.desiredAccuracykCLLocationAccuracyBest;
self._locationManager.delegateself;
[self._locationManagerstartUpdatingLocation];

}








三、更新定位
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
//在地图上加大头针
MKPointAnnotation*annotation = [[MKPointAnnotationallocinit];
    annotation.coordinate = newLocation.coordinate;
    [self._mapView addAnnotation:annotation];//
    [self._saveLocations addObject:annotation];


if(UIApplication.sharedApplication.applicationState== UIApplicationStateActive)
    {
if(backgroundTask!= UIBackgroundTaskInvalid)//如果后台没有关闭,结束
        {
[[UIApplicationsharedApplicationendBackgroundTask:backgroundTask];
backgroundTaskUIBackgroundTaskInvalid;
        }


//显示所有的大头针
        for (MKPointAnnotation *annotation in self._saveLocations)
        {
            CLLocationCoordinate2D coordinate = annotation.coordinate;

MKCoordinateRegionregion=MKCoordinateRegionMakeWithDistance(coordinate,storedLatitudeDelta,storedLongitudeDelta);
            MKCoordinateRegion adjustedRegion = [_mapView regionThatFits:region];
            [_mapView setRegion:adjustedRegion animated:NO];
        }
    }
    else
    {
NSLog(@"applicationD in Background,newLocation:%@", newLocation);
    }
}






四、后台加入计时器
//用定时器控制后台运行定位时间
-(void)applicationDidEnterBackground:(NSNotificationCenter *)notication{
UIApplication* app = [UIApplicationsharedApplication];

backgroundTask= [app beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"applicationD in Background");
    }];


//加入定时器,用来控制后台运行时间
self._updateTimer= [NSTimerscheduledTimerWithTimeInterval:backgroundUpdateInterval
                                                     target:self
                                                   selector:@selector(stopUpdate)
                                                   userInfo:nil
                                                    repeats:YES];
[[NSRunLoopcurrentRunLoopaddTimer:self._updateTimerforMode:NSRunLoopCommonModes];
}








五、计时时间到,停止后台运行与定位
-(void)stopUpdate{
[self._locationManagerstopUpdatingLocation];


[self._updateTimerinvalidate];
self._updateTimernil;
if(backgroundTask!= UIBackgroundTaskInvalid)
    {
[[UIApplicationsharedApplicationendBackgroundTask:backgroundTask];
backgroundTaskUIBackgroundTaskInvalid;
    }
}












六、用模拟器测试方法
用模拟器测试的时候选择:调试-位置-后三者都行

 



然后在控制台就可以看到后台输出的信息了

 










IOS的后台持续定位

阅读数 149

IOS后台持续定位

阅读数 8

IOS app crash 定位

阅读数 15

没有更多推荐了,返回首页