From 764d8c9fc07a16138d095c1e58adf60b02ed5200 Mon Sep 17 00:00:00 2001 From: lon9 <815882449@qq.com> Date: Fri, 19 Sep 2025 15:53:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=82=E5=B8=B8=E6=8D=95=E8=8E=B7=E6=95=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/ets/entryability/EntryAbility.ets | 17 +- entry/src/main/ets/pages/Index.ets | 19 +- entry/src/main/ets/utils/CameraUtil.ets | 286 ++++++++++-------- entry/src/main/ets/utils/WindowUtil.ets | 30 +- 4 files changed, 203 insertions(+), 149 deletions(-) diff --git a/entry/src/main/ets/entryability/EntryAbility.ets b/entry/src/main/ets/entryability/EntryAbility.ets index f377163..12e3415 100644 --- a/entry/src/main/ets/entryability/EntryAbility.ets +++ b/entry/src/main/ets/entryability/EntryAbility.ets @@ -56,15 +56,26 @@ export default class EntryAbility extends UIAbility { setOrientation(width: number, height: number): void { // When the minimum value of window width and height is greater than the md breakpoint threshold, rotation is supported. if (Math.min(width, height) >= 600) { - this.windowData?.setPreferredOrientation(window.Orientation.AUTO_ROTATION_RESTRICTED); + this.windowData?.setPreferredOrientation(window.Orientation.AUTO_ROTATION_RESTRICTED).catch((error: BusinessError) => { + hilog.error(0x0000, `MultiDeviceCamera`, + `Set window orientation failed. Code: ${error.code}, message: ${error.message}`); + }); } else { - this.windowData?.setPreferredOrientation(window.Orientation.PORTRAIT); + this.windowData?.setPreferredOrientation(window.Orientation.PORTRAIT).catch((error: BusinessError) => { + hilog.error(0x0000, `MultiDeviceCamera`, + `Set window orientation failed. Code: ${error.code}, message: ${error.message}`); + }); } } // [StartExclude Bp2] onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'MultiDeviceCamera', `Failed to set color mode. Code: ${err.code}, message: ${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index bdc3d80..8f1fafc 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -15,6 +15,7 @@ import { abilityAccessCtrl, Permissions } from '@kit.AbilityKit'; import { display, window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; import { camera } from '@kit.CameraKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { ChooseMusic, SettingButton, ShotArea, ShotAreaHalfFolded, ShotAreaSm } from '../views/CommonView'; @@ -95,7 +96,12 @@ struct Index { // [End FoldStatusChange] aboutToAppear(): void { - display.on('foldStatusChange', this.onFoldStatusChange); + try { + display.on('foldStatusChange', this.onFoldStatusChange); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'MultiDeviceCamera', `Failed to obtain fold status. Code: ${err.code}, message: ${err.message}`); + } } // [End SelectCamera2] @@ -113,14 +119,19 @@ struct Index { this.cameraUtil.cameraShooting(this.surfaceId, this.context!, camera.CameraPosition.CAMERA_POSITION_BACK); } }, 200); - }).catch(() => { - hilog.error(0x0000, 'testTag', `Failed to requestPermissionsFromUser.`); + }).catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag', `Failed to requestPermissionsFromUser. Code: ${err.code}, message: ${err.message}`); }) } // [End SelectCamera1] aboutToDisappear(): void { - display.off('foldStatusChange'); + try { + display.off('foldStatusChange'); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'MultiDeviceCamera', `Failed to requestPermissionsFromUser. Code: ${err.code}, message: ${err.message}`); + } this.windowUtil.offWindowSizeChange(); } diff --git a/entry/src/main/ets/utils/CameraUtil.ets b/entry/src/main/ets/utils/CameraUtil.ets index 4467333..0decbc1 100644 --- a/entry/src/main/ets/utils/CameraUtil.ets +++ b/entry/src/main/ets/utils/CameraUtil.ets @@ -40,65 +40,70 @@ export class CameraUtil { this.currentContext = context; // Release camera session and streams, to avoid conflicts in camera resource usage. this.releaseCamera(); - let cameraManager: camera.CameraManager = camera.getCameraManager(context); - if (!cameraManager) { - return; - } - // Obtaining the camera list. - let cameraArray: camera.CameraDevice[] = cameraManager.getSupportedCameras(); - if (cameraArray.length <= 0) { - return; - } - // Select front and rear camera. - let cameraIndex: number = this.getCamera(cameraArray, cameraPosition); - // Create a camera input stream based on the camera. - this.cameraInput = cameraManager.createCameraInput(cameraArray[cameraIndex]); - // Open the camera. - await this.cameraInput.open(); - // Get the supported modes of the camera and select the photo mode. - let sceneModes: camera.SceneMode[] = cameraManager.getSupportedSceneModes(cameraArray[cameraIndex]); - let cameraOutputCap: camera.CameraOutputCapability = - cameraManager.getSupportedOutputCapability(cameraArray[cameraIndex], camera.SceneMode.NORMAL_PHOTO); - let isSupportPhotoMode: boolean = sceneModes.indexOf(camera.SceneMode.NORMAL_PHOTO) >= 0; - if (!isSupportPhotoMode) { - return; - } - if (!cameraOutputCap) { - return; - } + try { + let cameraManager: camera.CameraManager = camera.getCameraManager(context); + if (!cameraManager) { + return; + } + // Obtaining the camera list. + let cameraArray: camera.CameraDevice[] = cameraManager.getSupportedCameras(); + if (cameraArray.length <= 0) { + return; + } + // Select front and rear camera. + let cameraIndex: number = this.getCamera(cameraArray, cameraPosition); + // Create a camera input stream based on the camera. + this.cameraInput = cameraManager.createCameraInput(cameraArray[cameraIndex]); + // Open the camera. + await this.cameraInput.open(); + // Get the supported modes of the camera and select the photo mode. + let sceneModes: camera.SceneMode[] = cameraManager.getSupportedSceneModes(cameraArray[cameraIndex]); + let cameraOutputCap: camera.CameraOutputCapability = + cameraManager.getSupportedOutputCapability(cameraArray[cameraIndex], camera.SceneMode.NORMAL_PHOTO); + let isSupportPhotoMode: boolean = sceneModes.indexOf(camera.SceneMode.NORMAL_PHOTO) >= 0; + if (!isSupportPhotoMode) { + return; + } + if (!cameraOutputCap) { + return; + } - // Get camera preview and photo configuration. - let previewProfileArray: camera.Profile[] = cameraOutputCap.previewProfiles; - let previewProfile: camera.Profile = this.getProfile(previewProfileArray); - let photoProfileArray: camera.Profile[] = cameraOutputCap.photoProfiles; - let photoProfile: camera.Profile = this.getProfile(photoProfileArray); - this.previewOutput = cameraManager.createPreviewOutput(previewProfile, surfaceId); - if (this.previewOutput === undefined) { - return; - } + // Get camera preview and photo configuration. + let previewProfileArray: camera.Profile[] = cameraOutputCap.previewProfiles; + let previewProfile: camera.Profile = this.getProfile(previewProfileArray); + let photoProfileArray: camera.Profile[] = cameraOutputCap.photoProfiles; + let photoProfile: camera.Profile = this.getProfile(photoProfileArray); + this.previewOutput = cameraManager.createPreviewOutput(previewProfile, surfaceId); + if (this.previewOutput === undefined) { + return; + } - this.photoOutput = cameraManager.createPhotoOutput(photoProfile); - if (this.photoOutput === undefined) { - return; - } - // Save photo. - this.setPhotoOutputCb(); - // Configure the camera preview stream to match the aspect ratio of the surface, otherwise the preview page will be compressed or stretched. - this.windowUtil = AppStorage.get('windowUtil'); - this.setXComponentRect(this.windowUtil!.getWindowSize()); - // Create the camera session and config. - this.photoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO); - if (this.photoSession === undefined) { + this.photoOutput = cameraManager.createPhotoOutput(photoProfile); + if (this.photoOutput === undefined) { + return; + } + // Save photo. + this.setPhotoOutputCb(); + // Configure the camera preview stream to match the aspect ratio of the surface, otherwise the preview page will be compressed or stretched. + this.windowUtil = AppStorage.get('windowUtil'); + this.setXComponentRect(this.windowUtil!.getWindowSize()); + // Create the camera session and config. + this.photoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO); + if (this.photoSession === undefined) { + return; + } + this.photoSession.beginConfig(); + this.photoSession.addInput(this.cameraInput); + this.photoSession.addOutput(this.previewOutput); + this.photoSession.addOutput(this.photoOutput); + this.photoSession.setColorSpace(colorSpaceManager.ColorSpace.DISPLAY_P3); + await this.photoSession.commitConfig(); + await this.photoSession.start(); return; + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'MultiDeviceCamera', `Camera shooting failed. Code: ${err.code}, message: ${err.message}`); } - this.photoSession.beginConfig(); - this.photoSession.addInput(this.cameraInput); - this.photoSession.addOutput(this.previewOutput); - this.photoSession.addOutput(this.photoOutput); - this.photoSession.setColorSpace(colorSpaceManager.ColorSpace.DISPLAY_P3); - await this.photoSession.commitConfig(); - await this.photoSession.start(); - return; } // [Start SelectCamera3] @@ -177,58 +182,68 @@ export class CameraUtil { // [Start Capture] capture(): void { let rotation: number = 0; - // Obtain the angle of the gravity sensor during shooting and set the shooting rotation angle. - sensor.once(sensor.SensorId.GRAVITY, (data: sensor.GravityResponse) => { - let degree: number = this.getCalDegree(data.x, data.y, data.z); - let isFront: boolean | undefined = AppStorage.get('isFront'); - if (degree >= 0 && (degree <= 30 || degree >= 300)) { - rotation = camera.ImageRotation.ROTATION_0; - } else if (degree > 30 && degree <= 120) { - if (isFront) { - // Use ROTATION_270 when degree range is (30, 120] for front camera. - rotation = camera.ImageRotation.ROTATION_270; - } else { - // Use ROTATION_90 when degree range is (30, 120] for back camera. - rotation = camera.ImageRotation.ROTATION_90; - } - } else if (degree > 120 && degree <= 210) { - // Use ROTATION_180 when degree range is (120, 210]. - rotation = camera.ImageRotation.ROTATION_180; - } else if (degree > 210 && degree <= 300) { - if (isFront) { - // Use ROTATION_90 when degree range is (210, 300] for front camera. - rotation = camera.ImageRotation.ROTATION_90; - } else { - // Use ROTATION_270 when degree range is (210, 300] for back camera. - rotation = camera.ImageRotation.ROTATION_270; - } - }; + try { + // Obtain the angle of the gravity sensor during shooting and set the shooting rotation angle. + sensor.once(sensor.SensorId.GRAVITY, (data: sensor.GravityResponse) => { + let degree: number = this.getCalDegree(data.x, data.y, data.z); + let isFront: boolean | undefined = AppStorage.get('isFront'); + if (degree >= 0 && (degree <= 30 || degree >= 300)) { + rotation = camera.ImageRotation.ROTATION_0; + } else if (degree > 30 && degree <= 120) { + if (isFront) { + // Use ROTATION_270 when degree range is (30, 120] for front camera. + rotation = camera.ImageRotation.ROTATION_270; + } else { + // Use ROTATION_90 when degree range is (30, 120] for back camera. + rotation = camera.ImageRotation.ROTATION_90; + } + } else if (degree > 120 && degree <= 210) { + // Use ROTATION_180 when degree range is (120, 210]. + rotation = camera.ImageRotation.ROTATION_180; + } else if (degree > 210 && degree <= 300) { + if (isFront) { + // Use ROTATION_90 when degree range is (210, 300] for front camera. + rotation = camera.ImageRotation.ROTATION_90; + } else { + // Use ROTATION_270 when degree range is (210, 300] for back camera. + rotation = camera.ImageRotation.ROTATION_270; + } + }; - let setting: camera.PhotoCaptureSetting = { - quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, - rotation: rotation, - mirror: isFront - } - this.photoOutput?.capture(setting); - }) + let setting: camera.PhotoCaptureSetting = { + quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, + rotation: rotation, + mirror: isFront + } + this.photoOutput?.capture(setting); + }) + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'MultiDeviceCamera', `Capture failed. Code: ${err.code}, message: ${err.message}`); + } } // [End Capture] releaseCamera(): void { - if (this.photoSession) { - this.photoSession.stop(); - } - if (this.cameraInput) { - this.cameraInput.close(); - } - if (this.previewOutput) { - this.previewOutput.release(); - } - if (this.photoSession) { - this.photoSession.stop(); - } - if (this.photoOutput) { - this.photoOutput.release(); + try { + if (this.photoSession) { + this.photoSession.stop(); + } + if (this.cameraInput) { + this.cameraInput.close(); + } + if (this.previewOutput) { + this.previewOutput.release(); + } + if (this.photoSession) { + this.photoSession.stop(); + } + if (this.photoOutput) { + this.photoOutput.release(); + } + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'MultiDeviceCamera', `Failed to release. Code: ${err.code}, message: ${err.message}`); } } @@ -274,41 +289,46 @@ export class CameraUtil { // [Start Preview1] // [Start SetXComponentRect] setXComponentRect(windowSize: window.Size): void { - // Initialize the width and height of the surface to match the full screen of the window. - let rect: SurfaceRect = { - surfaceWidth: windowSize.width, - surfaceHeight: windowSize.height - }; - let widthBp: WidthBreakpoint = this.uiContext!.getWindowWidthBreakpoint(); - let heightBp: HeightBreakpoint = this.uiContext!.getWindowHeightBreakpoint(); - let displayRotation: number = display.getDefaultDisplaySync().rotation * 90; - if (widthBp === WidthBreakpoint.WIDTH_SM && heightBp === HeightBreakpoint.HEIGHT_MD) { - this.xComponentController!.setXComponentSurfaceRect(rect); - return; - } - if (AppStorage.get('isHalfFolded')) { - this.setHalfFoldedRect(windowSize); - return; - } - if (displayRotation === 0 || displayRotation === 180) { - if (windowSize.height * 3 / 4 > windowSize.width) { - rect.surfaceHeight = windowSize.width / 3 * 4; - } else { - rect.surfaceWidth = windowSize.height / 4 * 3; + try { + // Initialize the width and height of the surface to match the full screen of the window. + let rect: SurfaceRect = { + surfaceWidth: windowSize.width, + surfaceHeight: windowSize.height + }; + let widthBp: WidthBreakpoint = this.uiContext!.getWindowWidthBreakpoint(); + let heightBp: HeightBreakpoint = this.uiContext!.getWindowHeightBreakpoint(); + let displayRotation: number = display.getDefaultDisplaySync().rotation * 90; + if (widthBp === WidthBreakpoint.WIDTH_SM && heightBp === HeightBreakpoint.HEIGHT_MD) { + this.xComponentController!.setXComponentSurfaceRect(rect); + return; } - if (widthBp === WidthBreakpoint.WIDTH_MD && heightBp === HeightBreakpoint.HEIGHT_MD) { - rect.offsetX = 0; - rect.offsetY = 0; + if (AppStorage.get('isHalfFolded')) { + this.setHalfFoldedRect(windowSize); + return; } - } - if (displayRotation === 90 || displayRotation === 270) { - if (windowSize.width * 3 / 4 > windowSize.height) { - rect.surfaceWidth = windowSize.height / 3 * 4; - } else { - rect.surfaceHeight = windowSize.width / 4 * 3; + if (displayRotation === 0 || displayRotation === 180) { + if (windowSize.height * 3 / 4 > windowSize.width) { + rect.surfaceHeight = windowSize.width / 3 * 4; + } else { + rect.surfaceWidth = windowSize.height / 4 * 3; + } + if (widthBp === WidthBreakpoint.WIDTH_MD && heightBp === HeightBreakpoint.HEIGHT_MD) { + rect.offsetX = 0; + rect.offsetY = 0; + } + } + if (displayRotation === 90 || displayRotation === 270) { + if (windowSize.width * 3 / 4 > windowSize.height) { + rect.surfaceWidth = windowSize.height / 3 * 4; + } else { + rect.surfaceHeight = windowSize.width / 4 * 3; + } } + this.xComponentController!.setXComponentSurfaceRect(rect); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'MultiDeviceCamera', `Failed to set XComponent rect. Code: ${err.code}, message: ${err.message}`); } - this.xComponentController!.setXComponentSurfaceRect(rect); } // [End SetXComponentRect] // [End Preview1] diff --git a/entry/src/main/ets/utils/WindowUtil.ets b/entry/src/main/ets/utils/WindowUtil.ets index 1f47c3a..7705713 100644 --- a/entry/src/main/ets/utils/WindowUtil.ets +++ b/entry/src/main/ets/utils/WindowUtil.ets @@ -50,21 +50,33 @@ export class WindowUtil { } getFoldCreaseRegion(context: UIContext): void { - if (display.isFoldable()) { - let foldRegion: display.FoldCreaseRegion = display.getCurrentFoldCreaseRegion(); - let rect: display.Rect = foldRegion.creaseRects[0]; - // Height of the avoidance area in the upper half screen and height of the avoidance area. - let creaseRegion: number[] = [context.px2vp(rect.top), context.px2vp(rect.height), context.px2vp(rect.width)]; - AppStorage.setOrCreate('creaseRegion', creaseRegion); + try { + if (display.isFoldable()) { + let foldRegion: display.FoldCreaseRegion = display.getCurrentFoldCreaseRegion(); + let rect: display.Rect = foldRegion.creaseRects[0]; + // Height of the avoidance area in the upper half screen and height of the avoidance area. + let creaseRegion: number[] = [context.px2vp(rect.top), context.px2vp(rect.height), context.px2vp(rect.width)]; + AppStorage.setOrCreate('creaseRegion', creaseRegion); + } + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'MultiDeviceCamera', `Isfoldable failed. Code: ${err.code}, message: ${err.message}`); } } getWindowSize(): window.Size { - let rect: window.Rect = this.mainWindow!.getWindowProperties().windowRect; let result: window.Size = { - width: rect.width, - height: rect.height + width: 0, + height: 0 }; + try { + let rect: window.Rect = this.mainWindow!.getWindowProperties().windowRect; + result.width = rect.width; + result.height = rect.height; + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'MultiDeviceCamera', `Get window properties failed. Code: ${err.code}, message: ${err.message}`); + } return result; } } \ No newline at end of file -- Gitee