0

我想在应用程序处于后台时发送用户位置。在应用程序中,用户可以设置一个计时器,从 1 分钟到 24 小时。我试图让应用程序在后台运行,它只运行了十分钟。如果我将计时器设置为超过十分钟,然后将应用程序后台运行,该应用程序不会在后台运行超过十分钟。是否可以让应用程序运行超过十分钟?最多至少两个小时?

这是我尝试过的:

我将此添加到我的 plist 中:

在此处输入图像描述

我将此添加到我的applicationDidEnterBackground:方法中:

    __weak BADAppDelegate * weakSelf = self;
    self.backgroundTaskIdentifier =
    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        int timeTilDone = timerSeconds;// two hours

        self.bgTimer =
        [NSTimer timerWithTimeInterval:timeTilDone
                                target:weakSelf
                              selector:@selector(startTrackLocation)
                              userInfo:nil
                               repeats:NO];

        [[NSRunLoop mainRunLoop] addTimer:self.bgTimer
                                  forMode:NSDefaultRunLoopMode];


        self.testTimer =
        [NSTimer timerWithTimeInterval:60
                                target:weakSelf
                              selector:@selector(playSilentSound)
                              userInfo:nil
                               repeats:YES];

        [[NSRunLoop mainRunLoop] addTimer:self.testTimer
                                  forMode:NSDefaultRunLoopMode];


    });

我试图通过每分钟播放一个声音来强迫它活着

-(void)playSilentSound
{
if(self.silentSnd == nil)
{
    NSString *soundFile;
    if ((soundFile = [[NSBundle mainBundle] pathForResource:@"halfsec" ofType:@"caf"]))
    {
        NSURL *url = [[NSURL alloc] initFileURLWithPath:soundFile];
        self.silentSnd = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
        self.silentSnd.delegate = self;
        [self.silentSnd setNumberOfLoops:1];
    }
}

[self.silentSnd prepareToPlay];
[self.silentSnd play];
}

但这无济于事。

谢谢!

更新:

这是我的 locationManager 初始化代码:

    NSLog(@"StartTrackLocation");
    if(self.locationManager == nil)
    {
        self.locationManager = [[CLLocationManager alloc] init];
    }
    self.locationManager.delegate = self;
    self.locationManager.distanceFilter = kCLDistanceFilterNone;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    self.locationManager.pausesLocationUpdatesAutomatically = NO;
    [self.locationManager startUpdatingLocation];
4

2 回答 2

1

在初始化时将CLLocationManager属性设置pausesLocationUpdatesAutomatically为 false。
如果设置为 true,Apple 认为用户不需要 GPS 并关闭该服务。

强烈建议您在每个主要 ios 更新(下一个将是 7.0)中每行读取CLLocationManager 类参考

(尽管您的问题并未真正记录在案)

忘记你的方法beginBackgroundTaskWithExpirationHandler,那是不必要的。

于 2013-08-05T19:40:31.850 回答
1

要跟踪位置,您需要告诉系统您需要更新。你可以通过调用startUpdatingLocation(以获得细粒度的更新)和/或startMonitoringSignificantLocationChanges(获得低能耗但不那么频繁的更新,大约 500m 的变化,通常在用户更换蜂窝塔时)来做到这一点。两者都使用是很常见的(因为...SignificantChanges如果你被终止会启动你,而startUpdatingLocation不会)。您还可以设置一个区域,startMonitoringForRegion:当用户进入或离开时,您会收到提醒。

除此之外,您还试图通过计时器等来超越系统。那只会给你带来麻烦。

也就是说,在最一般的情况下,您的具体要求是不可能的。你不能说“我想在某时醒来”。这在 iOS 6 中不是一个可以解决的问题。你可以说你是一个位置应用程序,并且会不断更新位置信息。然后,您可以在每次更新位置时检查是否该做某事。但是如果用户坐了几个小时,而你在后台(特别是如果你被终止了),那么就没有办法被唤醒。

在未发布的 iOS 版本中可能有解决此问题的方法,但您必须在开发者论坛上讨论。

于 2013-08-05T19:58:29.047 回答