Search code examples
androidmvvmandroid-jetpack-compose

the display of the variable value does not change when the variable is changed (Jetpack Compose Android Studio)


the application uses mvvm and jetpack compose, the screen (View, compose) shows whether permission has been obtained using the following code:

val context = LocalContext.current
val access by remember { mutableStateOf(
    NotificationManagerCompat.getEnabledListenerPackages(context)
        .contains(context.packageName)
    ) }
Text(if (access) "good" else "bad")

after that, the settings are opened using:

context.startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))

after changing the settings, the old value is displayed on the screen (not updated), but if you go to another screen and open this screen again, the displayed value is updated

  1. how make that after changing the settings, the displayed value on the screen is immediately updated?
  2. Is it possible to transfer the reading of the parameter of this setting to the ViewModel?

Solution

  • You probably need to refresh the Composable as soon as your App comes back to foreground. You initialize the value of access to the current preferences, but the value of the variable is not refreshed automatically, because NotificationManagerCompat does not return Flow or LiveData. Even if a recomposition happened, you would not get the updated value, because you use remember, which saves its state across recompositions.

    You can try to refresh the variable whenever the App is brought to foreground again. Use the onResume Activity lifecycle callback to detect this. See the following code for example:

    val lifecycleOwner = LocalLifecycleOwner.current
    val lifecycleState by lifecycleOwner.lifecycle.currentStateFlow.collectAsState()
    
    val access by remember { mutableStateOf(
        NotificationManagerCompat.getEnabledListenerPackages(context)
            .contains(context.packageName)
        ) 
    }
    
    LaunchedEffect(lifecycleState) {
        if (lifecycleState == Lifecycle.State.RESUMED ) {
            access = NotificationManagerCompat.getEnabledListenerPackages(context)
               .contains(context.packageName)
        )
    }
    

    Note that collectAsState requires the following dependency, add it to your module's build.gradle file:

    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")