DocumentFileX
This commit is contained in:
@@ -60,9 +60,6 @@ dependencies {
|
|||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
implementation 'androidx.preference:preference:1.1.0'
|
implementation 'androidx.preference:preference:1.1.0'
|
||||||
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
|
||||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
|
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
|
||||||
implementation "androidx.biometric:biometric:1.0.1"
|
implementation "androidx.biometric:biometric:1.0.1"
|
||||||
implementation 'com.android.support:multidex:1.0.3'
|
implementation 'com.android.support:multidex:1.0.3'
|
||||||
implementation "com.daimajia.swipelayout:library:1.2.0@aar"
|
implementation "com.daimajia.swipelayout:library:1.2.0@aar"
|
||||||
@@ -72,7 +69,7 @@ dependencies {
|
|||||||
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
|
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
|
||||||
implementation 'com.github.arimorty:floatingsearchview:2.1.1'
|
implementation 'com.github.arimorty:floatingsearchview:2.1.1'
|
||||||
implementation 'com.github.clans:fab:1.6.4'
|
implementation 'com.github.clans:fab:1.6.4'
|
||||||
implementation 'com.github.bumptech.glide:glide:4.10.0'
|
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
||||||
implementation('com.github.bumptech.glide:recyclerview-integration:4.11.0') {
|
implementation('com.github.bumptech.glide:recyclerview-integration:4.11.0') {
|
||||||
transitive = false
|
transitive = false
|
||||||
}
|
}
|
||||||
@@ -81,7 +78,7 @@ dependencies {
|
|||||||
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
||||||
implementation 'com.andrognito.patternlockview:patternlockview:1.0.0'
|
implementation 'com.andrognito.patternlockview:patternlockview:1.0.0'
|
||||||
implementation "ru.noties.markwon:core:${markwonVersion}"
|
implementation "ru.noties.markwon:core:${markwonVersion}"
|
||||||
kapt 'com.github.bumptech.glide:compiler:4.10.0'
|
kapt 'com.github.bumptech.glide:compiler:4.11.0'
|
||||||
testImplementation 'junit:junit:4.13'
|
testImplementation 'junit:junit:4.13'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||||
androidTestImplementation 'androidx.test:rules:1.2.0'
|
androidTestImplementation 'androidx.test:rules:1.2.0'
|
||||||
|
|||||||
52
app/src/main/java/xyz/quaver/pupil/util/saf/DocumentFileX.kt
Normal file
52
app/src/main/java/xyz/quaver/pupil/util/saf/DocumentFileX.kt
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Pupil, Hitomi.la viewer for Android
|
||||||
|
* Copyright (C) 2020 tom5079
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package xyz.quaver.pupil.util.saf
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
abstract class DocumentFileX {
|
||||||
|
|
||||||
|
abstract fun createFile(displayName: String): DocumentFileX?
|
||||||
|
abstract fun createDirectory(displayName: String): DocumentFileX?
|
||||||
|
abstract fun getUri(): Uri
|
||||||
|
abstract fun getName(): String
|
||||||
|
abstract fun getParentFile(): DocumentFileX?
|
||||||
|
abstract fun isDirectory(): Boolean
|
||||||
|
abstract fun isFile(): Boolean
|
||||||
|
abstract fun length(): Long
|
||||||
|
abstract fun canRead(): Boolean
|
||||||
|
abstract fun canWrite(): Boolean
|
||||||
|
abstract fun delete(): Boolean
|
||||||
|
abstract fun exists(): Boolean
|
||||||
|
abstract fun listFiles(): List<DocumentFileX>?
|
||||||
|
abstract fun findFile(displayName: String): DocumentFileX?
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromFile(file: File): DocumentFileX {
|
||||||
|
return RawDocumentFileX(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fromTreeUri(context: Context, uri: Uri): DocumentFileX {
|
||||||
|
return TreeDocumentFileX(context, uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Pupil, Hitomi.la viewer for Android
|
||||||
|
* Copyright (C) 2020 tom5079
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package xyz.quaver.pupil.util.saf
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class RawDocumentFileX(private var file: File) : DocumentFileX() {
|
||||||
|
|
||||||
|
override fun createFile(displayName: String) =
|
||||||
|
File(file, displayName).let {
|
||||||
|
try {
|
||||||
|
it.createNewFile()
|
||||||
|
RawDocumentFileX(it)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createDirectory(displayName: String) =
|
||||||
|
File(file, displayName).let {
|
||||||
|
if (it.isDirectory || it.mkdir())
|
||||||
|
RawDocumentFileX(it)
|
||||||
|
else
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUri() = Uri.fromFile(file)!!
|
||||||
|
|
||||||
|
override fun getName() = file.name
|
||||||
|
|
||||||
|
override fun getParentFile() =
|
||||||
|
file.parentFile.let {
|
||||||
|
if (it == null)
|
||||||
|
null
|
||||||
|
else
|
||||||
|
RawDocumentFileX(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isDirectory() = file.isDirectory
|
||||||
|
|
||||||
|
override fun isFile() = file.isFile
|
||||||
|
|
||||||
|
override fun length() = file.length()
|
||||||
|
|
||||||
|
override fun canRead() = file.canRead()
|
||||||
|
|
||||||
|
override fun canWrite() = file.canWrite()
|
||||||
|
|
||||||
|
override fun delete() =
|
||||||
|
if (file.isDirectory)
|
||||||
|
file.deleteRecursively()
|
||||||
|
else
|
||||||
|
file.delete()
|
||||||
|
|
||||||
|
override fun exists() = file.exists()
|
||||||
|
|
||||||
|
override fun listFiles() = file.listFiles()?.map { RawDocumentFileX(it) }
|
||||||
|
|
||||||
|
override fun findFile(displayName: String) =
|
||||||
|
File(file, displayName).let {
|
||||||
|
if (it.exists())
|
||||||
|
RawDocumentFileX(it)
|
||||||
|
else
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
118
app/src/main/java/xyz/quaver/pupil/util/saf/TreeDocumentFileX.kt
Normal file
118
app/src/main/java/xyz/quaver/pupil/util/saf/TreeDocumentFileX.kt
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Pupil, Hitomi.la viewer for Android
|
||||||
|
* Copyright (C) 2020 tom5079
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package xyz.quaver.pupil.util.saf
|
||||||
|
|
||||||
|
import android.annotation.TargetApi
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
|
import android.provider.DocumentsContract
|
||||||
|
|
||||||
|
@TargetApi(21)
|
||||||
|
class TreeDocumentFileX(
|
||||||
|
private val context: Context,
|
||||||
|
private val uri: Uri,
|
||||||
|
private var name: String? = null,
|
||||||
|
private var documentID: String? = null,
|
||||||
|
private var length: Long? = null
|
||||||
|
) : DocumentFileX() {
|
||||||
|
|
||||||
|
init {
|
||||||
|
val projection = mutableListOf<String>()
|
||||||
|
|
||||||
|
if (name == null)
|
||||||
|
projection.add(DocumentsContract.Document.COLUMN_DISPLAY_NAME)
|
||||||
|
if (documentID == null)
|
||||||
|
projection.add(DocumentsContract.Document.COLUMN_DOCUMENT_ID)
|
||||||
|
if (length == null)
|
||||||
|
projection.add(DocumentsContract.Document.COLUMN_SIZE)
|
||||||
|
|
||||||
|
if (projection.isNotEmpty()) {
|
||||||
|
val contentResolver = context.contentResolver
|
||||||
|
|
||||||
|
contentResolver.query(uri, projection.toTypedArray(), null, null, null).use { cursor ->
|
||||||
|
while (cursor?.moveToNext() == true) {
|
||||||
|
cursor.columnNames.forEach { column ->
|
||||||
|
val index = cursor.getColumnIndex(column)
|
||||||
|
|
||||||
|
when (column) {
|
||||||
|
DocumentsContract.Document.COLUMN_DISPLAY_NAME -> this.name = cursor.getString(index)
|
||||||
|
DocumentsContract.Document.COLUMN_DOCUMENT_ID -> this.documentID = cursor.getString(index)
|
||||||
|
DocumentsContract.Document.COLUMN_SIZE -> this.length = cursor.getLong(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createFile(displayName: String): DocumentFileX? {
|
||||||
|
val uri = kotlin.runCatching {
|
||||||
|
DocumentsContract.createDocument(context.contentResolver, uri, "null", displayName)
|
||||||
|
}.getOrNull() ?: return null
|
||||||
|
|
||||||
|
return TreeDocumentFileX(context, uri, displayName, DocumentsContract.getDocumentId(uri), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createDirectory(displayName: String): DocumentFileX? {
|
||||||
|
val uri = kotlin.runCatching {
|
||||||
|
DocumentsContract.createDocument(context.contentResolver, uri, "null", displayName)
|
||||||
|
}.getOrNull() ?: return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUri() = uri
|
||||||
|
|
||||||
|
override fun getName() = name ?: "null"
|
||||||
|
|
||||||
|
override fun getParentFile(): DocumentFileX?
|
||||||
|
|
||||||
|
override fun isDirectory() = name?.contains('.') == false
|
||||||
|
override fun isFile() = name?.contains('.') == true
|
||||||
|
|
||||||
|
override fun length() = length ?: -1
|
||||||
|
|
||||||
|
override fun canRead(): Boolean
|
||||||
|
override fun canWrite(): Boolean
|
||||||
|
|
||||||
|
override fun delete() =
|
||||||
|
kotlin.runCatching {
|
||||||
|
DocumentsContract.deleteDocument(context.contentResolver, uri)
|
||||||
|
}.getOrElse { false }
|
||||||
|
|
||||||
|
override fun exists() = documentID == null
|
||||||
|
|
||||||
|
override fun listFiles(): List<DocumentFileX>? {
|
||||||
|
val contentResolver = context.contentResolver
|
||||||
|
val children = DocumentsContract.buildChildDocumentsUriUsingTree(uri, DocumentsContract.getDocumentId(uri))
|
||||||
|
|
||||||
|
contentResolver.query(
|
||||||
|
children,
|
||||||
|
arrayOf(
|
||||||
|
DocumentsContract.Document.COLUMN_MIME_TYPE
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
).use {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findFile(displayName: String): DocumentFileX?
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user