From a3f575581f1c5b60d6ac383779f2034471c4c88d Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Mon, 13 Nov 2023 17:45:39 +0000 Subject: [PATCH 1/9] feat: show alert dialog when camera permission is denied Context: Following the UI/UX design, we should present this dialog when the permission to the camera is denied, so that the user can more easily navigate to the settings. References: https://outsystemsrd.atlassian.net/browse/RMET-2764 --- .../barcode/view/OSBARCScannerActivity.kt | 99 +++++++++++++++++-- 1 file changed, 93 insertions(+), 6 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 9ecbb6e..c4d6973 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -1,7 +1,10 @@ package com.outsystems.plugins.barcode.view import android.Manifest +import android.content.Context import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri import android.os.Bundle import android.util.Log import androidx.activity.ComponentActivity @@ -22,9 +25,13 @@ 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.material3.AlertDialog +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.SideEffect import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner +import androidx.compose.ui.unit.sp import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.ContextCompat import com.outsystems.plugins.barcode.controller.OSBARCBarcodeAnalyzer @@ -43,6 +50,9 @@ import java.lang.Exception */ class OSBARCScannerActivity : ComponentActivity() { + private var permissionRequestCount = 0 + private var showDialog by mutableStateOf(false) + companion object { private const val SCAN_SUCCESS_RESULT_CODE = -1 private const val SCAN_RESULT = "scanResult" @@ -51,8 +61,6 @@ class OSBARCScannerActivity : ComponentActivity() { private const val CAM_DIRECTION_FRONT = 2 } - private lateinit var parameters: OSBARCScanParameters - /** * Overrides the onCreate method from Activity, setting the UI of the screen */ @@ -66,6 +74,13 @@ class OSBARCScannerActivity : ComponentActivity() { } } + override fun onResume() { + super.onResume() + if (!hasCameraPermission(this.applicationContext)) { + showDialog = true + } + } + /** * Composable function, responsible for declaring the UI of the screen, * as well as creating an instance of OSBARCBarcodeAnalyzer for image analysis. @@ -74,20 +89,33 @@ class OSBARCScannerActivity : ComponentActivity() { fun ScanScreen(parameters: OSBARCScanParameters) { val lifecycleOwner = LocalLifecycleOwner.current val context = LocalContext.current + var permissionGiven by remember { mutableStateOf(true) } // permissions val requestPermissionLauncher = rememberLauncherForActivityResult( ActivityResultContracts.RequestPermission() ) { isGranted: Boolean -> if (isGranted) { - // do nothing, continue + permissionGiven = true + showDialog = false } else { - this.setResult(OSBARCError.CAMERA_PERMISSION_DENIED_ERROR.code) - this.finish() + permissionGiven = false + showDialog = true } } SideEffect { - requestPermissionLauncher.launch(Manifest.permission.CAMERA) + if (permissionRequestCount == 0) { + permissionRequestCount++ + requestPermissionLauncher.launch(Manifest.permission.CAMERA) + } + } + + if (!permissionGiven) { + CameraPermissionRequiredDialog( + showDialog, + dialogTitle = "Camera Access Not Enabled", + dialogText = "To continue, please go to the Settings app and enable it." + ) } // rest of the UI @@ -152,4 +180,63 @@ class OSBARCScannerActivity : ComponentActivity() { } } + @Composable + fun CameraPermissionRequiredDialog( + shouldShowDialog: Boolean, + dialogTitle: String, + dialogText: String, + ) { + var dialogOpen by remember { mutableStateOf(true) } + val context = LocalContext.current + + if (shouldShowDialog) { + AlertDialog( + title = { + Text( + text = dialogTitle, + fontSize = 20.sp + ) + }, + text = { + Text(text = dialogText) + }, + onDismissRequest = { + dialogOpen = false + }, + confirmButton = { + TextButton( + onClick = { + showDialog = false + val intent = Intent().apply { + action = android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS + data = Uri.fromParts("package", context.packageName, null) + } + context.startActivity(intent) + } + ) { + Text("Settings") + } + }, + dismissButton = { + TextButton( + onClick = { + showDialog = false + this.setResult(OSBARCError.CAMERA_PERMISSION_DENIED_ERROR.code) + this.finish() + } + ) { + Text("Ok") + } + } + ) + } + } + + private fun hasCameraPermission(context: Context): Boolean { + return ContextCompat.checkSelfPermission( + context, + Manifest.permission.CAMERA + ) == PackageManager.PERMISSION_GRANTED + } + } \ No newline at end of file From a3370cc5c2a6b63ed9b04554b0f0a69a9a350ff2 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Mon, 13 Nov 2023 18:24:10 +0000 Subject: [PATCH 2/9] refactor: use separate file for dialog References: https://outsystemsrd.atlassian.net/browse/RMET-2764 --- .../view/OSBARCCameraPermissionDialog.kt | 51 +++++++++++++ .../barcode/view/OSBARCScannerActivity.kt | 72 ++++--------------- 2 files changed, 64 insertions(+), 59 deletions(-) create mode 100644 src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCCameraPermissionDialog.kt diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCCameraPermissionDialog.kt b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCCameraPermissionDialog.kt new file mode 100644 index 0000000..bd32264 --- /dev/null +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCCameraPermissionDialog.kt @@ -0,0 +1,51 @@ +package com.outsystems.plugins.barcode.view + +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.unit.sp + +@Composable +fun CameraPermissionRequiredDialog( + onDismissRequest: () -> Unit, + onConfirmation: () -> Unit, + shouldShowDialog: Boolean, + dialogTitle: String, + dialogText: String, +) { + if (shouldShowDialog) { + AlertDialog( + title = { + Text( + text = dialogTitle, + fontSize = 20.sp + ) + }, + text = { + Text(text = dialogText) + }, + onDismissRequest = { + onDismissRequest() + }, + confirmButton = { + TextButton( + onClick = { + onConfirmation() + } + ) { + Text("Settings") + } + }, + dismissButton = { + TextButton( + onClick = { + onDismissRequest() + } + ) { + Text("Ok") + } + } + ) + } +} \ No newline at end of file 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 c4d6973..c916b14 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -6,6 +6,7 @@ import android.content.Intent import android.content.pm.PackageManager import android.net.Uri import android.os.Bundle +import android.provider.Settings import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -25,13 +26,9 @@ 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.material3.AlertDialog -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton import androidx.compose.runtime.SideEffect import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.compose.ui.unit.sp import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.ContextCompat import com.outsystems.plugins.barcode.controller.OSBARCBarcodeAnalyzer @@ -76,9 +73,7 @@ class OSBARCScannerActivity : ComponentActivity() { override fun onResume() { super.onResume() - if (!hasCameraPermission(this.applicationContext)) { - showDialog = true - } + showDialog = !hasCameraPermission(this.applicationContext) } /** @@ -112,6 +107,17 @@ class OSBARCScannerActivity : ComponentActivity() { if (!permissionGiven) { CameraPermissionRequiredDialog( + { + this.setResult(OSBARCError.CAMERA_PERMISSION_DENIED_ERROR.code) + this.finish() + }, + { + val intent = Intent().apply { + action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS + data = Uri.fromParts("package", context.packageName, null) + } + context.startActivity(intent) + }, showDialog, dialogTitle = "Camera Access Not Enabled", dialogText = "To continue, please go to the Settings app and enable it." @@ -180,58 +186,6 @@ class OSBARCScannerActivity : ComponentActivity() { } } - @Composable - fun CameraPermissionRequiredDialog( - shouldShowDialog: Boolean, - dialogTitle: String, - dialogText: String, - ) { - var dialogOpen by remember { mutableStateOf(true) } - val context = LocalContext.current - - if (shouldShowDialog) { - AlertDialog( - title = { - Text( - text = dialogTitle, - fontSize = 20.sp - ) - }, - text = { - Text(text = dialogText) - }, - onDismissRequest = { - dialogOpen = false - }, - confirmButton = { - TextButton( - onClick = { - showDialog = false - val intent = Intent().apply { - action = android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS - data = Uri.fromParts("package", context.packageName, null) - } - context.startActivity(intent) - } - ) { - Text("Settings") - } - }, - dismissButton = { - TextButton( - onClick = { - showDialog = false - this.setResult(OSBARCError.CAMERA_PERMISSION_DENIED_ERROR.code) - this.finish() - } - ) { - Text("Ok") - } - } - ) - } - } - private fun hasCameraPermission(context: Context): Boolean { return ContextCompat.checkSelfPermission( context, From 1aca15bfa05f944c579c4d92c6413fd4d1967a5b Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Mon, 13 Nov 2023 18:24:36 +0000 Subject: [PATCH 3/9] refactor: remove unused variable References: https://outsystemsrd.atlassian.net/browse/RMET-2764 --- .../outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 4 ---- 1 file changed, 4 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 c916b14..ce3b35b 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -128,9 +128,6 @@ class OSBARCScannerActivity : ComponentActivity() { val cameraProviderFuture = remember { ProcessCameraProvider.getInstance(context) } - var barcode by remember { - mutableStateOf("") - } Column ( modifier = Modifier.fillMaxSize() @@ -155,7 +152,6 @@ class OSBARCScannerActivity : ComponentActivity() { OSBARCMLKitHelper() ), // temporary { result -> - barcode = result val resultIntent = Intent() resultIntent.putExtra(SCAN_RESULT, result) setResult(SCAN_SUCCESS_RESULT_CODE, resultIntent) From 73a7f6123d739feec2062d3e6216d9455531e03b Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Mon, 13 Nov 2023 18:27:10 +0000 Subject: [PATCH 4/9] chore: raise lib version to 0.0.13 References: https://outsystemsrd.atlassian.net/browse/RMET-2764 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ecaadcf..63abe3d 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 0.0.12 + 0.0.13 From 2781a655a344d3f1f01ad07c355c92d50c7b0a22 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 09:13:29 +0000 Subject: [PATCH 5/9] refactor: include buttons text as parameters References: https://outsystemsrd.atlassian.net/browse/RMET-2764 --- .../plugins/barcode/view/OSBARCCameraPermissionDialog.kt | 6 ++++-- .../plugins/barcode/view/OSBARCScannerActivity.kt | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCCameraPermissionDialog.kt b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCCameraPermissionDialog.kt index bd32264..4e31b4a 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCCameraPermissionDialog.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCCameraPermissionDialog.kt @@ -13,6 +13,8 @@ fun CameraPermissionRequiredDialog( shouldShowDialog: Boolean, dialogTitle: String, dialogText: String, + confirmButtonText: String, + dismissButtonText: String ) { if (shouldShowDialog) { AlertDialog( @@ -34,7 +36,7 @@ fun CameraPermissionRequiredDialog( onConfirmation() } ) { - Text("Settings") + Text(confirmButtonText) } }, dismissButton = { @@ -43,7 +45,7 @@ fun CameraPermissionRequiredDialog( onDismissRequest() } ) { - Text("Ok") + Text(dismissButtonText) } } ) 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 ce3b35b..a92545b 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -120,7 +120,9 @@ class OSBARCScannerActivity : ComponentActivity() { }, showDialog, dialogTitle = "Camera Access Not Enabled", - dialogText = "To continue, please go to the Settings app and enable it." + dialogText = "To continue, please go to the Settings app and enable it.", + "Settings", + "Ok" ) } From 51a077116ccaf81a42f98d6f5f18e5432339d480 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 09:14:04 +0000 Subject: [PATCH 6/9] chore: raise lib version to 0.0.14 References: https://outsystemsrd.atlassian.net/browse/RMET-2764 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 63abe3d..c59e8ec 100644 --- a/pom.xml +++ b/pom.xml @@ -7,5 +7,5 @@ 4.0.0 com.github.outsystems osbarcode-android - 0.0.13 + 0.0.14 From edf6224884e09451d8f48c154e9d6e5626900d13 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 09:15:17 +0000 Subject: [PATCH 7/9] chore: remove comment References: https://outsystemsrd.atlassian.net/browse/RMET-2764 --- .../outsystems/plugins/barcode/view/OSBARCScannerActivity.kt | 2 +- 1 file changed, 1 insertion(+), 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 a92545b..5ad10d2 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -152,7 +152,7 @@ class OSBARCScannerActivity : ComponentActivity() { parameters.androidScanningLibrary ?: "", OSBARCZXingHelper(), OSBARCMLKitHelper() - ), // temporary + ), { result -> val resultIntent = Intent() resultIntent.putExtra(SCAN_RESULT, result) From a521f9cacdf09738993b7cd8c62e45f9469389d2 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 09:21:42 +0000 Subject: [PATCH 8/9] chore: update changelog References: https://outsystemsrd.atlassian.net/browse/RMET-2764 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 933ef9e..21b75e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ The changes documented here do not include those from the original repository. ## [Unreleased] +### 13-11-2023 +Android - Implement AlertDialog to settings (https://outsystemsrd.atlassian.net/browse/RMET-2764) + ### 13-11-2023 Android - Select Camera (Back or Front) (https://outsystemsrd.atlassian.net/browse/RMET-2764) From 1a9b4fe18d980b56684a6bb8b2a4eba34d090020 Mon Sep 17 00:00:00 2001 From: Alexandre Jacinto Date: Tue, 14 Nov 2023 09:33:06 +0000 Subject: [PATCH 9/9] refactor: use named parameters References: https://outsystemsrd.atlassian.net/browse/RMET-2764 --- .../plugins/barcode/view/OSBARCScannerActivity.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 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 5ad10d2..ec5d34c 100644 --- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt +++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt @@ -107,22 +107,22 @@ class OSBARCScannerActivity : ComponentActivity() { if (!permissionGiven) { CameraPermissionRequiredDialog( - { + onDismissRequest = { this.setResult(OSBARCError.CAMERA_PERMISSION_DENIED_ERROR.code) this.finish() }, - { + onConfirmation = { val intent = Intent().apply { action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS data = Uri.fromParts("package", context.packageName, null) } context.startActivity(intent) }, - showDialog, + shouldShowDialog = showDialog, dialogTitle = "Camera Access Not Enabled", dialogText = "To continue, please go to the Settings app and enable it.", - "Settings", - "Ok" + confirmButtonText = "Settings", + dismissButtonText = "Ok" ) }