How to detect call incoming programmatically

懵懂的女人 提交于 2019-12-17 18:07:34

问题


I need my app to send a notification when there is a call (incoming call, connected, call ended) I registered my viewController with notification.

 [[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];

I also made a method to check call state

-(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");
        }
    };
}

But none of this works. Please help me.

Where is the mistake? Is there any code which tells how to use core telephony?


回答1:


use this

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");
       }
     };
  }



回答2:


In Swift 3 

Use 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)")
      }
  }
}



回答3:


for iOS 10 AND swift 3:

a) copy and paste in a new empty controller in a new project b) run it, asyncAfter will trigger a call... NOTE: works only on device.

// 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)")
    }
}



回答4:


These are the state names, not notification names. You need to setup callEventHandler and check the state there.



来源:https://stackoverflow.com/questions/23535355/how-to-detect-call-incoming-programmatically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!