Fix UniFile.fromUri for children of tree uri
This commit is contained in:
1 parent
65613f07ba
commit
b39e24467c
6 files changed
+13
-44
No files matched your search
@@ -15,20 +15,18 @@
|
||||
*/
|
||||
package com.hippo.unifile
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.provider.DocumentsContract
|
||||
import splitties.init.appCtx
|
||||
|
||||
object DocumentsContractApi21 {
|
||||
private const val PATH_DOCUMENT = "document"
|
||||
private const val PATH_TREE = "tree"
|
||||
private val resolver = appCtx.contentResolver
|
||||
private val projection = arrayOf(
|
||||
DocumentsContract.Document.COLUMN_DOCUMENT_ID,
|
||||
DocumentsContract.Document.COLUMN_DISPLAY_NAME,
|
||||
DocumentsContract.Document.COLUMN_MIME_TYPE,
|
||||
)
|
||||
|
||||
fun createFile(self: Uri, mimeType: String, displayName: String) = runCatching {
|
||||
DocumentsContract.createDocument(resolver, self, mimeType, displayName)
|
||||
}.getOrNull()
|
||||
@@ -38,22 +36,14 @@ object DocumentsContractApi21 {
|
||||
fun prepareTreeUri(treeUri: Uri?): Uri {
|
||||
return DocumentsContract.buildDocumentUriUsingTree(
|
||||
treeUri,
|
||||
DocumentsContract.getTreeDocumentId(treeUri),
|
||||
DocumentsContract.getDocumentId(treeUri),
|
||||
)
|
||||
}
|
||||
|
||||
fun getTreeDocumentPath(documentUri: Uri): String {
|
||||
val paths = documentUri.pathSegments
|
||||
if (paths.size >= 4 && PATH_TREE == paths[0] && PATH_DOCUMENT == paths[2]) {
|
||||
return paths[3]
|
||||
}
|
||||
error("Invalid URI: $documentUri")
|
||||
}
|
||||
|
||||
fun buildChildUri(uri: Uri, displayName: String): Uri {
|
||||
return DocumentsContract.buildDocumentUriUsingTree(
|
||||
uri,
|
||||
getTreeDocumentPath(uri) + "/" + displayName,
|
||||
DocumentsContract.getDocumentId(uri) + "/" + displayName,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -70,7 +60,7 @@ object DocumentsContractApi21 {
|
||||
}
|
||||
}
|
||||
|
||||
fun renameTo(context: Context, self: Uri, displayName: String) = runCatching {
|
||||
DocumentsContract.renameDocument(context.contentResolver, self, displayName)
|
||||
fun renameTo(self: Uri, displayName: String) = runCatching {
|
||||
DocumentsContract.renameDocument(resolver, self, displayName)
|
||||
}.getOrNull()
|
||||
}
|
||||
@@ -18,7 +18,7 @@ package com.hippo.unifile
|
||||
import android.net.Uri
|
||||
import java.io.IOException
|
||||
|
||||
class MediaFile(override val uri: Uri) : UniFile(null) {
|
||||
class MediaFile(override val uri: Uri) : UniFile() {
|
||||
override fun createFile(displayName: String) = null
|
||||
|
||||
override fun createDirectory(displayName: String) = null
|
||||
|
||||
@@ -24,8 +24,7 @@ import eu.kanade.tachiyomi.util.system.logcat
|
||||
import java.io.File
|
||||
import java.util.Locale
|
||||
|
||||
class RawFile(parent: UniFile?, private var file: File) : UniFile(parent) {
|
||||
private val parent = parent as? RawFile
|
||||
class RawFile(private val parent: RawFile?, private var file: File) : UniFile() {
|
||||
|
||||
private var cachePresent = false
|
||||
private val allChildren by lazy {
|
||||
|
||||
@@ -17,7 +17,7 @@ package com.hippo.unifile
|
||||
|
||||
import android.net.Uri
|
||||
|
||||
class SingleDocumentFile(parent: UniFile?, override val uri: Uri) : UniFile(parent) {
|
||||
class SingleDocumentFile(override val uri: Uri) : UniFile() {
|
||||
|
||||
override fun createFile(displayName: String) = null
|
||||
|
||||
|
||||
@@ -18,19 +18,16 @@ package com.hippo.unifile
|
||||
import android.net.Uri
|
||||
import android.provider.DocumentsContract.Document.MIME_TYPE_DIR
|
||||
import android.webkit.MimeTypeMap
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import splitties.init.appCtx
|
||||
|
||||
class TreeDocumentFile(
|
||||
parent: UniFile?,
|
||||
private val parent: UniFile?,
|
||||
override var uri: Uri,
|
||||
override var name: String = getFilenameForUri(uri),
|
||||
mimeType: String? = null,
|
||||
) : UniFile(parent) {
|
||||
) : UniFile() {
|
||||
private var cachePresent = false
|
||||
private val allChildren by lazy {
|
||||
cachePresent = true
|
||||
logcat { "Directory lookup cache created for $name" }
|
||||
DocumentsContractApi21.listFiles(uri).mapTo(mutableListOf()) { (uri, name, mimeType) ->
|
||||
TreeDocumentFile(this, uri, name, mimeType)
|
||||
}
|
||||
@@ -98,7 +95,6 @@ class TreeDocumentFile(
|
||||
override fun ensureDir(): Boolean {
|
||||
if (isDirectory) return true
|
||||
if (isFile) return false
|
||||
val parent = parentFile
|
||||
return if (parent != null && parent.ensureDir()) {
|
||||
parent.createDirectory(name) != null
|
||||
} else {
|
||||
@@ -109,7 +105,6 @@ class TreeDocumentFile(
|
||||
override fun ensureFile(): Boolean {
|
||||
if (isFile) return true
|
||||
if (isDirectory) return false
|
||||
val parent = parentFile
|
||||
return if (parent != null && parent.ensureDir()) {
|
||||
parent.createFile(name) != null
|
||||
} else {
|
||||
@@ -135,7 +130,7 @@ class TreeDocumentFile(
|
||||
}
|
||||
|
||||
override fun renameTo(displayName: String): Boolean {
|
||||
val result = DocumentsContractApi21.renameTo(appCtx, uri, displayName)
|
||||
val result = DocumentsContractApi21.renameTo(uri, displayName)
|
||||
if (result != null) {
|
||||
uri = result
|
||||
name = displayName
|
||||
|
||||
@@ -28,7 +28,7 @@ import splitties.init.appCtx
|
||||
* In Android files can be accessed via [java.io.File] and [android.net.Uri].
|
||||
* The UniFile is designed to emulate File interface for both File and Uri.
|
||||
*/
|
||||
abstract class UniFile internal constructor(private val parent: UniFile?) {
|
||||
sealed class UniFile {
|
||||
/**
|
||||
* Create a new file as a direct child of this directory.
|
||||
*
|
||||
@@ -79,21 +79,6 @@ abstract class UniFile internal constructor(private val parent: UniFile?) {
|
||||
*/
|
||||
abstract val type: String?
|
||||
|
||||
/**
|
||||
* Return the parent file of this file. Only defined inside of the
|
||||
* user-selected tree; you can never escape above the top of the tree.
|
||||
*
|
||||
*
|
||||
* The underlying [android.provider.DocumentsProvider] only defines a
|
||||
* forward mapping from parent to child, so the reverse mapping of child to
|
||||
* parent offered here is purely a convenience method, and it may be
|
||||
* incorrect if the underlying tree structure changes.
|
||||
*
|
||||
* @return parent of the file, or null if it is the top of the file tree
|
||||
*/
|
||||
val parentFile: UniFile?
|
||||
get() = parent
|
||||
|
||||
/**
|
||||
* Indicates if this file represents a *directory*.
|
||||
*
|
||||
@@ -235,7 +220,7 @@ abstract class UniFile internal constructor(private val parent: UniFile?) {
|
||||
companion object {
|
||||
fun fromFile(file: File) = RawFile(null, file)
|
||||
|
||||
private fun fromSingleUri(singleUri: Uri) = SingleDocumentFile(null, singleUri)
|
||||
private fun fromSingleUri(singleUri: Uri) = SingleDocumentFile(singleUri)
|
||||
|
||||
private fun fromTreeUri(treeUri: Uri) = TreeDocumentFile(null, DocumentsContractApi21.prepareTreeUri(treeUri))
|
||||
|
||||
|
||||
Reference in new issue
Block a user