2013-10-22 30 views
4

我正在开发基于VoIP的IOS应用程序。有没有办法在VoIP应用程序来电时永远持续响铃?

有玩一些声音来通知用户两种方式,当一个电话进来:

  1. 发送UILocalNotification有声录像。声音将持续最多30秒;
  2. 播放本地音乐资产setKeepAliveTimeout:handler:函数。但系统只给了我10秒钟来完成操作。

有没有什么方法可以像原生Phone应用一样永远播放声音?

+0

鉴于Skype的起着〜25第二声,我认为这是比较节省假设30秒是限制。 – Dan2552

回答

1

恐怕@ Dan2552是正确的。

这里是苹果states

那么持续时间大于30秒

声音不被支持。如果 指定播放时间超过30秒的文件,则会播放默认的 声音。


编辑:

播放音频文件超过30秒(或永远,对于缘故)可以通过使用AVAudioPlayerAVFoundation

@import AVFoundation; // module -> no need to link the framework 
// #import <AVFoundation/AVFoundation.h> // old style 

- (void)playAudio 
{ 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp3"]; 
    NSError *error = nil; 
    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error]; 
    if (!error) { 
     player.numberOfLoops = -1; // infinite loop 
     [player play]; 
    } else { 
     NSLog(@"Audio player init error: %@", error.localizedDescription); 
    } 
} 

然后实现而不是设置本地通知的soundName属性,您必须必须调用此方法d的主线程上:

[self performSelectorOnMainThread:@selector(playAudio) withObject:nil waitUntilDone:NO]; 
1

伊斯兰教问的回答的问题是,AVAudioPlayer不会为通知工作,因为该应用程序会当你不使用的应用程序静音。只有UILocalNotification可以让您的应用程序在不活动时发出声音。 30秒的限制是真实的。应该通过以另外30秒通知重复通知来完成。我不知道其他VOIP应用会持续多久,但即使使用传统电话,通常也会有限制,例如一分钟。

我的策略是:

  • 发送初始通知29秒报警说有人试图 联系
  • 发送第二通知具有不同29秒报警器40秒,你将要错过后叫
  • 发送你错过100秒

后打电话第三通知这将允许时间的用户1:40回应电话。

您的代码将是这个样子:

UILocalNotification* notification = [[UILocalNotification alloc] init]; 
notification.alertBody = NSLocalizedString(@"FIRST_CALL", @"%@ is calling you!"); 
notification.soundName = @"normal_ring.mp3"; 
[[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 

dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(40 * NSEC_PER_SEC)); 
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
    if (!phone.isRinging) 
    { 
     // Somebody picked it up already in the mean time 
     return; 
    }  

    UILocalNotification* notification = [[UILocalNotification alloc] init]; 
    notification.alertBody = NSLocalizedString(@"HURRY_CALL", @"Hurry, you are about to miss a call from %@!"); 
    notification.soundName = @"hurry_ring.mp3"; 
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 

    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
     if (!phone.isRinging) 
     { 
      // Somebody picked it up already in the mean time 
      return; 
     } 

     UILocalNotification* notification = [[UILocalNotification alloc] init]; 
     notification.alertBody = NSLocalizedString(@"MISSED_CALL", @"You've just missed a call from %@"); 
     notification.soundName = @"missed_call.mp3"; 
     [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 

    }); 
}); 

如果您使用的代码,请记住,您首先需要确保应用程序在后台运行,因此UILocalNotification将是你唯一的选择。在前台使用普通的AVAudioPlayer时,要灵活得多。第二件事是,当用户响应呼叫时,应用程序变为前景,因此应该将警报静音并让AVAudioPlayer接管。

您希望或多或少地在警报和应用内声音之间平滑过渡,以便为用户提供完美的体验,因此最好的方法是测量铃声之间的时间并让AVAudioPlayer以精确的在新循环开始时的正确时间。

第二个问题是让应用程序在后台保持活动状态。这个简单的代码将会不时地轮询应用程序,以保持它的活力。它从工作应用,不只是这个,这个代码投票如果计时器仍在运行,睡五秒钟,当它来直:

UIBackgroundTaskIdentifier backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{ 
}]; 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    [timerExecuted timerUpdate]; 

    while (!timerExecuted.isStopped) 
    { 
     [NSThread sleepForTimeInterval:5]; 
    } 

    [application endBackgroundTask:backgroundTask]; 
}); 
相关问题