cordova二维码扫码插件

image.png

插件原地址如下:
barcode-scanner-plugin

BarcodeScanner

  • src
    • android
      • com
      • LibraryProject
      • com.google.zxing.client.android.capture.jar
      • readme.md
        ...

主要目录如上。
集成说明。
当添加插件后,会将com.google.zxing.client.android.capture.jar文件拷贝到安卓项目的libs下,作为jar包使用。是zxing的打包,原文件就在LibraryProject中。

当你不进过修改直接使用该插件时,其扫码界面非常简陋。我们如何自定义扫码界面?

  • 修改原文件,在LibraryProject目录中。

有两个难点,一是如何修改,二是如何打包成jar。

打包jar

我们先看怎么打包。
该目录下,我们看到ant.properties这个文件和config.xml文件。
如果你熟悉安卓开发就知道ant这个工具是做什么的,我猜测可能是打包工具,于是搜索了下ant,果然是我想的那样。


如何使用ant?

  1. 下载ant的安装包,这里是地址,下完后解压缩。
  2. 配置环境变量(目的是使用ant命令),如何添加环境变量不多说,每个人的shell配置文件不同
vi ~/.zshrc
# ==> 添加下列代码(注意修改自己的路径)
# ant
export ANT_HOME=/Users/mrchen/Applications/apache-ant
export PATH=$PATH:$ANT_HOME/bin
  1. 打开新terminal窗口,ant -version,查看是否配置正确。

进入LibraryProject目录下,使用ant命令打包jar文件。

cd LibraryProject
ant ij-release

生成的jar文件在:LibraryProject/bin/classes.jar
将该文件重命名并覆盖com.google.zxing.client.android.capture.jar文件即可。

接下来将涉及源码的修改,当你知道怎么打包jar,源码修改就好办了。

图片变形的问题

源码修改主要是界面图像和扫描界面。文件集中在src/com/google/zxing/client/android中,其他文件都是核心文件,如果了解zxing项目就会知道,这个插件作者整理了下,将核心和安卓代码整合起来了。

主要做的改变是两个。

  1. 固定为竖屏
  2. 修改camera的分辨率

文件:CameraConfigurationManager.java
initFromCameraParameters() => 这个方法主要是初始化camera的参数

第一步: 修改始终为竖屏(默认是横屏),将下面的代码插入到
cameraResolution = findBestPreviewSizeValue(parameters, screenResolution);
之前,并将这一行改为
cameraResolution = findBestPreviewSizeValue(parameters, screenResolutionForCamera);

Point screenResolutionForCamera = new Point();
screenResolutionForCamera.x = screenResolution.x;
screenResolutionForCamera.y = screenResolution.y;
// preview size is always something like 480*320, other 320*480
if (screenResolution.x < screenResolution.y) {
  screenResolutionForCamera.x = screenResolution.y;
  screenResolutionForCamera.y = screenResolution.x;
}

第二步: 修改camera默认参数
在方法findBestPreviewSizeValue中,会根据屏幕分辨率和摄像头默认参数(比如支持的拍摄分辨率),进行计算得到合适的camera分辨率。

修改 MAX_PREVIEW_PIXELS 参数的默认值,该值是指定拍摄的分辨率,默认的720p。
private static final int MAX_PREVIEW_PIXELS = 1920 * 1080; // 最大支持1080p的图片

这里只需要在initFromCameraParameters 和 findBestPreviewSizeValue方法中修改即可。

扫码框尺寸和位置修改

代码位置
CameraManager.java
方法:Rect getFramingRect() => 获取扫码框尺寸位置参数, return rect(left, top, left, bottom);

这里非常简单,看下源码就懂了

修改扫码框边框和扫描线条

代码位置
ViewfinderView.java
void onDraw() => 使用的是canvas画的扫描框和激光线条。示例代码如下:

@Override
public void onDraw(Canvas canvas) {
    if (cameraManager == null) {
      return; // not ready yet, early draw before done configuring
    }
    Rect frame = cameraManager.getFramingRect();
    if (frame == null) {
      return;
    }
    int width = canvas.getWidth();
    int height = canvas.getHeight();

    // Draw the exterior (i.e. outside the framing rect) darkened
    paint.setColor(resultBitmap != null ? resultColor : maskColor);
    canvas.drawRect(0, 0, width, frame.top, paint);
    canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
    canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
    canvas.drawRect(0, frame.bottom + 1, width, height, paint);

    // change.cf
    paint.setColor(frameAngleColor);

    canvas.drawRect(frame.left, frame.top, frame.left + 60, frame.top + 20, paint);
    canvas.drawRect(frame.left, frame.top, frame.left + 20, frame.top + 60, paint);

    canvas.drawRect(frame.right - 60, frame.top, frame.right, frame.top + 20, paint);
    canvas.drawRect(frame.right - 20, frame.top, frame.right, frame.top + 60, paint);

    canvas.drawRect(frame.left, frame.bottom - 60, frame.left + 20, frame.bottom, paint);
    canvas.drawRect(frame.left, frame.bottom - 20, frame.left + 60, frame.bottom, paint);

    canvas.drawRect(frame.right - 20, frame.bottom - 60, frame.right, frame.bottom, paint);
    canvas.drawRect(frame.right - 60, frame.bottom - 20, frame.right, frame.bottom, paint);

    Log.i("ViewfinderView", "**** draw rect angle ****");

    // change.end

    if (resultBitmap != null) {
      // Draw the opaque result bitmap over the scanning rectangle
      paint.setAlpha(CURRENT_POINT_OPACITY);
      canvas.drawBitmap(resultBitmap, null, frame, paint);

    } else {

      // Draw a red "laser scanner" line through the middle to show decoding is active
      paint.setColor(laserColor);
      paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
      scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
      // int middle = frame.height() / 2 + frame.top;
      // canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);

      canvas.drawRect(frame.left + 2, frame.top + laserPosition - 4, frame.right + 2, frame.top + laserPosition + 4, paint);

      laserPosition += laserSpeed;
      if (laserPosition > frame.height()) {
        laserSpeed = -20;
        laserPosition = frame.height();
      }

      if (laserPosition < 0) {
        laserSpeed = 20;
        laserPosition = 0;
      }

      /*Rect previewFrame = cameraManager.getFramingRectInPreview();
      float scaleX = frame.width() / (float) previewFrame.width();
      float scaleY = frame.height() / (float) previewFrame.height();

      List<ResultPoint> currentPossible = possibleResultPoints;
      List<ResultPoint> currentLast = lastPossibleResultPoints;
      int frameLeft = frame.left;
      int frameTop = frame.top;
      if (currentPossible.isEmpty()) {
        lastPossibleResultPoints = null;
      } else {
        possibleResultPoints = new ArrayList<ResultPoint>(5);
        lastPossibleResultPoints = currentPossible;
        paint.setAlpha(CURRENT_POINT_OPACITY);
        paint.setColor(resultPointColor);
        synchronized (currentPossible) {
          for (ResultPoint point : currentPossible) {
            canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
              frameTop + (int) (point.getY() * scaleY),
              POINT_SIZE, paint);
          }
        }
      }
      if (currentLast != null) {
        paint.setAlpha(CURRENT_POINT_OPACITY / 2);
        paint.setColor(resultPointColor);
        synchronized (currentLast) {
          float radius = POINT_SIZE / 2.0f;
          for (ResultPoint point : currentLast) {
            canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
              frameTop + (int) (point.getY() * scaleY),
              radius, paint);
          }
        }
      }*/

      // Request another update at the animation interval, but only repaint the laser line,
      // not the entire viewfinder mask.
      postInvalidateDelayed(ANIMATION_DELAY,
        frame.left - POINT_SIZE,
        frame.top - POINT_SIZE,
        frame.right + POINT_SIZE,
        frame.bottom + POINT_SIZE);
    }
}

很简单,可以自己随便发挥画。注意上面代码我增加了几个变量。

private int laserPosition = 0;
private int laserSpeed = 20;
private int frameAngleColor = resources.getColor(fakeR.getId("color", "frame_angle"));

并且在res文件夹下的colors.xml中新增一条。

    <color name="frame_angle">#feee00</color>

说明

修改后的源代码地址 =>
百度云

使用方法,解压缩后,添加到cordova插件中

cordova plugin add <your_barcode_scanner_path>

$(function() {
  $('.scan-btn').click(function() {

   cordova.plugins.barcodeScanner.scan(
    function (result) {
      alert("We got a barcode\n" +
        "Result: " + result.text + "\n" +
        "Format: " + result.format + "\n" +
        "Cancelled: " + result.cancelled);
    },
    function (error) {
      alert("Scanning failed: " + error);
    },
    {
      preferFrontCamera : false, // iOS and Android
      showFlipCameraButton : false, // iOS and Android
      showTorchButton : false, // iOS and Android
      torchOn: false, // Android, launch with the torch switched on (if available)
      prompt : "Place a barcode inside the scan area", // Android
      resultDisplayDuration: 0, // Android, display scanned text for X ms. 0 suppresses it entirely, default 1500
      formats : "QR_CODE,PDF_417", // default: all but PDF_417 and RSS_EXPANDED
      orientation : "portrait", // Android only (portrait|landscape), default unset so it rotates with the device
      disableAnimations : true, // iOS
      disableSuccessBeep: false // iOS
    }
    );
 });
});

示例项目地址 =>
coding.cordova_test
项目比较小,测试用,不是很完整,ignore文件什么都没有配,所以插件所有文件都上传上去了的。

示例apk下载 =>
cordova_test.apk
可以试试哦😁

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,048评论 25 707
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,678评论 6 342
  • 2017年1月18日 今天回剧组去看了一眼,然后布布说我昨天下午没在他都觉得工作不顺了。哈哈哈哈,看来我也是不可或...
    一字记之曰沉阅读 141评论 0 0
  • 你给予我 是城墙给予城门 是深海给予孤岛 是暗夜给予繁星 是天地给予巨像 是草木给予诗歌 是众神给予朝圣 新雨给予...
    戒凉阅读 440评论 2 5
  • 第一轮评课上完了,感谢大家的厚爱,有背后曹老师和孩子们的支持,有现场评课老师给出的宝贵建议,方感要细细研磨,...
    如水的日记阅读 167评论 0 0