1# Sample for Camera Recovery from the Background (ArkTS) 2 3This sample demonstrates the complete process for transitioning a camera application from the background to the foreground, providing you with a clear understanding of the entire sequence of API calls. 4 5The state changes during the camera application's transition between foreground and background are as follows: 6- When the camera application transitions to the background, it is forcibly disconnected due to security policies, and the camera status callback returns the camera available state, indicating that the camera device is now idle. 7- When the camera application returns to the foreground, the camera status callback returns the camera unavailable state, indicating that the camera device is now busy. 8- Upon transitioning from the background to the foreground, the camera application must restart the preview stream, photo stream, and camera session management accordingly. 9 10Before referring to the sample code, you are advised to read [Camera Device Management](camera-device-management.md), [Device Input Management](camera-device-input.md), [Camera Session Management](camera-session-management.md), and other related topics in [Camera Development (ArkTS)](camera-preparation.md). 11 12## Development Process 13 14The figure below shows the process of transitioning a camera application from the background to the foreground. 15 16 17 18## Sample 19 20For details about how to obtain the context, see [Obtaining the Context of UIAbility](../../application-models/uiability-usage.md#obtaining-the-context-of-uiability). 21 22During the transition of the camera application from the background to the foreground, call the **onPageShow** callback function to re-initialize the camera device. 23 24 ```ts 25 import { camera } from '@kit.CameraKit'; 26 import { BusinessError } from '@kit.BasicServicesKit'; 27 import { common } from '@kit.AbilityKit'; 28 29 let context: common.BaseContext; 30 let surfaceId: string = ''; 31 async function onPageShow(): Promise<void> { 32 // Reinitialize the camera when the application transitions from the background to the foreground. 33 await initCamera(context, surfaceId); 34 } 35 36 async function initCamera(baseContext: common.BaseContext, surfaceId: string): Promise<void> { 37 console.info('onForeGround recovery begin.'); 38 let cameraManager: camera.CameraManager = camera.getCameraManager(context); 39 if (!cameraManager) { 40 console.error("camera.getCameraManager error"); 41 return; 42 } 43 // Listen for camera status changes. 44 cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { 45 if (err !== undefined && err.code !== 0) { 46 console.error('cameraStatus with errorCode = ' + err.code); 47 return; 48 } 49 console.info(`camera : ${cameraStatusInfo.camera.cameraId}`); 50 console.info(`status: ${cameraStatusInfo.status}`); 51 }); 52 53 // Obtain the camera list. 54 let cameraArray: Array<camera.CameraDevice> = cameraManager.getSupportedCameras(); 55 if (cameraArray.length <= 0) { 56 console.error("cameraManager.getSupportedCameras error"); 57 return; 58 } 59 60 for (let index = 0; index < cameraArray.length; index++) { 61 console.info('cameraId : ' + cameraArray[index].cameraId); // Obtain the camera ID. 62 console.info('cameraPosition : ' + cameraArray[index].cameraPosition); // Obtain the camera position. 63 console.info('cameraType : ' + cameraArray[index].cameraType); // Obtain the camera type. 64 console.info('connectionType : ' + cameraArray[index].connectionType); // Obtain the camera connection type. 65 } 66 67 // Create a camera input stream. 68 let cameraInput: camera.CameraInput | undefined = undefined; 69 try { 70 cameraInput = cameraManager.createCameraInput(cameraArray[0]); 71 } catch (error) { 72 let err = error as BusinessError; 73 console.error('Failed to createCameraInput errorCode = ' + err.code); 74 } 75 if (cameraInput === undefined) { 76 return; 77 } 78 79 // Listen for camera input errors. 80 let cameraDevice: camera.CameraDevice = cameraArray[0]; 81 cameraInput.on('error', cameraDevice, (error: BusinessError) => { 82 console.error(`Camera input error code: ${error.code}`); 83 }); 84 85 // Open a camera. 86 await cameraInput.open(); 87 88 // Obtain the supported modes. 89 let sceneModes: Array<camera.SceneMode> = cameraManager.getSupportedSceneModes(cameraArray[0]); 90 let isSupportPhotoMode: boolean = sceneModes.indexOf(camera.SceneMode.NORMAL_PHOTO) >= 0; 91 if (!isSupportPhotoMode) { 92 console.error('photo mode not support'); 93 return; 94 } 95 // Obtain the output streams supported by the camera device. 96 let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0], camera.SceneMode.NORMAL_PHOTO); 97 if (!cameraOutputCap) { 98 console.error("cameraManager.getSupportedOutputCapability error"); 99 return; 100 } 101 console.info("outputCapability: " + JSON.stringify(cameraOutputCap)); 102 103 let previewProfilesArray: Array<camera.Profile> = cameraOutputCap.previewProfiles; 104 if (!previewProfilesArray) { 105 console.error("createOutput previewProfilesArray == null || undefined"); 106 } 107 108 let photoProfilesArray: Array<camera.Profile> = cameraOutputCap.photoProfiles; 109 if (!photoProfilesArray) { 110 console.error("createOutput photoProfilesArray == null || undefined"); 111 } 112 113 // Create a preview output stream. For details about the surfaceId parameter, see the XComponent. The preview stream uses the surface provided by the XComponent. 114 let previewOutput: camera.PreviewOutput | undefined = undefined; 115 try { 116 previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); 117 } catch (error) { 118 let err = error as BusinessError; 119 console.error(`Failed to create the PreviewOutput instance. error code: ${err.code}`); 120 } 121 if (previewOutput === undefined) { 122 return; 123 } 124 // Listen for preview output errors. 125 previewOutput.on('error', (error: BusinessError) => { 126 console.error(`Preview output error code: ${error.code}`); 127 }); 128 129 // Create a photo output stream. 130 let photoOutput: camera.PhotoOutput | undefined = undefined; 131 try { 132 photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]); 133 } catch (error) { 134 let err = error as BusinessError; 135 console.error('Failed to createPhotoOutput errorCode = ' + err.code); 136 } 137 if (photoOutput === undefined) { 138 return; 139 } 140 141 // Create a session. 142 let photoSession: camera.PhotoSession | undefined = undefined; 143 try { 144 photoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession; 145 } catch (error) { 146 let err = error as BusinessError; 147 console.error('Failed to create the session instance. errorCode = ' + err.code); 148 } 149 if (photoSession === undefined) { 150 return; 151 } 152 // Listen for session errors. 153 photoSession.on('error', (error: BusinessError) => { 154 console.error(`Capture session error code: ${error.code}`); 155 }); 156 157 // Start configuration for the session. 158 try { 159 photoSession.beginConfig(); 160 } catch (error) { 161 let err = error as BusinessError; 162 console.error('Failed to beginConfig. errorCode = ' + err.code); 163 } 164 165 // Add the camera input stream to the session. 166 try { 167 photoSession.addInput(cameraInput); 168 } catch (error) { 169 let err = error as BusinessError; 170 console.error('Failed to addInput. errorCode = ' + err.code); 171 } 172 173 // Add the preview output stream to the session. 174 try { 175 photoSession.addOutput(previewOutput); 176 } catch (error) { 177 let err = error as BusinessError; 178 console.error('Failed to addOutput(previewOutput). errorCode = ' + err.code); 179 } 180 181 // Add the photo output stream to the session. 182 try { 183 photoSession.addOutput(photoOutput); 184 } catch (error) { 185 let err = error as BusinessError; 186 console.error('Failed to addOutput(photoOutput). errorCode = ' + err.code); 187 } 188 189 // Commit the session configuration. 190 await photoSession.commitConfig(); 191 192 // Start the session. 193 await photoSession.start().then(() => { 194 console.info('Promise returned to indicate the session start success.'); 195 }); 196 // Check whether the camera has flash. 197 let flashStatus: boolean = false; 198 try { 199 flashStatus = photoSession.hasFlash(); 200 } catch (error) { 201 let err = error as BusinessError; 202 console.error('Failed to hasFlash. errorCode = ' + err.code); 203 } 204 console.info('Returned with the flash light support status:' + flashStatus); 205 206 if (flashStatus) { 207 // Check whether the auto flash mode is supported. 208 let flashModeStatus: boolean = false; 209 try { 210 let status: boolean = photoSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO); 211 flashModeStatus = status; 212 } catch (error) { 213 let err = error as BusinessError; 214 console.error('Failed to check whether the flash mode is supported. errorCode = ' + err.code); 215 } 216 if(flashModeStatus) { 217 // Set the flash mode to auto. 218 try { 219 photoSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO); 220 } catch (error) { 221 let err = error as BusinessError; 222 console.error('Failed to set the flash mode. errorCode = ' + err.code); 223 } 224 } 225 } 226 227 // Check whether the continuous auto focus is supported. 228 let focusModeStatus: boolean = false; 229 try { 230 let status: boolean = photoSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); 231 focusModeStatus = status; 232 } catch (error) { 233 let err = error as BusinessError; 234 console.error('Failed to check whether the focus mode is supported. errorCode = ' + err.code); 235 } 236 237 if (focusModeStatus) { 238 // Set the focus mode to continuous auto focus. 239 try { 240 photoSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); 241 } catch (error) { 242 let err = error as BusinessError; 243 console.error('Failed to set the focus mode. errorCode = ' + err.code); 244 } 245 } 246 247 // Obtain the zoom ratio range supported by the camera. 248 let zoomRatioRange: Array<number> = []; 249 try { 250 zoomRatioRange = photoSession.getZoomRatioRange(); 251 } catch (error) { 252 let err = error as BusinessError; 253 console.error('Failed to get the zoom ratio range. errorCode = ' + err.code); 254 } 255 if (zoomRatioRange.length <= 0) { 256 return; 257 } 258 // Set a zoom ratio. 259 try { 260 photoSession.setZoomRatio(zoomRatioRange[0]); 261 } catch (error) { 262 let err = error as BusinessError; 263 console.error('Failed to set the zoom ratio value. errorCode = ' + err.code); 264 } 265 let photoCaptureSetting: camera.PhotoCaptureSetting = { 266 quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // Set the photo quality to high. 267 rotation: camera.ImageRotation.ROTATION_0 // Set the rotation angle of the photo to 0. 268 } 269 // Use the current photo capture settings to take photos. 270 photoOutput.capture(photoCaptureSetting, (err: BusinessError) => { 271 if (err) { 272 console.error(`Failed to capture the photo ${err.message}`); 273 return; 274 } 275 console.info('Callback invoked to indicate the photo capture request success.'); 276 }); 277 278 console.info('onForeGround recovery end.'); 279 } 280 ``` 281