1、修改了以下代码,后台到前台已可以正常显示预览流。主要修改点:增加“自定义组件监听页面生命周期”方法,以及在页面关闭的生命周期中增加“停止释放预览流”的代码。2、具体代码如下,仅供参考:import { customScan, scanBarcode, scanCore } from '@kit.ScanKit'; import { UIObserver, uiObserver } from '@kit.ArkUI'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { CameraPermissions } from './CameraPermissions'; import GuideToOpenCameraDialog from '../view/dialog/GuideToOpenCameraDialog'; import deviceUtil from '../util/DeviceUtil'; @Entry @Component export struct FlashLightPage { listener: (info: uiObserver.RouterPageInfo) => void = (info: uiObserver.RouterPageInfo) => { let routerInfo: uiObserver.RouterPageInfo | undefined = this.queryRouterPageInfo(); if (info.pageId === routerInfo?.pageId) { if (info.state === uiObserver.RouterPageState.ON_PAGE_SHOW) { console.log(`SubComponent onPageShow`); this.onPageShow() } else if (info.state === uiObserver.RouterPageState.ON_PAGE_HIDE) { console.log(`SubComponent onPageHide`); this.onPageHide() } } } /** * SOS规则 : ...___... 为一组,两组之间有间隔 */ /** * SOS求救三短三长三短:三短时间间隔 */ readonly SOS_SHORT_TIME: number = 300 /** * SOS求救三短三长三短:三长时间间隔 */ readonly SOS_LONG_TIME: number = 900 /** * SOS求救三短三长三短:一组信号完毕后时间间隔 */ readonly SOS_INTERVAL_TIME = 1800 cameraPermissions: CameraPermissions = new CameraPermissions() options: scanBarcode.ScanOptions = { scanTypes: [scanCore.ScanType.ALL], enableMultiMode: true, enableAlbum: true }; // 设置预览流高度,默认单位:vp @State cameraHeight: number = 100 // 设置预览流宽度,默认单位:vp @State cameraWidth: number = 100 private mXComponentController: XComponentController = new XComponentController(); @State havaCameraPermission: boolean = false @State isStartCamera: boolean = false @State isLightOpen: boolean = false @State isSosLightOpen: boolean = false @State intervalId: number = 0 @State sosShortLightTime: number = 0 @State sosLongLightTime: number = 0 @State sosIntervalTime: boolean = false clickToOpenCamera: boolean = false @State isReleaseCamera: boolean = false // 是否已释放相机流 //引导用户开启相机权限弹框 toOpenCameraDialog: CustomDialogController = new CustomDialogController({ builder: GuideToOpenCameraDialog({ confirm: () => { this.clickToOpenCamera = true deviceUtil.startAppDetail() }, cancel: () => { } }), autoCancel: false, alignment: DialogAlignment.Center }) async aboutToAppear() { let uiObserver: UIObserver = this.getUIContext().getUIObserver(); uiObserver.on('routerPageUpdate', this.listener); this.cameraPermissions.setListener({ result: (type: number) => { if (type === 0) { this.havaCameraPermission = true } else { this.showOpenCameraPermission() } } }) await this.cameraPermissions.getHaveCameraPermission() } aboutToDisappear(): void { let uiObserver: UIObserver = this.getUIContext().getUIObserver(); uiObserver.off('routerPageUpdate', this.listener); } showOpenCameraPermission() { this.toOpenCameraDialog.open() } onPageShow(): void { console.log('tag--------------onPageShow()') if (this.clickToOpenCamera) { this.clickToOpenCamera = false this.cameraPermissions.getHaveCameraPermission() }else if(this.havaCameraPermission){ this.customScanStart() } } async onPageHide() { this.releaseCamera(); } // 释放相机流 async releaseCamera() { if (!this.isReleaseCamera) { await this.stopCamera(); await customScan.release(); this.isReleaseCamera = true; } } // 暂停相机流 async stopCamera() { if (!this.isReleaseCamera) { customScan.stop(); } } build() { Column() { Image(this.isLightOpen ? $r('app.media.switch_on') : $r('app.media.switch_off')) .width(151) .height(151) .onClick(() => { try { if (this.havaCameraPermission) { if (this.isSosLightOpen) { this.clearSosStatus() if (customScan.getFlashLightStatus()) { customScan.closeFlashLight(); } this.isSosLightOpen = false this.isLightOpen = false } // 根据当前闪光灯状态,选择打开或关闭闪关灯 else if (customScan.getFlashLightStatus()) { customScan.closeFlashLight(); this.isLightOpen = false } else { customScan.openFlashLight(); this.isLightOpen = true } } else { this.cameraPermissions.getHaveCameraPermission() } } catch (e) { if (this.havaCameraPermission) { this.customScanStart() } console.log(e) } }) Image(this.isSosLightOpen ? $r('app.media.sos_on_btn') : $r('app.media.sos_off_btn')) .width(89) .height(59) .margin({ top: 15 }) .onClick(() => { try { if (this.havaCameraPermission) { if (this.isSosLightOpen) { this.clearSosStatus() if (customScan.getFlashLightStatus()) { customScan.closeFlashLight(); } this.isSosLightOpen = false this.isLightOpen = false } else { this.sosShortInterval() this.isSosLightOpen = true this.isLightOpen = true } } else { this.cameraPermissions.getHaveCameraPermission() } } catch (e) { if (this.havaCameraPermission) { this.customScanStart() } console.log(e) } }) if (this.havaCameraPermission) { Stack() { XComponent({ id: 'componentId', type: 'surface', controller: this.mXComponentController }) .onLoad(() => { // 获取XComponent的surfaceId this.customScanStart(); customScan.openFlashLight(); this.isLightOpen = true; })// 预览流宽、高,默认单位vp,支持px、lpx、vp .height(this.cameraHeight) .width(this.cameraWidth) .position({ x: 0, y: 0 }) } .alignContent(Alignment.Bottom) .height(1) .width(1) .position({ x: 0, y: 0 }) } } .width('100%') .height('100%') .backgroundImage($r('app.media.screen_bg')) .backgroundImageSize({ width: '100%', height: '100%' }) .justifyContent(FlexAlign.Center) } /** * 开启相机流 */ private customScanStart() { this.isReleaseCamera = false let surfaceId: string = this.mXComponentController.getXComponentSurfaceId(); // 设置ViewControl相应字段 let viewControl: customScan.ViewControl = { width: this.cameraWidth, height: this.cameraHeight, surfaceId: surfaceId }; customScan.init(this.options); customScan.start(viewControl).then((scanResult: Array<scanBarcode.ScanResult>) => { this.isStartCamera = true; hilog.info(0x0001, '[Scan Sample]', `Succeeded in getting ScanResult by promise, scanResult is ${JSON.stringify(scanResult)}`); }).catch((error: BusinessError) => { this.isStartCamera = false; hilog.error(0x0001, '[Scan Sample]', `Failed to get ScanResult by promise. Code: ${error.code}, message: ${error.message}`); }); } //短信号 sosShortInterval() { this.intervalId = setInterval(() => { if (this.sosShortLightTime === 3) { this.sosShortLightTime = 0 clearInterval(this.intervalId) if (this.sosIntervalTime) { this.sosInterval() } else { this.sosLongInterval() } } if (customScan.getFlashLightStatus()) { customScan.closeFlashLight() } else { customScan.openFlashLight() this.sosShortLightTime++ } }, this.SOS_SHORT_TIME) } //长信号 sosLongInterval() { this.intervalId = setInterval(() => { if (this.sosLongLightTime === 3) { this.sosLongLightTime = 0 clearInterval(this.intervalId) this.sosIntervalTime = true this.sosShortInterval() } if (customScan.getFlashLightStatus()) { customScan.closeFlashLight() } else { customScan.openFlashLight() this.sosLongLightTime++ } }, this.SOS_LONG_TIME) } //一组sos信号完毕之后间隔 sosInterval() { setTimeout(() => { this.sosIntervalTime = false this.sosShortInterval() }, this.SOS_INTERVAL_TIME) } //清空sos 的状态 clearSosStatus() { clearInterval(this.intervalId) this.sosIntervalTime = false this.sosLongLightTime = 0 this.sosShortLightTime = 0 } }
1、修改了以下代码,后台到前台已可以正常显示预览流。主要修改点:增加“自定义组件监听页面生命周期”方法,以及在页面关闭的生命周期中增加“停止释放预览流”的代码。
2、具体代码如下,仅供参考: