gpt4 book ai didi

ios - 在任何时候在iOS 7或更高版本中在后台启动定位服务

转载 作者:行者123 更新时间:2023-12-01 16:46:37 26 4
gpt4 key购买 nike

我的算法希望以这种方式工作:
如果服务器状态发生变化,我会向应用程序发送远程通知(其状态可能会被挂起或未运行)。但是,在通知用户之前,我希望运行一些代码。在iOS 7之前是不可能的,但是在iOS 7和更高版本中是可能的。 (Visit this for further details)

我希望运行的代码包括一次跟踪用户的位置,然后停止。但是,用于跟踪位置的后台模式需要开始更新前景中的位置,并且当应用程序移至后台时,CLLocationManager Delegate会自动获取位置更新。
但是,我只想在某个时间点跟踪一次,然后停止它。

PS:我的服务器状态可以随时更改。所以,我不能使用任何计时器或间隔

最佳答案

我找到了问题/解决方案。 当需要启动定位服务并停止后台任务时,应该延迟后台任务(我设置为1秒)。否则,定位服务将不会启动。

另一个重要的注意事项是,iOS 7中的最长后台时间现在是3分钟,而不是10分钟。

也许会帮助某人。

编辑:

在写了一个小示例之后,我发现定位服务也应该保持打开状态几秒钟(在我的示例中为3秒)。在“.plist”文件中,将UIBackgroundModes设置为“location”。例:

ScheduledLocationManager.h

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

@interface ScheduledLocationManager : NSObject <CLLocationManagerDelegate>

-(void)getUserLocationWithInterval:(int ) interval ;

@end

ScheduledLocationManager.m
#import "ScheduledLocationManager.h"

int const kMaxBGTime = 170; //3 min - 10 seconds (as bg task is killed faster)
int const kTimeToGetLocations = 3;

@implementation ScheduledLocationManager{
UIBackgroundTaskIdentifier bgTask;
CLLocationManager *locationManager;
NSTimer *checkLocationTimer;
int checkLocationInterval;
NSTimer *waitForLocationUpdatesTimer;
}

- (id)init
{
self = [super init];
if (self) {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
}
return self;
}

-(void)getUserLocationWithInterval:(int ) interval
{
checkLocationInterval = (interval > kMaxBGTime)? kMaxBGTime : interval;
[locationManager startUpdatingLocation];
}

- (void)timerEvent:(NSTimer*)theTimer
{
[self stopCheckLocationTimer];
[locationManager startUpdatingLocation];

// in iOS 7 we need to stop background task with delay, otherwise location service won't start
[self performSelector:@selector(stopBackgroundTask) withObject:nil afterDelay:1];
}

-(void)startCheckLocationTimer
{
[self stopCheckLocationTimer];
checkLocationTimer = [NSTimer scheduledTimerWithTimeInterval:checkLocationInterval target:self selector:@selector(timerEvent:) userInfo:NULL repeats:NO];
}

-(void)stopCheckLocationTimer
{
if(checkLocationTimer){
[checkLocationTimer invalidate];
checkLocationTimer=nil;
}
}

-(void)startBackgroundTask
{
[self stopBackgroundTask];
bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
//in case bg task is killed faster than expected, try to start Location Service
[self timerEvent:checkLocationTimer];
}];
}

-(void)stopBackgroundTask
{
if(bgTask!=UIBackgroundTaskInvalid){
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}

-(void)stopWaitForLocationUpdatesTimer
{
if(waitForLocationUpdatesTimer){
[waitForLocationUpdatesTimer invalidate];
waitForLocationUpdatesTimer =nil;
}
}

-(void)startWaitForLocationUpdatesTimer
{
[self stopWaitForLocationUpdatesTimer];
waitForLocationUpdatesTimer = [NSTimer scheduledTimerWithTimeInterval:kTimeToGetLocations target:self selector:@selector(waitForLoactions:) userInfo:NULL repeats:NO];
}

- (void)waitForLoactions:(NSTimer*)theTimer
{
[self stopWaitForLocationUpdatesTimer];

if(([[UIApplication sharedApplication ]applicationState]==UIApplicationStateBackground ||
[[UIApplication sharedApplication ]applicationState]==UIApplicationStateInactive) &&
bgTask==UIBackgroundTaskInvalid){
[self startBackgroundTask];
}

[self startCheckLocationTimer];
[locationManager stopUpdatingLocation];
}

#pragma mark - CLLocationManagerDelegate methods

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
if(checkLocationTimer){
//sometimes it happens that location manager does not stop even after stopUpdationLocations
return;
}

//TODO: save locations

if(waitForLocationUpdatesTimer==nil){
[self startWaitForLocationUpdatesTimer];
}
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
//TODO: handle error
}

#pragma mark - UIAplicatin notifications

- (void)applicationDidEnterBackground:(NSNotification *) notification
{
if([self isLocationServiceAvailable]==YES){
[self startBackgroundTask];
}
}

- (void)applicationDidBecomeActive:(NSNotification *) notification
{
[self stopBackgroundTask];
if([self isLocationServiceAvailable]==NO){
//TODO: handle error
}
}

#pragma mark - Helpers

-(BOOL)isLocationServiceAvailable
{
if([CLLocationManager locationServicesEnabled]==NO ||
[CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied ||
[CLLocationManager authorizationStatus]==kCLAuthorizationStatusRestricted){
return NO;
}else{
return YES;
}
}


@end

您必须创建ScheduledLocationManager的实例,并调用getUserLocationWithInterval传递以秒为单位的间隔。

关于ios - 在任何时候在iOS 7或更高版本中在后台启动定位服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19407875/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com