From 0b4494e883e6e6e7322dcd9ee0913ecbf2caeca0 Mon Sep 17 00:00:00 2001 From: OS-pedrogustavobilro Date: Mon, 3 Aug 2026 12:47:08 +0100 Subject: [PATCH 1/2] fix: only show camera preview after grating permission References: Discovered while working on https://outsystemsrd.atlassian.net/browse/RMET-5329 --- .../barcode/view/OSBARCScannerActivity.kt | 111 ++++++++---------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt index b8adab2..180c535 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -139,6 +139,7 @@ class OSBARCScannerActivity : ComponentActivity() { private lateinit var selector: CameraSelector private var permissionRequestCount = 0 private var showDialog by mutableStateOf(false) + private var permissionGiven by mutableStateOf(false) private var isScanning = false private lateinit var cameraExecutor: ExecutorService @@ -213,7 +214,7 @@ class OSBARCScannerActivity : ComponentActivity() { override fun onResume() { super.onResume() - showDialog = !hasCameraPermission(this.applicationContext) + updatePermissionState(hasCameraPermission(this.applicationContext)) } override fun onDestroy() { @@ -231,20 +232,13 @@ class OSBARCScannerActivity : ComponentActivity() { fun ScanScreen(parameters: OSBARCScanParameters, windowSizeClass: WindowSizeClass) { val lifecycleOwner = LocalLifecycleOwner.current val context = LocalContext.current - var permissionGiven by remember { mutableStateOf(true) } var uiState by remember { mutableStateOf(OSBARCScannerUiState.DEFAULT) } // permissions val requestPermissionLauncher = rememberLauncherForActivityResult( ActivityResultContracts.RequestPermission() ) { isGranted: Boolean -> - if (isGranted) { - permissionGiven = true - showDialog = false - } else { - permissionGiven = false - showDialog = true - } + updatePermissionState(isGranted) } SideEffect { if (permissionRequestCount == 0) { @@ -278,61 +272,53 @@ class OSBARCScannerActivity : ComponentActivity() { ProcessCameraProvider.getInstance(context) } - try { - camera = cameraProviderFuture.get().bindToLifecycle( - lifecycleOwner, - selector - ) - } catch (e: Exception) { - e.message?.let { Log.e(LOG_TAG, it) } - setResult(OSBARCError.SCANNING_GENERAL_ERROR.code) - finish() - } - Box( modifier = Modifier .fillMaxSize() + .background(ScannerBackgroundBlack) ) { - AndroidView( - factory = { context -> - val previewView = PreviewView(context) - val preview = Preview.Builder().build() - preview.setSurfaceProvider(previewView.surfaceProvider) - - val resolutionSelector = ResolutionSelector.Builder().setResolutionStrategy( - ResolutionStrategy(android.util.Size(1920, 1080), // high resolution for optimal scanning - ResolutionStrategy.FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER) - ).build() - val imageAnalysis = ImageAnalysis.Builder() - .setResolutionSelector(resolutionSelector) - .setBackpressureStrategy(STRATEGY_KEEP_ONLY_LATEST) - .build() - imageAnalysis.setAnalyzer( - cameraExecutor, - barcodeAnalyzer - ) - try { - camera = cameraProviderFuture.get().bindToLifecycle( - lifecycleOwner, - selector, - preview, - imageAnalysis - ).also { - uiState = OSBARCScannerUiState( - hasFlashUnit = it.cameraInfo.hasFlashUnit(), - minZoomRatio = it.cameraInfo.zoomState.value?.minZoomRatio ?: 1f, - maxZoomRatio = it.cameraInfo.zoomState.value?.maxZoomRatio ?: 1f - ) + if (permissionGiven) { + AndroidView( + factory = { context -> + val previewView = PreviewView(context) + val preview = Preview.Builder().build() + preview.setSurfaceProvider(previewView.surfaceProvider) + + val resolutionSelector = ResolutionSelector.Builder().setResolutionStrategy( + ResolutionStrategy(android.util.Size(1920, 1080), // high resolution for optimal scanning + ResolutionStrategy.FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER) + ).build() + val imageAnalysis = ImageAnalysis.Builder() + .setResolutionSelector(resolutionSelector) + .setBackpressureStrategy(STRATEGY_KEEP_ONLY_LATEST) + .build() + imageAnalysis.setAnalyzer( + cameraExecutor, + barcodeAnalyzer + ) + try { + camera = cameraProviderFuture.get().bindToLifecycle( + lifecycleOwner, + selector, + preview, + imageAnalysis + ).also { + uiState = OSBARCScannerUiState( + hasFlashUnit = it.cameraInfo.hasFlashUnit(), + minZoomRatio = it.cameraInfo.zoomState.value?.minZoomRatio ?: 1f, + maxZoomRatio = it.cameraInfo.zoomState.value?.maxZoomRatio ?: 1f + ) + } + } catch (e: Exception) { + e.message?.let { Log.e(LOG_TAG, it) } + setResult(OSBARCError.SCANNING_GENERAL_ERROR.code) + finish() } - } catch (e: Exception) { - e.message?.let { Log.e(LOG_TAG, it) } - setResult(OSBARCError.SCANNING_GENERAL_ERROR.code) - finish() - } - previewView - }, - modifier = Modifier.fillMaxSize() - ) + previewView + }, + modifier = Modifier.fillMaxSize() + ) + } ScanScreenUI(parameters, windowSizeClass, uiState) @@ -957,6 +943,13 @@ class OSBARCScannerActivity : ComponentActivity() { ) == PackageManager.PERMISSION_GRANTED } + private fun updatePermissionState(hasPermission: Boolean) { + permissionGiven = hasPermission + if (permissionRequestCount > 0) { + showDialog = !hasPermission + } + } + private fun processReadSuccess(result: OSBARCScanResult) { // we only want to process the scan result if scanning is active if (isScanning) { From b321fe8e047f865b1b573ca58bce7310bc7daa03 Mon Sep 17 00:00:00 2001 From: OS-pedrogustavobilro Date: Mon, 3 Aug 2026 12:49:41 +0100 Subject: [PATCH 2/2] chore(release): prepare version 2.1.1 --- CHANGELOG.md | 6 ++++++ docs/README.md | 2 +- pom.xml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b178c7..1ddea46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 The changes documented here do not include those from the original repository. +# [2.1.1] + +### 2026-08-03 + +- Show camera preview only after permission is granted. This issue was uncovered while updating a consumer app's androidx camera2 dependency do 1.6.2 (https://outsystemsrd.atlassian.net/browse/RMET-5329 + https://github.com/OutSystems/OSBarcodeLib-Android/issues/57) + # [2.1.0] ### 2026-06-26 diff --git a/docs/README.md b/docs/README.md index f4b7856..b4fa9e1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -46,7 +46,7 @@ In your app-level gradle file, import the OSBarcodeLib library like so: ```gradle dependencies { - implementation("com.github.outsystems:osbarcode-android:2.1.0@aar") + implementation("com.github.outsystems:osbarcode-android:2.1.1@aar") } ``` diff --git a/pom.xml b/pom.xml index 5ae04cd..ddde6e8 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 io.ionic.libs ionbarcode-android - 2.1.0 + 2.1.1