Implemented asking for Camera permission
This commit is contained in:
parent
316a0027f7
commit
e1bb7722ff
|
@ -106,6 +106,7 @@ kotlin {
|
|||
androidMain.dependencies {
|
||||
implementation(compose.preview)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(libs.androidx.fragment) // to fix bug IllegalArgumentException: Can only use lower 16 bits for requestCode
|
||||
implementation(libs.androidx.biometric)
|
||||
|
||||
implementation(libs.favre.bcrypt)
|
||||
|
|
|
@ -2,6 +2,7 @@ package net.codinux.banking.ui
|
|||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
|
@ -11,6 +12,11 @@ import net.codinux.banking.ui.service.BiometricAuthenticationService
|
|||
import net.codinux.banking.ui.service.ImageService
|
||||
|
||||
class MainActivity : FragmentActivity() {
|
||||
|
||||
private val request = ActivityResultContracts.RequestMultiplePermissions()
|
||||
|
||||
private val activityResultLauncher = registerForActivityResult(request) { }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
@ -23,8 +29,29 @@ class MainActivity : FragmentActivity() {
|
|||
App()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun requestPermissions(requiredPermissions: List<String>): Boolean {
|
||||
val requiredPermissionsArray = requiredPermissions.toTypedArray()
|
||||
|
||||
activityResultLauncher.launch(requiredPermissionsArray)
|
||||
|
||||
var result = request.getSynchronousResult(baseContext, requiredPermissionsArray)
|
||||
while (result == null) {
|
||||
result = request.getSynchronousResult(baseContext, requiredPermissionsArray)
|
||||
}
|
||||
|
||||
return if (result.value != null) {
|
||||
val allPermissionsGranted = result.value.entries.filter { it.key in requiredPermissions }.all { it.value == true }
|
||||
allPermissionsGranted
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun AppAndroidPreview() {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package net.codinux.banking.ui.service
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.core.content.ContextCompat
|
||||
|
||||
object PermissionsService {
|
||||
|
||||
fun allPermissionsGranted(baseContext: Context, permissions: List<String>) = permissions.all {
|
||||
ContextCompat.checkSelfPermission(baseContext, it) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package net.codinux.banking.ui.service
|
||||
|
||||
import android.Manifest
|
||||
import androidx.camera.core.*
|
||||
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||
import androidx.camera.view.PreviewView
|
||||
|
@ -7,15 +8,14 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.google.zxing.*
|
||||
import com.google.zxing.common.HybridBinarizer
|
||||
import com.google.zxing.qrcode.QRCodeReader
|
||||
import net.codinux.banking.persistence.AndroidContext
|
||||
import net.codinux.banking.ui.MainActivity
|
||||
import net.codinux.banking.ui.config.DI
|
||||
import net.codinux.log.logger
|
||||
import java.nio.ByteBuffer
|
||||
|
@ -23,6 +23,8 @@ import java.util.concurrent.Executors
|
|||
|
||||
actual object QrCodeService {
|
||||
|
||||
private val RequiredPermissions = listOf(Manifest.permission.CAMERA)
|
||||
|
||||
private val cameraExecutor = Executors.newCachedThreadPool()
|
||||
|
||||
private val log by logger()
|
||||
|
@ -32,16 +34,17 @@ actual object QrCodeService {
|
|||
|
||||
@Composable
|
||||
actual fun readQrCodeFromCamera(resultCallback: (QrCodeReadResult) -> Unit) {
|
||||
val context = AndroidContext.mainActivity
|
||||
val cameraProviderFuture = ProcessCameraProvider.getInstance(context)
|
||||
val mainActivity = LocalLifecycleOwner.current as MainActivity // we only have MainActivity, so we can be sure that LocalLifecycleOwner.current is MainActivity
|
||||
|
||||
val localContext = LocalContext.current
|
||||
log.info { "LocalContext.current = ${localContext.javaClass} ${localContext}" }
|
||||
if (PermissionsService.allPermissionsGranted(AndroidContext.applicationContext, RequiredPermissions) == false &&
|
||||
mainActivity.requestPermissions(RequiredPermissions) == false) {
|
||||
return // we don't have the permission to start the camera
|
||||
}
|
||||
|
||||
val cameraProviderFuture = ProcessCameraProvider.getInstance(mainActivity)
|
||||
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
// val context = LocalContext.current
|
||||
val previewView = remember {
|
||||
PreviewView(context)
|
||||
PreviewView(mainActivity)
|
||||
}
|
||||
|
||||
cameraProviderFuture.addListener({
|
||||
|
@ -69,13 +72,13 @@ actual object QrCodeService {
|
|||
cameraProvider.unbindAll()
|
||||
|
||||
// Bind use cases to camera
|
||||
cameraProvider.bindToLifecycle(context as FragmentActivity, cameraSelector, preview, imageAnalyzer)
|
||||
cameraProvider.bindToLifecycle(mainActivity, cameraSelector, preview, imageAnalyzer)
|
||||
|
||||
} catch(e: Exception) {
|
||||
log.error(e) { "Use case binding failed" }
|
||||
}
|
||||
|
||||
}, ContextCompat.getMainExecutor(context))
|
||||
}, ContextCompat.getMainExecutor(mainActivity))
|
||||
|
||||
|
||||
AndroidView(factory = { previewView }, modifier = Modifier.fillMaxSize())
|
||||
|
|
|
@ -24,6 +24,7 @@ android-targetSdk = "34"
|
|||
|
||||
androidx-activityCompose = "1.9.2"
|
||||
androidx-lifecycle = "2.8.2"
|
||||
androidx-fragment = "1.8.3"
|
||||
androidx-biometric = "1.1.0"
|
||||
compose-plugin = "1.6.11"
|
||||
|
||||
|
@ -57,6 +58,7 @@ sqldelight-native-driver = { module = "app.cash.sqldelight:native-driver", versi
|
|||
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
|
||||
androidx-lifecycle-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "androidx-lifecycle" }
|
||||
androidx-lifecycle-runtime-compose = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
|
||||
androidx-fragment = { group = "androidx.fragment", name = "fragment", version.ref = "androidx-fragment" }
|
||||
androidx-biometric = { group = "androidx.biometric", name = "biometric", version.ref = "androidx-biometric" }
|
||||
kotlinx-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" }
|
||||
|
||||
|
|
Loading…
Reference in New Issue