Skip to content

Commit 3e26202

Browse files
committed
A bug fix in settings
1 parent de2c22f commit 3e26202

2 files changed

Lines changed: 31 additions & 21 deletions

File tree

app/src/main/java/com/aidinhut/simpletextcrypt/ui/screen/MainScreen.kt

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import androidx.compose.material3.TextButton
4343
import androidx.compose.material3.TopAppBar
4444
import androidx.compose.material3.TopAppBarDefaults
4545
import androidx.compose.runtime.Composable
46+
import androidx.compose.runtime.DisposableEffect
4647
import androidx.compose.runtime.LaunchedEffect
4748
import androidx.compose.runtime.collectAsState
4849
import androidx.compose.runtime.getValue
@@ -56,9 +57,9 @@ import androidx.compose.ui.res.stringResource
5657
import androidx.compose.ui.text.style.TextAlign
5758
import androidx.compose.ui.unit.dp
5859
import androidx.compose.ui.unit.sp
60+
import androidx.activity.ComponentActivity
5961
import androidx.lifecycle.Lifecycle
6062
import androidx.lifecycle.LifecycleEventObserver
61-
import androidx.lifecycle.compose.LocalLifecycleOwner
6263
import androidx.lifecycle.viewmodel.compose.viewModel
6364
import com.aidinhut.simpletextcrypt.R
6465
import com.aidinhut.simpletextcrypt.viewmodel.MainViewModel
@@ -76,21 +77,26 @@ fun MainScreen(
7677
var showAbout by remember { mutableStateOf(false) }
7778
var showHelp by remember { mutableStateOf(false) }
7879

79-
// Handle lock timeout on lifecycle events.
80-
val lifecycleOwner = LocalLifecycleOwner.current
81-
LaunchedEffect(lifecycleOwner) {
80+
// Check lock timeout every time this screen enters composition
81+
// (returning from Settings or from background).
82+
LaunchedEffect(Unit) {
83+
viewModel.checkLockTimeout(context)
84+
}
85+
86+
// Handle lock-on-background using the Activity lifecycle.
87+
// Using Activity lifecycle (not NavBackStackEntry) so in-app navigation
88+
// to Settings doesn't trigger the pause lock.
89+
val activity = context as ComponentActivity
90+
DisposableEffect(activity) {
8291
val observer = LifecycleEventObserver { _, event ->
83-
when (event) {
84-
Lifecycle.Event.ON_RESUME -> {
85-
viewModel.checkLockTimeout(context)
86-
}
87-
Lifecycle.Event.ON_PAUSE -> {
88-
viewModel.checkPauseLock(context)
89-
}
90-
else -> {}
92+
if (event == Lifecycle.Event.ON_STOP) {
93+
viewModel.checkPauseLock(context)
9194
}
9295
}
93-
lifecycleOwner.lifecycle.addObserver(observer)
96+
activity.lifecycle.addObserver(observer)
97+
onDispose {
98+
activity.lifecycle.removeObserver(observer)
99+
}
94100
}
95101

96102
// Navigate to lock when shouldLock triggers.

app/src/main/java/com/aidinhut/simpletextcrypt/ui/screen/SettingsScreen.kt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import androidx.compose.material3.TextButton
3939
import androidx.compose.material3.TopAppBar
4040
import androidx.compose.material3.TopAppBarDefaults
4141
import androidx.compose.runtime.Composable
42+
import androidx.compose.runtime.DisposableEffect
4243
import androidx.compose.runtime.LaunchedEffect
4344
import androidx.compose.runtime.collectAsState
4445
import androidx.compose.runtime.getValue
@@ -48,9 +49,9 @@ import androidx.compose.ui.res.stringResource
4849
import androidx.compose.ui.text.input.KeyboardType
4950
import androidx.compose.ui.unit.dp
5051
import androidx.compose.ui.unit.sp
52+
import androidx.activity.ComponentActivity
5153
import androidx.lifecycle.Lifecycle
5254
import androidx.lifecycle.LifecycleEventObserver
53-
import androidx.lifecycle.compose.LocalLifecycleOwner
5455
import androidx.lifecycle.viewmodel.compose.viewModel
5556
import com.aidinhut.simpletextcrypt.R
5657
import com.aidinhut.simpletextcrypt.viewmodel.SettingsViewModel
@@ -77,17 +78,20 @@ fun SettingsScreen(
7778
}
7879
}
7980

80-
// This activity won't lock. So, if the user sends the app to the background while on
81-
// the settings activity, anyone can get back to it without the need to enter passcode.
82-
// So we finish (navigate back) on pause.
83-
val lifecycleOwner = LocalLifecycleOwner.current
84-
LaunchedEffect(lifecycleOwner) {
81+
// Navigate back when the app goes to background (security: prevent returning
82+
// to settings without passcode). Using Activity lifecycle so that in-app
83+
// navigation doesn't trigger this.
84+
val activity = context as ComponentActivity
85+
DisposableEffect(activity) {
8586
val observer = LifecycleEventObserver { _, event ->
86-
if (event == Lifecycle.Event.ON_PAUSE) {
87+
if (event == Lifecycle.Event.ON_STOP) {
8788
onNavigateBack()
8889
}
8990
}
90-
lifecycleOwner.lifecycle.addObserver(observer)
91+
activity.lifecycle.addObserver(observer)
92+
onDispose {
93+
activity.lifecycle.removeObserver(observer)
94+
}
9195
}
9296

9397
Scaffold(

0 commit comments

Comments
 (0)