這篇會介紹我是如何使用Ionic來實現「條碼掃描功能(Barcode Scanner)」,我使用在Capacitor-Community找到的【capacitor-community/barcode-sacnner】插件來做演示。
安裝Plugins
使用命令安裝Barcode Scanner套件並且同步專案
npm install @capacitor-community/barcode-scanner
Android
ionic cap sync android
Ios
ionic cap sync ios
Android設定
找到「Android\app\src\main\AndroidManifest.xml」在裡面加入以下設定
manifest
xmlns:tools="http://schemas.android.com/tools"
application
android:hardwareAccelerated="true"
permission
<uses-permission android:name="android.permission.CAMERA" />
SDK
<uses-sdk tools:overrideLibrary="com.google.zxing.client.android" />
Ios設定
Barcode Scanner設定
在Html和ts裡面加入以下程式碼,範例使用Rxjs來呈現,另外再注入Document和Renderer2來操作DOM元素,最後使用Ionic CLI編譯專案即可
global.scss
body.scanner-active {
--background: transparent;
--ion-background-color: transparent;
}
tab1.page.html
<ng-container *ngIf="(scanActive$ | async); else stopScanTemplate">
<ion-button expand="full" (click)="stopScanner()">停止掃描</ion-button>
</ng-container>
<ng-template #stopScanTemplate>
<ion-button expand="full" (click)="startScanner()">開始掃描</ion-button>
</ng-template>
tab1.page.ts
private scanActiveSubject$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
private destroy$ = new Subject();
private checkPermission$ = defer(() => from(BarcodeScanner.checkPermission({ force: true }))).pipe(
map(permissionResult => {
if (permissionResult.granted) {
return true;
}
return false;
})
);
private startActiveProgram$ = this.scanActiveSubject$.pipe(
switchMap(scanActiveResult => {
if (scanActiveResult) {
return this.checkPermission$.pipe(
switchMap(checkPermissionResult => {
if (checkPermissionResult) {
return defer(() => from(BarcodeScanner.prepare())).pipe(
tap(() => this.renderer.addClass(this.document.body, 'scanner-active')),
switchMap(() => defer(() => from(BarcodeScanner.startScan()))),
tap(barcodeScannerResult => {
if (barcodeScannerResult.hasContent) {
alert(barcodeScannerResult.content);
this.scanActiveSubject$.next(false);
}
})
);
}
return of(checkPermissionResult);
})
)
}
return defer(() => from(BarcodeScanner.stopScan())).pipe(
tap(() => this.renderer.removeClass(this.document.body, 'scanner-active')),
);
}),
takeUntil(this.destroy$)
);
constructor(@Inject(DOCUMENT) private document: Document, private renderer: Renderer2) {}
ngOnInit(): void {
this.startActiveProgram$.subscribe();
}
get scanActive$(): Observable<boolean> {
return this.scanActiveSubject$.asObservable();
}
ngOnDestroy(): void {
this.destroy$.next('');
this.destroy$.complete();
}
startScanner() {
this.scanActiveSubject$.next(true);
}
stopScanner() {
this.scanActiveSubject$.next(false);
}
💡BarcodeScanner.checkPermission是用來判斷和詢問相機的使用權限,這裡範例的關係就簡單寫個判斷呈現而已
💡BarcodeScanner.prepare則是官方宣稱可以提高性能(一點點XD)【點我前往參考】
💡Renderer2則是用來替換Body的class(原生相機會呈現在WebView底下因此需要把Body的背景色調整成透明的)
tab1.page.scss
.scan-box {
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 300px;
height: 300px;
border-radius: 10px;
background:
linear-gradient(to right, white 10px, transparent 10px) 0 0,
linear-gradient(to right, white 10px, transparent 10px) 0 100%,
linear-gradient(to left, white 10px, transparent 10px) 100% 0,
linear-gradient(to left, white 10px, transparent 10px) 100% 100%,
linear-gradient(to bottom, white 10px, transparent 10px) 0 0,
linear-gradient(to bottom, white 10px, transparent 10px) 100% 0,
linear-gradient(to top, white 10px, transparent 10px) 0 100%,
linear-gradient(to top, white 10px, transparent 10px) 100% 100%;
background-repeat: no-repeat;
background-size: 50px 50px;
box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.3);
}
tab1.page.html
<ng-container *ngIf="(scanActive$ | async); else stopScanTemplate">
<ion-button expand="full" (click)="stopScanner()">停止掃描</ion-button>
<div class="scan-box"></div>
</ng-container>
<ng-template #stopScanTemplate>
<ion-button expand="full" (click)="startScanner()">開始掃描</ion-button>
</ng-template>
0 Comments
張貼留言