近期在公司里參与了M3项目的开发,这个项目是使用HTML5开发的前端页面,在开发完成后,把项目地址写入Android、iOS的壳源代码里面,这样当应用被打开时候自己主动加载项目首页的URL。这样的做法对于用户来说,能够不用更新client,对于开发者来说,发现问题能够及时修复并更新,当然这也是B/S软件的长处。

在这个APP里面是有个拨号功能的,即点击界面上的电话小图标。能够直接通过手机拨出号码。

昨天同事丁丁告知我们这个APP有个BUG:在iOS里面拨号是没有问题的,可是在Android里面拨号时。会跳转到一个报错页面,类似于我们常见的404页面。无法实现拨号操作。我们的代码写的就是常见的tel:19212345678这样的。

我先讲一下我们的处理过程。

话说知之为知之。不知百度知。

所以在接到问题反馈后,我和同事明明先到百度上面搜索了一下,得到下面的结果:

在开源中国社区里面,有人建议在tel:后面加上双斜杠,类似tel://19212345678。我看到后立刻试了一下。不行。

在还有一个站点里面,有人建议在号码背后加上微信的官网地址。

类似tel:19212345678#weixin.qq.com。

我试了一下。还是老样子。

同事们聚在一起看了下,这段拨号的代码,在iOS上面是没有不论什么问题的,在微信的自带的浏览器里面是没有不论什么问题的。在Android手机自带的浏览器里面也是没有不论什么问题的。只有在打包成APP后訪问时出了问题!

后来同事华华给我发来一段代码。这个是在设置属性的时候重写shouldOverrideUrlLoading(WebView view, String url)这种方法。代码大意是,先推断传入的URL是不是以“tel:”开头的,假设是的,那就运行拨号操作;假设不是的。那就运行载入URL的操作。

我加进去试了一下,这下能够拨号了,可是不能高兴得太早。

还发现有个小问题,在拨号界面弹出的同一时候。那个类似404的错误界面还是会弹出来的,仅仅只是是被拨号的界面给遮挡住了。在通话完成挂机之后,那个错误界面又会出来。

今天丁丁又在催问这个拨号的问题了,我说我仅仅完毕了50%。还有个小问题还没解决。我还不惬意。

丁丁狡猾地说道:假设你今天不能解决,我也不惬意。

下午我把手头上的任务完毕了之后,就又開始研究这个奇葩的问题了。同事涛涛和华华也过来协助把脉。

同事涛涛在QQ上给我发的几个网址。我都点开一一试了下。

第一个是重写shouldOverrideUrlLoading(WebView view, String url)这种方法的。我回复说昨天已经试过了,能生效可是错误的界面还是会跟着弹出,体验不是非常好;

第二个是使用wati协议拨打电话。类似<a href="wtai://wp//mc;10086">拨打10086 </a>  。我回复说这个也试了,也是不起作用。

在同事华华的建议下,我把模拟器打开了,研究了下载整个拨号操作中的过程,花费了一些时间。

除了证明shouldOverrideUrlLoading这段代码的推断是对的。并没有什么其它的收获。

正当一筹莫展的时候,华华忽然想起了一年前和还有一位同事做的户型图展示功能。当时也是因为技术的局限性不得不使用js调用了Android的浏览器API,想看看能不能仿照那个问题的解决思路来解决这个拨号的问题。

这个WebView与js的交互是在jsp页面上定义个函数。

在Android壳源代码里面通过addJavascriptInterface(new JavascriptInterface(this),"jsInterface")来加入定义在jsp页面上定义的js接口。当然前提是要在壳源代码里面加入javascript交互支持。这个我已经加了。

在jsp里面,原来的<a href=”tel:XXX”>已经被改造成了个点击事件,详细的运行内容写在了js函数里面,从而避免了会被识别为个超链接而跳到一个404页面。

假设你觉得在这里就成功了,那也太easy了。

试了一下,点击图片后页面是一明一暗地闪烁,并没有运行拨号操作。

在Logcat看到,它事实上是没取到值的。是在取值的时候的时候出了问题?我把取值的${clientInfoVO.clientMobile}换成了<s:property value='clientMobile' />。居然就取到值了!

剩下的就是针对Android和iOS两种操作系统进行推断了。

感谢你有足够的耐心看完了上面这长长的流水账,假设你也遇到了和我类似的问题,那么你是幸运的。

以下我总结下WebView与js交互这类的问题的解决的方法:

1、在Android壳源代码里面加入权限声明:

<uses-permission android:name="android.permission.CALL_PHONE" />

须要声明打电话的权限并获取用户授权,不然不能通过Android壳去运行拨号操作。

假设你要是要发短信,那就是短信相关的权限啦,灵活处理;

2、在Android壳源代码里面启用JavaScript支持:

contentWebView.getSettings().setJavaScriptEnabled(true);

这样才干在壳源代码里面调用web页面的js函数

3、重写shouldOverrideUrlLoading(WebView view, String url)方法。对符合和不符合的两种URL进行推断,并运行不同的操作。演示样例代码例如以下:

public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("tel:")) {
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(url));
startActivity(intent);
return false;
} else {
view.loadUrl(url);
return true;
}
}

4、在web页面的链接改造成调用js函数,在函数里面运行类似window.js交互接口名.js函数名()

演示样例代码例如以下:

function exitSys(tel){
window.jsInterface.exitSys(tel);
}

5、在Android壳源代码里面相应加上js接口声明,比方我的名称是jsInterface,就是在第四步里面写的js交互接口名:

contentWebView.addJavascriptInterface(new JavascriptInterface(this),
"jsInterface");

6、在JavascriptInterface类里面声明与js相应的方法。这里我就写在Android里面运行拨打电话的代码。

比如:

public void exitSys(String number) {
Intent intent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+number));
startActivity(intent);
}

7、须要被调用的这个js里面假设须要动态传參,给这个js函数相关的參数值赋值最好用<s:property >。而不要用${}

否则可能会莫名其妙地取不到值(假设你在模拟器上測试,出现invalid MMI code的时候。也能够说明成功了。

由于模拟器是没有与通信运营商联通的,所以会报这个小错误,这时候建议你能够换用真机去測试);

8、在web页面加上浏览器推断:默认运行tel:,假设是iOS浏览器。就继续沿用之前万能的<a href=”tel:XXX”>,假设是Android浏览器,就运行自己定义的这个js函数,改变点击操作调用的URL。

<a href="tel:<s:property value='clientMobile' />" ><img src="<%=basePath %>crm/html5_new/myCustomer/images/phone.png"></a>
		$(document).ready(function(){
$("a").each(function(){
var u = navigator.userAgent;
if(u.indexOf('iPhone') > -1){ }
else {
if($(this).attr("href").length>4&&$(this).attr("href").indexOf("tel:")==0){
$(this).attr("href","javascript:exitSys('"+$(this).attr("href").replace("tel:","")+"')");
}
}
});
});

一处疑难杂症的术后总结:WebView和JavaScript之间的交互的更多相关文章

  1. 在android中实现webview与javascript之间的交互(转)

    参见“在android中实现webview与javascript之间的交互”

  2. webview与JavaScript之间的交互

    据说WebView的强大之处就是能和JavaScript进行交互调用. 参考博客:http://droidyue.com/blog/2014/09/20/interaction-between-jav ...

  3. WebView之javascript与android交互基础加强

    一.什么是js与android交互? 通俗一点就是使用js代码调用java代码,或者使用java代码调用js代码. 二.为什么要使用js与java代码交互? 1.可以做一些js网页做本身处理不了的事情 ...

  4. Android中webview跟JAVASCRIPT中的交互

    在android的应用程序中,可以直接调用webview中的javascript代码,而webview中的javascript代码,也可以去调用ANDROID应用程序(也就是JAVA部分的代码).下面 ...

  5. Android中webview和js之间的交互(转)

    http://www.cnblogs.com/leizhenzi/archive/2011/06/29/2093636.html 1.android中利用webview调用网页上的js代码. Andr ...

  6. Android WebView与JavaScript交互操作(Demo)

    应用场景: 为了使Android移动项目能够在较短的时间内完成开发,同时降低技术人员开发的成本投入,往往会采用Hybrid APP的开发模式.相关Hybrid APP(混合型应用)参看:http:// ...

  7. Android混合开发之WebView与Javascript交互

    前言: 最近公司的App为了加快开发效率选择了一部分功能采用H5开发,从目前市面的大部分App来讲,大致分成Native App.Web App.Hybrid App三种方式,个人觉得目前以Hybri ...

  8. WebView与JavaScript的交互

    目录: 一.整体思路 二.简单例子实现过程        1.打开项目的asset目录,创建新的文件test.html        2.补充html代码:添加供本地调用的js方法.调用本地方法的js ...

  9. webview调用javascript脚本无反应

    最近遇到一个问题:在html中有一段javascript脚本定义了一个方法,在使用webview.loadUrl("javascript:方法名()")时方法未执行,后来 查资料发 ...

随机推荐

  1. php平滑升级

    php平滑升级 1.既然是平滑升级,是不需要宕机,也不需要停止服务,是不存在关闭网站的说法 2.而升级最后的重启,重启的是PHP加载的配置文件,不影响你当前运行的网站 3.php-fpm是属于Fast ...

  2. hbase-0.94安装方法具体解释

    先决条件:     1)java环境,须要安装java1.6以上版本号     2)hadoop环境.因为HBase架构是基于其它文件存储系统的,因此在分布式模式下安装Hadoop是必须的,可是,假设 ...

  3. CentOS6.X下安装配置独立SVN服务器Subversion server

    Subversion(简称SVN,svn),一个开放源码的版本号控制系统.相较于RCS.CVS,它採用了分支管理系统,它的设计目标就是代替CVS.互联网上非常多版本号控***务已从CVS转移到Subv ...

  4. Timus 2005. Taxi for Programmers 题解

    The clock shows 11:30 PM. The sports programmers of the institute of maths and computer science have ...

  5. oracle最大连接数相关

    1.连接数据库 sqlplus / as sysdba 2.查看当前数据库连接数 select count(*) fromv$process; 3.查看当前数据库允许的最大连接数 select val ...

  6. 算法笔记_206:第五届蓝桥杯软件类决赛真题(Java语言A组)

    目录 1 海盗分金币 2 六角幻方 3 格子放鸡蛋 4 排列序数 5 幂一矩阵 6 供水设施    前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 海盗分金币 有5个海盗,相约进行一次帆船比赛. 比 ...

  7. C/C++程序内存分类

    程序中内存分类主要有下面几种: (1)栈存储区:主要存储局部变量.函数參数.函数返回值等. 栈内存由编译器在须要时自己主动分配,使用完后自己主动释放. (2)堆存储区:由new.malloc申请到的空 ...

  8. VB.NET服务器端令客户端下载PDF文件

    后台JS调用另一个控件,通过SESSION传递sDocumentPath 控件后台代码如下     Response.Clear() '如果不清,则有可能将页面源码作为文件内容的一部分传递给用户    ...

  9. Ubuntu的一些小技巧, 备忘

    Ubuntu下打开Scroll Lock键盘灯 一直以为灯坏了, 后来发现在win7下工作正常... 原来是跟系统有关系的. 在Ubuntu18.04下可以通过这个命令开关Scroll Lock灯 # ...

  10. Android倒计时CountDownTimer小记

    Android 超简便的倒计时实现:  CountDownTimer CountDownTimer由系统提供 查资料的时候 发现了CountDownTimer这个类之后 果断抛弃了曾经的倒计时做法 功 ...