Add camera to QR tab

This commit is contained in:
Andrew 2024-03-01 11:47:54 +10:30
parent 79cfde1924
commit 437d0de5e1
2 changed files with 43 additions and 40 deletions

View File

@ -371,10 +371,12 @@ dependencies {
implementation 'androidx.compose.foundation:foundation-layout:1.6.2' implementation 'androidx.compose.foundation:foundation-layout:1.6.2'
implementation 'androidx.compose.material:material:1.6.2' implementation 'androidx.compose.material:material:1.6.2'
// implementation "androidx.camera:camera-camera2:1.3.1" implementation "androidx.camera:camera-camera2:1.3.1"
// implementation "androidx.camera:camera-lifecycle:1.3.1" implementation "androidx.camera:camera-lifecycle:1.3.1"
// implementation "androidx.camera:camera-view:1.3.1" implementation "androidx.camera:camera-view:1.3.1"
// implementation "com.google.mlkit:barcode-scanning:17.2.0"
implementation 'com.google.firebase:firebase-core:21.1.1'
implementation "com.google.mlkit:barcode-scanning:17.2.0"
} }
static def getLastCommitTimestamp() { static def getLastCommitTimestamp() {

View File

@ -6,6 +6,10 @@ import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -33,6 +37,7 @@ import androidx.compose.material.TextFieldDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -44,6 +49,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted import com.google.accompanist.permissions.isGranted
@ -69,6 +75,11 @@ class LinkDeviceActivity : BaseActionBarActivity() {
val viewModel: LinkDeviceViewModel by viewModels() val viewModel: LinkDeviceViewModel by viewModels()
val preview = Preview.Builder().build()
val selector = CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
supportActionBar?.title = "Load Account" supportActionBar?.title = "Load Account"
@ -96,8 +107,8 @@ class LinkDeviceActivity : BaseActionBarActivity() {
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun LoadAccountScreen(state: LinkDeviceState, onChange: (String) -> Unit = {}, onContinue: () -> Unit = {}) { fun LoadAccountScreen(state: LinkDeviceState, onChange: (String) -> Unit = {}, onContinue: () -> Unit = {}) {
val tabs = listOf(R.string.activity_recovery_password, R.string.activity_link_device_scan_qr_code) val titles = listOf(R.string.activity_recovery_password, R.string.activity_link_device_scan_qr_code)
val pagerState = rememberPagerState { tabs.size } val pagerState = rememberPagerState { titles.size }
Column { Column {
TabRow( TabRow(
@ -105,7 +116,7 @@ class LinkDeviceActivity : BaseActionBarActivity() {
modifier = Modifier.height(48.dp) modifier = Modifier.height(48.dp)
) { ) {
val animationScope = rememberCoroutineScope() val animationScope = rememberCoroutineScope()
tabs.forEachIndexed { i, it -> titles.forEachIndexed { i, it ->
Tab(i == pagerState.currentPage, onClick = { animationScope.launch { pagerState.animateScrollToPage(i) } }) { Tab(i == pagerState.currentPage, onClick = { animationScope.launch { pagerState.animateScrollToPage(i) } }) {
Text(stringResource(id = it)) Text(stringResource(id = it))
} }
@ -114,8 +125,19 @@ class LinkDeviceActivity : BaseActionBarActivity() {
HorizontalPager( HorizontalPager(
state = pagerState, state = pagerState,
modifier = Modifier.weight(1f) modifier = Modifier.weight(1f)
) { i -> ) { page ->
when(tabs[i]) { val title = titles[page]
val localContext = LocalContext.current
val cameraProvider = remember { ProcessCameraProvider.getInstance(localContext) }
runCatching {
when (title) {
R.string.activity_link_device_scan_qr_code -> cameraProvider.get().bindToLifecycle(LocalLifecycleOwner.current, selector, preview)
else -> cameraProvider.get().unbind(preview)
}
}
when (title) {
R.string.activity_recovery_password -> RecoveryPassword(state, onChange, onContinue) R.string.activity_recovery_password -> RecoveryPassword(state, onChange, onContinue)
R.string.activity_link_device_scan_qr_code -> MaybeScanQrCode() R.string.activity_link_device_scan_qr_code -> MaybeScanQrCode()
} }
@ -123,7 +145,6 @@ class LinkDeviceActivity : BaseActionBarActivity() {
} }
} }
@OptIn(ExperimentalPermissionsApi::class) @OptIn(ExperimentalPermissionsApi::class)
@Composable @Composable
fun MaybeScanQrCode() { fun MaybeScanQrCode() {
@ -131,7 +152,7 @@ class LinkDeviceActivity : BaseActionBarActivity() {
val cameraPermissionState = rememberPermissionState(android.Manifest.permission.CAMERA) val cameraPermissionState = rememberPermissionState(android.Manifest.permission.CAMERA)
if (cameraPermissionState.status.isGranted) { if (cameraPermissionState.status.isGranted) {
ScanQrCode() ScanQrCode(preview)
} else if (cameraPermissionState.status.shouldShowRationale) { } else if (cameraPermissionState.status.shouldShowRationale) {
Column( Column(
modifier = Modifier.align(Alignment.Center) modifier = Modifier.align(Alignment.Center)
@ -164,35 +185,15 @@ class LinkDeviceActivity : BaseActionBarActivity() {
} }
@Composable @Composable
fun ScanQrCode() { fun ScanQrCode(preview: Preview) {
val localContext = LocalContext.current AndroidView(
val lifecycleOwner = LocalLifecycleOwner.current modifier = Modifier.fillMaxSize(),
// val cameraProviderFuture = remember { factory = { context ->
// ProcessCameraProvider.getInstance(localContext) PreviewView(context).apply {
// } preview.setSurfaceProvider(surfaceProvider)
// AndroidView( }
// modifier = Modifier.fillMaxSize(), }
// factory = { context -> )
// val previewView = PreviewView(context)
// val preview = Preview.Builder().build()
// val selector = CameraSelector.Builder()
// .requireLensFacing(CameraSelector.LENS_FACING_BACK)
// .build()
//
// preview.setSurfaceProvider(previewView.surfaceProvider)
//
// runCatching {
// cameraProviderFuture.get().bindToLifecycle(
// lifecycleOwner,
// selector,
// preview
// )
// }.onFailure {
// Log.e("CAMERA", "Camera bind error", it)
// }
// previewView
// }
// )
} }
@Composable @Composable