fix: Fix recording for Android API 30

This commit is contained in:
Myzel394 2024-01-05 19:12:53 +01:00
parent 0372b44901
commit 08a6d557f8
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
8 changed files with 50 additions and 34 deletions

View File

@ -27,6 +27,8 @@
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<!-- Todo: Check android permissions -->
<!-- Starting with Android 29, apps don't need to request the READ_EXTERNAL_STORAGE permission
for files in their own MediaStore -->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />

View File

@ -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

View File

@ -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!!

View File

@ -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,

View File

@ -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 {

View File

@ -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(

View File

@ -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"

View File

@ -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,