2013-04-30 3 views
1

Я разрабатываю приложение, которое работает в фоновом режиме. Иногда мне нужно сказать пользователю, что что-то происходит, поэтому я играю звук определенное количество раз. Для этого я сделал таймер, но проблема в том, что он не может превышать 10 с общего времени задержки, после чего больше нет звуков (но приложение все еще работает). Я проверил это поведение в режиме переднего плана, и он отлично работает.dispatch_after ограничен 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&ltNUM_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

Что установлено NUM_ALARM? Возможно, это ограничение числа циклов. Кроме того, кажется, что у вас есть последовательность из двух вторых задержек, а не задержка в 10 секунд. – aLevelOfIndirection

+0

Привет @aLevelOfIndirection, NUM_ALARM - это константа, которую я установил для проверки этого временного ограничения (#define NUM_ALARM 20). Таким образом, я вижу, сколько раз звучит звук. Другой способ, который я тестировал, - изменить значение «delay_in_seconds». Если я установил это значение 8 (например), он воспроизводит только 2 звука. Если я установил это значение в 12 (более 10), он воспроизводит только один звук. – Kanick

ответ

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; 
    }); 

И здесь вы можете увидеть обсуждения на форумах Apple, где они объясняют это лучше, чем у меня.

AppleForums discussion

Я надеюсь, что это помогает.

Kanick

+0

Где вы добавите задержку? –

0

Вы можете попробовать повторно установив значение задержки после превышать 10с от общего с задержкой времени или может быть после того, как она играет звук для определенного количества времени.

+0

Да, действительно, это то, что я сделал. Я установил задержку на 2 секунды и (для тестирования) это повторяется более 5 раз (> 10 секунд). Как только это достигается, через 10 секунд больше нет ответа (это кажется бесконечным временем). Поэтому я не могу повторить это снова. – Kanick

+0

Можете уделить вам значение образца, которое будет отправлено на dispatch_after dispatch_after (delay, queue,^{ [self fiBGTemps: ALARM]; }); Необходимо знать, что хранят эти переменные (задержка и очередь) ... 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); – ManikantThakur

+0

Привет, @ManikantThakur. Это то, что передается в диспетчер__после: delay_in_seconds = 8 (с этим значением он воспроизводит только один звук), NSEC_PER_SEC - это константа, объявленная в clock_types.h (#define NSEC_PER_SEC 1000000000ull), очередь одинакова Я показал в приведенном выше коде, а NUM_ALARM - 15 (эти значения не имеют большого значения, для отображения эффекта важна NUM_ALARM * delay_in_seconds> 10s). Это то, о чем вы просите? – Kanick

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; 
     ... 
    } 
} 
+0

Спасибо @aLevelOfIndirection. Я только что пробовал ваш подход, и я наблюдал те же результаты. Может быть, проблема не в коде (чище или нет на переднем плане хорошо работает). Может быть, есть какой-то параметр конфигурации или что-то в этом роде. – Kanick

+0

Как долго (в секундах) звуковые файлы для сигналов тревоги? – aLevelOfIndirection

+0

1 секунда (или меньше). – Kanick

Смежные вопросы