ios - 如何使用 CTCallCenter :setCallEventHandler: that occurred while the app was suspended? 获取调用事件

标签 ios core-telephony

CTCallCenter:setCallEventHandler: 的文档指出:

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

暗示该应用程序将收到一个调用事件,该事件与过去在该应用程序暂停时发生的调用有关。根据这个问题的答案,这是可能的:How does the Navita TEM app get call log information?

我的问题是:如果我的应用挂起并且发生了调用,那么当我的应用恢复事件状态时它如何检索发生的调用的调用事件?

我已经尝试了很多很多代码实验,但是当我的应用程序恢复事件状态时无法检索到任何调用信息。

这是我尝试过的最简单的事情: 1) 使用 Xcode 单 View 应用程序模板创建一个新项目。 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) 文档指出 block 对象是在默认优先级全局调度队列上调度的,因此我尝试将 setCallEventHandler 的注册放在 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{})

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

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

4) 以上的各种组合。

一旦我在我的设备上运行能够获取应用程序暂停时发生的调用事件的代码,就会获得赏金。

这是在 iOS 7 上。

最佳答案

我找到了一个解决方案,但我不知道它为什么有效。我唯一能想到的是 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 个调用事件:传入、连接、断开连接。

关于ios - 如何使用 CTCallCenter :setCallEventHandler: that occurred while the app was suspended? 获取调用事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21195732/

相关文章:

ios - 在 xamarin 的钥匙串(keychain)中找不到有效的 iPhone 代码签名 key

ios - 从 JSON 中一张一张加载照片

iphone - iOS 5 - CTCallCenter 不适合我

android - 查找正在使用的运营商信息,而不是 SIM 卡信息

ios - PHAssetCollectionChangeRequest : addAssets() now accepts NSFastEnumeration. 这个怎么实现?

ios - 通过 TableView 将 XML 数组数据传递到 CollectionView

ios - 使用 ReactiveCocoa 将 UIKit 与 View 模型绑定(bind) 3/4

ios - CTTelephonyNetworkInfo().serviceSubscriberCellularProviders 和 CTTelephonyNetworkInfo().serviceCurrentRadioAccessTechnology 中的关键是什么

ios - CoreTelephony 因 : Received a notification with no notification name 原因崩溃

iphone - 使用 IOS SDK 是否可以在另一个调用正在进行时(在后台)检测来电?