feat: Check if folder is accessible via IO

Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com>
This commit is contained in:
Myzel394 2024-04-20 22:05:22 +02:00
parent f77aeb78c6
commit 257e38632b
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
2 changed files with 59 additions and 46 deletions

View File

@ -25,6 +25,9 @@ import app.myzel394.alibi.ui.SUPPORTS_SCOPED_STORAGE
import app.myzel394.alibi.ui.utils.PermissionHelper import app.myzel394.alibi.ui.utils.PermissionHelper
import com.arthenica.ffmpegkit.FFmpegKitConfig import com.arthenica.ffmpegkit.FFmpegKitConfig
import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -592,20 +595,29 @@ abstract class BatchesFolder(
return 350 * 1024 * 1024 return 350 * 1024 * 1024
} }
fun canAccessFolder(context: Context, uri: Uri): Boolean { suspend fun canAccessFolder(context: Context, uri: Uri): Boolean {
return try { var canAccess = false
// Create temp file
val tempFile = DocumentFile.fromSingleUri(context, uri)!!.createFile(
"application/octet-stream",
"temp"
)!!
tempFile.delete()
true CoroutineScope(Dispatchers.IO).launch {
} catch (error: RuntimeException) { try {
error.printStackTrace() // Create temp file
false val documentFile = DocumentFile.fromTreeUri(context, uri)!!
} val tempFile = documentFile.createFile(
"application/octet-stream",
"temp"
)!!
if (!tempFile.exists() || !tempFile.canWrite() || !tempFile.canRead()) {
return@launch
}
tempFile.delete()
canAccess = true
} catch (error: RuntimeException) {
error.printStackTrace()
}
}.join()
return canAccess
} }
} }
} }

View File

@ -96,43 +96,44 @@ fun SaveFolderTile(
val successMessage = stringResource(R.string.ui_settings_option_saveFolder_success) val successMessage = stringResource(R.string.ui_settings_option_saveFolder_success)
fun updateValue(path: String?) { fun updateValue(path: String?) {
if (path != null && path != RECORDER_MEDIA_SELECTED_VALUE) { scope.launch {
context.contentResolver.takePersistableUriPermission( if (path != null && path != RECORDER_MEDIA_SELECTED_VALUE) {
path.toUri(), context.contentResolver.takePersistableUriPermission(
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION path.toUri(),
)
if (!BatchesFolder.canAccessFolder(context, path.toUri())) {
showError = true
runCatching {
context.contentResolver.releasePersistableUriPermission(
path.toUri(),
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
}
return
}
}
runCatching {
// Clean up
val grantedURIs = context.contentResolver.persistedUriPermissions;
grantedURIs.forEach { permission ->
if (permission.uri == path?.toUri()) {
return@forEach
}
context.contentResolver.releasePersistableUriPermission(
permission.uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION
or Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
) )
}
}
scope.launch { if (!BatchesFolder.canAccessFolder(context, path.toUri())) {
showError = true
runCatching {
context.contentResolver.releasePersistableUriPermission(
path.toUri(),
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
}
return@launch
}
}
runCatching {
// Clean up
val grantedURIs = context.contentResolver.persistedUriPermissions;
grantedURIs.forEach { permission ->
if (permission.uri == path?.toUri()) {
return@forEach
}
context.contentResolver.releasePersistableUriPermission(
permission.uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
}
}
dataStore.updateData { dataStore.updateData {
it.setSaveFolder(path) it.setSaveFolder(path)
} }