盒子
盒子
文章目录
  1. 应用场景:
  2. 解决方案(Android & IOS)
  3. H5中使用第三方API,比如百度的导航

HTML与Android、IOS的JS调用

前言

近期研究了H5界面与移动端(Android,IOS)的交互方案,记录一下以飨众友。学习小组QQ群: 193765960

本篇重点介绍H5调用移动端接口的通用方案,其他方案或者移动端调用H5接口的方法请自行研究。

版权归作者所有,如有转发,请注明文章出处:https://xiaodanchen.github.io/archives/

应用场景:

  • 移动端使用H5自带的标题栏,通过点击H5标题栏返回按钮回退或者跳转到移动端的某个原生界面。
  • 点击H5的电话号码,本地拨打电话

    解决方案(Android & IOS)

    1,定义接口
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class AndroidJsInterface {
    private Context mContext;
    public AndroidJsInterface(Context activity) {
    mContext = activity;
    }
    @JavascriptInterface//系统sdk 版本在v4.2以上时,必须加这个注解(安全性)
    public void fun1() {
    //点击H5的某个区域,实现APP的跳转(退出WebpageActivity)
    Intent intent = new Intent(mContext, MainActivity.class);
    mContext.startActivity(intent);
    }
    }

2,activity处理

  • 方式一:向webview注册js接口–存在安全隐患(适用于Android,IOS是否适用待确认)
    1
    2
    3
    4
    //Android端主要代码
    WebSettings webSettings = mWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    mWebView.addJavascriptInterface(new AndroidJsInterface(context), "android");//注意:这里一定要让别名的首字母为小写,因为JS端实际调用中会将别名处理成小写。
1
2
3
4
5
6
7
8
//JS端主要代码
jsFun = new function(){
if(app.isIOS()){
......
}else if(app.isAndroid()){
android.fun1();//别名首字母默认会被处理成小写,所以为了避免调用出错,最好统一采用小写字母
}
}
1
2
//Html端主要代码
......(通过href或者onclick调用js的jsFun)
  • 方式二:h5重定向URL,移动端捕获(Android,IOS均可)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    //Android端主要代码
    mWebView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (url.length() != 0 && url.startsWith("app:")) {//和后台约定好移动端js交互接口重定向URL的前缀:例如“app:”
    // 获得方法名
    String methodName = url.substring("app:".length());
    // 通过方法名反射获得方法
    Method method;
    Class<?> c;
    try {
    c = Class.forName("com.base.web.AndroidJsInterface");
    Constructor<?>[] constructors = c.getDeclaredConstructors();
    Constructor<?> constructor = null;
    for (int i = 0; i < constructors.length; i++) {
    constructor = constructors[i];
    if (constructor.getGenericParameterTypes().length == 0)
    break;
    }
    constructor.setAccessible(true);
    Object clazz = constructor.newInstance(context);
    method = clazz.getClass().getDeclaredMethod(methodName);
    // 执行该方法
    if(null != method){
    method.setAccessible(true);
    method.invoke(clazz);
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }else if(url.length() != 0 && url.startsWith("tel:")){
    //打电话:H5直接重定向href=“tel:13120003456”
    Intent intent = new Intent(Intent.ACTION_DIAL,
    Uri.parse(url));
    startActivity(intent);
    }else{
    view.loadUrl(url);
    }
    return true;
    }
    });
1
2
3
4
5
6
7
8
//JS端主要代码
jsFun1 = new function(){
window.location.href="app:fun1";//"app:"是和服务器约定好的前缀,fun1是移动端定义的名为fun1的js回调接口
}
jsFun2 = new function(){
window.location.href="app:fun2";
}
1
2
//Html端主要代码
......(通过href或者onclick调用js的jsFun*)

需要注意的几点:
1,采用方式一,一定要注意别名的首字母小写(是不是需要全部小写没有验证)
2,小米系列的手机可能对webview和Android的交互存在一些问题,如果发现交互怎么都不起作用,试试把APP卸载后重新安装(有缓存)。
3,使用方式二,一定要注意使用反射时,要调用反射类的构造函数实例化,否则会报告一堆的异常。

H5中使用第三方API,比如百度的导航

Android中需要做一些特别的设置才可以

1
2
//h5 调用第三方的API:百度导航
webSettings.setDomStorageEnabled(true);

扫描加群
好好学习,天天向上!