mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-18 23:05:26 +02:00
Merge pull request #103 from Myzel394/fix-100
Improve folder access test
This commit is contained in:
commit
5d0e84e4ab
@ -441,23 +441,28 @@ abstract class BatchesFolder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun checkIfFolderIsAccessible(): Boolean {
|
fun checkIfFolderIsAccessible(): Boolean {
|
||||||
return when (type) {
|
try {
|
||||||
BatchType.INTERNAL -> true
|
return when (type) {
|
||||||
BatchType.CUSTOM -> getCustomDefinedFolder().canWrite() && getCustomDefinedFolder().canRead()
|
BatchType.INTERNAL -> true
|
||||||
BatchType.MEDIA -> {
|
BatchType.CUSTOM -> getCustomDefinedFolder().canWrite() && getCustomDefinedFolder().canRead()
|
||||||
if (SUPPORTS_SCOPED_STORAGE) {
|
BatchType.MEDIA -> {
|
||||||
return true
|
if (SUPPORTS_SCOPED_STORAGE) {
|
||||||
}
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
return PermissionHelper.hasGranted(
|
return PermissionHelper.hasGranted(
|
||||||
context,
|
context,
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||||
) &&
|
) &&
|
||||||
PermissionHelper.hasGranted(
|
PermissionHelper.hasGranted(
|
||||||
context,
|
context,
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (error: NullPointerException) {
|
||||||
|
error.printStackTrace()
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,6 +591,22 @@ abstract class BatchesFolder(
|
|||||||
// 350 MiB sounds like a good default
|
// 350 MiB sounds like a good default
|
||||||
return 350 * 1024 * 1024
|
return 350 * 1024 * 1024
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun canAccessFolder(context: Context, uri: Uri): Boolean {
|
||||||
|
return try {
|
||||||
|
// Create temp file
|
||||||
|
val tempFile = DocumentFile.fromSingleUri(context, uri)!!.createFile(
|
||||||
|
"application/octet-stream",
|
||||||
|
"temp"
|
||||||
|
)!!
|
||||||
|
tempFile.delete()
|
||||||
|
|
||||||
|
true
|
||||||
|
} catch (error: RuntimeException) {
|
||||||
|
error.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,8 @@ abstract class IntervalRecorderService<I, B : BatchesFolder> :
|
|||||||
|
|
||||||
if (!batchesFolder.checkIfFolderIsAccessible()) {
|
if (!batchesFolder.checkIfFolderIsAccessible()) {
|
||||||
onBatchesFolderNotAccessible()
|
onBatchesFolderNotAccessible()
|
||||||
|
|
||||||
|
throw AvoidErrorDialogError()
|
||||||
}
|
}
|
||||||
|
|
||||||
createTimer()
|
createTimer()
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
package app.myzel394.alibi.services
|
package app.myzel394.alibi.services
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.ActivityManager
|
|
||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Binder
|
import android.os.Binder
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.core.content.ContextCompat.getSystemService
|
|
||||||
import androidx.lifecycle.LifecycleService
|
import androidx.lifecycle.LifecycleService
|
||||||
import app.myzel394.alibi.NotificationHelper
|
import app.myzel394.alibi.NotificationHelper
|
||||||
import app.myzel394.alibi.enums.RecorderState
|
import app.myzel394.alibi.enums.RecorderState
|
||||||
@ -63,7 +61,16 @@ abstract class RecorderService : LifecycleService() {
|
|||||||
|
|
||||||
startForegroundService()
|
startForegroundService()
|
||||||
changeState(RecorderState.RECORDING)
|
changeState(RecorderState.RECORDING)
|
||||||
start()
|
|
||||||
|
try {
|
||||||
|
start()
|
||||||
|
} catch (error: RuntimeException) {
|
||||||
|
error.printStackTrace()
|
||||||
|
|
||||||
|
if (error !is AvoidErrorDialogError) {
|
||||||
|
onError()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun stopRecording() {
|
suspend fun stopRecording() {
|
||||||
@ -194,4 +201,9 @@ abstract class RecorderService : LifecycleService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Throw this error if you show a dialog yourself.
|
||||||
|
// This will prevent the service from showing their generic error dialog.
|
||||||
|
class AvoidErrorDialogError : RuntimeException()
|
||||||
}
|
}
|
@ -356,17 +356,16 @@ fun RecorderEventsHandler(
|
|||||||
progress = processingProgress,
|
progress = processingProgress,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (showRecorderError)
|
|
||||||
RecorderErrorDialog(
|
|
||||||
onClose = {
|
|
||||||
showRecorderError = false
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if (showBatchesInaccessibleError)
|
if (showBatchesInaccessibleError)
|
||||||
BatchesInaccessibleDialog(
|
BatchesInaccessibleDialog(
|
||||||
onClose = {
|
onClose = {
|
||||||
showBatchesInaccessibleError = false
|
showBatchesInaccessibleError = false
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
else if (showRecorderError)
|
||||||
|
RecorderErrorDialog(
|
||||||
|
onClose = {
|
||||||
|
showRecorderError = false
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
@ -2,7 +2,6 @@ package app.myzel394.alibi.ui.components.SettingsScreen.Tiles
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
@ -22,6 +21,7 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.automirrored.filled.InsertDriveFile
|
import androidx.compose.material.icons.automirrored.filled.InsertDriveFile
|
||||||
import androidx.compose.material.icons.filled.CameraAlt
|
import androidx.compose.material.icons.filled.CameraAlt
|
||||||
import androidx.compose.material.icons.filled.Cancel
|
import androidx.compose.material.icons.filled.Cancel
|
||||||
|
import androidx.compose.material.icons.filled.Error
|
||||||
import androidx.compose.material.icons.filled.Folder
|
import androidx.compose.material.icons.filled.Folder
|
||||||
import androidx.compose.material.icons.filled.Lock
|
import androidx.compose.material.icons.filled.Lock
|
||||||
import androidx.compose.material.icons.filled.Mic
|
import androidx.compose.material.icons.filled.Mic
|
||||||
@ -62,6 +62,7 @@ import app.myzel394.alibi.R
|
|||||||
import app.myzel394.alibi.dataStore
|
import app.myzel394.alibi.dataStore
|
||||||
import app.myzel394.alibi.db.AppSettings
|
import app.myzel394.alibi.db.AppSettings
|
||||||
import app.myzel394.alibi.helpers.AudioBatchesFolder
|
import app.myzel394.alibi.helpers.AudioBatchesFolder
|
||||||
|
import app.myzel394.alibi.helpers.BatchesFolder
|
||||||
import app.myzel394.alibi.helpers.VideoBatchesFolder
|
import app.myzel394.alibi.helpers.VideoBatchesFolder
|
||||||
import app.myzel394.alibi.ui.AUDIO_RECORDING_BATCHES_SUBFOLDER_NAME
|
import app.myzel394.alibi.ui.AUDIO_RECORDING_BATCHES_SUBFOLDER_NAME
|
||||||
import app.myzel394.alibi.ui.MEDIA_SUBFOLDER_NAME
|
import app.myzel394.alibi.ui.MEDIA_SUBFOLDER_NAME
|
||||||
@ -91,22 +92,44 @@ fun SaveFolderTile(
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dataStore = context.dataStore
|
val dataStore = context.dataStore
|
||||||
|
|
||||||
|
var showError by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
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 (settings.saveFolder != null && settings.saveFolder != RECORDER_MEDIA_SELECTED_VALUE) {
|
if (path != null && path != RECORDER_MEDIA_SELECTED_VALUE) {
|
||||||
runCatching {
|
context.contentResolver.takePersistableUriPermission(
|
||||||
context.contentResolver.releasePersistableUriPermission(
|
path.toUri(),
|
||||||
Uri.parse(settings.saveFolder),
|
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
)
|
||||||
)
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path != null && path != RECORDER_MEDIA_SELECTED_VALUE) {
|
runCatching {
|
||||||
context.contentResolver.takePersistableUriPermission(
|
// Clean up
|
||||||
Uri.parse(path),
|
val grantedURIs = context.contentResolver.persistedUriPermissions;
|
||||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
|
||||||
)
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.launch {
|
scope.launch {
|
||||||
@ -130,6 +153,45 @@ fun SaveFolderTile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (showError) {
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = {
|
||||||
|
showError = false
|
||||||
|
},
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.Error,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
title = {
|
||||||
|
Text(stringResource(R.string.ui_error_occurred_title))
|
||||||
|
},
|
||||||
|
confirmButton = {
|
||||||
|
Button(onClick = {
|
||||||
|
showError = false
|
||||||
|
}) {
|
||||||
|
Text(stringResource(R.string.dialog_close_neutral_label))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.verticalScroll(rememberScrollState()),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(32.dp),
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
stringResource(R.string.ui_settings_option_saveFolder_batchesFolderInaccessible_error),
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (selectionVisible) {
|
if (selectionVisible) {
|
||||||
SelectionSheet(
|
SelectionSheet(
|
||||||
sheetState = selectionSheetState,
|
sheetState = selectionSheetState,
|
||||||
|
@ -222,4 +222,6 @@
|
|||||||
<string name="ui_about_support_title">Get Support</string>
|
<string name="ui_about_support_title">Get Support</string>
|
||||||
<string name="ui_about_support_message">If you have any questions, feedback or face any issues, please don\'t hesitate to contact me. I\'m happy to help you! Below is a list of ways to get in touch with me:</string>
|
<string name="ui_about_support_message">If you have any questions, feedback or face any issues, please don\'t hesitate to contact me. I\'m happy to help you! Below is a list of ways to get in touch with me:</string>
|
||||||
<string name="ui_welcome_timeSettings_values_1min">1 Minute</string>
|
<string name="ui_welcome_timeSettings_values_1min">1 Minute</string>
|
||||||
|
<string name="ui_error_occurred_title">There was an error</string>
|
||||||
|
<string name="ui_settings_option_saveFolder_batchesFolderInaccessible_error">Alibi can\'t access this folder. Please select a different one</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user