首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在VoIP应用程序中,是否有一种方法可以使来电永远持续?

在VoIP应用程序中,是否有一种方法可以使来电永远持续?
EN

Stack Overflow用户
提问于 2013-10-22 12:08:44
回答 2查看 766关注 0票数 4

我正在开发一个基于VoIP的IOS应用程序。

在接到电话时,有两种播放声音通知用户的方法:

  1. 用声音发送UILocalNotification。声音最多持续30秒;
  2. setKeepAliveTimeout:handler:函数中播放本地音乐资产。但系统只给我10秒的时间来做手术。

有没有办法像本地手机应用程序那样永远播放声音?

EN

回答 2

Stack Overflow用户

发布于 2014-03-27 17:43:26

恐怕丹2552是对的。

这里是苹果

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

编辑:

播放一个音频文件超过30秒(或永远,为了这个目的)可以通过使用AVAudioPlayerAVFoundation实现。

代码语言:javascript
复制
@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);
    }
}

然后,不必设置本地通知的属性,而是在主线程上调用该方法。

代码语言:javascript
复制
[self performSelectorOnMainThread:@selector(playAudio) withObject:nil waitUntilDone:NO];
票数 1
EN

Stack Overflow用户

发布于 2014-06-07 15:47:09

伊斯兰Q的问题在于,AVAudioPlayer不适用于通知,因为当你不使用该应用程序时,应用程序将不会发出声音。只有UILocalNotification才能让你的应用程序在不活动时发出声音。30秒的限制是真实的。它应该通过再通知30秒来完成。我不知道其他VOIP应用程序会持续多久,但即使是传统的手机,通常也有限制,比如一分钟。

我的策略是:

  • 用29秒的警报发送初始通知,有人试图联系。
  • 发送第二次通知,在40秒后发出不同的29秒警报,说明您即将错过一个电话。
  • 发送第三个通知,通知你100秒钟后错过了一个电话。

这将允许用户在1:40的时间内响应呼叫。

您的代码应该如下所示:

代码语言:javascript
复制
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秒,此代码将轮询:

代码语言:javascript
复制
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];
});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19517460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档