diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/DownloadScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/DownloadScreen.kt index b90d1844d..e3b4978aa 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/DownloadScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/DownloadScreen.kt @@ -1,7 +1,10 @@ package com.hippo.ehviewer.ui.settings +import android.Manifest +import android.content.ActivityNotFoundException import android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION import android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION +import android.os.Environment import android.provider.DocumentsContract import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts @@ -54,11 +57,14 @@ import com.hippo.ehviewer.ui.tools.rememberedAccessor import com.hippo.ehviewer.util.AppConfig import com.hippo.ehviewer.util.displayPath import com.hippo.ehviewer.util.displayString +import com.hippo.ehviewer.util.isAtLeastQ +import com.hippo.ehviewer.util.requestPermission import com.hippo.files.delete import com.hippo.files.find import com.hippo.files.isDirectory import com.hippo.files.list import com.hippo.files.metadataOrNull +import com.hippo.files.mkdirs import com.hippo.files.toOkioPath import com.hippo.files.toUri import com.ramcosta.composedestinations.annotation.Destination @@ -132,7 +138,24 @@ fun AnimatedVisibilityScope.DownloadScreen(navigator: DestinationsNavigator) = c Text(stringResource(id = R.string.default_download_dir_not_empty)) } } - selectDownloadDirLauncher.launch(null) + try { + selectDownloadDirLauncher.launch(null) + } catch (_: ActivityNotFoundException) { + // Best effort for devices without DocumentsUI + if (!isAtLeastQ && requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) { + runCatching { + val path = Environment.getExternalStorageDirectory().toOkioPath() / AppConfig.APP_DIRNAME + path.mkdirs() + check(path.isDirectory) { "$path is not a directory" } + keepNoMediaFileStatus(path) // Check if the directory is writable + downloadLocationState = path + return@launchIO + }.onFailure { + logcat(it) + } + } + launchSnackBar(cannotGetDownloadLocation) + } } } val mediaScan = Settings::mediaScan.observed