mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-16 01:09:20 +01:00
Merge pull request #11742 from K0bin/document-provider-2
Android: Document Provider improvements
This commit is contained in:
commit
1a2dcc53f2
@ -40,7 +40,6 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO If this is ever modified, change application_id in strings.xml
|
|
||||||
applicationId "org.dolphinemu.dolphinemu"
|
applicationId "org.dolphinemu.dolphinemu"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
@ -74,6 +73,7 @@ android {
|
|||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resValue 'string', 'app_name_suffixed', 'Dolphin Emulator'
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
shrinkResources true
|
shrinkResources true
|
||||||
proguardFiles getDefaultProguardFile(
|
proguardFiles getDefaultProguardFile(
|
||||||
@ -86,13 +86,14 @@ android {
|
|||||||
// Signed by debug key disallowing distribution on Play Store.
|
// Signed by debug key disallowing distribution on Play Store.
|
||||||
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
|
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
|
||||||
debug {
|
debug {
|
||||||
// TODO If this is ever modified, change application_id in debug/strings.xml
|
resValue 'string', 'app_name_suffixed', 'Dolphin Debug'
|
||||||
applicationIdSuffix ".debug"
|
applicationIdSuffix ".debug"
|
||||||
versionNameSuffix '-debug'
|
versionNameSuffix '-debug'
|
||||||
jniDebuggable true
|
jniDebuggable true
|
||||||
}
|
}
|
||||||
|
|
||||||
benchmark {
|
benchmark {
|
||||||
|
resValue 'string', 'app_name_suffixed', 'Dolphin Benchmark'
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
matchingFallbacks = ['release']
|
matchingFallbacks = ['release']
|
||||||
debuggable false
|
debuggable false
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".DolphinApplication"
|
android:name=".DolphinApplication"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name_suffixed"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:preserveLegacyExternalStorage="true"
|
android:preserveLegacyExternalStorage="true"
|
||||||
@ -97,7 +97,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".activities.CustomFilePickerActivity"
|
android:name=".activities.CustomFilePickerActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name_suffixed"
|
||||||
android:theme="@style/Theme.Dolphin.FilePicker">
|
android:theme="@style/Theme.Dolphin.FilePicker">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
@ -54,12 +54,11 @@ class DocumentProvider : DocumentsProvider() {
|
|||||||
|
|
||||||
override fun queryRoots(projection: Array<String>?): Cursor {
|
override fun queryRoots(projection: Array<String>?): Cursor {
|
||||||
val result = MatrixCursor(projection ?: DEFAULT_ROOT_PROJECTION)
|
val result = MatrixCursor(projection ?: DEFAULT_ROOT_PROJECTION)
|
||||||
rootDirectory = rootDirectory ?: DirectoryInitialization.getUserDirectoryPath(context)
|
|
||||||
rootDirectory ?: return result
|
rootDirectory ?: return result
|
||||||
|
|
||||||
result.newRow().apply {
|
result.newRow().apply {
|
||||||
add(DocumentsContract.Root.COLUMN_ROOT_ID, ROOT_ID)
|
add(DocumentsContract.Root.COLUMN_ROOT_ID, ROOT_ID)
|
||||||
add(DocumentsContract.Root.COLUMN_TITLE, context!!.getString(R.string.app_name))
|
add(DocumentsContract.Root.COLUMN_TITLE, context!!.getString(R.string.app_name_suffixed))
|
||||||
add(DocumentsContract.Root.COLUMN_ICON, R.drawable.ic_dolphin)
|
add(DocumentsContract.Root.COLUMN_ICON, R.drawable.ic_dolphin)
|
||||||
add(
|
add(
|
||||||
DocumentsContract.Root.COLUMN_FLAGS,
|
DocumentsContract.Root.COLUMN_FLAGS,
|
||||||
@ -73,7 +72,6 @@ class DocumentProvider : DocumentsProvider() {
|
|||||||
|
|
||||||
override fun queryDocument(documentId: String, projection: Array<String>?): Cursor {
|
override fun queryDocument(documentId: String, projection: Array<String>?): Cursor {
|
||||||
val result = MatrixCursor(projection ?: DEFAULT_DOCUMENT_PROJECTION)
|
val result = MatrixCursor(projection ?: DEFAULT_DOCUMENT_PROJECTION)
|
||||||
rootDirectory = rootDirectory ?: DirectoryInitialization.getUserDirectoryPath(context)
|
|
||||||
rootDirectory ?: return result
|
rootDirectory ?: return result
|
||||||
val file = documentIdToPath(documentId)
|
val file = documentIdToPath(documentId)
|
||||||
appendDocument(file, result)
|
appendDocument(file, result)
|
||||||
@ -102,7 +100,9 @@ class DocumentProvider : DocumentsProvider() {
|
|||||||
documentId: String,
|
documentId: String,
|
||||||
mode: String,
|
mode: String,
|
||||||
signal: CancellationSignal?
|
signal: CancellationSignal?
|
||||||
): ParcelFileDescriptor {
|
): ParcelFileDescriptor? {
|
||||||
|
rootDirectory ?: return null
|
||||||
|
|
||||||
val file = documentIdToPath(documentId)
|
val file = documentIdToPath(documentId)
|
||||||
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.parseMode(mode))
|
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.parseMode(mode))
|
||||||
}
|
}
|
||||||
@ -111,7 +111,9 @@ class DocumentProvider : DocumentsProvider() {
|
|||||||
parentDocumentId: String,
|
parentDocumentId: String,
|
||||||
mimeType: String,
|
mimeType: String,
|
||||||
displayName: String
|
displayName: String
|
||||||
): String {
|
): String? {
|
||||||
|
rootDirectory ?: return null
|
||||||
|
|
||||||
val folder = documentIdToPath(parentDocumentId)
|
val folder = documentIdToPath(parentDocumentId)
|
||||||
val file = findFileNameForNewFile(File(folder, displayName))
|
val file = findFileNameForNewFile(File(folder, displayName))
|
||||||
if (mimeType == DocumentsContract.Document.MIME_TYPE_DIR) {
|
if (mimeType == DocumentsContract.Document.MIME_TYPE_DIR) {
|
||||||
@ -122,56 +124,40 @@ class DocumentProvider : DocumentsProvider() {
|
|||||||
return pathToDocumentId(file)
|
return pathToDocumentId(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun copyDocument(sourceDocumentId: String, targetParentDocumentId: String): String {
|
override fun deleteDocument(documentId: String) {
|
||||||
val file = documentIdToPath(sourceDocumentId)
|
rootDirectory ?: return
|
||||||
val target = documentIdToPath(targetParentDocumentId)
|
|
||||||
val copy = copyRecursively(file, File(target, file.name))
|
|
||||||
return pathToDocumentId(copy)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun removeDocument(documentId: String, parentDocumentId: String) {
|
|
||||||
val file = documentIdToPath(documentId)
|
val file = documentIdToPath(documentId)
|
||||||
file.deleteRecursively()
|
file.deleteRecursively()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun moveDocument(
|
override fun renameDocument(documentId: String, displayName: String): String? {
|
||||||
sourceDocumentId: String,
|
rootDirectory ?: return null
|
||||||
sourceParentDocumentId: String,
|
|
||||||
targetParentDocumentId: String
|
val file = documentIdToPath(documentId)
|
||||||
): String {
|
val dest = findFileNameForNewFile(File(file.parentFile, displayName))
|
||||||
val copy = copyDocument(sourceDocumentId, targetParentDocumentId)
|
file.renameTo(dest)
|
||||||
val file = documentIdToPath(sourceDocumentId)
|
return pathToDocumentId(dest)
|
||||||
file.delete()
|
|
||||||
return copy
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renameDocument(documentId: String, displayName: String): String {
|
override fun isChildDocument(parentDocumentId: String, documentId: String): Boolean
|
||||||
val file = documentIdToPath(documentId)
|
= documentId.startsWith(parentDocumentId)
|
||||||
file.renameTo(findFileNameForNewFile(File(file.parentFile, displayName)))
|
|
||||||
return pathToDocumentId(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isChildDocument(parentDocumentId: String, documentId: String): Boolean {
|
|
||||||
val file = documentIdToPath(documentId)
|
|
||||||
val folder = documentIdToPath(parentDocumentId)
|
|
||||||
return file.relativeToOrNull(folder) != null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun appendDocument(file: File, cursor: MatrixCursor) {
|
private fun appendDocument(file: File, cursor: MatrixCursor) {
|
||||||
var flags = 0
|
var flags = 0
|
||||||
if (file.isDirectory && file.canWrite()) {
|
if (file.canWrite()) {
|
||||||
flags = DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE
|
flags = if (file.isDirectory) {
|
||||||
} else if (file.canWrite()) {
|
DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE
|
||||||
flags = DocumentsContract.Document.FLAG_SUPPORTS_WRITE
|
} else {
|
||||||
|
DocumentsContract.Document.FLAG_SUPPORTS_WRITE
|
||||||
|
}
|
||||||
flags = flags or DocumentsContract.Document.FLAG_SUPPORTS_DELETE
|
flags = flags or DocumentsContract.Document.FLAG_SUPPORTS_DELETE
|
||||||
flags = flags or DocumentsContract.Document.FLAG_SUPPORTS_REMOVE
|
|
||||||
flags = flags or DocumentsContract.Document.FLAG_SUPPORTS_MOVE
|
|
||||||
flags = flags or DocumentsContract.Document.FLAG_SUPPORTS_COPY
|
|
||||||
flags = flags or DocumentsContract.Document.FLAG_SUPPORTS_RENAME
|
flags = flags or DocumentsContract.Document.FLAG_SUPPORTS_RENAME
|
||||||
|
// The system will handle copy + move for us
|
||||||
}
|
}
|
||||||
|
|
||||||
val name = if (file == rootDirectory) {
|
val name = if (file == rootDirectory) {
|
||||||
context!!.getString(R.string.app_name)
|
context!!.getString(R.string.app_name_suffixed)
|
||||||
} else {
|
} else {
|
||||||
file.name
|
file.name
|
||||||
}
|
}
|
||||||
@ -217,22 +203,6 @@ class DocumentProvider : DocumentsProvider() {
|
|||||||
unusedFile = File("$pathWithoutExtension.$i.$extension")
|
unusedFile = File("$pathWithoutExtension.$i.$extension")
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
return file
|
return unusedFile
|
||||||
}
|
|
||||||
|
|
||||||
private fun copyRecursively(src: File, dst: File): File {
|
|
||||||
val actualDst = findFileNameForNewFile(dst)
|
|
||||||
if (src.isDirectory) {
|
|
||||||
actualDst.mkdirs()
|
|
||||||
val children = src.listFiles()
|
|
||||||
if (children !== null) {
|
|
||||||
for (file in children) {
|
|
||||||
copyRecursively(file, File(actualDst, file.name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
src.copyTo(actualDst)
|
|
||||||
}
|
|
||||||
return actualDst
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,7 @@ public final class MainActivity extends AppCompatActivity
|
|||||||
setInsets();
|
setInsets();
|
||||||
ThemeHelper.enableStatusBarScrollTint(this, mBinding.appbarMain);
|
ThemeHelper.enableStatusBarScrollTint(this, mBinding.appbarMain);
|
||||||
|
|
||||||
|
mBinding.toolbarMain.setTitle(R.string.app_name);
|
||||||
setSupportActionBar(mBinding.toolbarMain);
|
setSupportActionBar(mBinding.toolbarMain);
|
||||||
|
|
||||||
// Set up the FAB.
|
// Set up the FAB.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user