From 08a6d557f8a3f39eae90f040600f674db7a22fff Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Fri, 5 Jan 2024 19:12:53 +0100 Subject: [PATCH] fix: Fix recording for Android API 30 --- app/src/main/AndroidManifest.xml | 2 + .../alibi/helpers/AudioBatchesFolder.kt | 9 ++++- .../myzel394/alibi/helpers/BatchesFolder.kt | 38 ++++++++++--------- .../alibi/helpers/VideoBatchesFolder.kt | 20 +++++----- .../alibi/services/AudioRecorderService.kt | 2 +- .../alibi/services/VideoRecorderService.kt | 3 +- .../java/app/myzel394/alibi/ui/Constants.kt | 5 ++- .../SettingsScreen/Tiles/SaveFolderTile.kt | 5 ++- 8 files changed, 50 insertions(+), 34 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4e2c5ab..2f83478 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,6 +27,8 @@ + diff --git a/app/src/main/java/app/myzel394/alibi/helpers/AudioBatchesFolder.kt b/app/src/main/java/app/myzel394/alibi/helpers/AudioBatchesFolder.kt index b709f4f..21ba373 100644 --- a/app/src/main/java/app/myzel394/alibi/helpers/AudioBatchesFolder.kt +++ b/app/src/main/java/app/myzel394/alibi/helpers/AudioBatchesFolder.kt @@ -64,7 +64,7 @@ class AudioBatchesFolder( val mediaUri = getOrCreateMediaFile( name = getName(date, extension), mimeType = "audio/$extension", - relativePath = Environment.DIRECTORY_DCIM + "/" + MEDIA_SUBFOLDER_NAME, + relativePath = BASE_SCOPED_STORAGE_RELATIVE_PATH + "/" + MEDIA_SUBFOLDER_NAME, ) return FFmpegKitConfig.getSafParameterForWrite( @@ -146,8 +146,13 @@ class AudioBatchesFolder( } val MEDIA_RECORDINGS_SUBFOLDER = MEDIA_SUBFOLDER_NAME + "/audio_recordings" + val BASE_SCOPED_STORAGE_RELATIVE_PATH = + (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) + Environment.DIRECTORY_RECORDINGS + else + Environment.DIRECTORY_PODCASTS) val SCOPED_STORAGE_RELATIVE_PATH = - Environment.DIRECTORY_DCIM + "/" + MEDIA_RECORDINGS_SUBFOLDER + BASE_SCOPED_STORAGE_RELATIVE_PATH + "/" + MEDIA_RECORDINGS_SUBFOLDER // Parameters to be passed in descending order // Those parameters first try to concatenate without re-encoding diff --git a/app/src/main/java/app/myzel394/alibi/helpers/BatchesFolder.kt b/app/src/main/java/app/myzel394/alibi/helpers/BatchesFolder.kt index cb89243..5162795 100644 --- a/app/src/main/java/app/myzel394/alibi/helpers/BatchesFolder.kt +++ b/app/src/main/java/app/myzel394/alibi/helpers/BatchesFolder.kt @@ -250,11 +250,13 @@ abstract class BatchesFolder( suspend fun concatenate( recordingStart: LocalDateTime, extension: String, - disableCache: Boolean = false, + disableCache: Boolean? = null, onNextParameterTry: (String) -> Unit = {}, durationPerBatchInMilliseconds: Long = 0, onProgress: (Float?) -> Unit = {}, ): String { + val disableCache = disableCache ?: (type != BatchType.INTERNAL) + if (!disableCache && checkIfOutputAlreadyExists(recordingStart, extension)) { return getOutputFileForFFmpeg( date = recordingStart, @@ -462,7 +464,7 @@ abstract class BatchesFolder( context.contentResolver.query( scopedMediaContentUri, arrayOf(MediaStore.MediaColumns._ID, MediaStore.MediaColumns.DISPLAY_NAME), - "${MediaStore.MediaColumns.DISPLAY_NAME} = '$name'", + "${MediaStore.MediaColumns.DISPLAY_NAME} = '$name' AND ${Media.RELATIVE_PATH} = '$relativePath'", null, null, )!!.use { cursor -> @@ -482,27 +484,29 @@ abstract class BatchesFolder( } if (uri == null) { - // Create empty output file to be able to write to it - uri = context.contentResolver.insert( - scopedMediaContentUri, - ContentValues().apply { - put( - MediaStore.MediaColumns.DISPLAY_NAME, - name - ) - put( - MediaStore.MediaColumns.MIME_TYPE, - mimeType - ) + try { + // Create empty output file to be able to write to it + uri = context.contentResolver.insert( + scopedMediaContentUri, + ContentValues().apply { + put( + MediaStore.MediaColumns.DISPLAY_NAME, + name + ) + put( + MediaStore.MediaColumns.MIME_TYPE, + mimeType + ) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { put( Media.RELATIVE_PATH, relativePath, ) } - } - )!! + )!! + } catch (e: Exception) { + Log.e("Media", "Failed to create file", e) + } } return uri!! diff --git a/app/src/main/java/app/myzel394/alibi/helpers/VideoBatchesFolder.kt b/app/src/main/java/app/myzel394/alibi/helpers/VideoBatchesFolder.kt index 7517c45..20a69e4 100644 --- a/app/src/main/java/app/myzel394/alibi/helpers/VideoBatchesFolder.kt +++ b/app/src/main/java/app/myzel394/alibi/helpers/VideoBatchesFolder.kt @@ -7,6 +7,7 @@ import android.os.Build import android.os.Environment import android.os.ParcelFileDescriptor import android.provider.MediaStore +import androidx.annotation.RequiresApi import androidx.documentfile.provider.DocumentFile import app.myzel394.alibi.helpers.MediaConverter.Companion.concatenateVideoFiles import app.myzel394.alibi.ui.MEDIA_SUBFOLDER_NAME @@ -108,17 +109,16 @@ class VideoBatchesFolder( } } + @RequiresApi(Build.VERSION_CODES.Q) fun asMediaGetScopedStorageContentValues(name: String) = ContentValues().apply { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - put( - MediaStore.Video.Media.IS_PENDING, - 1 - ) - put( - MediaStore.Video.Media.RELATIVE_PATH, - SCOPED_STORAGE_RELATIVE_PATH, - ) - } + put( + MediaStore.Video.Media.IS_PENDING, + 1 + ) + put( + MediaStore.Video.Media.RELATIVE_PATH, + SCOPED_STORAGE_RELATIVE_PATH, + ) put( MediaStore.Video.Media.DISPLAY_NAME, diff --git a/app/src/main/java/app/myzel394/alibi/services/AudioRecorderService.kt b/app/src/main/java/app/myzel394/alibi/services/AudioRecorderService.kt index 604ec98..ee39570 100644 --- a/app/src/main/java/app/myzel394/alibi/services/AudioRecorderService.kt +++ b/app/src/main/java/app/myzel394/alibi/services/AudioRecorderService.kt @@ -162,7 +162,7 @@ class AudioRecorderService : } private fun getNameForMediaFile() = - "${batchesFolder.mediaPrefix}$counter.${settings.videoRecorderSettings.fileExtension}" + "${batchesFolder.mediaPrefix}$counter.${settings.audioRecorderSettings.fileExtension}" // ==== Actual recording related ==== private fun createRecorder(): MediaRecorder { diff --git a/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt b/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt index d9f50a2..0dd9cd2 100644 --- a/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt +++ b/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt @@ -25,6 +25,7 @@ import app.myzel394.alibi.db.RecordingInformation import app.myzel394.alibi.enums.RecorderState import app.myzel394.alibi.helpers.BatchesFolder import app.myzel394.alibi.helpers.VideoBatchesFolder +import app.myzel394.alibi.ui.SUPPORTS_SAVING_VIDEOS_IN_CUSTOM_FOLDERS import app.myzel394.alibi.ui.SUPPORTS_SCOPED_STORAGE import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope @@ -231,7 +232,7 @@ class VideoRecorderService : private fun prepareVideoRecording() = videoCapture!!.output .let { - if (batchesFolder.type == BatchesFolder.BatchType.CUSTOM && SUPPORTS_SCOPED_STORAGE) { + if (batchesFolder.type == BatchesFolder.BatchType.CUSTOM && SUPPORTS_SAVING_VIDEOS_IN_CUSTOM_FOLDERS) { it.prepareRecording( this, FileDescriptorOutputOptions.Builder( diff --git a/app/src/main/java/app/myzel394/alibi/ui/Constants.kt b/app/src/main/java/app/myzel394/alibi/ui/Constants.kt index 32e871b..68afb9d 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/Constants.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/Constants.kt @@ -11,11 +11,14 @@ val SUPPORTS_DARK_MODE_NATIVELY = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q val MEDIA_SUBFOLDER_NAME = "alibi" -val SUPPORTS_SCOPED_STORAGE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O +val SUPPORTS_SCOPED_STORAGE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q +val SUPPORTS_SAVING_VIDEOS_IN_CUSTOM_FOLDERS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O val MEDIA_RECORDINGS_PREFIX = "alibi-recording-" val RECORDER_MEDIA_SELECTED_VALUE = "_'media" val RECORDER_INTERNAL_SELECTED_VALUE = "_'internal" +// TODO: Check API 24 + // You are not allowed to change the constants below. // If you do so, you will be blocked on GitHub. const val REPO_URL = "https://github.com/Myzel394/Alibi" diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/Tiles/SaveFolderTile.kt b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/Tiles/SaveFolderTile.kt index 546d646..c24aa51 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/Tiles/SaveFolderTile.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/Tiles/SaveFolderTile.kt @@ -55,6 +55,7 @@ import app.myzel394.alibi.dataStore import app.myzel394.alibi.db.AppSettings import app.myzel394.alibi.ui.RECORDER_MEDIA_SELECTED_VALUE import app.myzel394.alibi.ui.SHEET_BOTTOM_OFFSET +import app.myzel394.alibi.ui.SUPPORTS_SAVING_VIDEOS_IN_CUSTOM_FOLDERS import app.myzel394.alibi.ui.SUPPORTS_SCOPED_STORAGE import app.myzel394.alibi.ui.components.atoms.MessageBox import app.myzel394.alibi.ui.components.atoms.MessageType @@ -256,7 +257,7 @@ fun SelectionSheet( SUPPORTS_SCOPED_STORAGE || PermissionHelper.hasGranted( context, - Manifest.permission.READ_EXTERNAL_STORAGE + Manifest.permission.WRITE_EXTERNAL_STORAGE ) ) { updateValue(RECORDER_MEDIA_SELECTED_VALUE) @@ -276,7 +277,7 @@ fun SelectionSheet( showCustomFolderWarning = true }, ) - if (!SUPPORTS_SCOPED_STORAGE) { + if (!SUPPORTS_SAVING_VIDEOS_IN_CUSTOM_FOLDERS) { Column( modifier = Modifier.padding(horizontal = 32.dp, vertical = 12.dp), horizontalAlignment = Alignment.CenterHorizontally,