Skip to content

Commit

Permalink
feat(android): support background scanning
Browse files Browse the repository at this point in the history
  • Loading branch information
robingenz committed Jan 27, 2024
1 parent 333e669 commit 5531920
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 14 deletions.
7 changes: 7 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="https"
android:host="nfc-demo.capawesome.io"
android:pathPrefix="/home" />
</intent-filter>

</activity>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import {
TransceiveResult,
WriteOptions,
} from '@capawesome-team/capacitor-nfc';
import { Observable, Subject } from 'rxjs';
import { Observable, ReplaySubject, Subject } from 'rxjs';
import { PlatformService } from '../../platform/platform.service';

@Injectable({
providedIn: 'root',
})
export class CapacitorNfcService {
private readonly scannedTagSubject = new Subject<NfcTag>();
private readonly lastScannedTagSubject = new ReplaySubject<NfcTag>(1);
private readonly sessionCanceledSubject = new Subject<void>();
private readonly sessionErrorSubject = new Subject<string>();

Expand All @@ -24,19 +25,17 @@ export class CapacitorNfcService {
) {
Nfc.removeAllListeners().then(() => {
Nfc.addListener('nfcTagScanned', event => {
console.log('nfcTagScanned', { event });
this.ngZone.run(() => {
this.scannedTagSubject.next(event.nfcTag);
this.lastScannedTagSubject.next(event.nfcTag);
});
});
Nfc.addListener('scanSessionCanceled', () => {
console.log('scanSessionCanceled');
this.ngZone.run(() => {
this.sessionCanceledSubject.next();
});
});
Nfc.addListener('scanSessionError', event => {
console.log('scanSessionError', { event });
this.ngZone.run(() => {
this.sessionErrorSubject.next(event.message);
});
Expand All @@ -48,6 +47,10 @@ export class CapacitorNfcService {
return this.scannedTagSubject.asObservable();
}

public get lastScannedTag$(): Observable<NfcTag> {
return this.lastScannedTagSubject.asObservable();
}

public get sessionCanceled$(): Observable<void> {
return this.sessionCanceledSubject.asObservable();
}
Expand Down
4 changes: 4 additions & 0 deletions src/app/core/services/nfc/nfc/nfc.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export class NfcService {
return this.capacitorNfcService.scannedTag$;
}

public get lastScannedTag$(): Observable<NfcTag> {
return this.capacitorNfcService.lastScannedTag$;
}

public async startScanSession(): Promise<void> {
const isSupported = await this.isSupported();
if (!isSupported) {
Expand Down
12 changes: 9 additions & 3 deletions src/app/core/services/router/router.service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { NavigationExtras, Router } from '@angular/router';

@Injectable({
providedIn: 'root',
})
export class RouterService {
constructor(private readonly router: Router) {}

public navigateToReadPage(): Promise<boolean> {
return this.router.navigate(['read']);
public navigateToReadPage(options?: {
showLastScannedTag?: boolean;
}): Promise<boolean> {
let extras: NavigationExtras = {};
if (options?.showLastScannedTag) {
extras.queryParams = { showLastScannedTag: 'true' };
}
return this.router.navigate(['read'], extras);
}

public navigateToWritePage(): Promise<boolean> {
Expand Down
34 changes: 31 additions & 3 deletions src/app/modules/home/pages/home/home.page.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,49 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { DialogService, PlatformService, RouterService } from '@app/core';
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import {
DialogService,
NfcService,
PlatformService,
RouterService,
} from '@app/core';
import { ViewDidEnter, ViewDidLeave } from '@ionic/angular';
import { skipWhile } from 'rxjs';

@Component({
selector: 'app-home',
templateUrl: './home.page.html',
styleUrls: ['./home.page.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HomePage {
export class HomePage implements OnInit, ViewDidEnter, ViewDidLeave {
public readonly isNativePlatform = this.platformService.isNativePlatform();

private viewDidLeave = false;

constructor(
private readonly routerService: RouterService,
private readonly platformService: PlatformService,
private readonly dialogService: DialogService,
private readonly nfcService: NfcService,
) {}

public ngOnInit(): void {
this.nfcService.lastScannedTag$
.pipe(skipWhile(() => this.viewDidLeave))
.subscribe(() => {
void this.routerService.navigateToReadPage({
showLastScannedTag: true,
});
});
}

public ionViewDidEnter(): void {
this.viewDidLeave = false;
}

public ionViewDidLeave(): void {
this.viewDidLeave = true;
}

public async navigateToReadPage(): Promise<void> {
await this.routerService.navigateToReadPage();
}
Expand Down
19 changes: 15 additions & 4 deletions src/app/modules/read/pages/read/read.page.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { NfcService, PlatformService } from '@app/core';
import { NfcTag } from '@capawesome-team/capacitor-nfc';
import { ViewDidEnter, ViewWillLeave } from '@ionic/angular';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { take } from 'rxjs';
import { Observable, take } from 'rxjs';

@UntilDestroy()
@Component({
Expand All @@ -12,12 +14,21 @@ import { take } from 'rxjs';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ReadPage implements ViewDidEnter, ViewWillLeave {
public scannedTag$ = this.nfcService.scannedTag$;
public scannedTag$: Observable<NfcTag>;

private showLastScannedTag = false;

constructor(
private readonly nfcService: NfcService,
private readonly platformService: PlatformService,
) {}
private readonly activatedRoute: ActivatedRoute,
) {
this.showLastScannedTag =
this.activatedRoute.snapshot.queryParams.showLastScannedTag === 'true';
this.scannedTag$ = this.showLastScannedTag
? this.nfcService.lastScannedTag$
: this.nfcService.scannedTag$;
}

public ionViewDidEnter(): void {
this.nfcService.startScanSession();
Expand All @@ -30,7 +41,7 @@ export class ReadPage implements ViewDidEnter, ViewWillLeave {

private subscribeToObservables(): void {
if (this.platformService.isIos()) {
this.nfcService.scannedTag$
this.scannedTag$
.pipe(take(1), untilDestroyed(this))
.subscribe(() => this.nfcService.stopScanSession());
}
Expand Down

0 comments on commit 5531920

Please sign in to comment.