Manuel Lorenzo
08/24/2022, 8:16 AMMainActivity
I have this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
PSPDFKitAssignmentTheme {
MainScreen()
}
}
}
@OptIn(ExperimentalAnimationApi::class)
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun MainScreen(
mainViewModel: MainViewModel = viewModel(),
savePDFViewModel: SavePDFViewModel = viewModel()
) {
val navController = rememberAnimatedNavController()
val navBackStackEntry by navController.currentBackStackEntryAsState()
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.MANAGE_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED
) {
OpenDownloadsFolderAsLaunchedEffect()
} else {
RequestPermissions()
}
Scaffold(...
But the problem is that of course, when I rotate the device, the activity gets recreated again and if the permissions are already granted the method OpenDownloadsFolderAsLaunchedEffect()
is called again and that breaks the appJan Starczewski
08/24/2022, 10:13 AMOpenDownloadsFolderAsLaunchedEffect
?Manuel Lorenzo
08/24/2022, 10:14 AMLaunchedEffect(true) {
mainViewModel.openFolder(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS))
}
Jan Starczewski
08/24/2022, 10:30 AMManuel Lorenzo
08/24/2022, 10:30 AMJan Starczewski
08/24/2022, 10:42 AMboolean
indicating whether you made a certain job inside effect or not with rememverSaveable
so It will not be launched on configuration change
val wasLaunched = rememberSaveable { mutableStateOf(false) }
if (wasLaunched.value.not()) {
LaunchedEffect(Unit) {
// do your calls
// mainViewModel.openFolder(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS))
// change value
wasLaunched.value = true
}
}
Manuel Lorenzo
08/24/2022, 10:45 AMJan Starczewski
08/24/2022, 10:45 AMManuel Lorenzo
08/24/2022, 10:45 AMJan Starczewski
08/24/2022, 10:46 AMManuel Lorenzo
08/24/2022, 10:47 AMJan Starczewski
08/24/2022, 11:02 AMManuel Lorenzo
08/24/2022, 11:05 AMOpenDownloadsFolderAsLaunchedEffect
is called again, which kind of restarts the data structure that holds the list of documents of the app, and thus the state isn’t savedJan Starczewski
08/24/2022, 11:06 AMManuel Lorenzo
08/24/2022, 11:06 AMJan Starczewski
08/24/2022, 11:07 AMManuel Lorenzo
08/24/2022, 11:07 AM@Composable
fun MainScreen(
mainViewModel: MainViewModel = viewModel(),
savePDFViewModel: SavePDFViewModel = viewModel()
) {
val navController = rememberAnimatedNavController()
val navBackStackEntry by navController.currentBackStackEntryAsState()
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.MANAGE_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED
) {
OpenDownloadsFolderAsLaunchedEffect()
} else {
RequestPermissions()
}
Scaffold(...
As you can see here it’s my MainScreen and of course, when rotated the checkSelfPermission
is called again because the activity was rotatedoverride fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
PSPDFKitAssignmentTheme {
MainScreen()
}
}
}
Not the best way I guessJan Starczewski
08/24/2022, 11:10 AMrememberSaveable
but to be honest it that case it may not be the best thing to do, because after process death when app is opened again it will prevent downloading the pdfs, I think we should go with viewModel approachopenFolder
function ?Manuel Lorenzo
08/24/2022, 11:12 AMfun openFolder(selectedItem: File) {
viewModelScope.launch(ioDispatcher) {
val filesList = getFilesList(selectedItem)
_documentListLiveData.postValue(buildDocumentListToShow(selectedItem, filesList))
}
}
Jan Starczewski
08/24/2022, 11:24 AM_documentListLiveData
is has an empty value before downloading it with getFilesList
or expose other live data like canOpenFolder
that can represent the state informing whether you should open the folder or not.
@Composable
fun OpenDownloadsFolderAsLaunchedEffectIfClosed(isClosed: Boolean) {
if (isClosed) {
LaunchedEffect(Unit) {
// do your calls
// mainViewModel.openFolder(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS))
}
}
}
And as the value of isClosed
use the value stored in your viewModelManuel Lorenzo
08/24/2022, 11:48 AM