【问题标题】:to run app continuously in the background在后台连续运行应用程序
【发布时间】:2011-04-26 06:08:31
【问题描述】:

我希望我的应用通过定位服务继续在后台运行。为此我使用过:

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

    [locationManager stopUpdatingLocation];
    [locationManager startUpdatingLocation];

    //timer=[NSTimer scheduledTimerWithTimeInterval:300 target:self selector:@selector(UpdateLocation) userInfo:nil repeats:YES];

}

但是当我使用NSTimer 时,它不会调用UpdateLocation。我尝试使用另一种方法调用它,但它也只调用了一次。

我想在后台连续运行应用程序,定期检测位置。

【问题讨论】:

    标签: iphone ios cocoa-touch cllocationmanager


    【解决方案1】:

    我在我正在开发的应用程序中执行此操作。当应用程序处于后台但应用程序不断接收位置更新时,计时器不起作用。我在文档的某处读到(我现在似乎找不到它,当我找到它时我会发布更新),当应用程序在后台时,只能在活动的运行循环上调用方法。即使在 bg 中,应用程序委托也有一个活动的运行循环,因此您无需创建自己的运行循环即可使其工作。 [我不确定这是否是正确的解释,但这就是我从阅读中理解的方式]

    首先,在应用的 info.plist 中为键“背景模式”添加“位置”对象。现在,您需要做的是在应用中的任何位置开始位置更新:

    CLLocationManager locationManager = [[CLLocationManager alloc] init];
    
    locationManager.delegate = self;//or whatever class you have for managing location
    
    [locationManager startUpdatingLocation];
    

    接下来,编写一个处理位置更新的方法, 在应用程序委托中说 -(void)didUpdateToLocation:(CLLocation*)location。然后在您启动位置管理器的类中实现 CLLocationManagerDelegate 的 locationManager:didUpdateLocation:fromLocation 方法(因为我们将位置管理器委托设置为“self”)。在此方法中,您需要检查您必须处理位置更新的时间间隔是否已过。您可以通过每次保存当前时间来做到这一点。如果该时间已过,请从您的应用委托中调用 UpdateLocation 方法:

    NSDate *newLocationTimestamp = newLocation.timestamp;
    NSDate *lastLocationUpdateTiemstamp;
    
    int locationUpdateInterval = 300;//5 mins
    
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    if (userDefaults) {
    
            lastLocationUpdateTiemstamp = [userDefaults objectForKey:kLastLocationUpdateTimestamp];
    
            if (!([newLocationTimestamp timeIntervalSinceDate:lastLocationUpdateTiemstamp] < locationUpdateInterval)) {
                //NSLog(@"New Location: %@", newLocation);
                [(AppDelegate*)[UIApplication sharedApplication].delegate didUpdateToLocation:newLocation];
                [userDefaults setObject:newLocationTimestamp forKey:kLastLocationUpdateTimestamp];
            }
        }
    }
    

    即使您的应用处于后台,这也会每 5 分钟调用一次您的方法。 Imp:此实现会耗尽电池电量,如果您的位置数据的准确性不重要,您应该使用 [locationManager startMonitoringSignificantLocationChanges]

    在将其添加到您的应用之前,请阅读位置感知编程指南,网址为 http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/LocationAwarenessPG/Introduction/Introduction.html

    【讨论】:

    • 如果我没记错的话,如果 didUpdateLocation 每隔 5 分钟调用一次,它只会每 5 分钟调用一次。如果您选择 startMonitoringSignificantChanges 并且不移动太多,那么您将不会以 5 百万的间隔获得更新。对吗?
    【解决方案2】:

    我知道这已经很晚了。但是,如果您仍然没有得到答案,这就是我所做的,我的应用程序在后台持续运行。

    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
         UIApplication *app = [UIApplication sharedApplication];
         UIBackgroundTaskIdentifier bgTask = 0;
    
         backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self  selector:@selector(backgroundTask) userInfo:nil repeats:YES];
    
         bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
            [app endBackgroundTask:bgTask];
        }];
    }
    

    现在在 backgroundTask 方法中做任何你想做的事情。

    【讨论】:

    • 它位于 AppDelegate 中,还是可以在任何类中?
    • 是的,这段代码在 AppDelegate 中。而且我自己还没有尝试过,但它应该也可以在任何其他课程中使用......
    • 肯定有什么我不明白的地方,因为如果我把这段代码和方法backgroundTask留空,我的应用程序在后台运行。如果我删除您的代码,它就不再存在了。
    • 您的意思是,如果您删除代码,您的应用程序不会在后台运行。??您是否通过在 backgroundTask 方法中输入日志进行检查?
    【解决方案3】:

    您可以用于在后台运行应用程序以执行特定任务。

    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
        UIApplication *app = [UIApplication sharedApplication];
        UIBackgroundTaskIdentifier bgTask = 0;
    
        backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(backgroundTask) userInfo:nil repeats:YES];
    
        bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
            [app endBackgroundTask:bgTask];
        }];
    }
    

    【讨论】:

    • 这似乎与@Vish_Obj-C 之前发布的解决方案完全相同。我错过了什么?
    • 代码看起来不对。该块在创建时会捕获bgTask 的值,为0,导致[app endBackgroundTask:0] 不正确。相反,您可能想要一个 bgTaskID ivar/property,以便分配可以传播到块。
    猜你喜欢
    • 1970-01-01
    • 2013-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-10
    • 2011-09-11
    相关资源
    最近更新 更多