版权声明:本文为博主原创文章,未经博主允许不得转载。

最近项目中有一个新的需求,大致是这样的:APP中通过WebView展示一个第三方的HTML5界面,用户可以在HTML5界面中调用Android摄像头进行二维码扫描,并将扫描结果显示在HTML5界面。这显然涉及到了Android原生与WebView之前的传值交互,由于之前对这一块不是很了解,所以特地写了一个小demo,方便自己以后使用,同时也分享给需要的人,先看一下demo的效果图吧。

我觉得主要有三个技术关键点:
1.Android 实现二维码扫描功能
2.Webview中点击事件拦截及跳转到原生二维码扫描界面
3.将扫描结果更新到Webview界面中

下面具体说明一下:
demo中显示在Webview中的HTML如下:

<body>    <script> //提供给Android调用的方法  function funFromjs(result){ document.getElementById("result").innerText= result; } script>      <a href='doScan' style='margin:30px;'>扫描二维码a>    <div id="result" style="margin:10px;">div>body>

其中funFromjs()方法是专门提供给Android原生调用的,将二维码扫描结构通过这个方法更新到Webview界面上。

再看看Android端是如何拦截HTML中的点击事件,然后调用原生二维码扫描的界面,并将扫描结果通过HTML中提供的js方法传给webview展示的。直接上代码:

package com.djj.webviewdemo;import android.Manifest;import android.content.Intent;import android.content.pm.PackageManager;import android.os.Build;import android.support.annotation.NonNull;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.KeyEvent;import android.view.View;import android.webkit.WebView;import android.webkit.WebViewClient;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    private final static int SCANNIN_GREQUEST_CODE = 1;    private WebView wvContent;    private Button btnPhoto;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //检查权限        checkPermission();        wvContent = (WebView) findViewById(R.id.wv_content);        // 设置WebView属性,能够执行Javascript脚本        wvContent.getSettings().setJavaScriptEnabled(true);        // 设置Web视图        wvContent.setWebViewClient(new MyWebViewClient());        String html ="扫描二维码";               html +="";// wvContent.loadDataWithBaseURL(null, html, "text/html", "utf-8", null);        wvContent.loadUrl("file:///android_asset/text.html");    }    // 监听 所有点击的链接,如果拦截到我们需要的,就跳转到相对应的页面。    private class MyWebViewClient extends WebViewClient {        @Override        public boolean shouldOverrideUrlLoading(WebView view, String url) {            if (url != null && url.contains("doScan")) {                Intent intent = new Intent();                intent.setClass(MainActivity.this, MipcaActivityCapture.class);                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);                startActivityForResult(intent, SCANNIN_GREQUEST_CODE);// finish();                return true;            }            return super.shouldOverrideUrlLoading(view, url);        }        @Override        public void onPageFinished(WebView view, String url) {            view.getSettings().setJavaScriptEnabled(true);            super.onPageFinished(view, url);        }    }    // 覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_BACK && wvContent.canGoBack()) {// webview.goBack();// 返回前一个页面            finish();            return true;        }        return super.onKeyDown(keyCode, event);    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        switch (requestCode) {            case SCANNIN_GREQUEST_CODE:                if(resultCode == RESULT_OK){                    //显示扫描到的内容                    String result="";                    result += "扫描结果:";                    result += data.getStringExtra("result").trim();// Toast.makeText(MainActivity.this,"扫描的结果:"+result,Toast.LENGTH_LONG).show();                    //更新webView内容                    wvContent.loadUrl("javascript:funFromjs('" + result + "')");                }                break;        }    }    private void checkPermission() {        if (Build.VERSION.SDK_INT >= 23) {            int checkCallPhonePermission = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA);            if(checkCallPhonePermission != PackageManager.PERMISSION_GRANTED){                ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CAMERA,Manifest.permission.VIBRATE},333);                return;            }else{            }        } else {        }    }    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);    }}

通过监听HTML中所有的点击事件,然后找出我们需要的那个点击事件,此demo中是监听“doScan”,如果用户点击了“二维码扫描”,则会跳转到原生的二维码扫描界面,并在onActivityResult方法中返回扫描的结果,并通过wvContent.loadUrl(“javascript:funFromjs(‘” + result + “’)”);调用js方法,并将结果展示到Webview中。

其中二维码扫描功能主要参照了这篇博客:
Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果

Webview点击事件拦截主要参照了这边博客:
Android中WebView点击事件的拦截跳转到原生的界面

非常感谢上面两篇博客的博主提供的技术支持,由于本人技术水平和写作能力有限,以上若有描述错误及表述不当之处,还望谅解!

最后附上该demo的整个项目源码,供大家参考。
demo源码链接

更多相关文章

  1. android下创建文件夹和修改其权限的方法
  2. Android 用户界面---XML布局
  3. 为Android的界面设计增加跳跃效果
  4. Android X86强制竖屏怎么办?安卓(Android)x86屏幕旋转成横屏解决
  5. android客户端和网站数据交互的实现(基于Http协议获取数据方法)
  6. 开启本地服务器,利用二维码进行通信[Demo]
  7. Qt on Android:创建可伸缩界面
  8. Andoid自动判断输入是电话,网址或者Email的方法----Linkify的应
  9. Android 二维码 生成和识别(附Demo源码)

随机推荐

  1. php switch判断一个数所在的范围
  2. PHP+MySQL+Zend+phhMyAdmin教程
  3. 电商网站项目总结(面向对象编程篇)
  4. ThinkPHP常用小知识
  5. php无wsdl webservice服务用法
  6. curl获取网页内容出现乱码或为空的解决方
  7. PHP: Join two separate mysql queries i
  8. 从PHP智能模板中剥离空白
  9. 如何在“”之前删除多个UTF-8 BOM序列?
  10. php吧字符串直接转换成数组处理