如何使用CTCallCenter获取呼叫事件:setCallEventHandler:应用程序暂停时发生的事件?

问题描述:

CTCallCenter的文档:setCallEventHandler:声明:

The documentation for CTCallCenter:setCallEventHandler: states that:


但是,当您的应用程序为$ b $时,也可能会发生呼叫事件b暂停。暂停时,您的应用程序不会收到
通话事件。当您的应用程序恢复活动状态时,
会为每次更改状态的呼叫收到一个呼叫事件

However, call events can also take place while your application is suspended. While it is suspended, your application does not receive call events. When your application resumes the active state, it receives a single call event for each call that changed state

相关部分这个问题是


当你的应用程序恢复活动状态时,它会为每次更改状态的调用收到一个
调用事件

When your application resumes the active state, it receives a single call event for each call that changed state

暗示应用程序将在应用程序暂停时收到过去发生的呼叫的呼叫事件。根据这个问题的答案,这是可能的: Navita TEM应用程序如何获取通话记录信息?

Implying the app will receive a call event for a call that took place in the past while the app was suspended. And this is possible according to the answer to this question: How does the Navita TEM app get call log information?

我的问题是:如果我的应用程序被暂停并且发生了呼叫,那么当我的应用程序恢复时活动状态如何检索发生的呼叫的呼叫事件?

My question is: if my app is suspended and a call takes place, then when my app resumes the active state how can it retrieve the call event for the call that took place?

我尝试了很多很多代码实验,但是当我无法检索任何呼叫信息时我的应用程序恢复活动状态。

I have tried many, many code experiments but have been unable to retrieve any call information when my app resumes the active state.

这是我尝试过的最简单的事情:
1)使用Xcode单视图应用程序模板创建一个新项目。
2)将下面显示的代码添加到didFinishLaunchingWithOptions
3)启动app
4)远离应用程序的任务
5)从另一台设备拨打电话,接听电话,挂断来自任一设备的呼叫
6)将应用程序返回到前台,从而恢复活动状态。

This is the most simplest thing I have tried: 1) Create a new project using the Xcode single view application template. 2) Add the code shown below to didFinishLaunchingWithOptions 3) Launch the app 4) Task away from the app 5) Make a call from another device, answer the call, hang up the call from either device 6) Bring the app back to the foreground thus resuming the active state.

注册呼叫事件的代码是:

The code to register for call events is:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
        self.callCenter = [[CTCallCenter alloc] init];
        [self.callCenter setCallEventHandler:^(CTCall *call)
         {
             NSLog(@"Event handler called");
             if ([call.callState isEqualToString: CTCallStateConnected])
             {
                 NSLog(@"Connected");
             }
             else if ([call.callState isEqualToString: CTCallStateDialing])
             {
                 NSLog(@"Dialing");
             }
             else if ([call.callState isEqualToString: CTCallStateDisconnected])
             {
                 NSLog(@"Disconnected");

             } else if ([call.callState isEqualToString: CTCallStateIncoming])
             {
                 NSLog(@"Incomming");
             }
         }];  

    return YES;
}

使用此代码,我可以在应用程序位于呼叫发生时的前景。但是,如果我在拨打电话之前离开应用程序,那么当我的应用程序下次恢复活动状态时,我无法收到呼叫事件 - 正如它在Apple文档中所说的那样。

With this code I am able to get call events if the app is in the foreground when the call occurs. But if I task away from the app before making the call then I am unable to get a call event when my app next resumes the active state - as it states it should in the Apple documentation.

我尝试过的其他事情:

1)文档说明块对象是在默认优先级全局调度队列上调度的,所以我试过放置在 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^ {})中注册setCallEventHandler

1) The documentation states that the block object is dispatched on the default priority global dispatch queue, so I have tried placing the registration of setCallEventHandler within dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{})

2)调用setCallEventHandler :在appBecameActive而不是didFinishLaunchingWithOptions

2) Calling setCallEventHandler: in appBecameActive instead of didFinishLaunchingWithOptions

3)向应用程序添加背景功能 - 通过beginBackgroundTaskWithExpirationHandler和/或使用startUpdatingLocation或startMonitoringForSignificantLocationChanges进行位置更新。

3) Adding background abilities to the app - via beginBackgroundTaskWithExpirationHandler and/or location updates using startUpdatingLocation or startMonitoringForSignificantLocationChanges.

4)以上的各种组合。

4) Various combinations of the above.

一旦我在我的代码上运行代码,奖励将被授予能够在应用程序暂停时发生呼叫事件的设备。

The bounty will be awarded once I get code running on my device which is able to get call events that took place while the app was suspended.

这是在iOS 7上。

我找到了一个解决方案,但我不知道它为什么会起作用。我唯一能想到的是GCD和/或CoreTelephony中的错误。

I've found a solution but I have no idea why it's working. Only thing I can think of is a bug in GCD and/or CoreTelephony.

基本上,我分配了两个 CTCallCenter $ c $的实例c>喜欢这个

Basically, I allocate two instances of CTCallCenter like this

void (^block)(CTCall*) = ^(CTCall* call) { NSLog(@"%@", call.callState); };

-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    callCenter1 = [[CTCallCenter alloc] init];
    callCenter1.callEventHandler = block;

    callCenter2 = [[CTCallCenter alloc] init];
    callCenter2.callEventHandler = block;

    return YES;
}

Swift中的类似代码:

Similar Code in Swift:

func block (call:CTCall!) {
        println(call.callState)
    }

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        //Declare callcenter in the class like 'var callcenter = CTCallCenter()'
        callcenter.callEventHandler = block

        return true
    }

为了测试这个,我打了一个电话,接了电话,然后在应用程序处于后台时挂了电话。当我启动它时,我收到了3个呼叫事件:传入,连接,断开连接。

To test this I made a call, answered it and then hanged up it while app was in background. When I launched it I received 3 call events: incoming, connected, disconnected.