如何以编程方式检测呼入

时间:2014-05-08 07:25:17

标签: ios iphone cocoa core-telephony

我需要我的应用程序在有通话时发送通知(来电,已连接,通话已结束)     我通过通知注册了我的viewController。

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callReceived:) name:CTCallStateIncoming object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callEnded:) name:CTCallStateDisconnected object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callConnected:) name:CTCallStateConnected object:nil];

我还制作了一种检查通话状态的方法

-(IBAction)checkForCall:(id)sender{
    NSLog(@"call state %@ id %@",call.callState,call.callID);
    CTCallCenter *callCenter = [[CTCallCenter alloc] init];
    callCenter.callEventHandler = ^(CTCall* call){
        if (call.callState == CTCallStateDisconnected)
        {
            NSLog(@"Call has been disconnected");

        }
        else if (call.callState == CTCallStateConnected)
        {
            NSLog(@"Call has just been connected");

        }
        else if(call.callState == CTCallStateIncoming)
        {
            NSLog(@"Call is incoming");

        }
        else
        {
            NSLog(@"None of the conditions");
        }
    };
}

但这一切都无效。请帮帮我。

错误在哪里?有没有代码说明如何使用核心电话?

4 个答案:

答案 0 :(得分:22)

使用此

Appdelegate.h

#import <CoreTelephony/CTCallCenter.h>
#import <CoreTelephony/CTCall.h>
...
@property (nonatomic, strong) CTCallCenter* callCenter;

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{  
   .... 
  self.callCenter = [[CTCallCenter alloc] init];
  [self handleCall];
   .... 
}

-(void)handleCall
{
    self.callCenter.callEventHandler = ^(CTCall *call){

       if ([call.callState isEqualToString: CTCallStateConnected])
       {
          //NSLog(@"call stopped");
       }
       else if ([call.callState isEqualToString: CTCallStateDialing])
       {
        }
       else if ([call.callState isEqualToString: CTCallStateDisconnected])
       {
          //NSLog(@"call played");
        }
       else if ([call.callState isEqualToString: CTCallStateIncoming])
       {
           //NSLog(@"call stopped");
       }
     };
  }

答案 1 :(得分:6)

In Swift 3 

使用CXCallObserver

import CallKit

var callObserver = CXCallObserver()

class AppDelegate: UIResponder, UIApplicationDelegate, CXCallObserverDelegate {

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

callObserver.setDelegate(self, queue: nil) //Set delegate to self to call delegate method. 

return true 

}

 func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {

    if call.hasConnected {
        Print("Call Connect -> \(call.uuid)")
    }

    if call.isOutgoing {
        Print("Call outGoing \(call.uuid)")
    }

    if call.hasEnded {
        Print("Call hasEnded \(call.uuid)")
    }

    if call.isOnHold {
        Print("Call onHold \(call.uuid)")
      }
  }
}

答案 2 :(得分:2)

for iOS 10 AND swift 3:

a)复制并粘贴到新项目中的新空控制器中 b)运行它,asyncAfter将触发一个调用... 注意:仅适用于设备。

// only for iOS10

import UIKit
import CoreTelephony
import CallKit

class ViewController: UIViewController, CXCallObserverDelegate {
    var callCenter : CTCallCenter?
    var observer : CXCallObserver?

    override func viewDidLoad() {
        super.viewDidLoad()

        setup()

        let delay = 2.0
        let when = DispatchTime.now() + delay
        DispatchQueue.main.asyncAfter(deadline: when, execute: { () -> Void in
            self.makeCall()
        })
    }

    final func setup() {

        let networkInfo = CTTelephonyNetworkInfo()
        let code = networkInfo.subscriberCellularProvider?.mobileCountryCode
        print("\(code)")

        self.observer = CXCallObserver()
        self.observer?.setDelegate(self, queue: nil)

        self.callCenter = CTCallCenter()
    }

    final func makeCall() {

        guard let url = URL(string: "telprompt://55555") else {
            print("illegal URL")
            return
        }

        guard UIApplication.shared.canOpenURL(url) else{
            print("cannot open url")
            return
        }

        // iso9.. UIApplication.shared.openURL(url)

        UIApplication.shared.open(url, options: [:], completionHandler: { (Bool) in

        })
    }

    public func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall){

        print("isOutgoing =  \(call.isOutgoing)")
        print("hasConnected =  \(call.hasConnected)")
        print("hasEnded = \(call.hasEnded)")
    }
}

答案 3 :(得分:0)

这些是州名,而不是通知名称。您需要设置callEventHandler并检查其中的状态。