@@ -102,6 +102,7 @@ fun SendRecipientScreen(
102102 val previewView = remember { PreviewView (context) }
103103 val preview = remember { CameraPreview .Builder ().build() }
104104 var camera by remember { mutableStateOf<Camera ?>(null ) }
105+ val executor = remember { Executors .newSingleThreadExecutor() }
105106
106107 val cameraSelector = remember {
107108 CameraSelector .Builder ()
@@ -140,20 +141,30 @@ fun SendRecipientScreen(
140141
141142 LaunchedEffect (cameraPermissionState.status, isCameraInitialized) {
142143 if (cameraPermissionState.status.isGranted && ! isCameraInitialized) {
143- delay(TRANSITION_SCREEN_MS )
144- imageAnalysis.setAnalyzer(Executors .newSingleThreadExecutor(), analyzer)
144+ runCatching {
145+ delay(TRANSITION_SCREEN_MS )
146+ imageAnalysis.setAnalyzer(executor, analyzer)
145147
146- val cameraProvider = withContext(Dispatchers .IO ) {
147- ProcessCameraProvider .getInstance(context).get()
148+ val cameraProvider = withContext(Dispatchers .IO ) {
149+ ProcessCameraProvider .getInstance(context).get()
150+ }
151+ camera = cameraProvider.bindToLifecycle(
152+ lifecycleOwner,
153+ cameraSelector,
154+ preview,
155+ imageAnalysis
156+ )
157+ preview.surfaceProvider = previewView.surfaceProvider
158+ isCameraInitialized = true
159+ }.onFailure { e ->
160+ Logger .error(" Camera initialization failed" , e)
161+ app?.toast(
162+ type = Toast .ToastType .ERROR ,
163+ title = context.getString(R .string.other__qr_error_header),
164+ description = " Failed to initialize camera: ${e.message} "
165+ )
166+ isCameraInitialized = false
148167 }
149- camera = cameraProvider.bindToLifecycle(
150- lifecycleOwner,
151- cameraSelector,
152- preview,
153- imageAnalysis
154- )
155- preview.surfaceProvider = previewView.surfaceProvider
156- isCameraInitialized = true
157168 }
158169 }
159170
@@ -169,6 +180,7 @@ fun SendRecipientScreen(
169180 }
170181 // Reset state - camera will reinit if needed on next composition
171182 isCameraInitialized = false
183+ executor.shutdown()
172184 }
173185 }
174186
@@ -213,8 +225,16 @@ fun SendRecipientScreen(
213225 SendRecipientContent (
214226 previewView = previewView,
215227 onClickFlashlight = {
216- isFlashlightOn = ! isFlashlightOn
217- camera?.cameraControl?.enableTorch(isFlashlightOn)
228+ camera?.cameraControl?.let { control ->
229+ isFlashlightOn = ! isFlashlightOn
230+ runCatching {
231+ control.enableTorch(isFlashlightOn)
232+ }.onFailure { e ->
233+ Logger .error(" Torch control failed" , e)
234+ // Revert state
235+ isFlashlightOn = ! isFlashlightOn
236+ }
237+ }
218238 },
219239 onClickGallery = {
220240 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .TIRAMISU ) {
0 commit comments