nativescript-barcodescanner
eddyverbruggen 编写 | v4.1.2
使用 NativeScript 应用扫描 QR 码/条形码。
npm i --save nativescript-barcodescanner

NativeScript BarcodeScanner

Build Status NPM version Downloads Twitter Follow

💡 插件版本 4.0.0+ 与 NativeScript 7+ 兼容。如果您需要针对较旧的 NativeScript 版本,请继续使用插件版本 3.4.2。

⚠️ 从 4.1.0+ 版本开始,您可以在 iOS 上再次使用 beepOnScan(在较旧的 4.x 版本中会导致崩溃)。

想要快速演示吗?

请注意,仅在真实设备上运行此操作才有意义。

git clone https://github.com/EddyVerbruggen/nativescript-barcodescanner barcodedemo
cd barcodedemo/src

全屏,编程方式(iOS 和 Android)

npm run demo.android (or demo.ios / demo.ios.device)

嵌入式(仅限 iOS)

npm run demo.ios

支持的条码类型

iOS 和 Android

  • CODE_39
  • CODE_93
  • CODE_128
  • DATA_MATRIX
  • EAN_8
  • EAN_13
  • ITF(也称为 ITF14)
  • PDF_417(仅在 Android 上,通过 formats 显式传递时可用)
  • QR_CODE
  • UPC_A
  • UPC_E

仅限 Android

  • CODABAR
  • MAXICODE
  • RSS_14

仅限 iOS

  • AZTEC
  • CODE_39_MOD_43
  • INTERLEAVED_2_OF_5

关于 UPC_AEAN_13 的说明

当指定(或同时指定)这两个时,都可以返回。您可以通过检查结果对象的 format 属性来检查实际类型。有关详细信息,请参阅 #176

安装

从命令提示符进入您的应用程序根目录并执行

tns plugin add nativescript-barcodescanner

在 iOS 中嵌入扫描仪

如果您还需要在 Android 中嵌入扫描仪,请考虑使用我添加到 NativeScript Firebase 插件的 ML Kit 功能 的条码扫描功能!

如您所见,您可以按任何方式对视图进行样式设置,甚至可以将其与图像或按钮叠加。要重新创建上面的布局,请查看 演示应用程序中的这些行

💡 小贴士:如果您没有销毁嵌入扫描仪的组件/页面(而是显示模态或导航“向前”),则可以“暂停”扫描仪(自插件版本 3.4.0 起可用)。当适用时,只需将 pause 属性设置为 true 即可。

XML

<Page xmlns="http://schemas.nativescript.org/tns.xsd" xmlns:Barcode="nativescript-barcodescanner">

以下是一个示例标签,显示所有当前支持的选项。属性的默认值与 scan 函数相同。

<iOS>
<Barcode:BarcodeScannerView
class="scanner-round"
formats="QR_CODE, EAN_13"
beepOnScan="true"
reportDuplicates="true"
preferFrontCamera="false"
pause="{{ pause }}"
scanResult="{{ onScanResult }}" />

</iOS>

在 Angular 中嵌入

组件/模块

import { registerElement } from "nativescript-angular/element-registry";
registerElement("BarcodeScanner", () => require("nativescript-barcodescanner").BarcodeScannerView);

视图

<BarcodeScanner
class="scanner-round"
formats="QR_CODE, EAN_13"
beepOnScan="true"
reportDuplicates="true"
preferFrontCamera="false"
[pause]="pause"
(scanResult)="onScanResult($event)">

</BarcodeScanner>

在 Vue 中嵌入

main.ts

Vue.registerElement('BarcodeScanner', () => require('nativescript-barcodescanner').BarcodeScannerView)

视图

<BarcodeScanner
row="1"
height="300"
formats="QR_CODE, EAN_13, UPC_A"
beepOnScan="true"
reportDuplicates="true"
preferFrontCamera="false"
:pause="pause"
@scanResult="onScanResult"
v-if="isIOS">

</BarcodeScanner>

有关详细信息,请参阅“demo-vue”。

iOS 运行时权限原因

您可能之前已经看到过这样的权限提示(此插件也将自动触发一个提示)

iOS 10+ 不仅需要此提示,还需要一个 原因。在这种情况下是“我们想使用相机 ..”。

您可以通过在 app/App_Resources/ios/Info.plist 中添加类似的内容来提供访问摄像头的自定义原因

  <key>NSCameraUsageDescription</key>
<string>My reason justifying fooling around with your camera</string>

为了避免在忘记提供原因的情况下崩溃您的应用程序,此插件在构建过程中将向 .plist 添加一个空的理由。此值将被您指定的任何内容覆盖。

用法

提示:在扫描过程中,您可以使用音量加减按钮切换手电筒。

函数:scan(单次模式)

TypeScript

  import { BarcodeScanner } from "nativescript-barcodescanner";
let barcodescanner = new BarcodeScanner();

barcodescanner.scan({
formats: "QR_CODE, EAN_13",
cancelLabel: "EXIT. Also, try the volume buttons!", // iOS only, default 'Close'
cancelLabelBackgroundColor: "#333333", // iOS only, default '#000000' (black)
message: "Use the volume buttons for extra light", // Android only, default is 'Place a barcode inside the viewfinder rectangle to scan it.'
showFlipCameraButton: true, // default false
preferFrontCamera: false, // default false
showTorchButton: true, // default false
beepOnScan: true, // Play or Suppress beep on scan (default true)
fullScreen: true, // Currently only used on iOS; with iOS 13 modals are no longer shown fullScreen by default, which may be actually preferred. But to use the old fullScreen appearance, set this to 'true'. Default 'false'.
torchOn: false, // launch with the flashlight on (default false)
closeCallback: () => { console.log("Scanner closed")}, // invoked when the scanner was closed (success or abort)
resultDisplayDuration: 500, // Android only, default 1500 (ms), set to 0 to disable echoing the scanned text
orientation: orientation, // Android only, default undefined (sensor-driven orientation), other options: portrait|landscape
openSettingsIfPermissionWasPreviouslyDenied: true, // On iOS you can send the user to the settings app if access was previously denied
presentInRootViewController: true // iOS-only; If you're sure you're not presenting the (non embedded) scanner in a modal, or are experiencing issues with fi. the navigationbar, set this to 'true' and see if it works better for your app (default false).
}).then((result) => {
// Note that this Promise is never invoked when a 'continuousScanCallback' function is provided
alert({
title: "Scan result",
message: "Format: " + result.format + ",\nValue: " + result.text,
okButtonText: "OK"
});
}, (errorMessage) => {
console.log("No scan. " + errorMessage);
}
);

请注意,上面的 result.format 是以下链接中的其中之一:这些

JavaScript

  var BarcodeScanner = require("nativescript-barcodescanner").BarcodeScanner;
var barcodescanner = new BarcodeScanner();

barcodescanner.scan({
formats: "QR_CODE,PDF_417", // Pass in of you want to restrict scanning to certain types
cancelLabel: "EXIT. Also, try the volume buttons!", // iOS only, default 'Close'
cancelLabelBackgroundColor: "#333333", // iOS only, default '#000000' (black)
message: "Use the volume buttons for extra light", // Android only, default is 'Place a barcode inside the viewfinder rectangle to scan it.'
showFlipCameraButton: true, // default false
preferFrontCamera: false, // default false
showTorchButton: true, // default false
beepOnScan: true, // Play or Suppress beep on scan (default true)
fullScreen: true, // Currently only used on iOS; with iOS 13 modals are no longer shown fullScreen by default, which may be actually preferred. But to use the old fullScreen appearance, set this to 'true'. Default 'false'.
torchOn: false, // launch with the flashlight on (default false)
closeCallback: function () { console.log("Scanner closed"); }, // invoked when the scanner was closed (success or abort)
resultDisplayDuration: 500, // Android only, default 1500 (ms), set to 0 to disable echoing the scanned text
orientation: "landscape", // Android only, optionally lock the orientation to either "portrait" or "landscape"
openSettingsIfPermissionWasPreviouslyDenied: true // On iOS you can send the user to the settings app if access was previously denied
}).then(
function(result) {
console.log("Scan format: " + result.format);
console.log("Scan text: " + result.text);
},
function(error) {
console.log("No scan: " + error);
}
);

函数:scan(批量/连续模式)

在此模式下,扫描仪将连续将扫描到的代码报告回您的代码,但只有在用户要求它这样做,或者您通过程序调用 stop 时才会停止。

插件会为您处理重复项,所以请不用担心检查这些项;在同一扫描会话内的每个结果都是唯一的,除非您将 reportDuplicates 设置为 true

以下是一个扫描3个唯一QR码然后程序性地停止扫描的示例。您会注意到Promise将不再接收结果,因为可能有多个结果

JavaScript

  var count = 0;
barcodescanner.scan({
formats: "QR_CODE",
// this callback will be invoked for every unique scan in realtime!
continuousScanCallback: function (result) {
count++;
console.log(result.format + ": " + result.text + " (count: " + count + ")");
if (count === 3) {
barcodescanner.stop();
}
},
closeCallback: function () { console.log("Scanner closed"); }, // invoked when the scanner was closed
reportDuplicates: false // which is the default
}).then(
function() {
console.log("We're now reporting scan results in 'continuousScanCallback'");
},
function(error) {
console.log("No scan: " + error);
}
);

函数:available

请注意,iOS实现目前始终返回 true,而在Android上,我们实际上会检查摄像头是否可用。

JavaScript

  var barcodescanner = require("nativescript-barcodescanner");

barcodescanner.available().then(
function(avail) {
console.log("Available? " + avail);
}
);

函数:hasCameraPermission / requestCameraPermission

在针对API级别23+的目标上,您需要在Android 6+上请求使用摄像头的权限。即使 uses-permission 标签在 AndroidManifest.xml 中存在,也需要这样做。

在iOS 10+上也有类似的情况。

从版本1.5.0开始,您可以允许插件为您处理此问题(如果需要,当扫描仪启动时将显示提示),但如果有某种原因您想自己处理权限,则可以使用这些函数。

JavaScript

  barcodescanner.hasCameraPermission().then(
function(granted) {
// if this is 'false' you probably want to call 'requestCameraPermission' now
console.log("Has Camera Permission? " + result);
}
);

// if no permission was granted previously this wil open a user consent screen
barcodescanner.requestCameraPermission().then(
function() {
console.log("Camera permission requested");
}
);

nativescript-angular 的使用

您可能以前在组件构造函数中注入了 BarcodeScanner 类,但请不要再这样做,因为在发布构建中您可能会遇到崩溃。

所以,而不是

// my-component.ts
import { Component, Inject } from '@angular/core';
import { BarcodeScanner } from 'nativescript-barcodescanner';

@Component({ ... })
export class MyComponent {
constructor(private barcodeScanner: BarcodeScanner) {
}

//use the barcodescanner wherever you need it. See general usage above.
scanBarcode() {
this.barcodeScanner.scan({ ... });
}
}

只需这样做

// my-component.ts
import { Component, Inject } from '@angular/core';
import { BarcodeScanner } from 'nativescript-barcodescanner';

@Component({ ... })
//use the barcodescanner wherever you need it. See general usage above.
scanBarcode() {
new BarcodeScanner().scan({ ... });
}
}

Webpack使用

如果您在Webpack运行时遇到错误,请打开 app.module.ts 并添加以下内容

import { BarcodeScanner } from "nativescript-barcodescanner";

export function createBarcodeScanner() {
return new BarcodeScanner();
}

providers: [
{ provide: BarcodeScanner, useFactory: (createBarcodeScanner) }
]

故障排除

如果您在Android上遇到 TypeError: Cannot read property 'zxing' of undefined 错误,请尝试以下步骤

  1. 从您的设备中删除应用程序
  2. 删除 platforms/android 文件夹。这将触发完整重建
  3. 运行 tns run android

依赖项/相关项目

此插件封装了Android和iOS的库,以便通过统一的API轻松访问条形码扫描仪。使用的库是

iOS

用于访问iOS API的自定义框架:https://github.com/EddyVerbruggen/ios-framework-barcodescanner

Android

ZXing: https://github.com/zxing/zxing/releases

由于将库作为直接依赖项使用并不实用,因此有一个库项目采用了ZXing的源代码,并编译成AAR以在Android上使用:https://github.com/EddyVerbruggen/barcodescanner-lib-aar/