我正在开发一个在后台运行的应用。有时我需要告诉用户发生了什么事情,所以我播放了一定次数的声音。为了做到这一点,我做了一个计时器,但问题是它不能超过总延迟时间的10s,之后,没有更多的声音(但应用程序仍在运行)。我已经在前台模式中检查了这种行为并且它运行良好。
当我需要通知用户时,这是我的代码:
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;
}
}
这种行为是正常的吗?我错过了什么吗?
由于
Kanick
答案 0 :(得分:1)
问题解决了。
这就是发生的事情。当应用程序在后台运行并执行任务时,此任务也在后台运行,但系统只允许一定的时间(10s围裙。)以安全电池。因此它仅适用于特定任务(本地化,下载等)。
我的情况我需要更多时间,因此解决方案是将任务定义为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;
});
在这里你可以看到关于Apple论坛的讨论,他们在那里解释这个比我更好。
我希望这会有所帮助。
Kanick
答案 1 :(得分:0)
您可以尝试在延迟时间超过总延迟时间的10秒后重新设置延迟值,也可以在延迟值播放声音一段时间后重新设置。
答案 2 :(得分: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;
...
}
}