gpt4 book ai didi

iOS 9 即使应用程序终止也如何获取位置

转载 作者:可可西里 更新时间:2023-11-01 17:15:24 25 4
gpt4 key购买 nike

我了解如何在后台检索位置。而且我知道即使终止也有机会获得位置Continious location updates even if app is terminated in iOS

但是。我有应用程序 Moves 和 Foursquare。如果这个应用程序甚至没有运行(我终止了所有应用程序并且没有应用程序运行)然后我转到“隐私”并将这个应用程序位置更改为禁用(从不),我可以看到状态栏中的箭头消失了。但是,当我启用位置更新(始终)时,箭头再次出现在状态栏中,此时应用程序未运行。所以这个应用程序开始获取有关位置的信息。如何?即使几天没有启动 MOves,此应用程序也会向我显示过去几天的正确路线。他们如何检索过去几天的位置信息,甚至应用程序未启动?

最佳答案

我找到了解决方案。这在 IOS 9 中对我有用。即使重新启动 IOS 设备,也能继续运行。

http://mobileoop.com/getting-location-updates-for-ios-7-and-8-when-the-app-is-killedterminatedsuspended

GitHub 示例: https://github.com/voyage11/GettingLocationWhenSuspended

已更新

您必须使用 [myLocationManager startMonitoringSignificantLocationChanges],而不是 [myLocationManager startUpdatingLocation]

下面是我的 AppDelegate。

@implementation LocationAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(@"didFinishLaunchingWithOptions");

self.shareModel = [LocationManager sharedManager];
self.shareModel.afterResume = NO;

[self.shareModel addApplicationStatusToPList:@"didFinishLaunchingWithOptions"];

UIAlertView * alert;

//We have to make sure that the Background App Refresh is enable for the Location updates to work in the background.
if ([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusDenied) {

alert = [[UIAlertView alloc]initWithTitle:@""
message:@"The app doesn't work without the Background App Refresh enabled. To turn it on, go to Settings > General > Background App Refresh"
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil, nil];
[alert show];

} else if ([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusRestricted) {

alert = [[UIAlertView alloc]initWithTitle:@""
message:@"The functions of this app are limited because the Background App Refresh is disable."
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil, nil];
[alert show];

} else {

// When there is a significant changes of the location,
// The key UIApplicationLaunchOptionsLocationKey will be returned from didFinishLaunchingWithOptions
// When the app is receiving the key, it must reinitiate the locationManager and get
// the latest location updates

// This UIApplicationLaunchOptionsLocationKey key enables the location update even when
// the app has been killed/terminated (Not in th background) by iOS or the user.

NSLog(@"UIApplicationLaunchOptionsLocationKey : %@" , [launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]);
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {

// This "afterResume" flag is just to show that he receiving location updates
// are actually from the key "UIApplicationLaunchOptionsLocationKey"
self.shareModel.afterResume = YES;

[self.shareModel startMonitoringLocation];
[self.shareModel addResumeLocationToPList];
}
}

return YES;
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"applicationDidEnterBackground");
[self.shareModel restartMonitoringLocation];

[self.shareModel addApplicationStatusToPList:@"applicationDidEnterBackground"];
}



- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"applicationDidBecomeActive");

[self.shareModel addApplicationStatusToPList:@"applicationDidBecomeActive"];

//Remove the "afterResume" Flag after the app is active again.
self.shareModel.afterResume = NO;

[self.shareModel startMonitoringLocation];
}


- (void)applicationWillTerminate:(UIApplication *)application {
NSLog(@"applicationWillTerminate");
[self.shareModel addApplicationStatusToPList:@"applicationWillTerminate"];
}


@end

我的自定义 LocationManager。

@implementation LocationManager

//Class method to make sure the share model is synch across the app
+ (id)sharedManager {
static id sharedMyModel = nil;
static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{
sharedMyModel = [[self alloc] init];
});

return sharedMyModel;
}


#pragma mark - CLLocationManager

- (void)startMonitoringLocation {
if (_anotherLocationManager)
[_anotherLocationManager stopMonitoringSignificantLocationChanges];

self.anotherLocationManager = [[CLLocationManager alloc]init];
_anotherLocationManager.delegate = self;
_anotherLocationManager.allowsBackgroundLocationUpdates = true;
_anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
_anotherLocationManager.activityType = CLActivityTypeOtherNavigation;

if(IS_OS_8_OR_LATER) {
[_anotherLocationManager requestAlwaysAuthorization];
}
[_anotherLocationManager startMonitoringSignificantLocationChanges];
}

- (void)restartMonitoringLocation {
[_anotherLocationManager stopMonitoringSignificantLocationChanges];

if (IS_OS_8_OR_LATER) {
[_anotherLocationManager requestAlwaysAuthorization];
}
[_anotherLocationManager startMonitoringSignificantLocationChanges];
}


#pragma mark - CLLocationManager Delegate

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{

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

for (int i = 0; i < locations.count; i++) {

CLLocation * newLocation = [locations objectAtIndex:i];
CLLocationCoordinate2D theLocation = newLocation.coordinate;
CLLocationAccuracy theAccuracy = newLocation.horizontalAccuracy;

self.myLocation = theLocation;
self.myLocationAccuracy = theAccuracy;
}

[self addLocationToPList:_afterResume];
}



#pragma mark - Plist helper methods

// Below are 3 functions that add location and Application status to PList
// The purpose is to collect location information locally

- (NSString *)appState {
UIApplication* application = [UIApplication sharedApplication];

NSString * appState;
if([application applicationState]==UIApplicationStateActive)
appState = @"UIApplicationStateActive";
if([application applicationState]==UIApplicationStateBackground)
appState = @"UIApplicationStateBackground";
if([application applicationState]==UIApplicationStateInactive)
appState = @"UIApplicationStateInactive";

return appState;
}

- (void)addResumeLocationToPList {

NSLog(@"addResumeLocationToPList");

NSString * appState = [self appState];

self.myLocationDictInPlist = [[NSMutableDictionary alloc]init];
[_myLocationDictInPlist setObject:@"UIApplicationLaunchOptionsLocationKey" forKey:@"Resume"];
[_myLocationDictInPlist setObject:appState forKey:@"AppState"];
[_myLocationDictInPlist setObject:[NSDate date] forKey:@"Time"];

[self saveLocationsToPlist];
}



- (void)addLocationToPList:(BOOL)fromResume {
NSLog(@"addLocationToPList");

NSString * appState = [self appState];

self.myLocationDictInPlist = [[NSMutableDictionary alloc]init];
[_myLocationDictInPlist setObject:[NSNumber numberWithDouble:self.myLocation.latitude] forKey:@"Latitude"];
[_myLocationDictInPlist setObject:[NSNumber numberWithDouble:self.myLocation.longitude] forKey:@"Longitude"];
[_myLocationDictInPlist setObject:[NSNumber numberWithDouble:self.myLocationAccuracy] forKey:@"Accuracy"];

[_myLocationDictInPlist setObject:appState forKey:@"AppState"];

if (fromResume) {
[_myLocationDictInPlist setObject:@"YES" forKey:@"AddFromResume"];
} else {
[_myLocationDictInPlist setObject:@"NO" forKey:@"AddFromResume"];
}

[_myLocationDictInPlist setObject:[NSDate date] forKey:@"Time"];

[self saveLocationsToPlist];
}

- (void)addApplicationStatusToPList:(NSString*)applicationStatus {

NSLog(@"addApplicationStatusToPList");

NSString * appState = [self appState];

self.myLocationDictInPlist = [[NSMutableDictionary alloc]init];
[_myLocationDictInPlist setObject:applicationStatus forKey:@"applicationStatus"];
[_myLocationDictInPlist setObject:appState forKey:@"AppState"];
[_myLocationDictInPlist setObject:[NSDate date] forKey:@"Time"];

[self saveLocationsToPlist];
}

- (void)saveLocationsToPlist {
NSString *plistName = [NSString stringWithFormat:@"LocationArray.plist"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *fullPath = [NSString stringWithFormat:@"%@/%@", docDir, plistName];

NSMutableDictionary *savedProfile = [[NSMutableDictionary alloc] initWithContentsOfFile:fullPath];

if (!savedProfile) {
savedProfile = [[NSMutableDictionary alloc] init];
self.myLocationArrayInPlist = [[NSMutableArray alloc]init];
} else {
self.myLocationArrayInPlist = [savedProfile objectForKey:@"LocationArray"];
}

if(_myLocationDictInPlist) {
[_myLocationArrayInPlist addObject:_myLocationDictInPlist];
[savedProfile setObject:_myLocationArrayInPlist forKey:@"LocationArray"];
}

if (![savedProfile writeToFile:fullPath atomically:FALSE]) {
NSLog(@"Couldn't save LocationArray.plist" );
}
}


@end

不要忘记在 plist 文件中启用背景位置。

enter image description here

并将消息设置为 LocationAlwaysUsageDescription。

enter image description here

关于iOS 9 即使应用程序终止也如何获取位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32749476/

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