一、前言

本文的内容有两个基础:ZXing.Net和ZXing.Net.Mobile

ZXing.Net:ZXing的C#实现,主要封装了各种二维码的编码、解码等跨平台的算法

ZXing.Net.Mobile:对ZXing.Net在xamarin的应用进行了封装,主要实现了摄像头扫描、扫描view、扫描activity、扫描Fragment等

          ZXing.Net.Mobile下载:xamarin组件市场 或者 github

二、效果图

       

三、基本实现

1、弹出新窗口进行扫描

public class MainFragment : Android.Support.V4.App.Fragment
{
MobileBarcodeScanner scanner; public override View OnCreateView(LayoutInflater inflater, ViewGroup p1, Bundle p2)
{
return inflater.Inflate(Resource.Layout.Main, null);
} public override void OnViewCreated(View view, Bundle savedInstanceState)
{
base.OnViewCreated(view, savedInstanceState); scanner = new MobileBarcodeScanner(this.Activity); this.View.FindViewById<Button>(Resource.Id.btnDefault).Click += btnDefault_Click;
this.View.FindViewById<Button>(Resource.Id.btnCustom).Click += btnCustom_Click;
} async void btnDefault_Click(object sender, EventArgs e)
{
//不使用自定义界面
scanner.UseCustomOverlay = false; //设置上下提示文字
scanner.TopText = "上面的文字";
scanner.BottomText = "下面的文字"; var result = await scanner.Scan(); HandleScanResult(result);
} async void btnCustom_Click(object sender, EventArgs e)
{
View zxingOverlay;
//使用自定义界面(可以给框内加个动画什么的,这个自由发挥)
scanner.UseCustomOverlay = true;
zxingOverlay = LayoutInflater.FromContext(this.Activity).Inflate(Resource.Layout.ZxingOverlay, null);
scanner.CustomOverlay = zxingOverlay; var result = await scanner.Scan(); HandleScanResult(result);
} void HandleScanResult(ZXing.Result result)
{
string msg = ""; if (result != null && !string.IsNullOrEmpty(result.Text))
msg = "扫描结果: " + result.Text;
else
msg = "扫描取消!"; this.Activity.RunOnUiThread(() =>
{
Toast.MakeText(this.Activity, msg, ToastLength.Short).Show();
});
}
}

btnDefault_Click中使用了默认的弹出扫描,可定制性差,只能修改上下的文字

btnCustom_Click中使用了自定义界面弹出扫描,其实就是给扫描界面上面覆盖一层自定义的布局

在HandleScanResult中进行扫描结果的处理,这里只是简单的Toast

2、Fragment中集成扫描

这里使用了ZXing.Net.Mobile库中已经封装好的ZXingScannerFragment,并使用了覆盖层进行界面自定义

public class ScannerFragment : Android.Support.V4.App.Fragment
{
ZXingScannerFragment scanFragment;
View zxingOverlay; public override View OnCreateView(LayoutInflater inflater, ViewGroup p1, Bundle p2)
{
return inflater.Inflate(Resource.Layout.Scanner, null);
} public override void OnViewCreated(View view, Bundle savedInstanceState)
{
base.OnViewCreated(view, savedInstanceState); zxingOverlay = LayoutInflater.FromContext(this.Activity).Inflate(Resource.Layout.ZxingOverlay, null); scanFragment = new ZXingScannerFragment(ScanResultCallback);
scanFragment.UseCustomView = true;
scanFragment.CustomOverlayView = zxingOverlay; this.Activity.SupportFragmentManager.BeginTransaction()
.Replace(Resource.Id.fragment_container, scanFragment)
.Commit();
} private void ScanResultCallback(ZXing.Result result)
{
if (result == null || string.IsNullOrEmpty(result.Text))
{
this.Activity.RunOnUiThread(() =>
{
Toast.MakeText(this.Activity, "扫描已取消!", ToastLength.Short).Show();
((HomeFragment)this.FragmentManager.Fragments[]).SetCurrentTab("Main");
});
return;
}
else
{
//扫描成功
this.Activity.RunOnUiThread(() =>
{
//震动
Vibrator vibrator = (Vibrator)Application.Context.GetSystemService(Context.VibratorService);
long[] pattern = { , , , };
vibrator.Vibrate(pattern, -); Console.WriteLine(result.Text); Toast.MakeText(this.Activity, result.Text, ToastLength.Short).Show();
((HomeFragment)this.FragmentManager.Fragments[]).SetCurrentTab("Main");
});
return;
}
}
}

初始化ZXingScannerFragment,为其传入一个Action<ZXing.Result>类型的ScanResultCallback回调,

在ScanResultCallback中进行扫描结果处理:震动、输出、Toast、切换Fragment等

四、连续扫描

现在基本能扫描了,不过现在有个需求:扫描后如果扫描结果不是手机号码则继续扫描。

OK,修改一下扫描完成后的回调处理

//此处加上二维码的格式要求,如果不符合要求,就继续扫描(我这里是判断是否是手机号码)
if (IsTelephone(result.Text))
{
Toast.MakeText(this.Activity, result.Text, ToastLength.Short).Show();
((HomeFragment)this.FragmentManager.Fragments[]).SetCurrentTab("Main");
}
else
{
Toast.MakeText(this.Activity, "扫描的二维码格式不正确!", ToastLength.Short).Show();
}
/// <summary>
/// 验证手机号码的格式
/// </summary>
public bool IsTelephone(string str_telephone)
{
return Regex.IsMatch(str_telephone, @"^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$");
}

本来以为这样就搞定了,没想到扫描结果不是手机号时,提示 "扫描的二维码格式不正确!"后便停止扫描了。

看来ZXing.Net.Mobile库只要扫描完成后,就会停止扫描(我想作者是为了防止重复扫描的问题吧)。

为了实现连续扫描就只能修改ZXing.Net.Mobile库了

下面只是“Fragment中集成扫描”中的实现,“弹出新窗口进行扫描”也有类似的问题,小伙伴们自己查看源码发挥吧,哈哈!

经过分析发现ZXingSurfaceView类中的OnPreviewFrame方法在扫描完成后,触发回调前,调用了ShutdownCamera ();

这便是停止扫描的罪魁祸首,OK,将其抹杀,这时是可以连续扫描了,不过即使扫描结果是手机号扫描还会继续,这样就有可能出现重复扫描的问题,

因此这种情况下,扫描结果符合要求后,需要手动“停止扫描”:ZXingScannerFragment.Shutdown()

//此处加上二维码的格式要求,如果不符合要求,就继续扫描(我这里是判断是否是手机号码)
if (IsTelephone(result.Text))
{
//主动关闭摄像头,防止重复扫描
scanFragment.Shutdown(); Toast.MakeText(this.Activity, result.Text, ToastLength.Short).Show();
((HomeFragment)this.FragmentManager.Fragments[]).SetCurrentTab("Main");
}
else
{
Toast.MakeText(this.Activity, "扫描的二维码格式不正确!", ToastLength.Short).Show();
}

源码下载

https://github.com/jordanqin/ZXing.Scanner

参考:

http://components.xamarin.com/view/zxing.net.mobile/

https://github.com/Redth/ZXing.Net.Mobile

如果你觉得文章对你有帮助,可以点击旁边的“推荐”按钮,这样会让更多需要的人有机会看到

Xamarin.Android-用ZXing实现二维码扫描以及连续扫描的更多相关文章

  1. 【转】Android手机客户端关于二维码扫描的源码--不错

    原文网址:https://github.com/SkillCollege/QrCodeScan QrCodeScan 这是Android手机客户端关于二维码扫描的源码,使用了高效的ZBar解码库,并修 ...

  2. Android利用zxing生成二维码

    感谢大佬:https://blog.csdn.net/mountain_hua/article/details/80646089 **gayhub上的zxing可用于生成二维码,识别二维码 gayhu ...

  3. Android之条形码、二维码扫描框架(非原创)

    文章大纲 一.条形码.二维码扫描框架介绍二.条形码.二维码的区别和组成结构介绍三.条形码.二维码扫描框架应用场景四.BGAQRCode-Android框架实战五.项目源码下载六.参考文章 一.条形码. ...

  4. Google zxing实现二维码扫描完美解决方案

    最近因项目需求,需要在App中集成二维码扫描的功能.网上找了很多资料,最后决定使用Google的zxing来实现.实现的过程遇到了很多的坑,也是因为这些坑在网上没有具体的解决方案,今天就把我的实现过程 ...

  5. Android 使用zxing生成二维码的方法

    public void createQRImage(String url) { try { // 判断URL合法性 if (url == null || "".equals(url ...

  6. (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例

    Android项目实战(二十八):使用Zxing实现二维码及优化实例 作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21我要评论 这篇文章主要介绍了Android项目 ...

  7. 基于zxing的二维码(网格)扫描

    基于zxing的二维码(网格)扫描 前言:对于二维码扫描我们使用的是开源框架Zxing或者Zbar,这里使用基于zxing的二维码扫描,类似支付宝网格扫描, 二维码原理介绍: 二维码是用某种特定的几何 ...

  8. XAMARIN ANDROID 二维码扫描示例

    现在二维码的应用越来越普及,二维码扫描也成为手机应用程序的必备功能了.本文将基于 Xamarin.Android 平台使用 ZXing.Net.Mobile  做一个简单的 Android 条码扫描示 ...

  9. Android—ZXing二维码扫描遇到的问题

    最近工作中需要开发带有二维码扫描功能的软件(基于开源项目ZXing),遇到的问题记录一下,也希望给大家带来帮助. 1.首先因为扫描要开摄像机所以加权限是一定的,不然后面什么都不能进行 <uses ...

随机推荐

  1. Windows2012R2备用域控搭建

    Windows2012R2备用域控搭建 前置操作 域控主域控的主dns:自己的ip,备dns:备域控的ip备域控的主dns:自己的ip,备dns:主域控的ip 客户端主dns:主域控的ip,备dns: ...

  2. nodejs进阶(1)—输出hello world

    下面将带领大家一步步学习nodejs,知道怎么使用nodejs搭建服务器,响应get/post请求,连接数据库等. 搭建服务器页面输出hello world var  http  =  require ...

  3. Android数据加密之SHA安全散列算法

    前言: 对于SHA安全散列算法,以前没怎么使用过,仅仅是停留在听说过的阶段,今天在看图片缓存框架Glide源码时发现其缓存的Key采用的不是MD5加密算法,而是SHA-256加密算法,这才勾起了我的好 ...

  4. .NET Core的日志[2]:将日志输出到控制台

    对于一个控制台应用,比如采用控制台应用作为宿主的ASP.NET Core应用,我们可以将记录的日志直接输出到控制台上.针对控制台的Logger是一个类型为ConsoleLogger的对象,Consol ...

  5. 算法与数据结构(十七) 基数排序(Swift 3.0版)

    前面几篇博客我们已经陆陆续续的为大家介绍了7种排序方式,今天博客的主题依然与排序算法相关.今天这篇博客就来聊聊基数排序,基数排序算法是不稳定的排序算法,在排序数字较小的情况下,基数排序算法的效率还是比 ...

  6. 【NLP】前戏:一起走进条件随机场(一)

    前戏:一起走进条件随机场 作者:白宁超 2016年8月2日13:59:46 [摘要]:条件随机场用于序列标注,数据分割等自然语言处理中,表现出很好的效果.在中文分词.中文人名识别和歧义消解等任务中都有 ...

  7. C++随笔:.NET CoreCLR之corleCLR核心探索之coreconsole(2)

    这篇文章是上篇的续集,本文将会继续介绍coreconsole.cpp里面的逻辑.也许大家会看一些CLR的书,我承认我没有看过,因为我觉得一个人,他再NB,那也是他自己的眼光,而且说句难听的,CLR也不 ...

  8. webpack学习总结

    前言 在还未接触webpack,就有几个疑问: 1. webpack本质上是什么? 2. 跟异步模块加载有关系吗? 3. 可否生成多个文件,一定是一个? 4. 被引用的文件有其他异步加载模块怎么办? ...

  9. BPM配置故事之案例10-获取外部数据

    老李:Hi,小明,我又来了 小明:--这次又怎么了. 老李:之前的物资管理方式太混乱了,这段时间我整理了采购物资清单,现在都录入到我们的ERP中了,以后申请物资改成从ERP数据选择吧.物资明细表我也做 ...

  10. 【从零开始学BPM,Day2】默认表单开发

    [课程主题]主题:5天,一起从零开始学习BPM[课程形式]1.为期5天的短任务学习2.每天观看一个视频,视频学习时间自由安排. [第二天课程] Step 1 软件下载:H3 BPM10.0全开放免费下 ...