【问题标题】:How can I find out whether the user pressed the Call or the Cancel button when making a call from my app?从我的应用程序拨打电话时,如何确定用户是否按下了呼叫或取消按钮?
【发布时间】:2012-11-24 11:11:02
【问题描述】:

从我的应用程序发出调用后,我需要返回我的应用程序,所以我使用以下代码:

NSURL *url = [NSURL URLWithString:@"telprompt://123-4567-890"]; 
[[UIApplication  sharedApplication] openURL:url]; 

当用户按下一个按钮来执行此代码时,会显示一个带有 2 个按钮的警报,“呼叫”和“取消”。

如何知道用户是否按下了“呼叫”按钮?

【问题讨论】:

    标签: iphone objective-c nsurl uiapplication


    【解决方案1】:

    这是适用于 Swift 4.2iOS 10+ 解决方案,在 iOS 12 上进行了测试,可检测到取消和通话按钮。

    别忘了导入 CallKit 并让你的类符合 CXCallObserverDelegate

    let callObserver = CXCallObserver()
    
    var didDetectOutgoingCall = false
    
    func showCallAlert() {
        guard let url = URL(string: "tel:+36201234567"),
            UIApplication.shared.canOpenURL(url) else {
                return
        }
    
        callObserver.setDelegate(self, queue: nil)
    
        didDetectOutgoingCall = false
    
        //we only want to add the observer after the alert is displayed,
        //that's why we're using asyncAfter(deadline:)
        UIApplication.shared.open(url, options: [:]) { [weak self] success in
            if success {
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                    self?.addNotifObserver()
                }
            }
        }
    }
    
    func addNotifObserver() {
        let selector = #selector(appDidBecomeActive)
        let notifName = UIApplication.didBecomeActiveNotification
        NotificationCenter.default.addObserver(self, selector: selector, name: notifName, object: nil)
    }
    
    @objc func appDidBecomeActive() {
        //if callObserver(_:callChanged:) doesn't get called after a certain time,
        //the call dialog was not shown - so the Cancel button was pressed
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
            if !(self?.didDetectOutgoingCall ?? true) {
                print("Cancel button pressed")
            }
        }
    }
    
    func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
        if call.isOutgoing && !didDetectOutgoingCall {
            didDetectOutgoingCall = true
    
            print("Call button pressed")
        }
    }
    

    【讨论】:

    • 这是完美的答案。
    【解决方案2】:

    这并不完美,但您可以通过侦听 UIApplicationSuspendedNotification 来识别按下“呼叫”而不是“取消”(当有人按下“home”键时,您必须添加一些逻辑来忽略此事件,或者正在接听来电...可能是通过在显示电话号码的逻辑周围添加/删除观察者):

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(suspended:) name:@"UIApplicationSuspendedNotification" object:nil];
    
    -(void)suspended:(NSNotification *) notification
    {
        NSLog(@"Suspended");
    }
    

    【讨论】:

    • 正是我所需要的,除了你的通知似乎在 iOS6 使用中不再存在:UIApplicationDidEnterBackgroundNotification
    • @NicolasManzini:我试过 UIApplicationDidEnterBackgroundNotification,但似乎在 iOS8 中不起作用
    【解决方案3】:
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(suspended:) name:@"UIApplicationSuspendedNotification" object:nil];
    

    @J Saprio 的上述代码运行良好。在暂停应用程序NSNotificationCenter 之前,请致电UIApplicationSuspendedNotification。单击“调用”后,它将执行(suspended:) 方法。这里要注意的是,每次调用NSNotificationCenter 方法时,它都会调用(suspended:),增量为1。解决方案是删除NSNotificationCenter 的观察者。以下是它的sn-p。它将帮助您只执行一次以下方法。

    -(void)suspended:(NSNotification *) notification
    {
        NSLog(@"Suspended");
       [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIApplicationSuspendedNotification" object:nil];
    
    }
    

    【讨论】:

      【解决方案4】:

      根据 iOS 条款,这是不可能的。完成通话时无法重定向到应用程序。

      只有在越狱手机中才有可能。

      【讨论】:

      • 有可能,您使用 safari API,它可以帮助您返回您离开的地方。
      【解决方案5】:

      当应用程序执行上述代码时,它将退出当前应用程序并导航到调用 iPhone 的应用程序。因此,应用程序无法识别用户是否按下了呼叫或取消。希望对你有帮助。

      【讨论】:

        【解决方案6】:

        试试这个,我处理这个问题如下:

        -(void)viewDidLoad 中添加以下内容:

        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        
        [center addObserverForName:UIApplicationDidBecomeActiveNotification
                            object:nil
                             queue:[NSOperationQueue mainQueue]
                        usingBlock:^(NSNotification *note)
         {
             // use instance flag to know
             if (self.isBeginCallPhone)
             {
                 //do some thing
                 self.isBeginCallPhone = NO;
             }
         }];
        

        别忘了:

        - (void)dealloc{
            [[NSNotificationCenter defaultCenter]removeObserver:self];
          }
        

        【讨论】:

          猜你喜欢
          • 2019-01-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-04
          • 1970-01-01
          • 2017-11-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多