From 43d346aba4e86839492234393165f81fd485afb4 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Fri, 24 Mar 2023 00:33:42 +0100 Subject: [PATCH 1/2] Android: Open DocumentProvider directly when tapping the File Manager button --- .../dolphinemu/activities/UserDataActivity.kt | 65 +++++++++++++------ .../dolphinemu/features/DocumentProvider.kt | 2 +- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt index dc11e811fc..152255eb63 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt @@ -8,6 +8,7 @@ import android.content.Intent import android.net.Uri import android.os.Build import android.os.Bundle +import android.provider.DocumentsContract import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat @@ -20,6 +21,7 @@ import org.dolphinemu.dolphinemu.databinding.ActivityUserDataBinding import org.dolphinemu.dolphinemu.dialogs.NotificationDialog import org.dolphinemu.dolphinemu.dialogs.TaskDialog import org.dolphinemu.dolphinemu.dialogs.UserDataImportWarningDialog +import org.dolphinemu.dolphinemu.features.DocumentProvider import org.dolphinemu.dolphinemu.model.TaskViewModel import org.dolphinemu.dolphinemu.utils.* import org.dolphinemu.dolphinemu.utils.ThemeHelper.enableScrollTint @@ -112,27 +114,43 @@ class UserDataActivity : AppCompatActivity() { } private fun openFileManager() { + // First, try to open the user data folder directly try { - // First, try the package name used on "normal" phones - startActivity(getFileManagerIntent("com.google.android.documentsui")) - } catch (e: ActivityNotFoundException) { - try { - // Next, try the AOSP package name - startActivity(getFileManagerIntent("com.android.documentsui")) - } catch (e2: ActivityNotFoundException) { - // Activity not found. Perhaps it was removed by the OEM, or by some new Android version - // that didn't exist at the time of writing. Not much we can do other than tell the user. - val arguments = Bundle() - arguments.putInt( - NotificationDialog.KEY_MESSAGE, - R.string.user_data_open_system_file_manager_failed - ) + startActivity(getFileManagerIntentOnDocumentProvider(Intent.ACTION_VIEW)) + return + } catch (_: ActivityNotFoundException) {} - val dialog = NotificationDialog() - dialog.arguments = arguments - dialog.show(supportFragmentManager, NotificationDialog.TAG) - } - } + try { + startActivity(getFileManagerIntentOnDocumentProvider("android.provider.action.BROWSE")) + return + } catch (_: ActivityNotFoundException) {} + + try { + // Just try to open the file manager, try the package name used on "normal" phones + startActivity(getFileManagerIntent("com.google.android.documentsui")) + return + } catch (_: ActivityNotFoundException) {} + + try { + // Next, try the AOSP package name + startActivity(getFileManagerIntent("com.android.documentsui")) + return + } catch (_: ActivityNotFoundException) {} + + try { + // Activity not found. Perhaps it was removed by the OEM, or by some new Android version + // that didn't exist at the time of writing. Not much we can do other than tell the user. + val arguments = Bundle() + arguments.putInt( + NotificationDialog.KEY_MESSAGE, + R.string.user_data_open_system_file_manager_failed + ) + + val dialog = NotificationDialog() + dialog.arguments = arguments + dialog.show(supportFragmentManager, NotificationDialog.TAG) + return + } catch (_: ActivityNotFoundException) {} } private fun getFileManagerIntent(packageName: String): Intent { @@ -143,6 +161,15 @@ class UserDataActivity : AppCompatActivity() { return intent } + private fun getFileManagerIntentOnDocumentProvider(action: String): Intent { + val authority = "$packageName.user" + val intent = Intent(action) + intent.addCategory(Intent.CATEGORY_DEFAULT) + intent.data = DocumentsContract.buildRootUri(authority, DocumentProvider.ROOT_ID) + intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or Intent.FLAG_GRANT_PREFIX_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION) + return intent + } + private fun importUserData() { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) intent.type = "application/zip" 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 5ce6aaac9a..089170125c 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 @@ -27,7 +27,7 @@ class DocumentProvider : DocumentsProvider() { private var rootDirectory: File? = null companion object { - private const val ROOT_ID = "root" + public const val ROOT_ID = "root" private val DEFAULT_ROOT_PROJECTION = arrayOf( DocumentsContract.Root.COLUMN_ROOT_ID, From ee563189fdb356c50c4640f6f42e839f4260a8f3 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Fri, 24 Mar 2023 00:53:40 +0100 Subject: [PATCH 2/2] Android: Adjust user data text to match DocumentProvider --- .../org/dolphinemu/dolphinemu/activities/UserDataActivity.kt | 5 +++++ Source/Android/app/src/main/res/values/strings.xml | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt index 152255eb63..3813427f26 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt @@ -51,6 +51,7 @@ class UserDataActivity : AppCompatActivity() { WindowCompat.setDecorFitsSystemWindows(window, false) + val android7 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N val android10 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q val android11 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R val legacy = DirectoryInitialization.isUsingLegacyUserDirectory() @@ -59,6 +60,10 @@ class UserDataActivity : AppCompatActivity() { if (android10) R.string.user_data_new_location_android_10 else R.string.user_data_new_location mBinding.textType.setText(if (legacy) R.string.user_data_old_location else userDataNewLocation) + val openFileManagerStringId = + if (android7) R.string.user_data_open_user_folder else R.string.user_data_open_system_file_manager + mBinding.buttonOpenSystemFileManager.setText(openFileManagerStringId) + mBinding.textPath.text = DirectoryInitialization.getUserDirectory() mBinding.textAndroid11.visibility = if (android11 && !legacy) View.VISIBLE else View.GONE diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index f2ecd4512c..c8c7efdb28 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -401,8 +401,10 @@ Your user data (settings, saves, etc.) is stored in a location which will be deleted when you uninstall the app: Your user data (settings, saves, etc.) is stored in a location which by default will be deleted when you uninstall the app: - Because you\'re using Android 11 or newer, file manager apps can\'t access this folder in the same way as regular folders. You might be able to access the folder using the system file manager (if present on your device), or by connecting your device to a PC. + Because you\'re using Android 11 or newer, file manager apps can\'t access this folder in the same way as regular folders. Instead, Dolphin acts as a file provider. Open System File Manager + Open User Data Folder + Import User Data Export User Data Sorry, Dolphin couldn\'t find the system file manager on your device.