CTCallCenter的文档:setCallEventHandler:声明:
但是,您的应用程序也可以进行呼叫事件 暂停。暂停时,您的应用程序无法接收 通话活动。当您的应用程序恢复活动状态时,它 每次更改状态的调用都会收到一个调用事件
与此问题相关的部分是
当您的应用程序恢复活动状态时,它会收到一个 每次更改状态的呼叫都会调用事件
暗示应用程序将在应用程序暂停时收到过去发生的呼叫的呼叫事件。根据这个问题的答案,这是可能的:How does the Navita TEM app get call log information?
我的问题是:如果我的应用程序被暂停并且发生了呼叫,那么当我的应用程序恢复活动状态时,它如何检索发生的呼叫的呼叫事件?
我尝试了很多很多代码实验,但是当我的应用程序恢复活动状态时,无法检索任何调用信息。
这是我尝试过的最简单的事情: 1)使用Xcode单视图应用程序模板创建一个新项目。 2)将下面显示的代码添加到didFinishLaunchingWithOptions中 3)启动应用程序 4)远离应用程序的任务 5)从另一台设备拨打电话,接听电话,从任一设备挂断电话 6)将应用程序带回前台,从而恢复活动状态。
注册呼叫事件的代码是:
- (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文档中所说的那样。
我尝试过的其他事情:
1)文档说明块对象是在默认优先级全局调度队列上调度的,所以我尝试将setCallEventHandler的注册放在dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{})
2)在appBecameActive中调用setCallEventHandler:而不是didFinishLaunchingWithOptions
3)向应用添加背景功能 - 通过beginBackgroundTaskWithExpirationHandler和/或使用startUpdatingLocation或startMonitoringForSignificantLocationChanges进行位置更新。
4)以上的各种组合。
一旦我在我的设备上运行代码就可以获得赏金,该代码可以在应用程序暂停时获得发生的呼叫事件。
这是在iOS 7上。
答案 0 :(得分:14)
我找到了一个解决方案,但我不知道它为什么会起作用。我唯一能想到的是GCD和/或CoreTelephony中的错误。
基本上,我像这样分配了CTCallCenter
的两个实例
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中的类似代码:
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个呼叫事件:传入,连接,断开连接。
答案 1 :(得分:3)
在我的情况下,我正在开发一个企业应用,它不需要Apple的应用市场批准 - 所以如果您开发企业应用这个解决方案是给你的。
此外,当应用为背景时,所选答案不。
解决方案很简单,基本上你只需要在Capabilities选项卡中添加2个功能(VOIP& Background fetch):
现在,您的应用已注册到iOS框架调用“委托”,因此OP代码剪辑解决方案:
[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");
}
}];
即使您的应用处于后台,您也会获得通知。