Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
```

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.ionic.libs</groupId>
<artifactId>ionbarcode-android</artifactId>
<version>2.1.0</version>
<version>2.1.1</version>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -213,7 +214,7 @@ class OSBARCScannerActivity : ComponentActivity() {

override fun onResume() {
super.onResume()
showDialog = !hasCameraPermission(this.applicationContext)
updatePermissionState(hasCameraPermission(this.applicationContext))
}

override fun onDestroy() {
Expand All @@ -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) {
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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) {
Expand Down
Loading