mirror of
https://github.com/SimpleMobileTools/Simple-Voice-Recorder.git
synced 2025-02-01 01:26:42 +01:00
Read using new queries on R+ devices to properly get trashed media
This commit is contained in:
parent
b9035f2612
commit
950f5a0207
@ -63,7 +63,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:f76d729b9d'
|
implementation 'com.github.esensar:Simple-Commons:6e36665609'
|
||||||
implementation 'org.greenrobot:eventbus:3.3.1'
|
implementation 'org.greenrobot:eventbus:3.3.1'
|
||||||
implementation 'com.github.Armen101:AudioRecordView:1.0.4'
|
implementation 'com.github.Armen101:AudioRecordView:1.0.4'
|
||||||
implementation 'androidx.documentfile:documentfile:1.0.1'
|
implementation 'androidx.documentfile:documentfile:1.0.1'
|
||||||
|
@ -3,13 +3,13 @@ package com.simplemobiletools.voicerecorder.extensions
|
|||||||
import android.content.ContentValues
|
import android.content.ContentValues
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.provider.MediaStore.Audio.Media
|
import android.provider.MediaStore.Audio.Media
|
||||||
import androidx.core.net.toUri
|
|
||||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||||
import com.simplemobiletools.commons.extensions.deleteFile
|
import com.simplemobiletools.commons.extensions.deleteFile
|
||||||
import com.simplemobiletools.commons.extensions.getParentPath
|
import com.simplemobiletools.commons.extensions.getParentPath
|
||||||
import com.simplemobiletools.commons.extensions.toFileDirItem
|
import com.simplemobiletools.commons.extensions.toFileDirItem
|
||||||
import com.simplemobiletools.commons.helpers.*
|
import com.simplemobiletools.commons.helpers.*
|
||||||
import com.simplemobiletools.commons.models.FileDirItem
|
import com.simplemobiletools.commons.models.FileDirItem
|
||||||
|
import com.simplemobiletools.voicerecorder.helpers.getAudioFileContentUri
|
||||||
import com.simplemobiletools.voicerecorder.models.Recording
|
import com.simplemobiletools.voicerecorder.models.Recording
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ fun BaseSimpleActivity.deleteRecordings(recordingsToRemove: Collection<Recording
|
|||||||
when {
|
when {
|
||||||
isRPlus() -> {
|
isRPlus() -> {
|
||||||
val fileUris = recordingsToRemove.map { recording ->
|
val fileUris = recordingsToRemove.map { recording ->
|
||||||
"${Media.EXTERNAL_CONTENT_URI}/${recording.id.toLong()}".toUri()
|
getAudioFileContentUri(recording.id.toLong())
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteSDK30Uris(fileUris, callback)
|
deleteSDK30Uris(fileUris, callback)
|
||||||
@ -52,7 +52,7 @@ fun BaseSimpleActivity.restoreRecordings(recordingsToRestore: Collection<Recordi
|
|||||||
when {
|
when {
|
||||||
isRPlus() -> {
|
isRPlus() -> {
|
||||||
val fileUris = recordingsToRestore.map { recording ->
|
val fileUris = recordingsToRestore.map { recording ->
|
||||||
"${Media.EXTERNAL_CONTENT_URI}/${recording.id.toLong()}".toUri()
|
getAudioFileContentUri(recording.id.toLong())
|
||||||
}
|
}
|
||||||
|
|
||||||
trashSDK30Uris(fileUris, false, callback)
|
trashSDK30Uris(fileUris, false, callback)
|
||||||
@ -107,7 +107,7 @@ fun BaseSimpleActivity.moveRecordingsToRecycleBin(recordingsToMove: Collection<R
|
|||||||
when {
|
when {
|
||||||
isRPlus() -> {
|
isRPlus() -> {
|
||||||
val fileUris = recordingsToMove.map { recording ->
|
val fileUris = recordingsToMove.map { recording ->
|
||||||
"${Media.EXTERNAL_CONTENT_URI}/${recording.id.toLong()}".toUri()
|
getAudioFileContentUri(recording.id.toLong())
|
||||||
}
|
}
|
||||||
|
|
||||||
trashSDK30Uris(fileUris, true, callback)
|
trashSDK30Uris(fileUris, true, callback)
|
||||||
|
@ -3,13 +3,16 @@ package com.simplemobiletools.voicerecorder.extensions
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
|
import android.content.ContentResolver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.database.Cursor
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.media.MediaMetadataRetriever
|
import android.media.MediaMetadataRetriever
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.provider.MediaStore.Audio.Media
|
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")
|
@SuppressLint("InlinedApi")
|
||||||
fun Context.getMediaStoreRecordings(trashed: Boolean = false): ArrayList<Recording> {
|
fun Context.getMediaStoreRecordings(trashed: Boolean = false): ArrayList<Recording> {
|
||||||
val recordings = 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 ->
|
queryCursor(uri, projection, selection, selectionArgs, sortOrder, true) { cursor ->
|
||||||
val id = cursor.getIntValue(Media._ID)
|
val recording = readRecordingFromCursor(cursor)
|
||||||
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)
|
|
||||||
recordings.add(recording)
|
recordings.add(recording)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +172,7 @@ fun Context.getAllRecordings(trashed: Boolean = false): ArrayList<Recording> {
|
|||||||
val recordings = ArrayList<Recording>()
|
val recordings = ArrayList<Recording>()
|
||||||
return when {
|
return when {
|
||||||
isRPlus() -> {
|
isRPlus() -> {
|
||||||
recordings.addAll(getMediaStoreRecordings(trashed))
|
recordings.addAll(getNewMediaStoreRecordings(trashed))
|
||||||
recordings.addAll(getSAFRecordings(trashed))
|
recordings.addAll(getSAFRecordings(trashed))
|
||||||
recordings
|
recordings
|
||||||
}
|
}
|
||||||
@ -181,6 +201,24 @@ fun Context.getOrCreateTrashFolder(): String {
|
|||||||
return trashFolder
|
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 {
|
private fun Context.getSizeFromUri(id: Long): Int {
|
||||||
val recordingUri = getAudioFileContentUri(id)
|
val recordingUri = getAudioFileContentUri(id)
|
||||||
return try {
|
return try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user