This commit is contained in:
Pupil
2020-02-11 21:23:34 +09:00
parent 5634e94f3e
commit a714a8230b
12 changed files with 57 additions and 66 deletions

View File

@@ -61,6 +61,7 @@ dependencies {
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.biometric:biometric:1.0.1" implementation "androidx.biometric:biometric:1.0.1"
implementation "androidx.documentfile:documentfile: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"
implementation 'com.google.android.material:material:1.2.0-alpha04' implementation 'com.google.android.material:material:1.2.0-alpha04'

View File

@@ -6,9 +6,7 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" /> <uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="21" />
<application <application
android:name=".Pupil" android:name=".Pupil"

View File

@@ -22,7 +22,6 @@ import android.app.Notification
import android.app.NotificationChannel import android.app.NotificationChannel
import android.app.NotificationManager import android.app.NotificationManager
import android.content.Context import android.content.Context
import android.net.Uri
import android.os.Build import android.os.Build
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@@ -41,6 +40,7 @@ class Pupil : MultiDexApplication() {
init { init {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
} }
override fun onCreate() { override fun onCreate() {
@@ -49,17 +49,6 @@ class Pupil : MultiDexApplication() {
histories = Histories(File(ContextCompat.getDataDir(this), "histories.json")) histories = Histories(File(ContextCompat.getDataDir(this), "histories.json"))
favorites = Histories(File(ContextCompat.getDataDir(this), "favorites.json")) favorites = Histories(File(ContextCompat.getDataDir(this), "favorites.json"))
val download = try {
preference.getString("dl_location", null)
} catch (e: Exception) {
preference.edit().remove("dl_location").apply()
}
if (download == null) {
val default = ContextCompat.getExternalFilesDirs(this, null)[0]
preference.edit().putString("dl_location", Uri.fromFile(default).toString()).apply()
}
try { try {
ProviderInstaller.installIfNeeded(this) ProviderInstaller.installIfNeeded(this)
} catch (e: GooglePlayServicesRepairableException) { } catch (e: GooglePlayServicesRepairableException) {

View File

@@ -124,10 +124,8 @@ class SettingsActivity : AppCompatActivity() {
REQUEST_DOWNLOAD_FOLDER -> { REQUEST_DOWNLOAD_FOLDER -> {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
data?.data?.also { uri -> data?.data?.also { uri ->
val takeFlags: Int = intent.flags and (Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
contentResolver.takePersistableUriPermission(uri, takeFlags) contentResolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
if (DocumentFile.fromTreeUri(this, uri)?.canWrite() == false) if (DocumentFile.fromTreeUri(this, uri)?.canWrite() == false)
Snackbar.make(settings, R.string.settings_dl_location_not_writable, Snackbar.LENGTH_LONG).show() Snackbar.make(settings, R.string.settings_dl_location_not_writable, Snackbar.LENGTH_LONG).show()

View File

@@ -37,6 +37,7 @@ import xyz.quaver.pupil.R
import xyz.quaver.pupil.util.REQUEST_DOWNLOAD_FOLDER import xyz.quaver.pupil.util.REQUEST_DOWNLOAD_FOLDER
import xyz.quaver.pupil.util.REQUEST_DOWNLOAD_FOLDER_OLD import xyz.quaver.pupil.util.REQUEST_DOWNLOAD_FOLDER_OLD
import xyz.quaver.pupil.util.byteToString import xyz.quaver.pupil.util.byteToString
import xyz.quaver.pupil.util.getDownloadDirectory
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
class DownloadLocationDialog(val activity: Activity) : AlertDialog(activity) { class DownloadLocationDialog(val activity: Activity) : AlertDialog(activity) {
@@ -106,9 +107,9 @@ class DownloadLocationDialog(val activity: Activity) : AlertDialog(activity) {
buttons.add(button to null) buttons.add(button to null)
}) })
val pref = Uri.parse(preference.getString("dl_location", null)) val pref = getDownloadDirectory(context)
val index = externalFilesDirs.indexOfFirst { val index = externalFilesDirs.indexOfFirst {
Uri.fromFile(it).toString() == pref.toString() Uri.fromFile(it).toString() == pref.uri.toString()
} }
if (index < 0) if (index < 0)

View File

@@ -21,4 +21,5 @@ package xyz.quaver.pupil.util
const val REQUEST_LOCK = 38238 const val REQUEST_LOCK = 38238
const val REQUEST_RESTORE = 16546 const val REQUEST_RESTORE = 16546
const val REQUEST_DOWNLOAD_FOLDER = 3874 const val REQUEST_DOWNLOAD_FOLDER = 3874
const val REQUEST_DOWNLOAD_FOLDER_OLD = 3425 const val REQUEST_DOWNLOAD_FOLDER_OLD = 3425
const val REQUEST_DOWNLOAD_FOLDER_AND_PERMISSION = 34257

View File

@@ -207,10 +207,7 @@ class Cache(context: Context) : ContextWrapper(context) {
throw IllegalArgumentException("File name is not a number") throw IllegalArgumentException("File name is not a number")
cache.let { cache.let {
if (it.findFile(name) != null) it.findFile(name) ?: it.createFile("null", name)
it
else
it.createFile("null", name)
}?.writeBytes(this, data) }?.writeBytes(this, data)
} }
@@ -221,11 +218,14 @@ class Cache(context: Context) : ContextWrapper(context) {
val download = getDownloadDirectory(this) val download = getDownloadDirectory(this)
if (!download.isParentOf(cache)) { if (!download.isParentOf(cache)) {
val target = getDownloadDirectory(this).let {
it.findFile(galleryID.toString()) ?: it.createDirectory(galleryID.toString())
}
cache.copyRecursively(this, download) cache.copyRecursively(this, download)
cache.deleteRecursively() cache.deleteRecursively()
} }
} else }
getDownloadDirectory(this).createDirectory(galleryID.toString())
} }
fun isDownloading(galleryID: Int) = getCachedMetadata(galleryID)?.isDownloading == true fun isDownloading(galleryID: Int) = getCachedMetadata(galleryID)?.isDownloading == true

View File

@@ -23,6 +23,7 @@ import android.content.Context
import android.content.ContextWrapper import android.content.ContextWrapper
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.util.Log
import android.util.SparseArray import android.util.SparseArray
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
@@ -152,12 +153,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
val request = chain.request() val request = chain.request()
var response = chain.proceed(request) var response = chain.proceed(request)
var retry = preferences.getInt("retry", 3)
while (!response.isSuccessful && retry > 0) {
response = chain.proceed(request)
retry--
}
response.newBuilder() response.newBuilder()
.body(ProgressResponseBody(request.tag(), response.body(), progressListener)) .body(ProgressResponseBody(request.tag(), response.body(), progressListener))
.build() .build()
@@ -288,6 +283,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
for (i in reader.galleryInfo.indices) { for (i in reader.galleryInfo.indices) {
val callback = object : Callback { val callback = object : Callback {
override fun onFailure(call: Call, e: IOException) { override fun onFailure(call: Call, e: IOException) {
Log.i("PUPILD", "FAILED $i")
if (Fabric.isInitialized()) if (Fabric.isInitialized())
Crashlytics.logException(e) Crashlytics.logException(e)
@@ -307,6 +303,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
} }
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
Log.i("PUPILD", "SUCCESS $i")
response.body().use { response.body().use {
val res = it.bytes() val res = it.bytes()
val ext = val ext =

View File

@@ -33,17 +33,22 @@ fun getCachedGallery(context: Context, galleryID: Int) =
DocumentFile.fromFile(File(context.cacheDir, "imageCache/$galleryID")) DocumentFile.fromFile(File(context.cacheDir, "imageCache/$galleryID"))
fun getDownloadDirectory(context: Context) : DocumentFile { fun getDownloadDirectory(context: Context) : DocumentFile {
val uri = PreferenceManager.getDefaultSharedPreferences(context).getString("dl_location", null).let { return runCatching {
val uri = PreferenceManager.getDefaultSharedPreferences(context).getString("dl_location", null).let {
if (it != null) if (it != null)
Uri.parse(it) Uri.parse(it)
else else
Uri.fromFile(context.getExternalFilesDir(null)) Uri.fromFile(context.getExternalFilesDir(null))
} }
return if (uri.toString().startsWith("file")) if (uri.toString().startsWith("file"))
DocumentFile.fromFile(File(uri.path!!)) DocumentFile.fromFile(File(uri.path!!))
else else
DocumentFile.fromTreeUri(context, uri) ?: DocumentFile.fromFile(context.getExternalFilesDir(null)!!) DocumentFile.fromTreeUri(context, uri) ?: DocumentFile.fromFile(context.getExternalFilesDir(null)!!)
}.getOrElse {
PreferenceManager.getDefaultSharedPreferences(context).edit().remove("dl_location").apply()
DocumentFile.fromFile(context.getExternalFilesDir(null)!!)
}
} }
fun convertUpdateUri(context: Context, uri: Uri) : Uri = fun convertUpdateUri(context: Context, uri: Uri) : Uri =
@@ -104,32 +109,26 @@ fun DocumentFile.copyRecursively(
if (!exists()) if (!exists())
throw Exception("The source file doesn't exist.") throw Exception("The source file doesn't exist.")
if (this.isFile) { this.listFiles().forEach { child ->
target.let { try {
if (it.findFile(name!!) != null) if (child.isFile) {
it target.findFile(name!!) ?: target.createFile("null", name!!)!!
else .writeBytes(
createFile("null", name!!)!! context,
}.writeBytes( readBytes(context)
context, )
readBytes(context) } else if (child.isDirectory) {
) target.findFile(name!!) ?: target.createDirectory(name!!).also { newTarget ->
} else if (this.isDirectory) { child.copyRecursively(context, newTarget!!)
target.createDirectory(name!!).also { newTarget -> }
listFiles().forEach { child ->
child.copyRecursively(context, newTarget!!)
} }
} catch (e: Exception) {
e.printStackTrace()
} }
} }
} }
fun DocumentFile.deleteRecursively() { fun DocumentFile.deleteRecursively() {
if (this.isDirectory)
listFiles().forEach {
it.deleteRecursively()
}
this.delete() this.delete()
} }

View File

@@ -28,7 +28,6 @@ abstract class DocumentFileX {
abstract fun createDirectory(displayName: String): DocumentFileX? abstract fun createDirectory(displayName: String): DocumentFileX?
abstract fun getUri(): Uri abstract fun getUri(): Uri
abstract fun getName(): String abstract fun getName(): String
abstract fun getParentFile(): DocumentFileX?
abstract fun isDirectory(): Boolean abstract fun isDirectory(): Boolean
abstract fun isFile(): Boolean abstract fun isFile(): Boolean
abstract fun length(): Long abstract fun length(): Long

View File

@@ -45,7 +45,7 @@ class RawDocumentFileX(private var file: File) : DocumentFileX() {
override fun getName() = file.name override fun getName() = file.name
override fun getParentFile() = fun getParentFile() =
file.parentFile.let { file.parentFile.let {
if (it == null) if (it == null)
null null

View File

@@ -73,21 +73,25 @@ class TreeDocumentFileX(
val uri = kotlin.runCatching { val uri = kotlin.runCatching {
DocumentsContract.createDocument(context.contentResolver, uri, "null", displayName) DocumentsContract.createDocument(context.contentResolver, uri, "null", displayName)
}.getOrNull() ?: return null }.getOrNull() ?: return null
return TreeDocumentFileX(context, uri, displayName, DocumentsContract.getDocumentId(uri), 0)
} }
override fun getUri() = uri override fun getUri() = uri
override fun getName() = name ?: "null" override fun getName() = name ?: "null"
override fun getParentFile(): DocumentFileX?
override fun isDirectory() = name?.contains('.') == false override fun isDirectory() = name?.contains('.') == false
override fun isFile() = name?.contains('.') == true override fun isFile() = name?.contains('.') == true
override fun length() = length ?: -1 override fun length() = length ?: -1
override fun canRead(): Boolean override fun canRead(): Boolean {
override fun canWrite(): Boolean TODO("Not impelmented")
}
override fun canWrite(): Boolean {
TODO("Not impelmented")
}
override fun delete() = override fun delete() =
kotlin.runCatching { kotlin.runCatching {
@@ -111,8 +115,12 @@ class TreeDocumentFileX(
).use { ).use {
} }
TODO("Not impelmented")
} }
override fun findFile(displayName: String): DocumentFileX? override fun findFile(displayName: String): DocumentFileX? {
TODO("Not impelmented")
}
} }