Android webView与java代码互调API 16+

来源:互联网 发布:联通云数据公司 编辑:程序博客网 时间:2024/06/04 17:54

使用javascript调用android代码

1.使用webview对象的addJavascriptInterface方法

2.addJavascriptInterface方法有两个参数,第一个参数就是我们一般会实现一个自己的类,类里面提供我们要提供给javascript访问的方法;第二个参数是访问我们在obj中声明的方法时候所用到的js对象,调用模式为window.interfaceName.方法名()或者是javascript: interfaceName.方法名() ;,如myWebView.addJavascriptInterface(new JavaScriptinterface(this), "android");

3.编写JavaScriptinterface类,如有一个函数名为showToast()的方法

4.在html中调用时的形式:javascript:android.showToast()。
附上一个小例子:


import android.content.Context;
import android.widget.Toast;

public class JavaScriptinterface {

    private Context mContext;

    /** Instantiate the interface and set the context */
    public JavaScriptinterface(Context c) {
        mContext = c;
    }

    /** Show a toast from the web page */
    public void showToast(String toast) {
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }
}



import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    private WebView myWebView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        myWebView = (WebView) findViewById(R.id.myWebView);
        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.addJavascriptInterface(new JavaScriptinterface(this),
                "android");
        String htmlText = getFromAssets("test.html");
        //把myWebView加载html
        myWebView.loadData(htmlText, "text/html", "utf-8");
        myWebView.setWebViewClient(new myWebViewClient());
        
    }

    // 此按键监听的是返回键,能够返回到上一个网页(通过网页的hostlistery)
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
            myWebView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    public String getFromAssets(String fileName) {
        try {
            InputStreamReader inputReader = new InputStreamReader(
                    getResources().getAssets().open(fileName));

            BufferedReader bufReader = new BufferedReader(inputReader);

            String line = "";
            String Result = "";

            while ((line = bufReader.readLine()) != null)
                Result += line;
            if (bufReader != null)
                bufReader.close();
            if (inputReader != null)
                inputReader.close();
            return Result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    class myWebViewClient extends WebViewClient {

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // TODO Auto-generated method stub
            view.loadUrl(url);
            return true;
        }

    }
}



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<script type="text/javascript">   
function showAndroidToast(toast) {       
    javascript:android.showToast(toast);   
     }
</script>

</head>
<body>
<input type="button" value="Say hello"
    onClick
="showAndroidToast('Hello Android!')" />
</body>
</html>



android的应用程序中,可以直接调用WebView 中的javascript 代码:


import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;

public class MainActivity02 extends Activity {
    /** Called when the activity is first created. */
    private WebView webView; 
      private Button button; 
      @Override 
      public void onCreate(Bundle savedInstanceState) { 
          super.onCreate(savedInstanceState); 
          setContentView(R.layout.main2); 
           
          webView=(WebView) this.findViewById(R.id.webView); 
          button=(Button) this.findViewById(R.id.button); 
           
          WebSettings setting=webView.getSettings(); 
          //设置支持javascript 
          setting.setJavaScriptEnabled(true); 
            //增加接口方法,让html页面调用   
          webView.addJavascriptInterface(new Object(){ 
              //这里我定义了一个拨打的方法   
              public void startPhone(String num){ 
                  Intent intent=new Intent(); 
                   
                  intent.setAction(Intent.ACTION_CALL); 
                  intent.setData(Uri.parse("tel:"+num)); 
                  startActivity(intent); 
              } 
          }, "demo"); 
          //加载页面 
          webView.loadUrl("file:///android_asset/test2.html"); 
           
          button.setOnClickListener(new OnClickListener() { 
               
              @Override 
              public void onClick(View v) { 
                  // TODO Auto-generated method stub 
                  webView.loadUrl("javascript:show('activity传过来的数据')"); //调用javascript函数
                  /*
                  * 通过webView.loadUrl("javascript:xxx")方式就可以调用当前网页中的名称
                  * 为xxx的javascript方法
                  
*/
              } 
          }); 
}

}  



<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Insert title here</title> 
<script type="text/javascript"> 
     function show(content){ 
         document.getElementById("countent").innerHTML= 
             "这是我的javascript调用. 这是:"+content; 
     } 
</script> 
</head> 
<body> 
  <table align="center"> 
     <tr><td>姓名</td><td>电话</td></tr> 
     <tr><td>小明</td><td><a  href="javascript:demo.startPhone(123)">123</a></td></tr> 
     <tr><td>小王</td><td><a  href="javascript:demo.startPhone(456)">456</a></td></tr> 
  </table> 
  <id="countent">html原始数据</p> 
</body> 
</html>


android addJavascriptInterface 不能生效 解决办法


常见的客户端与H5的混合编程是使用scheme+、JS bridge、provider等。

在做Android 与 H5 客户端交互时,发现一个很诡异的错误。在一个4.2.2的 三星S3上,Android Javascript Bridge 会出现回调出错。

所有挂在Bridge对象下的函数均无法找到。于是一点点排查问题到底出现在哪。

其他手机H5混合编程消息回调正常,本以为是因为是旅行V3.0是基于Fragment引起的,即fragment下不能使用。后来经过排查发现不是这个问题。

发现就是手上的一台S3不行,其他基本都可以进行消息回调。

排查了一大圈,发现在Android SDK Target API Level 16+的情况下,使用以往的方式进行Native 与 H5进行混合编程均无法搞定。

解决办法:

 

  1. 推荐使用较高的Target SDK去编译【4.0+】.

2. 在Javascript Bridge对象下的所有回调方法使用 @JavascriptInterface 进行注解声明

3. 需要 import android.webkit.JavascriptInterface;

使用4.0+版本的Target SDK时,需要注意对回调方法进行注解声明!这种坑 很难发现,使用类似的混合编程技术的团队请关注这点~

 

设备ROM版本

开发环境 Target SDK

不用注解,消息是否能生效

<4.0

>4.0

Ok

<4.0

<4.0

Ok

>4.0

>4.0

NO

<4.0

>4.0

OK

 

public class J2NBridgeManager {

 

@JavascriptInterface

public void startNativeService(String schemeUrl) {

// js回调为空 则直接返回

if (TextUtils .isEmpty(schemeUrl)) {

return;

}

 

final TripURL mServiceUrl = Utils.getURIByUrlWithDecoded(schemeUrl);

// 执行本地一个service ,异步处理完后,回调js

mHandler.post( new Runnable() {

@Override

public void run() {

doService(mServiceUrl);

}

});

}

}

参考文章:

如何建立通信: http://stackoverflow.com/questions/13063222/web-view-addjavascriptinterface-issue

解决问题说明: http://stackoverflow.com/questions/16353430/appview-addjavascriptinterface-doen-not-work-on-api-17

2.微信android 5.0+版本的消息分享,无法通过scheme唤起 第三方客户端

之前我们会通过provider 在微信webview中JS检查手机是否安装旅行客户端,然后通过下面的方式进行逻辑分发:

通过scheme唤醒第三方客户端,在<5.0版本前均可以通过window.location.href = 'taobaotravel://h5_homepage';的自定义的scheme去实现,但是微信5.0版本后,貌似是在微信的webview中进行了url过滤,对应非信任的url进行了屏蔽,所以导致不能发起scheme去唤醒客户端。

关于URL白名单这个东西,目前仅仅为猜测,如果谁有微信的那边的朋友【微信研发团队是在广州】,可以帮忙确认下。

如果确认是微信加了白名单,目前通过微信5.0+webview唤醒我们的第三方app将变成死路。。。。

如果能通过商业合作的方式也是可取的

 

if(isMac) { if(getAvailabled()) { $('J_btn').innerHTML = '旅行启动中…';   setTimeout(function() { if(window.location.href.match('promo-assit.php')) { window.location.href = 'taobaotravel://h5_homepage'; $('J_btn').innerHTML = '启动旅行客户端'; return;   window.location.href = 'taobaotravel://h5_webview?' + param; $('J_btn').innerHTML = '启动旅行客户端'; }, 1300); } else { // 跳活动页面 if(window.location.href.match('promo-assit.php')) { window.location.href = 'http://lv.taobao.com/'; } else { window.location.href = fixUrl(jmpurl); }

转载至:

http://www.cnblogs.com/lee0oo0/archive/2012/08/01/2617953.html

http://blog.sina.com.cn/s/blog_4e1e357d0101gju8.html

0 0
原创粉丝点击