Lock Android app on background for biometrics
This commit is contained in:
+6
-1
@@ -2,10 +2,15 @@
|
|||||||
|
|
||||||
## Versión actual
|
## Versión actual
|
||||||
|
|
||||||
- Versión base: `1.2.4`
|
- Versión base: `1.2.5`
|
||||||
|
|
||||||
## Historial
|
## Historial
|
||||||
|
|
||||||
|
### 1.2.5 - 2026-04-23
|
||||||
|
|
||||||
|
- Android vuelve a bloquearse al pasar a segundo plano cuando la biometría está activa, para que al regresar sí pida huella.
|
||||||
|
- Se publica APK nuevo con versión visible `1.2.5`.
|
||||||
|
|
||||||
### 1.2.4 - 2026-04-23
|
### 1.2.4 - 2026-04-23
|
||||||
|
|
||||||
- Android corrige el cierre de sesión para volver a ofrecer la pantalla biométrica cuando existen credenciales biométricas guardadas.
|
- Android corrige el cierre de sesión para volver a ofrecer la pantalla biométrica cuando existen credenciales biométricas guardadas.
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ android {
|
|||||||
applicationId "net.linkedcorp.linkedsign"
|
applicationId "net.linkedcorp.linkedsign"
|
||||||
minSdk 26
|
minSdk 26
|
||||||
targetSdk 35
|
targetSdk 35
|
||||||
versionCode 10204
|
versionCode 10205
|
||||||
versionName "1.2.4"
|
versionName "1.2.5"
|
||||||
|
|
||||||
buildConfigField "String", "API_BASE_URL", "\"${apiBaseUrl}\""
|
buildConfigField "String", "API_BASE_URL", "\"${apiBaseUrl}\""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ import androidx.compose.material3.TopAppBar
|
|||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -113,6 +114,9 @@ import androidx.compose.ui.layout.ContentScale
|
|||||||
import androidx.compose.ui.layout.onSizeChanged
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.LifecycleEventObserver
|
||||||
|
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||||
@@ -209,6 +213,7 @@ fun LinkedSignApp(viewModel: MainViewModel, appContext: Context, activity: Compo
|
|||||||
var selectedTab by rememberSaveable { mutableStateOf(AppTab.Documents) }
|
var selectedTab by rememberSaveable { mutableStateOf(AppTab.Documents) }
|
||||||
var pendingSignDocumentId by rememberSaveable { mutableStateOf<String?>(null) }
|
var pendingSignDocumentId by rememberSaveable { mutableStateOf<String?>(null) }
|
||||||
val biometricAvailable = remember(activity) { canUseBiometricAccess(activity) }
|
val biometricAvailable = remember(activity) { canUseBiometricAccess(activity) }
|
||||||
|
val lifecycleOwner = LocalLifecycleOwner.current
|
||||||
var appUnlocked by rememberSaveable { mutableStateOf(false) }
|
var appUnlocked by rememberSaveable { mutableStateOf(false) }
|
||||||
var bootstrapGateHandled by rememberSaveable { mutableStateOf(false) }
|
var bootstrapGateHandled by rememberSaveable { mutableStateOf(false) }
|
||||||
var showBiometricOptIn by rememberSaveable { mutableStateOf(false) }
|
var showBiometricOptIn by rememberSaveable { mutableStateOf(false) }
|
||||||
@@ -235,6 +240,23 @@ fun LinkedSignApp(viewModel: MainViewModel, appContext: Context, activity: Compo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DisposableEffect(lifecycleOwner, biometricAvailable, state.biometricEnabled, state.biometricHasCredentials) {
|
||||||
|
val observer = LifecycleEventObserver { _, event ->
|
||||||
|
if (event == Lifecycle.Event.ON_STOP &&
|
||||||
|
biometricAvailable &&
|
||||||
|
state.biometricEnabled &&
|
||||||
|
state.biometricHasCredentials
|
||||||
|
) {
|
||||||
|
appUnlocked = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lifecycleOwner.lifecycle.addObserver(observer)
|
||||||
|
onDispose {
|
||||||
|
lifecycleOwner.lifecycle.removeObserver(observer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.pointerInput(state.authenticated) {
|
modifier = Modifier.pointerInput(state.authenticated) {
|
||||||
if (!state.authenticated) return@pointerInput
|
if (!state.authenticated) return@pointerInput
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "linkedsign-backend",
|
"name": "linkedsign-backend",
|
||||||
"version": "1.2.4",
|
"version": "1.2.5",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Initial backend for LinkedSign",
|
"description": "Initial backend for LinkedSign",
|
||||||
"main": "src/server.js",
|
"main": "src/server.js",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "frontend",
|
"name": "frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.2.4",
|
"version": "1.2.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
Reference in New Issue
Block a user