【问题标题】:Not able to make phone call无法拨打电话
【发布时间】:2014-06-25 18:21:54
【问题描述】:

我想打电话,我使用下面的代码。

- (void)callPhoneNumber:(NSString *)phoneNumber
{
    UIWebView * webView2 = [[UIWebView alloc] init];

    // Remove non-digits from phone number
    phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];

    // Make a call
    NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"tel:%@", phoneNumber]];
    [webView2 loadRequest:[NSURLRequest requestWithURL:url]];
    [self.view addSubview:webView2];
}

在拨打电话之前,我要求用户使用UIActionSheet 选择一个选项。当用户选择一个选项时,我会根据它拨打电话。

问题是如果我不显示UIActionSheet 并直接拨打电话,上面的代码可以正常工作。它会提示一个警报,要求用户确认拨打电话。但在显示UIActionSheet 后,如果我调用上述方法,则不会显示确认警报。

奇怪的是,在此之后,如果我从 Xcode 中停止应用程序,那么应用程序会按应有的方式放置离子背景。但我也在设备的主屏幕上看到了确认警报。它如何显示在设备的主屏幕而不是应用程序中?

以前有人遇到过吗?可能是什么原因?

编辑:我也试过下面的代码。但它有同样的问题。每当上面的 webview 代码有效时,下面的代码也有效。当它不起作用时也是如此。

NSString *phoneNumberURL = [NSString  stringWithFormat:@"telprompt:%@", phoneNumber];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumberURL]];

编辑:为操作表和委托添加代码。

我首先显示一个警报。在按下警报按钮时,我会显示操作表。并从操作表中选择选项我拨打电话。

# pragma mark - ALERT VIEW DELEGATE

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if(alertView.tag == MY_TAG)
    {
        // Ask to select option
        UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Select Option" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Option1", @"Option2", nil];
        actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
        [actionSheet showInView:self.view];   
    }
}


#pragma mark - UIActionSheet Methods

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    // If not pressed cancel button.i.e. selected one of the options
    if (buttonIndex != actionSheet.cancelButtonIndex)
    {
        // Place a call
        [self callPhoneNumber:@"1234567890"];
    }
}

【问题讨论】:

  • 你为什么要使用 webview?为什么不[[UIApplication sharedApplication] openURL:…]
  • @vikingosegundo 查看已编辑的问题。

标签: ios objective-c ios7 uiwebview telprompt


【解决方案1】:

如果您的号码中有任何空格,它将不起作用,因此需要将其删除,同样在使用tel:telprompt: 时,它需要是tel://telprompt://,请注意额外的//

如果您需要其他任何内容,我已经注释了我的代码并解释了每个步骤,我会提供更多。

- (void)callPhoneNumber:(NSString *)phoneNumber
{
    // If statement to check we actually have something
    if(phoneNumber) {
        // Remove any unwanted whitespace, if there is any whitespace it will not work
        phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:@" " withString:@""];
        // Create an NSURL instance of your number
        // Note the extra `//` in the string
        // Also note you can also use: `telprompt://` instead of `tel://`
        NSURL *urlPhoneNumber = [NSURL URLWithString:[NSString stringWithFormat:@"tel://%@", phoneNumber]];
        // Check to make sure we can open this because iPad and iPod will not respond to phone calls
        if([[UIApplication sharedApplication] canOpenURL:urlPhoneNumber]) {
            // If we can (So if iPhone really) make the call.
            [[UIApplication sharedApplication] openURL:urlPhoneNumber];
        }
    }
}

编辑额外注释

阅读有关 here 的 Apple 文档

我会注意到苹果文档说tel:telprompt: 应该可以工作,不需要额外的//,但我发现它仍然可以与额外的// 一起工作。这确实让我有点困惑,因为在技术上 tel:telprompt:URL Schemes 并且额外的 // 在“URL 方案”中是必需的。这是iPhone Development 101的一个很好的教程

Here 是一些附加信息

【讨论】:

    【解决方案2】:

    使用 OpenURL 通过 URL 拨打电话。

    - (void)callPhoneNumber:(NSString *)phoneNumber
    {
        // Remove non-digits from phone number
        phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];
    
        // Make a call
        NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"tel:%@", phoneNumber]];
        [[UIApplication sharedApplication] openURL:url];
    }
    

    【讨论】:

      【解决方案3】:

      不要使用 UIWebView,而是尝试以下操作:

      NSURL *phoneUrl = [NSURL URLWithString:[NSString  stringWithFormat:@"telprompt:%@",phoneNumber]];
      
      if ([[UIApplication sharedApplication] canOpenURL:phoneUrl]) {
          [[UIApplication sharedApplication] openURL:phoneUrl];
      }
      

      已编辑: 通过放置断点检查电话呼叫功能是否被调用。 如果没有调用该电话呼叫功能,则将操作表的按钮索引检查功能替换如下:

      - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
      {
          if (buttonIndex == 0)
          {
               //Code for cancel button
          }
          if (buttonIndex == 1)
          {
             //Code for calling phone call
             [self callPhoneNumber:@"1234567890"];
          }
      }
      

      编辑 2:

      现在这样说:

        - (void)checkCallAlert :(NSInteger)index
       {
          UIAlertView *checkCallAlert = [[UIAlertView alloc] initWithTitle:@"Check?" message:@"Are you sure you want to continue?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Call", nil];
          [checkCallAlert setTag:index];
          [checkCallAlert show];
      }
      
      - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
      {
          if (buttonIndex == 0)
          {
               //Code for cancel button
          }
          if (buttonIndex == 1)
          {
      
             [self checkCallAlert : buttonIndex];
      
      
          }
      
      }
      
      - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
      {
         if(alertView.tag == 1){
         //Destination 1 clicked
          //Code for calling phone call
             [self callPhoneNumber:@"1234567890"];
      }
      }
      

      这将是我的最终解决方案。

      【讨论】:

      • @Geek ,如果不是这种情况,那么 UIActionSheet 一定有问题,您能否展示一下您是如何实现 UIActionSheet 视图及其委托方法的。
      • @Geek,查看我编辑的 2:答案。我想这肯定会解决这个问题。
      • @Geek 很抱歉这个小故障,现在是最后一个了。alertviewdelegate 的这个实现应该可以工作。
      【解决方案4】:
      NSString * telephoneNumber;
      
      [[UIApplication sharedApplication] openURL:[NSURL URLWithString:telephoneNumber]];
      
      [telephoneNumber release];
      

      【讨论】:

        【解决方案5】:

        在完成当前更新循环后尝试使用以下而不是[self callPhoneNumber ... ] 来调用callPhoneNumber

        [self performSelector:@selector(callPhoneNumber:) withObject:@"1234567890" afterDelay:0];
        

        UIActionSheet 参考文档指出:

        在 iOS 4.0 及更高版本中,当应用程序移至后台时,操作表不会自动关闭

        因此,如果正在显示 actionSheet,则需要签入 applicationWillResignActive,并以编程方式将其关闭。

        【讨论】:

        • 但应用程序不在后台。那么为什么这很重要呢?
        【解决方案6】:

        尝试调用didDismissWithButtonIndex:,这样 UIActionSheet 已经被解除了,也许它正在阻塞某些东西。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-21
          • 2021-11-11
          相关资源
          最近更新 更多