1

我正在开发一个在后台运行的应用程序。有时我需要告诉用户某事正在发生,所以我播放声音一定次数。为此,我制作了一个计时器,但问题是它不能超过总延迟时间的 10 秒,之后,不再有声音(但应用程序仍在运行)。我已经在前台模式下检查了这种行为,它运行良好。

当我需要通知用户时,这是我的代码:



    AudioServicesPlaySystemSound(alarma);
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    numAlarm = 1;  
    NSTimeInterval delay_in_seconds = 2.0;
    dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW,delay_in_seconds*NSEC_PER_SEC);
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
    dispatch_after(delay,queue,^{
        [self fiBGTemps:ALARM];
    });

“fiBGTemps”是这样的,


- (void)fiBGTemps:(int)sender
{
    switch (sender){
        case TEMP_SCAN:
            (…)
            break;
        case ALARM:
            if (numAlarm>0 && numAlarm<NUM_ALARM)
            {
                AudioServicesPlaySystemSound(alarma);
                AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
                NSTimeInterval delay_in_seconds = 2;
                dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW,delay_in_seconds*NSEC_PER_SEC);
                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
                dispatch_after(delay,queue,^{
                    [self fiBGTemps:ALARM];
                });
                numAlarm++;
            }
            break;
    }
}

这种行为正常吗?我错过了什么吗?

谢谢

卡尼克

4

3 回答 3

1

问题解决了。

这就是发生的事情。当应用程序在后台运行并执行任务时,该任务也在后台运行,但系统只允许一定的时间(10 秒停机时间)以保护电池安全。因此它仅适用于特定任务(本地化、下载等)。

在我的情况下,我需要更多时间,因此解决方案是将任务定义为 UIBackgroundTask 以这样一种方式,即在完成时通知系统并因此可以终止的任务。

这是称为任务的代码:



    UIApplication *application = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier background_task;
    background_task = [application beginBackgroundTaskWithExpirationHandler: ^{
        [application endBackgroundTask: background_task];
        background_task = UIBackgroundTaskInvalid;
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self fiBGTemps:@(ALARM)];
        [application endBackgroundTask: background_task];
        background_task = UIBackgroundTaskInvalid;
    });

在这里你可以看到苹果论坛上的讨论,他们比我解释得更好。

苹果论坛讨论

我希望这有帮助。

卡尼克

于 2013-05-05T09:32:23.213 回答
0

您可以尝试在延迟值超过总延迟时间的 10 秒后重新设置延迟值,或者可能在播放声音一定时间后重新设置延迟值。

于 2013-04-30T09:06:09.360 回答
0

我怀疑将异步块链接起来以定期播放声音有点过头了。也许按照以下几行更简单的东西会更容易理解和维护:

// To initiate the alarm:
[self fiBGTemps: ALARM];

- (void)fiBGTemps:(int)sender
{
    switch (sender) {
       ...
       case ALARM:
           dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
                int count = 0;
                while (count < NUM_ALARM /* AND not interrupted by user? */) {
                    sleep(2);
                    AudioServicesPlaySystemSound(alarma);
                    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
                    count++;
                }
            });
            break;
        ...
    }
}
于 2013-04-30T10:07:31.127 回答