iPhone桌面快捷电话的实现原理

本文介绍如何通过Safari的‘添加至主屏幕’功能,在iPhone上创建桌面快捷电话,实现一键拨号,主要涉及JavaScript、DataURISchema、Socket基本知识和Base64编码等技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

众所周知,Safari有一个“添加至主屏幕”的功能,其实就是在桌面添加了一个网页书签,本文讲述的是如何利用此功能实现桌面快捷电话。

 

一,主要用到的技术知识有以下几个(当然iPhone程序开发技能自然不可少)

1. JavaScript

2. Data URI Schema

3. Socket基本知识

4. Base64编码

 

二,基本原理

 程序内部创建一个简单的Web站点,通过这个站点调用Safari,站点将自定义的Html页面返回给Safari,此时利用Safari的“添加至主屏幕”功能,将自定义的Html制作成桌面书签,当用户点击桌面图标时,则运行自定义的Javascript脚本拨打电话。

 

三,实现方法

1. 创建一个简易的Web站点,代码如下:

[cpp:nogutter]  view plain copy
  1. - (void) startServer {  
  2.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
  3.       
  4.     int socketfd;  
  5.     socklen_t length;  
  6.     static struct sockaddr_in cli_addr;   
  7.     static struct sockaddr_in serv_addr;  
  8.       
  9.     // Set up socket  
  10.     if((listenfd = socket(AF_INET, SOCK_STREAM,0)) <0) {  
  11.         isServing = NO;  
  12.         return;  
  13.     }  
  14.       
  15.     // Serve to a random port  
  16.     serv_addr.sin_family = AF_INET;  
  17.     serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);  
  18.     serv_addr.sin_port = 0;  
  19.       
  20.     // Bind  
  21.     if(bind(listenfd, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) <0) {  
  22.         isServing = NO;  
  23.         return;  
  24.     }  
  25.       
  26.     // Find out what port number was chosen.  
  27.     int namelen = sizeof(serv_addr);  
  28.     if (getsockname(listenfd, (struct sockaddr *)&serv_addr, (void *) &namelen) < 0) {  
  29.         close(listenfd);  
  30.         isServing = NO;  
  31.         return;  
  32.     }  
  33.     chosenPort = ntohs(serv_addr.sin_port);  
  34.       
  35.     // Listen  
  36.     if(listen(listenfd, 64) < 0) {  
  37.         isServing = NO;  
  38.         return;  
  39.     }   
  40.     // Respond to requests until the service shuts down  
  41.     while (isServing) {  
  42.         length = sizeof(cli_addr);  
  43.         if((socketfd = accept(listenfd, (struct sockaddr *)&cli_addr, &length)) < 0) {  
  44.             isServing = NO;  
  45.             return;  
  46.         }  
  47.         [self handleWebRequest:[NSNumber numberWithInt:socketfd]];  
  48.     }  
  49.       
  50.     [pool release];  
  51. }  
  52. - (void) handleWebRequest:(NSNumber *)fdNum {  
  53.     int fd = [fdNum intValue];  
  54.     NSLog(@"handleWebRequest: %@", fdNum);  
  55. }  
 

 

2. 制作Html页面模板,代码如下,请注意代码中$XXX$标识串,主要在程序中将其替换成实际内容

[xhtml:nogutter]  view plain copy
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. <meta content="yes" name="apple-mobile-web-app-capable" />  
  5. <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />  
  6. <link rel="apple-touch-icon-precomposed" href="$TOUCH_ICON_URL$" mce_href="$TOUCH_ICON_URL$" />  
  7. <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />  
  8. <mce:style type="text/css"><!--  
  9. body  
  10. {position:relative;  
  11. margin:0;  
  12. min-height:416px;  
  13. font-family:helvetica,sans-serif;  
  14. }  
  15. --></mce:style><style type="text/css" mce_bogus="1">body  
  16. {position:relative;  
  17. margin:0;  
  18. min-height:416px;  
  19. font-family:helvetica,sans-serif;  
  20. }</style>  
  21. <mce:script type="text/javascript"><!--  
  22. var timerInit = 0;  
  23. addEventListener("load", function() { timerInit = setTimeout(InitPage, 0.2); }, false);  
  24. function InitPage(){  
  25.     clearTimeout(timerInit);  
  26.     window.scrollTo(0,1);  
  27.     document.body.ontouchstart = function(e) {  
  28.         window.scrollTo(0,1);  
  29.         e.preventDefault();  
  30.     };  
  31.     document.body.ontouchmove = function(e) {  
  32.         e.preventDefault();  
  33.     };  
  34.     document.body.ontouched = function(e) {  
  35.         e.preventDefault();  
  36.     };  
  37.     if (window.navigator.standalone == true) {  
  38.         var lnk = document.getElementById("qbt");  
  39.         var evt = document.createEvent('MouseEvent');  
  40.         evt.initMouseEvent('click');  
  41.         lnk.dispatchEvent(evt);  
  42.     }  
  43.     else{  
  44.         ip = document.getElementById("ip");  
  45.         its = document.getElementById("it").style;  
  46.         ip.style.position = "absolute";  
  47.         ip.style.top = window.innerHeight - 320 + "px";  
  48.         ip.style.visibility = "visible";  
  49.         ip.innerHTML = '<img src="$INSTRUCTION_IMG_URL$" mce_src="$INSTRUCTION_IMG_URL$" width="320" height="320"/>';  
  50.         its.position = "absolute";  
  51.         its.top = window.innerHeight - 114 + "px";  
  52.         its.left = 112 + "px";  
  53.         its.visibility = "visible";  
  54.     }  
  55. }  
  56. // --></mce:script>  
  57. <title>$TITLE$</title></head>  
  58. <body bgcolor="#ffffff"><a href="$URL$" mce_href="$URL$" id="qbt" style="display: none;" mce_style="display: none;"> </a>  
  59. <div id="ip" style="visibility:hidden;z-index:1;" mce_style="visibility:hidden;z-index:1;"></div>  
  60. <div id="it" style="font-size:14px;color:#000055;visibility:hidden;z-index:2;" mce_style="font-size:14px;color:#000055;visibility:hidden;z-index:2;">$INSTRUCTIONTXT$</div>  
  61. </body></html>  
 

 

3. 程序调用Safari

  (1) 使用[[UIApplication sharedApplication]openURL:]方法,url地址为自定义的web站点,如http://localhost:端口号。

      (2) 在Web站点中的handleWebRequest方法中,将自定义的html内容发送给safari

 

 

4. 程序在info.plist中注册自定义schema,此处主要解决浏览器拨打时会弹出确认对话框,所以先打开我们的程序,通过程序去拨打电话,代码如下:

[cpp:nogutter]  view plain copy
  1. - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {  
  2.     if ([[url scheme] isEqualToString:@"quickdial"]) {  
  3.         NSString *hostName = [url host];  
  4.         if ([hostName isEqualToString:@"tel"]) {  
  5.             NSString *phoneNo = [url query];  
  6.             [[UIApplication sharedApplication]openURL:[NSURL URLWithString:[NSString stringWithFormat:@"tel://%@", phoneNo]]];  
  7.         }  
  8.     }  
  9.     return NO;  
  10. }  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值