技术标签: webview交互 h5 调android相机 H5调用安卓扫码 js 调用android扫码界面 android h5交互
1.通过 JavascriptInterface 方式扫码:
2.通url拦截方式扫码:
本人也是安卓新手,技术水平和文采能力有限,如果觉得有什么不妥的地方多多交流,
码字不易,转载说明出处:https://blog.csdn.net/pysunwen/article/details/81182582
首先就是项目里面需要集成Zxing扫码类库,可以在Github上集成官方的,也可以集成一些第三方的,第三方的比较简单,基本添加一行依赖,再初始化一下就可以了,很简单的,我这里是直接从项目里拷贝的类库,然后import Module 就可以了,这里不详细介绍
MainActivity
public class MainActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webview);
WebSettings settings = webView.getSettings();
//webView支持JS
settings.setJavaScriptEnabled(true);
webView.loadUrl("file:///android_asset/test.html");
webView.addJavascriptInterface(this,"android");//"android" 和h5要一致
setWebViewClient();
}
/**
* WebViewClient
*/
private void setWebViewClient() {
webView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//通过url拦截进行跳转
if (url != null && url.contains("doscan")){
Intent intent = new Intent(MainActivity.this,MyScanActivity.class);
startActivityForResult(intent, 666);
return true;
} else {
return false;
}
}
});
}
/**
* 注解方法 注意:doScan()一定要和h5里面的 android.doScan();方法一致
*/
@JavascriptInterface
public void doScan(){
Intent intent = new Intent(this,MyScanActivity.class);
startActivityForResult(intent,666);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode ==666 && null !=data){
String result = data.getStringExtra("result").trim();
//setScanResult(result) 方法就是调用H5里面的有参方法,注意方法名要一致
webView.loadUrl("javascript:setScanResult('" + result + "')");
}
}
}
这个主界面一打开就加载本地的test.html 文件,放在assers 目录下,H5里面就两个button ,和一个展示扫码结果的div标签,h5不懂也没关系,主要和前段约定好一些方法名和参数名就可以了
这种方法在4.2之前是有漏洞的,4.2之后为了补掉漏洞提供了
@JavascriptInterface
对象注解的方式建立Javascript对象和android原生对象的绑定,提供给JavaScript调用的方法必须带有@JavascriptInterface
。
这个方法就是暴露给JavaScript调用的,方法里面可以做一些操作:比如界面跳转,打开相机,拨打电话等等操作,比较注意的是一定记得家注解:@JavascriptInterface 然后注意的是WebView 调用webView.addJavascriptInterface(this,"android");方法如下:
webView.addJavascriptInterface(this,"android");
//java方法
@JavascriptInterface
public void doScan(){
Intent intent = new Intent(this,MyScanActivity.class);
startActivityForResult(intent,666);
}
//js方法
document.getElementById("butten1").onclick = function(){
android.doScan();
};
这个方法也比较简单,就是js点击触发一个事件,按钮指向一个地址,android在webView的setWebViewClient 里面重写
shouldOverrideUrlLoading 这个方法,事先和前端约定好关键字,如果地址里面包含"xxx" 就做一些本地的操作如下:
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//通过url拦截进行跳转
if (url != null && url.contains("doscan")){
Intent intent = new Intent(MainActivity.this,MyScanActivity.class);
startActivityForResult(intent, 666);
return true;
} else {
return false;
}
}
activity_main.xml 里面仅仅一个webview没啥好说的
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="dahuatech.bocai.com.webscan.MainActivity">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</WebView>
</RelativeLayout>
test.html 就两个button 和一个div标签用于展示结果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title></title>
</head>
<body>
<button id="butten1" style="width:200px;height:30px;margin-bottom: 20px;">通过注解方式调用安卓扫码</button>
<br/>
<a href="doscan:androidscan" ><input type="button" value="通过url拦截方式调用安卓扫码" style="width:200px;height:30px;"></a>
<br/>
<div id="text"></div>
</body>
<script type="text/javascript">
document.getElementById("butten1").onclick = function(){
<!--调用安卓原生方法-->
android.doScan();
};
var text = document.getElementById("text");
<!--安卓调用js有参方法,参数就是扫码结果-->
function setScanResult(result){
text.innerHTML = "扫码结果:"+result;
};
</script>
</html>
这里是我直接用的项目里面的库,当然你也可以直接用github封装好的库,比我自定义更方便,我这里直接用项目里现成的,就不用地方的了,下面是自定的扫码界面:
MyScanActivity
public class MyScanActivity extends CaptureActivity implements View.OnClickListener {
private ImageView ivOpenlight;
private LinearLayout ll_openlight;
private TextView tvOpenlight;
private boolean isLightOpen = true;
private ImageView ivBack;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_scan);
initEvent();
}
private void initEvent() {
ivBack = findViewById(R.id.iv_back);
ivOpenlight = findViewById(R.id.iv_openlight);
ll_openlight = findViewById(R.id.ll_openlight);
tvOpenlight = findViewById(R.id.tv_openlight);
ll_openlight.setOnClickListener(this);
ivBack.setOnClickListener(this);
}
@Override
public int layoutID() {
return R.layout.activity_my_scan;
}
@Override
public int surfaceViewID() {
return R.id.preview_view;
}
@Override
public int viewFindViewID() {
return R.id.viewfinder_view;
}
@Override
public void handleQrContent(String qrContent) {
String qrContent1 = qrContent;
ivOpenlight.setImageResource(R.mipmap.iv_light_closed);
tvOpenlight.setText("打开闪光灯");
isLightOpen = false;
super.onPause();
super.onDestroy();
super.onResume();
//扫码完成直接关闭当前Act,并把结果带过去
Intent intent = new Intent();
intent.putExtra("result", qrContent);
setResult(666, intent);
finish();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ll_openlight:
if (isLightOpen) {
if (cameraManager != null) {
ivOpenlight.setImageResource(R.mipmap.iv_light_closed);
tvOpenlight.setText("打开闪光灯");
cameraManager.offLight();
isLightOpen = false;
}
} else {
if (cameraManager != null) {
ivOpenlight.setImageResource(R.mipmap.iv_light_open);
tvOpenlight.setText("关闭闪光灯");
cameraManager.openLight();
isLightOpen = true;
}
}
break;
case R.id.iv_back:
finish();
break;
}
}
}
activity_myscan.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:wang="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_scan_h5"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="dahuatech.bocai.com.webscan.MyScanActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="@+id/preview_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#44000000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="扫一扫"
android:textColor="#ffffff"
android:textSize="16dp" />
<ImageView
android:id="@+id/iv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:src="@mipmap/pic_back" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="7"
android:gravity="center_horizontal"
android:orientation="vertical">
<com.wang.zxinglibrary.zXing.ViewfinderView
android:id="@+id/viewfinder_view"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
wang:angleLength="30dp"
wang:angleWidth="3dp"
wang:borderColor="@color/viewfinder_laser"
wang:hint=""
wang:hintPaddingTop="20dp"
wang:hintTextColor="@color/viewfinder_laser"
wang:hintTextSize="16sp"
wang:lineColor="@color/viewfinder_laser"
wang:mastColor="@color/viewfinder_laser" />
<LinearLayout
android:id="@+id/ll_openlight"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_marginTop="80dp"
android:background="@drawable/shape_scanh5">
<ImageView
android:paddingTop="3dp"
android:paddingBottom="3dp"
android:id="@+id/iv_openlight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/iv_light_open" />
<TextView
android:id="@+id/tv_openlight"
android:textSize="15dp"
android:paddingRight="15dp"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="关闭闪光灯"
android:textColor="#ffffff" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout>
</LinearLayout>
最后扫码结束后在onActivityResult方法里面调用webView.loadUrl("javascript:setScanResult('" + result + "')"); 把结果传回去了
文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib
文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang
文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些
文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器
文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距
文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器
文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn
文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios
文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql
文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...
文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120
文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数