Read using new queries on R+ devices to properly get trashed media

This commit is contained in:
Ensar Sarajčić 2023-07-25 12:13:54 +02:00
parent b9035f2612
commit 950f5a0207
3 changed files with 59 additions and 21 deletions

View File

@ -63,7 +63,7 @@ android {
}
dependencies {
implementation 'com.github.SimpleMobileTools:Simple-Commons:f76d729b9d'
implementation 'com.github.esensar:Simple-Commons:6e36665609'
implementation 'org.greenrobot:eventbus:3.3.1'
implementation 'com.github.Armen101:AudioRecordView:1.0.4'
implementation 'androidx.documentfile:documentfile:1.0.1'

View File

@ -3,13 +3,13 @@ package com.simplemobiletools.voicerecorder.extensions
import android.content.ContentValues
import android.provider.MediaStore
import android.provider.MediaStore.Audio.Media
import androidx.core.net.toUri
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.deleteFile
import com.simplemobiletools.commons.extensions.getParentPath
import com.simplemobiletools.commons.extensions.toFileDirItem
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.voicerecorder.helpers.getAudioFileContentUri
import com.simplemobiletools.voicerecorder.models.Recording
import java.io.File
@ -17,7 +17,7 @@ fun BaseSimpleActivity.deleteRecordings(recordingsToRemove: Collection<Recording
when {
isRPlus() -> {
val fileUris = recordingsToRemove.map { recording ->
"${Media.EXTERNAL_CONTENT_URI}/${recording.id.toLong()}".toUri()
getAudioFileContentUri(recording.id.toLong())
}
deleteSDK30Uris(fileUris, callback)
@ -52,7 +52,7 @@ fun BaseSimpleActivity.restoreRecordings(recordingsToRestore: Collection<Recordi
when {
isRPlus() -> {
val fileUris = recordingsToRestore.map { recording ->
"${Media.EXTERNAL_CONTENT_URI}/${recording.id.toLong()}".toUri()
getAudioFileContentUri(recording.id.toLong())
}
trashSDK30Uris(fileUris, false, callback)
@ -107,7 +107,7 @@ fun BaseSimpleActivity.moveRecordingsToRecycleBin(recordingsToMove: Collection<R
when {
isRPlus() -> {
val fileUris = recordingsToMove.map { recording ->
"${Media.EXTERNAL_CONTENT_URI}/${recording.id.toLong()}".toUri()
getAudioFileContentUri(recording.id.toLong())
}
trashSDK30Uris(fileUris, true, callback)

View File

@ -3,13 +3,16 @@ package com.simplemobiletools.voicerecorder.extensions
import android.annotation.SuppressLint
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.media.MediaMetadataRetriever
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.provider.MediaStore.Audio.Media
@ -57,6 +60,37 @@ fun Context.getDefaultRecordingsRelativePath(): String {
}
}
@SuppressLint("InlinedApi")
fun Context.getNewMediaStoreRecordings(trashed: Boolean = false): ArrayList<Recording> {
val recordings = ArrayList<Recording>()
val uri = Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val projection = arrayOf(
Media._ID,
Media.DISPLAY_NAME,
Media.DATE_ADDED,
Media.DURATION,
Media.SIZE
)
val bundle = Bundle().apply {
putStringArray(ContentResolver.QUERY_ARG_SORT_COLUMNS, arrayOf(Media.DATE_ADDED))
putInt(ContentResolver.QUERY_ARG_SORT_DIRECTION, ContentResolver.QUERY_SORT_DIRECTION_DESCENDING)
putString(ContentResolver.QUERY_ARG_SQL_SELECTION, "${Media.OWNER_PACKAGE_NAME} = ?")
putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, arrayOf(packageName))
if (config.useRecycleBin) {
val trashedValue = if (trashed) MediaStore.MATCH_ONLY else MediaStore.MATCH_EXCLUDE
putInt(MediaStore.QUERY_ARG_MATCH_TRASHED, trashedValue)
}
}
queryCursor(uri, projection, bundle, true) { cursor ->
val recording = readRecordingFromCursor(cursor)
recordings.add(recording)
}
return recordings
}
@SuppressLint("InlinedApi")
fun Context.getMediaStoreRecordings(trashed: Boolean = false): ArrayList<Recording> {
val recordings = ArrayList<Recording>()
@ -81,21 +115,7 @@ fun Context.getMediaStoreRecordings(trashed: Boolean = false): ArrayList<Recordi
}
queryCursor(uri, projection, selection, selectionArgs, sortOrder, true) { cursor ->
val id = cursor.getIntValue(Media._ID)
val title = cursor.getStringValue(Media.DISPLAY_NAME)
val timestamp = cursor.getIntValue(Media.DATE_ADDED)
var duration = cursor.getLongValue(Media.DURATION) / 1000
var size = cursor.getIntValue(Media.SIZE)
if (duration == 0L) {
duration = getDurationFromUri(getAudioFileContentUri(id.toLong()))
}
if (size == 0) {
size = getSizeFromUri(id.toLong())
}
val recording = Recording(id, title, "", timestamp, duration.toInt(), size)
val recording = readRecordingFromCursor(cursor)
recordings.add(recording)
}
@ -152,7 +172,7 @@ fun Context.getAllRecordings(trashed: Boolean = false): ArrayList<Recording> {
val recordings = ArrayList<Recording>()
return when {
isRPlus() -> {
recordings.addAll(getMediaStoreRecordings(trashed))
recordings.addAll(getNewMediaStoreRecordings(trashed))
recordings.addAll(getSAFRecordings(trashed))
recordings
}
@ -181,6 +201,24 @@ fun Context.getOrCreateTrashFolder(): String {
return trashFolder
}
private fun Context.readRecordingFromCursor(cursor: Cursor): Recording {
val id = cursor.getIntValue(Media._ID)
val title = cursor.getStringValue(Media.DISPLAY_NAME)
val timestamp = cursor.getIntValue(Media.DATE_ADDED)
var duration = cursor.getLongValue(Media.DURATION) / 1000
var size = cursor.getIntValue(Media.SIZE)
if (duration == 0L) {
duration = getDurationFromUri(getAudioFileContentUri(id.toLong()))
}
if (size == 0) {
size = getSizeFromUri(id.toLong())
}
return Recording(id, title, "", timestamp, duration.toInt(), size)
}
private fun Context.getSizeFromUri(id: Long): Int {
val recordingUri = getAudioFileContentUri(id)
return try {