From d667fca8d32df385f7b7e2a9d19cdb00bb24fbe6 Mon Sep 17 00:00:00 2001 From: BlakDulz Date: Sat, 23 Dec 2023 20:42:00 +0700 Subject: [PATCH 1/2] Implement Refresh on DocumentProvider "When interacting with DocumentUI or the built-in Android System Internal Files Manager app and performing Create, Rename, and Delete operations, DocumentsUI will not automatically refresh the changes. Previously, users had to manually pull down from the top to refresh the changes. This commit aims to fix this issue by automatically notifying the system that changes have occurred and triggering a requery." --- .../dolphinemu/features/DocumentProvider.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/DocumentProvider.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/DocumentProvider.kt index b637962177..434b344417 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/DocumentProvider.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/DocumentProvider.kt @@ -9,8 +9,10 @@ package org.dolphinemu.dolphinemu.features import android.annotation.TargetApi +import android.content.Context import android.database.Cursor import android.database.MatrixCursor +import android.net.Uri import android.os.Build import android.os.CancellationSignal import android.os.ParcelFileDescriptor @@ -93,6 +95,8 @@ class DocumentProvider : DocumentsProvider() { appendDocument(file, result) } } + result.setNotificationUri(context!!.contentResolver, DocumentsContract.buildChildDocumentsUri( + "${context!!.packageName}.user", parentDocumentId)) return result } @@ -121,6 +125,7 @@ class DocumentProvider : DocumentsProvider() { } else { file.createNewFile() } + refreshDocument(parentDocumentId) return pathToDocumentId(file) } @@ -128,7 +133,9 @@ class DocumentProvider : DocumentsProvider() { rootDirectory ?: return val file = documentIdToPath(documentId) + val fileParent = file.parentFile file.deleteRecursively() + refreshDocument(pathToDocumentId(fileParent!!)) } override fun renameDocument(documentId: String, displayName: String): String? { @@ -137,9 +144,19 @@ class DocumentProvider : DocumentsProvider() { val file = documentIdToPath(documentId) val dest = findFileNameForNewFile(File(file.parentFile, displayName)) file.renameTo(dest) + refreshDocument(pathToDocumentId(file.parentFile!!)) return pathToDocumentId(dest) } + private fun refreshDocument(parentDocumentId: String) { + val parentUri: Uri = + DocumentsContract.buildChildDocumentsUri( + "${context!!.packageName}.user", + parentDocumentId + ) + context!!.contentResolver.notifyChange(parentUri, null) + } + override fun isChildDocument(parentDocumentId: String, documentId: String): Boolean = documentId.startsWith(parentDocumentId) From 45d3c41d68b466115e2fe877305f32cb271aa6c0 Mon Sep 17 00:00:00 2001 From: BlakDulz Date: Sun, 24 Dec 2023 15:34:10 +0700 Subject: [PATCH 2/2] Make DocumentProvider Support Thumbnail This will make DocumentUI or the built-in Android System Internal Files Manager app showing Thumbnail of Image file instead of image type icon. --- .../dolphinemu/features/DocumentProvider.kt | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/DocumentProvider.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/DocumentProvider.kt index 434b344417..63d72160c5 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/DocumentProvider.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/DocumentProvider.kt @@ -9,9 +9,10 @@ package org.dolphinemu.dolphinemu.features import android.annotation.TargetApi -import android.content.Context +import android.content.res.AssetFileDescriptor import android.database.Cursor import android.database.MatrixCursor +import android.graphics.Point import android.net.Uri import android.os.Build import android.os.CancellationSignal @@ -29,7 +30,7 @@ class DocumentProvider : DocumentsProvider() { private var rootDirectory: File? = null companion object { - public const val ROOT_ID = "root" + const val ROOT_ID = "root" private val DEFAULT_ROOT_PROJECTION = arrayOf( DocumentsContract.Root.COLUMN_ROOT_ID, @@ -111,6 +112,16 @@ class DocumentProvider : DocumentsProvider() { return ParcelFileDescriptor.open(file, ParcelFileDescriptor.parseMode(mode)) } + override fun openDocumentThumbnail( + documentId: String, + sizeHint: Point, + signal: CancellationSignal + ): AssetFileDescriptor { + val file = documentIdToPath(documentId) + val pfd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY) + return AssetFileDescriptor(pfd, 0, AssetFileDescriptor.UNKNOWN_LENGTH) + } + override fun createDocument( parentDocumentId: String, mimeType: String, @@ -178,6 +189,10 @@ class DocumentProvider : DocumentsProvider() { } else { file.name } + val mimeType = getTypeForFile(file) + if (file.exists() && mimeType.startsWith("image/")) { + flags = flags or DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL + } cursor.newRow().apply { add(DocumentsContract.Document.COLUMN_DOCUMENT_ID, pathToDocumentId(file)) add(DocumentsContract.Document.COLUMN_MIME_TYPE, getTypeForFile(file))