DocumentFileX

This commit is contained in:
Pupil
2020-02-10 16:28:13 +09:00
parent d93e7f8834
commit 5634e94f3e
4 changed files with 256 additions and 5 deletions

View File

@@ -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'

View 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)
}
}
}

View File

@@ -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
}
}

View 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?
}