Android webView与JavaScript的交互

本文介绍如何实现WebView上的JavaScript与Android应用之间的交互。通过创建一个JavaScript接口,允许JS调用Android的方法来读取SIM卡信息,并展示如何在HTML页面中调用该接口。

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

新人第一次发。。。

 

今天下午接到一个题目,要求是:WebView上面加载的Web页面,要和Android项目交互。也就是Web页面的Js要调用Android程序的一个方法。写一个供JavaScript调用的接口。

首先加载WebView:

import android.app.Activity;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.Menu;
import android.webkit.WebView;

public class MainActivity extends Activity {

    WebView webView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        readSIMCard();
        webView = (WebView) findViewById(R.id.web_view);

        webView.getSettings().setJavaScriptEnabled(true);

        webView.addJavascriptInterface(new AndroidBridge(this,readSIMCard()), "android");
        // webView添加JavaScript的接口   
        webView.loadUrl("file:///android_asset/form.html");

    }
 
    // 获取SIM卡上的信息    
    public  String readSIMCard() {
        TelephonyManager tm = (TelephonyManager)this.getSystemService(TELEPHONY_SERVICE);//取得相关系统服务
    StringBuffer sb = new StringBuffer();
    switch(tm.getSimState()){ //getSimState()取得sim的状态  有下面6中状态
            case TelephonyManager.SIM_STATE_ABSENT :sb.append("无卡");break; 
            case TelephonyManager.SIM_STATE_UNKNOWN :sb.append("未知状态");break;
            case TelephonyManager.SIM_STATE_NETWORK_LOCKED :sb.append("需要NetworkPIN解锁");break;
            case TelephonyManager.SIM_STATE_PIN_REQUIRED :sb.append("需要PIN解锁");break;
            case TelephonyManager.SIM_STATE_PUK_REQUIRED :sb.append("需要PUK解锁");break;
            case TelephonyManager.SIM_STATE_READY :sb.append("良好");break;
    }
    
    if(tm.getSimSerialNumber()!=null){
        sb.append("@" + tm.getLine1Number().toString());
    }else{
        sb.append("@无法取得手机号");                  // 大部分手机卡无法获取号码
    }
    if(tm.getSimSerialNumber()!=null){
        sb.append("@" + tm.getSubscriberId().toString());
    }else{
        sb.append("@无法取得imsi码号");
    }
    if(tm.getSimSerialNumber()!=null){
        sb.append("@" + tm.getDeviceId().toString());
    }else{
        sb.append("@无法取得imei号");
    }
    if(tm.getSimSerialNumber()!=null){
            sb.append("@" + tm.getSimSerialNumber().toString());
    }else{
            sb.append("@无法取得SIM卡号");
    }
    
    if(tm.getSimOperator().equals("")){
            sb.append("@无法取得供货商代码");
    }else{
            sb.append("@" + tm.getSimOperator().toString());
    }
    
    if(tm.getSimOperatorName().equals("")){
            sb.append("@无法取得供货商");
    }else{
            sb.append("@" + tm.getSimOperatorName().toString());
    }
    
    if(tm.getSimCountryIso().equals("")){
            sb.append("@无法取得国籍");
    }else{
            sb.append("@" + tm.getSimCountryIso().toString());
    }
    
    if (tm.getNetworkOperator().equals("")) {
            sb.append("@无法取得网络运营商");
    } else {
            sb.append("@" + tm.getNetworkOperator());
    }
    if (tm.getNetworkOperatorName().equals("")) {
            sb.append("@无法取得网络运营商名称");
    } else {
            sb.append("@" + tm.getNetworkOperatorName());
    }
    if (tm.getNetworkType() == 0) {
            sb.append("@无法取得网络类型");
    } else {
            sb.append("@" + tm.getNetworkType());
    }
    return sb.toString();
}

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

Android程序的JavaScript接口:

public class AndroidBridge {

    private static final String TAG = "AndroidBridge";
    private final Handler handler = new Handler();
    private Activity activity;
    private String simStr;

    public AndroidBridge(Activity activity,String str) {
        this.activity = activity;
        this.simStr = str;
    }

    public Activity getActivity() {
        return activity;
    }

    public void setActivity(Activity activity) {
        this.activity = activity;
    }

    public void submit(final String json) { // must be final
        handler.post(new Runnable() {
            public void run() {
                try {
                    JSONObject jsonObject = new JSONObject(json.toString());
                    JSONObject jsonUser = (JSONObject) jsonObject.get("user");

                    TextView firstName = (TextView) activity.findViewById(R.id.first_name);
                    TextView lastName = (TextView) activity.findViewById(R.id.last_name);

                    firstName.setText(jsonUser.getString("firstname"));
//                    lastName.setText(jsonUser.getString("lastname"));
                    lastName.setText(simStr);
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }
}


HTML页面调用Android接口

<html>

  <head>
    <script type="text/javascript">
      function prepareToSubmit(){

        var myJSONObject = {"user":
            {"firstname": document.getElementById('firstname').value, 
             "lastname": document.getElementById('lastname').value, }
        };

        window.android.submit(JSON.stringify(myJSONObject));
      }
    </script>
  </head>

  <body>
    <h2>Form</h2>

    <form>
    First name: <input type="text" name="firstname" id="firstname"/><br />
    Last name: <input type="text" name="lastname" id="lastname"/><br />

    <input type="button" onclick="prepareToSubmit();" value="submit">

    </form>
  </body>
</html>

js调用java的时候,如果设置了targetSdkVersion,当targetSdkVersion<17时没问题,targetSdkVersion>=17时不成功

 

如果您在编写HTML5应用,需要在JS代码中访问Java中的函数,则您会用到WebView的addJavascriptInterface()函数。因为安全问题,在Android4.2中(如果应用的android:targetSdkVersion数值为17+)JS只能访问带有 @JavascriptInterface注解的Java函数。
之前,任何Public的函数都可以在JS代码中访问,而Java对象继承关系会导致很多Public的函数都可以在JS中访问,其中一个重要的函数就是  getClass()。然后JS可以通过反射来访问其他一些内容。通过引入 @JavascriptInterface注解,则在JS中只能访问 @JavascriptInterface注解的函数。这样就可以增强安全性。
如果您的应用android:targetSdkVersion数值为17或者大于17记得添加 @JavascriptInterface 注解。

 

注意:配置<uses-permission android:name="android.permission.READ_PHONE_STATE"/>权限

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值