您的位置:首页 > 移动开发

Android中Webview与原生界面交互及二维码扫描功能实现

2018-01-06 15:28 621 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。

最近项目中有一个新的需求,大致是这样的: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 ="<a href='doScan' style='margin:30px;'>扫描二维码</a>";
html +="<div></div>";
//        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);

4000
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源码链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息