我正在开发一个基于VoIP的IOS应用程序。
在接到电话时,有两种播放声音通知用户的方法:
UILocalNotification。声音最多持续30秒;setKeepAliveTimeout:handler:函数中播放本地音乐资产。但系统只给我10秒的时间来做手术。有没有办法像本地手机应用程序那样永远播放声音?
发布于 2014-03-27 17:43:26
恐怕丹2552是对的。
这里是苹果州
不支持持续时间超过30秒的声音。如果指定一个声音超过30秒的文件,则将播放默认声音。
编辑:
播放一个音频文件超过30秒(或永远,为了这个目的)可以通过使用AVAudioPlayer从AVFoundation实现。
@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);
}
}然后,不必设置本地通知的属性,而是在主线程上调用该方法。
[self performSelectorOnMainThread:@selector(playAudio) withObject:nil waitUntilDone:NO];发布于 2014-06-07 15:47:09
伊斯兰Q的问题在于,AVAudioPlayer不适用于通知,因为当你不使用该应用程序时,应用程序将不会发出声音。只有UILocalNotification才能让你的应用程序在不活动时发出声音。30秒的限制是真实的。它应该通过再通知30秒来完成。我不知道其他VOIP应用程序会持续多久,但即使是传统的手机,通常也有限制,比如一分钟。
我的策略是:
这将允许用户在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接管。
您希望在警报和in应用程序声音之间有一个平稳的过渡,以便为您的用户提供完全完善的体验,所以最好的方法是测量环之间的时间,并让AVAudioPlayer在新循环的开始时准确地启动。
你的第二个问题是在后台保持应用程序的活力。这个简单的代码只会时不时地轮询这个应用程序来保持它的活力。它直接来自一个正在工作的应用程序,它就是这样做的,如果计时器仍然在运行,并在此情况下睡眠5秒,此代码将轮询:
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];
});https://stackoverflow.com/questions/19517460
复制相似问题