From 1de666fbd072a88a983aa62f999a23d14d6fc8c1 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 15:07:19 +0000 Subject: [PATCH 01/24] feat: implement flashlight Context: The flashlight button should only be presented if the flashlight is available in the camera that is being used (front or back). References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../barcode/view/OSBARCScannerActivity.kt | 75 ++++++++++++++++--- 1 file changed, 64 insertions(+), 11 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 ec5d34c..e2b156b 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -4,29 +4,37 @@ import android.Manifest import android.content.Context import android.content.Intent import android.content.pm.PackageManager +import android.hardware.camera2.CameraAccessException +import android.hardware.camera2.CameraCharacteristics +import android.hardware.camera2.CameraManager import android.net.Uri import android.os.Bundle import android.provider.Settings import android.util.Log import androidx.activity.ComponentActivity +import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.setContent +import androidx.activity.result.contract.ActivityResultContracts +import androidx.camera.core.Camera import androidx.camera.core.CameraSelector import androidx.camera.core.ImageAnalysis +import androidx.camera.core.ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST import androidx.camera.core.Preview import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.view.PreviewView import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Info +import androidx.compose.material3.Button +import androidx.compose.material3.Icon import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.camera.core.ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST import androidx.compose.ui.Modifier -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.runtime.SideEffect import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.viewinterop.AndroidView @@ -38,7 +46,6 @@ import com.outsystems.plugins.barcode.controller.helper.OSBARCZXingHelper import com.outsystems.plugins.barcode.model.OSBARCError import com.outsystems.plugins.barcode.model.OSBARCScanParameters import com.outsystems.plugins.barcode.view.ui.theme.BarcodeScannerTheme -import java.lang.Exception /** * This class is responsible for implementing the UI of the scanning screen using Jetpack Compose. @@ -46,7 +53,8 @@ import java.lang.Exception * implements the ImageAnalysis.Analyzer interface. */ class OSBARCScannerActivity : ComponentActivity() { - + private lateinit var camera: Camera + private lateinit var selector: CameraSelector private var permissionRequestCount = 0 private var showDialog by mutableStateOf(false) @@ -64,9 +72,14 @@ class OSBARCScannerActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + val parameters = intent.extras?.getSerializable(SCAN_PARAMETERS) as OSBARCScanParameters + selector = CameraSelector.Builder() + .requireLensFacing(if (parameters.cameraDirection == CAM_DIRECTION_FRONT) CameraSelector.LENS_FACING_FRONT else CameraSelector.LENS_FACING_BACK) + .build() + setContent { BarcodeScannerTheme { - ScanScreen(intent.extras?.getSerializable(SCAN_PARAMETERS) as OSBARCScanParameters) + ScanScreen(parameters) } } } @@ -138,9 +151,6 @@ class OSBARCScannerActivity : ComponentActivity() { factory = { context -> val previewView = PreviewView(context) val preview = Preview.Builder().build() - val selector = CameraSelector.Builder() - .requireLensFacing(if (parameters.cameraDirection == CAM_DIRECTION_FRONT) CameraSelector.LENS_FACING_FRONT else CameraSelector.LENS_FACING_BACK) - .build() preview.setSurfaceProvider(previewView.surfaceProvider) val imageAnalysis = ImageAnalysis.Builder() .setBackpressureStrategy(STRATEGY_KEEP_ONLY_LATEST) @@ -166,7 +176,7 @@ class OSBARCScannerActivity : ComponentActivity() { ) ) try { - cameraProviderFuture.get().bindToLifecycle( + camera = cameraProviderFuture.get().bindToLifecycle( lifecycleOwner, selector, preview, @@ -181,6 +191,28 @@ class OSBARCScannerActivity : ComponentActivity() { }, modifier = Modifier.weight(1f) ) + + if (isFlashAvailable(context)) { + TorchButton() + } + } + } + + @Composable + fun TorchButton() { + var isFlashlightOn by remember { mutableStateOf(false) } + + Button( + onClick = { + toggleFlashlight(isFlashlightOn) + isFlashlightOn = !isFlashlightOn + }, + modifier = Modifier, + ) { + Icon( + imageVector = Icons.Default.Info, + contentDescription = "Torch" + ) } } @@ -191,4 +223,25 @@ class OSBARCScannerActivity : ComponentActivity() { ) == PackageManager.PERMISSION_GRANTED } + private fun toggleFlashlight(isFlashlightOn: Boolean) { + try { + camera.cameraControl.enableTorch(!isFlashlightOn) + } catch (e: CameraAccessException) { + e.message?.let { Log.e(LOG_TAG, it) } + } catch (e: Exception) { + e.message?.let { Log.e(LOG_TAG, it) } + } + } + + private fun isFlashAvailable(context: Context): Boolean { + val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager + val cameraId = cameraManager.cameraIdList.find { + val characteristics = cameraManager.getCameraCharacteristics(it) + val facing = characteristics.get(CameraCharacteristics.LENS_FACING) + facing == selector.lensFacing + } + if (cameraId.isNullOrEmpty()) return false + return cameraManager.getCameraCharacteristics(cameraId).get(CameraCharacteristics.FLASH_INFO_AVAILABLE) == true + } + } \ No newline at end of file From 2b024786903fe66db13e45fbb38d69ca51dd239c Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 16:16:28 +0000 Subject: [PATCH 02/24] refactor: use hasFlashUnit to determine if camera has flash Context: Our previous way of determining if the camera had a flashlight available was using the "isFlashAvailable" helper method. This method required a SuppressLint("RestrictedApi") annotation because of "selector.lensFacing". We should avoid using this specific annotation, and method "selector.lensFacing" isn't supposed to be used. References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../barcode/view/OSBARCScannerActivity.kt | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 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 e2b156b..cbb633d 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -5,8 +5,6 @@ import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.hardware.camera2.CameraAccessException -import android.hardware.camera2.CameraCharacteristics -import android.hardware.camera2.CameraManager import android.net.Uri import android.os.Bundle import android.provider.Settings @@ -144,6 +142,17 @@ 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() + } + Column ( modifier = Modifier.fillMaxSize() ) { @@ -192,7 +201,7 @@ class OSBARCScannerActivity : ComponentActivity() { modifier = Modifier.weight(1f) ) - if (isFlashAvailable(context)) { + if (camera.cameraInfo.hasFlashUnit()) { TorchButton() } } @@ -233,15 +242,4 @@ class OSBARCScannerActivity : ComponentActivity() { } } - private fun isFlashAvailable(context: Context): Boolean { - val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager - val cameraId = cameraManager.cameraIdList.find { - val characteristics = cameraManager.getCameraCharacteristics(it) - val facing = characteristics.get(CameraCharacteristics.LENS_FACING) - facing == selector.lensFacing - } - if (cameraId.isNullOrEmpty()) return false - return cameraManager.getCameraCharacteristics(cameraId).get(CameraCharacteristics.FLASH_INFO_AVAILABLE) == true - } - } \ No newline at end of file From b6f998c9862f26ca3fc599e3979eee15a16da171 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 16:20:32 +0000 Subject: [PATCH 03/24] chore: raise lib version to 0.0.15 References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c59e8ec..fa3f3c5 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 0.0.14 + 0.0.15 From a377eb685aebc739af7739bb97d74d9107dfb678 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 16:44:48 +0000 Subject: [PATCH 04/24] refactor: remove extra line References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 1 - 1 file changed, 1 deletion(-) 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 cbb633d..c3b313a 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -210,7 +210,6 @@ class OSBARCScannerActivity : ComponentActivity() { @Composable fun TorchButton() { var isFlashlightOn by remember { mutableStateOf(false) } - Button( onClick = { toggleFlashlight(isFlashlightOn) From ac6c8bc310c3d3e00798cd5ae73d46316c7c5b75 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 17:47:50 +0000 Subject: [PATCH 05/24] feat: update button according to flashlight state Context: We need to use different images to represent the on and off state. References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../barcode/view/OSBARCScannerActivity.kt | 24 ++++++++++++++----- src/main/res/drawable/flash_off.xml | 10 ++++++++ src/main/res/drawable/flash_on.xml | 10 ++++++++ 3 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 src/main/res/drawable/flash_off.xml create mode 100644 src/main/res/drawable/flash_on.xml 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 c3b313a..569d8e6 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -20,12 +20,12 @@ import androidx.camera.core.ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST import androidx.camera.core.Preview import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.view.PreviewView +import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Info +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Button -import androidx.compose.material3.Icon +import androidx.compose.material3.ButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue @@ -33,10 +33,13 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner +import androidx.compose.ui.res.painterResource import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.ContextCompat +import com.outsystems.plugins.barcode.R import com.outsystems.plugins.barcode.controller.OSBARCBarcodeAnalyzer import com.outsystems.plugins.barcode.controller.OSBARCScanLibraryFactory import com.outsystems.plugins.barcode.controller.helper.OSBARCMLKitHelper @@ -210,18 +213,27 @@ class OSBARCScannerActivity : ComponentActivity() { @Composable fun TorchButton() { var isFlashlightOn by remember { mutableStateOf(false) } + val onIcon = painterResource(id = R.drawable.flash_on) + val offIcon = painterResource(id = R.drawable.flash_off) + Button( onClick = { toggleFlashlight(isFlashlightOn) isFlashlightOn = !isFlashlightOn }, modifier = Modifier, + colors = ButtonDefaults.buttonColors( + containerColor = if (isFlashlightOn) Color.White else Color.Black + ), + shape = CircleShape ) { - Icon( - imageVector = Icons.Default.Info, - contentDescription = "Torch" + val icon = if (isFlashlightOn) onIcon else offIcon + Image( + painter = icon, + contentDescription = null ) } + } private fun hasCameraPermission(context: Context): Boolean { diff --git a/src/main/res/drawable/flash_off.xml b/src/main/res/drawable/flash_off.xml new file mode 100644 index 0000000..d6342f5 --- /dev/null +++ b/src/main/res/drawable/flash_off.xml @@ -0,0 +1,10 @@ + + + diff --git a/src/main/res/drawable/flash_on.xml b/src/main/res/drawable/flash_on.xml new file mode 100644 index 0000000..9ffd696 --- /dev/null +++ b/src/main/res/drawable/flash_on.xml @@ -0,0 +1,10 @@ + + + From 6ceaecd91830253ab1fa5b18923c680a4997908a Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 18:14:01 +0000 Subject: [PATCH 06/24] refactor: replace Column with Box Context: We want to overlay Buttons and more elements on top of the Camera view. To do that, we need to use the Box composable that is designed for that. References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../barcode/view/OSBARCScannerActivity.kt | 59 ++++++++----------- 1 file changed, 26 insertions(+), 33 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 569d8e6..1bea316 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -21,7 +21,7 @@ import androidx.camera.core.Preview import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.view.PreviewView import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Button @@ -32,6 +32,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext @@ -39,7 +40,6 @@ import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.painterResource import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.ContextCompat -import com.outsystems.plugins.barcode.R import com.outsystems.plugins.barcode.controller.OSBARCBarcodeAnalyzer import com.outsystems.plugins.barcode.controller.OSBARCScanLibraryFactory import com.outsystems.plugins.barcode.controller.helper.OSBARCMLKitHelper @@ -47,6 +47,7 @@ import com.outsystems.plugins.barcode.controller.helper.OSBARCZXingHelper import com.outsystems.plugins.barcode.model.OSBARCError import com.outsystems.plugins.barcode.model.OSBARCScanParameters import com.outsystems.plugins.barcode.view.ui.theme.BarcodeScannerTheme +import com.outsystemsenterprise.enmobile11dev.BarcodeSampleAppNew.R /** * This class is responsible for implementing the UI of the scanning screen using Jetpack Compose. @@ -156,9 +157,7 @@ class OSBARCScannerActivity : ComponentActivity() { finish() } - Column ( - modifier = Modifier.fillMaxSize() - ) { + Box(modifier = Modifier.fillMaxSize()) { AndroidView( factory = { context -> val previewView = PreviewView(context) @@ -200,39 +199,33 @@ class OSBARCScannerActivity : ComponentActivity() { finish() } previewView - }, - modifier = Modifier.weight(1f) + } ) if (camera.cameraInfo.hasFlashUnit()) { - TorchButton() + var isFlashlightOn by remember { mutableStateOf(false) } + val onIcon = painterResource(id = R.drawable.flash_on) + val offIcon = painterResource(id = R.drawable.flash_off) + + Button( + onClick = { + toggleFlashlight(isFlashlightOn) + isFlashlightOn = !isFlashlightOn + }, + modifier = Modifier.align(Alignment.BottomEnd), + colors = ButtonDefaults.buttonColors( + containerColor = if (isFlashlightOn) Color.White else Color.Black + ), + shape = CircleShape + ) { + val icon = if (isFlashlightOn) onIcon else offIcon + Image( + painter = icon, + contentDescription = null + ) + } } } - } - - @Composable - fun TorchButton() { - var isFlashlightOn by remember { mutableStateOf(false) } - val onIcon = painterResource(id = R.drawable.flash_on) - val offIcon = painterResource(id = R.drawable.flash_off) - - Button( - onClick = { - toggleFlashlight(isFlashlightOn) - isFlashlightOn = !isFlashlightOn - }, - modifier = Modifier, - colors = ButtonDefaults.buttonColors( - containerColor = if (isFlashlightOn) Color.White else Color.Black - ), - shape = CircleShape - ) { - val icon = if (isFlashlightOn) onIcon else offIcon - Image( - painter = icon, - contentDescription = null - ) - } } From dd4896be4f416dcd4a368fdb19475664a08159a5 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 18:14:25 +0000 Subject: [PATCH 07/24] chore: raise lib version to 0.0.16 References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fa3f3c5..7942fc2 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 0.0.15 + 0.0.16 From 8ae91a80da78a7f5082961ca2e952586f081cb37 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 18:16:05 +0000 Subject: [PATCH 08/24] fix: properly import R class References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 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 1bea316..a35dc88 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -40,6 +40,7 @@ import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.painterResource import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.ContextCompat +import com.outsystems.plugins.barcode.R import com.outsystems.plugins.barcode.controller.OSBARCBarcodeAnalyzer import com.outsystems.plugins.barcode.controller.OSBARCScanLibraryFactory import com.outsystems.plugins.barcode.controller.helper.OSBARCMLKitHelper @@ -47,7 +48,6 @@ import com.outsystems.plugins.barcode.controller.helper.OSBARCZXingHelper import com.outsystems.plugins.barcode.model.OSBARCError import com.outsystems.plugins.barcode.model.OSBARCScanParameters import com.outsystems.plugins.barcode.view.ui.theme.BarcodeScannerTheme -import com.outsystemsenterprise.enmobile11dev.BarcodeSampleAppNew.R /** * This class is responsible for implementing the UI of the scanning screen using Jetpack Compose. @@ -206,7 +206,7 @@ class OSBARCScannerActivity : ComponentActivity() { var isFlashlightOn by remember { mutableStateOf(false) } val onIcon = painterResource(id = R.drawable.flash_on) val offIcon = painterResource(id = R.drawable.flash_off) - + Button( onClick = { toggleFlashlight(isFlashlightOn) From c2f405cb0a7bbc492fb0ed8d4be5ed8a1423fc16 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 18:30:05 +0000 Subject: [PATCH 09/24] refactor: use helper method for flashlight button References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../barcode/view/OSBARCScannerActivity.kt | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 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 a35dc88..b7101e8 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -32,7 +32,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext @@ -203,32 +202,36 @@ class OSBARCScannerActivity : ComponentActivity() { ) if (camera.cameraInfo.hasFlashUnit()) { - var isFlashlightOn by remember { mutableStateOf(false) } - val onIcon = painterResource(id = R.drawable.flash_on) - val offIcon = painterResource(id = R.drawable.flash_off) - - Button( - onClick = { - toggleFlashlight(isFlashlightOn) - isFlashlightOn = !isFlashlightOn - }, - modifier = Modifier.align(Alignment.BottomEnd), - colors = ButtonDefaults.buttonColors( - containerColor = if (isFlashlightOn) Color.White else Color.Black - ), - shape = CircleShape - ) { - val icon = if (isFlashlightOn) onIcon else offIcon - Image( - painter = icon, - contentDescription = null - ) - } + TorchButton() } } } + @Composable + fun TorchButton() { + var isFlashlightOn by remember { mutableStateOf(false) } + val onIcon = painterResource(id = R.drawable.flash_on) + val offIcon = painterResource(id = R.drawable.flash_off) + + Button( + onClick = { + toggleFlashlight(isFlashlightOn) + isFlashlightOn = !isFlashlightOn + }, + colors = ButtonDefaults.buttonColors( + containerColor = if (isFlashlightOn) Color.White else Color.Black + ), + shape = CircleShape + ) { + val icon = if (isFlashlightOn) onIcon else offIcon + Image( + painter = icon, + contentDescription = null + ) + } + } + private fun hasCameraPermission(context: Context): Boolean { return ContextCompat.checkSelfPermission( context, From d5056155baa300a88b1da04eeba9ce325a5bcc67 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 18:33:07 +0000 Subject: [PATCH 10/24] chore: raise lib version to 0.0.17 References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7942fc2..387af7f 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 0.0.16 + 0.0.17 From 9ef7d46f8c8550f2d7c9afe25fbfdfff262eb59f Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 19:00:20 +0000 Subject: [PATCH 11/24] chore: update changelog References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21b75e5..3ad77c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ The changes documented here do not include those from the original repository. ## [Unreleased] +### 14-11-2023 +Android - Implement Torch Button to settings (https://outsystemsrd.atlassian.net/browse/RMET-2759) + ### 13-11-2023 Android - Implement AlertDialog to settings (https://outsystemsrd.atlassian.net/browse/RMET-2764) From 41f141bc009d796cfc77131727b7b42971803af4 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 19:17:17 +0000 Subject: [PATCH 12/24] test: use theme to remove action bar from activity References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- src/main/AndroidManifest.xml | 3 ++- src/main/res/values/styles.xml | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 src/main/res/values/styles.xml diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 46c545d..5220d30 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -5,6 +5,7 @@ + android:exported="false" + android:theme="@style/AppTheme.NoActionBar"/> \ No newline at end of file diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml new file mode 100644 index 0000000..ce8f742 --- /dev/null +++ b/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file From b39c2a152cd8d6d0a37480f62fc4e5853a210cd0 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 19:17:37 +0000 Subject: [PATCH 13/24] chore: raise lib version to 0.0.18 References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 387af7f..f7c004d 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 0.0.17 + 0.0.18 From 195ce5ff237e7f5e25db30055a989a5448fae5f6 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 19:31:23 +0000 Subject: [PATCH 14/24] Revert "test: use theme to remove action bar from activity" This reverts commit 41f141bc009d796cfc77131727b7b42971803af4. --- src/main/AndroidManifest.xml | 3 +-- src/main/res/values/styles.xml | 8 -------- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 src/main/res/values/styles.xml diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 5220d30..46c545d 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -5,7 +5,6 @@ + android:exported="false" /> \ No newline at end of file diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml deleted file mode 100644 index ce8f742..0000000 --- a/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file From e7718a4814f10e39e326775da3c7d6390efa5377 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 19:34:25 +0000 Subject: [PATCH 15/24] fix: hide action bar References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 2 ++ 1 file changed, 2 insertions(+) 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 b7101e8..3d9421c 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -73,6 +73,8 @@ class OSBARCScannerActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + actionBar?.hide() + val parameters = intent.extras?.getSerializable(SCAN_PARAMETERS) as OSBARCScanParameters selector = CameraSelector.Builder() .requireLensFacing(if (parameters.cameraDirection == CAM_DIRECTION_FRONT) CameraSelector.LENS_FACING_FRONT else CameraSelector.LENS_FACING_BACK) From c1283372985750129f7793499f711213e8d1e3d6 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 19:34:44 +0000 Subject: [PATCH 16/24] chore: raise lib version to 0.0.19 References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f7c004d..5577903 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 0.0.18 + 0.0.19 From 8394489dbea08b349402e5c0f0a674be69a8cbaa Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 20:08:20 +0000 Subject: [PATCH 17/24] Revert "fix: hide action bar" This reverts commit e7718a4814f10e39e326775da3c7d6390efa5377. --- .../outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 2 -- 1 file changed, 2 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 3d9421c..b7101e8 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -73,8 +73,6 @@ class OSBARCScannerActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - actionBar?.hide() - val parameters = intent.extras?.getSerializable(SCAN_PARAMETERS) as OSBARCScanParameters selector = CameraSelector.Builder() .requireLensFacing(if (parameters.cameraDirection == CAM_DIRECTION_FRONT) CameraSelector.LENS_FACING_FRONT else CameraSelector.LENS_FACING_BACK) From d0b8c3702cdc21f6e9079088590243701f57624c Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 20:26:49 +0000 Subject: [PATCH 18/24] feat: hide action bar (title bar) and fill the whole screen with Camera stream References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 b7101e8..41714cc 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -72,6 +72,7 @@ class OSBARCScannerActivity : ComponentActivity() { */ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + actionBar?.hide() val parameters = intent.extras?.getSerializable(SCAN_PARAMETERS) as OSBARCScanParameters selector = CameraSelector.Builder() @@ -198,7 +199,8 @@ class OSBARCScannerActivity : ComponentActivity() { finish() } previewView - } + }, + modifier = Modifier.fillMaxSize() ) if (camera.cameraInfo.hasFlashUnit()) { From b4a9247048ec38768a8c6ce8a76b0ff8d4c65f4d Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 20:27:08 +0000 Subject: [PATCH 19/24] chore: raise lib version to 0.0.20 References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5577903..e0e1c63 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 0.0.19 + 0.0.20 From 47bb7afeb0018197c3bc33d7ed30722236186de9 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 20:33:53 +0000 Subject: [PATCH 20/24] misc: add extra line References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 1 + 1 file changed, 1 insertion(+) 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 41714cc..5a078b4 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -206,6 +206,7 @@ class OSBARCScannerActivity : ComponentActivity() { if (camera.cameraInfo.hasFlashUnit()) { TorchButton() } + } } From 8914520db4f16064009fc91bdb217bfce257846c Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Wed, 15 Nov 2023 08:18:07 +0000 Subject: [PATCH 21/24] refactor: remove extra lines References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 2 -- 1 file changed, 2 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 5a078b4..608b4b8 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -206,9 +206,7 @@ class OSBARCScannerActivity : ComponentActivity() { if (camera.cameraInfo.hasFlashUnit()) { TorchButton() } - } - } @Composable From 5ae992cbec9448c0a02ddfe876d18ab8bfa9fe4d Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Wed, 15 Nov 2023 09:32:57 +0000 Subject: [PATCH 22/24] refactor: only use one catch Context: Since both catches do the exact same thing, we might as well only catch "Exception", that will include "CameraAccessException". References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 2 -- 1 file changed, 2 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 608b4b8..70bfaae 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -243,8 +243,6 @@ class OSBARCScannerActivity : ComponentActivity() { private fun toggleFlashlight(isFlashlightOn: Boolean) { try { camera.cameraControl.enableTorch(!isFlashlightOn) - } catch (e: CameraAccessException) { - e.message?.let { Log.e(LOG_TAG, it) } } catch (e: Exception) { e.message?.let { Log.e(LOG_TAG, it) } } From 4d5fc6a28f8430d62acdbb38aa732f941a3ec92d Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Wed, 15 Nov 2023 09:38:49 +0000 Subject: [PATCH 23/24] refactor: remove unused import References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 1 - 1 file changed, 1 deletion(-) 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 70bfaae..841ffe8 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -4,7 +4,6 @@ import android.Manifest import android.content.Context import android.content.Intent import android.content.pm.PackageManager -import android.hardware.camera2.CameraAccessException import android.net.Uri import android.os.Bundle import android.provider.Settings From 38251b3e2a4f254eebdab517b2bb01438af95f3a Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Wed, 15 Nov 2023 09:46:56 +0000 Subject: [PATCH 24/24] fix: only set isFlashlightOn if enableTorch goes OK Context: If "enableTorch" throws an exception, we don't want to alter the value of "isFlashlightOn" because we failed to alter the flashlight's state. References: https://outsystemsrd.atlassian.net/browse/RMET-2759 --- .../barcode/view/OSBARCScannerActivity.kt | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 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 841ffe8..7dc815c 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -216,8 +216,12 @@ class OSBARCScannerActivity : ComponentActivity() { Button( onClick = { - toggleFlashlight(isFlashlightOn) - isFlashlightOn = !isFlashlightOn + try { + camera.cameraControl.enableTorch(!isFlashlightOn) + isFlashlightOn = !isFlashlightOn + } catch (e: Exception) { + e.message?.let { Log.e(LOG_TAG, it) } + } }, colors = ButtonDefaults.buttonColors( containerColor = if (isFlashlightOn) Color.White else Color.Black @@ -239,12 +243,4 @@ class OSBARCScannerActivity : ComponentActivity() { ) == PackageManager.PERMISSION_GRANTED } - private fun toggleFlashlight(isFlashlightOn: Boolean) { - try { - camera.cameraControl.enableTorch(!isFlashlightOn) - } catch (e: Exception) { - e.message?.let { Log.e(LOG_TAG, it) } - } - } - } \ No newline at end of file