This commit is contained in:
kunfei 2020-02-08 23:38:13 +08:00
parent c97017e961
commit 952abab4f9
4 changed files with 191 additions and 298 deletions

View File

@ -10,6 +10,7 @@ import io.legado.app.utils.FileUtils
import io.legado.app.utils.ZipUtils
import io.legado.app.utils.getPrefString
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.withContext
import org.jetbrains.anko.selector
import java.io.File
@ -58,9 +59,11 @@ object WebDavHelp {
suspend fun showRestoreDialog(context: Context, restoreSuccess: () -> Unit): Boolean {
val names = withContext(IO) { getWebDavFileNames() }
return if (names.isNotEmpty()) {
context.selector(title = "选择恢复文件", items = names) { _, index ->
if (index in 0 until names.size) {
restoreWebDav(names[index], restoreSuccess)
withContext(Main) {
context.selector(title = "选择恢复文件", items = names) { _, index ->
if (index in 0 until names.size) {
restoreWebDav(names[index], restoreSuccess)
}
}
}
true

View File

@ -15,19 +15,19 @@ import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import io.legado.app.R
import io.legado.app.constant.PreferKey
import io.legado.app.help.AppConfig
import io.legado.app.help.IntentHelp
import io.legado.app.help.permission.Permissions
import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.help.storage.Backup
import io.legado.app.help.storage.Restore
import io.legado.app.help.storage.WebDavHelp
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.noButton
import io.legado.app.lib.dialogs.yesButton
import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.accentColor
import io.legado.app.utils.*
import io.legado.app.utils.DocumentUtils
import io.legado.app.utils.LogUtils
import io.legado.app.utils.applyTint
import io.legado.app.utils.getPrefString
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO
import org.jetbrains.anko.toast
@ -38,8 +38,6 @@ class BackupConfigFragment : PreferenceFragmentCompat(),
CoroutineScope {
private lateinit var job: Job
private val oldDataRequestCode = 11
private val backupSelectRequestCode = 22
private val restoreSelectRequestCode = 33
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
@ -137,122 +135,14 @@ class BackupConfigFragment : PreferenceFragmentCompat(),
override fun onPreferenceTreeClick(preference: Preference?): Boolean {
when (preference?.key) {
PreferKey.backupPath -> selectBackupFolder()
"web_dav_backup" -> backup()
"web_dav_restore" -> restore()
PreferKey.backupPath -> BackupRestoreUi.selectBackupFolder(this)
"web_dav_backup" -> BackupRestoreUi.backup(this)
"web_dav_restore" -> BackupRestoreUi.restore(this)
"import_old" -> importOldData()
}
return super.onPreferenceTreeClick(preference)
}
private fun backup() {
val backupPath = AppConfig.backupPath
if (backupPath.isNullOrEmpty()) {
selectBackupFolder()
} else {
if (backupPath.isContentPath()) {
val uri = Uri.parse(backupPath)
val doc = DocumentFile.fromTreeUri(requireContext(), uri)
if (doc?.canWrite() == true) {
launch {
Backup.backup(requireContext(), backupPath)
toast(R.string.backup_success)
}
} else {
selectBackupFolder()
}
} else {
backupUsePermission()
}
}
}
private fun backupUsePermission(path: String = Backup.legadoPath) {
PermissionsCompat.Builder(this)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
launch {
Backup.backup(requireContext(), path)
toast(R.string.backup_success)
}
}
.request()
}
private fun selectBackupFolder() {
alert {
titleResource = R.string.select_folder
items(arrayListOf("默认路径", "系统文件夹选择器", "自带文件夹选择器")) { _, index ->
when (index) {
0 -> PermissionsCompat.Builder(this@BackupConfigFragment)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
launch {
AppConfig.backupPath = Backup.legadoPath
}
}
.request()
1 -> {
try {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivityForResult(intent, backupSelectRequestCode)
} catch (e: java.lang.Exception) {
e.printStackTrace()
toast(e.localizedMessage ?: "ERROR")
}
}
2 -> {
}
}
}
}.show()
}
fun restore() {
launch {
if (!WebDavHelp.showRestoreDialog(requireContext()) {
toast(R.string.restore_success)
}) {
val backupPath = getPrefString(PreferKey.backupPath)
if (backupPath?.isNotEmpty() == true) {
val uri = Uri.parse(backupPath)
val doc = DocumentFile.fromTreeUri(requireContext(), uri)
if (doc?.canWrite() == true) {
Restore.restore(requireContext(), uri)
toast(R.string.restore_success)
} else {
selectBackupFolder()
}
} else {
selectRestoreFolder()
}
}
}
}
private fun selectRestoreFolder() {
try {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivityForResult(intent, restoreSelectRequestCode)
} catch (e: java.lang.Exception) {
PermissionsCompat.Builder(this)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
launch {
Restore.restore(Backup.legadoPath)
toast(R.string.restore_success)
}
}
.request()
}
}
private fun importOldData() {
try {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
@ -351,37 +241,12 @@ class BackupConfigFragment : PreferenceFragmentCompat(),
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
BackupRestoreUi.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
oldDataRequestCode ->
if (resultCode == RESULT_OK) data?.data?.let { uri ->
importOldData(uri)
}
backupSelectRequestCode -> if (resultCode == RESULT_OK) {
data?.data?.let { uri ->
requireContext().contentResolver.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
AppConfig.backupPath = uri.toString()
launch {
Backup.backup(requireContext(), uri.toString())
toast(R.string.backup_success)
}
}
}
restoreSelectRequestCode -> if (resultCode == RESULT_OK) {
data?.data?.let { uri ->
requireContext().contentResolver.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
AppConfig.backupPath = uri.toString()
launch {
Restore.restore(requireContext(), uri)
toast(R.string.restore_success)
}
}
}
}
}
}

View File

@ -0,0 +1,173 @@
package io.legado.app.ui.config
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.net.Uri
import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.Fragment
import io.legado.app.App
import io.legado.app.R
import io.legado.app.constant.PreferKey
import io.legado.app.help.AppConfig
import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.permission.Permissions
import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.help.storage.Backup
import io.legado.app.help.storage.Restore
import io.legado.app.help.storage.WebDavHelp
import io.legado.app.lib.dialogs.alert
import io.legado.app.utils.getPrefString
import io.legado.app.utils.isContentPath
import io.legado.app.utils.toast
import kotlinx.coroutines.Dispatchers.Main
import org.jetbrains.anko.toast
object BackupRestoreUi {
private const val backupSelectRequestCode = 22
private const val restoreSelectRequestCode = 33
fun backup(fragment: Fragment) {
val backupPath = AppConfig.backupPath
if (backupPath.isNullOrEmpty()) {
selectBackupFolder(fragment)
} else {
if (backupPath.isContentPath()) {
val uri = Uri.parse(backupPath)
val doc = DocumentFile.fromTreeUri(fragment.requireContext(), uri)
if (doc?.canWrite() == true) {
Coroutine.async {
Backup.backup(fragment.requireContext(), backupPath)
}.onSuccess {
fragment.toast(R.string.backup_success)
}
} else {
selectBackupFolder(fragment)
}
} else {
backupUsePermission(fragment)
}
}
}
private fun backupUsePermission(fragment: Fragment, path: String = Backup.legadoPath) {
PermissionsCompat.Builder(fragment)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
Coroutine.async {
Backup.backup(fragment.requireContext(), path)
}.onSuccess {
fragment.toast(R.string.backup_success)
}
}
.request()
}
fun selectBackupFolder(fragment: Fragment) {
fragment.alert {
titleResource = R.string.select_folder
items(arrayListOf("默认路径", "系统文件夹选择器", "自带文件夹选择器")) { _, index ->
when (index) {
0 -> PermissionsCompat.Builder(fragment)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
AppConfig.backupPath = Backup.legadoPath
backupUsePermission(fragment)
}
.request()
1 -> {
try {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
fragment.startActivityForResult(intent, backupSelectRequestCode)
} catch (e: java.lang.Exception) {
e.printStackTrace()
fragment.toast(e.localizedMessage ?: "ERROR")
}
}
2 -> {
}
}
}
}.show()
}
fun restore(fragment: Fragment) {
Coroutine.async(context = Main) {
if (!WebDavHelp.showRestoreDialog(fragment.requireContext()) {
fragment.toast(R.string.restore_success)
}) {
val backupPath = fragment.getPrefString(PreferKey.backupPath)
if (backupPath?.isNotEmpty() == true) {
val uri = Uri.parse(backupPath)
val doc = DocumentFile.fromTreeUri(fragment.requireContext(), uri)
if (doc?.canWrite() == true) {
Restore.restore(fragment.requireContext(), uri)
fragment.toast(R.string.restore_success)
} else {
selectRestoreFolder(fragment)
}
} else {
selectRestoreFolder(fragment)
}
}
}
}
private fun selectRestoreFolder(fragment: Fragment) {
try {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
fragment.startActivityForResult(intent, restoreSelectRequestCode)
} catch (e: java.lang.Exception) {
PermissionsCompat.Builder(fragment)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
Coroutine.async {
Restore.restore(Backup.legadoPath)
}.onSuccess {
fragment.toast(R.string.restore_success)
}
}
.request()
}
}
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
backupSelectRequestCode -> if (resultCode == RESULT_OK) {
data?.data?.let { uri ->
App.INSTANCE.contentResolver.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
AppConfig.backupPath = uri.toString()
Coroutine.async {
Backup.backup(App.INSTANCE, uri.toString())
}.onSuccess {
App.INSTANCE.toast(R.string.backup_success)
}
}
}
restoreSelectRequestCode -> if (resultCode == RESULT_OK) {
data?.data?.let { uri ->
App.INSTANCE.contentResolver.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
AppConfig.backupPath = uri.toString()
Coroutine.async {
Restore.restore(App.INSTANCE, uri)
}.onSuccess {
App.INSTANCE.toast(R.string.restore_success)
}
}
}
}
}
}

View File

@ -1,14 +1,11 @@
package io.legado.app.ui.main.my
import android.app.Activity
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.documentfile.provider.DocumentFile
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import io.legado.app.App
@ -16,31 +13,22 @@ import io.legado.app.R
import io.legado.app.base.BaseFragment
import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey
import io.legado.app.help.AppConfig
import io.legado.app.help.BookHelp
import io.legado.app.help.permission.Permissions
import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.help.storage.Backup
import io.legado.app.help.storage.Restore
import io.legado.app.help.storage.WebDavHelp
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.prefs.ATESwitchPreference
import io.legado.app.service.WebService
import io.legado.app.ui.about.AboutActivity
import io.legado.app.ui.about.DonateActivity
import io.legado.app.ui.book.source.manage.BookSourceActivity
import io.legado.app.ui.config.BackupRestoreUi
import io.legado.app.ui.config.ConfigActivity
import io.legado.app.ui.config.ConfigViewModel
import io.legado.app.ui.replacerule.ReplaceRuleActivity
import io.legado.app.utils.*
import kotlinx.android.synthetic.main.view_title_bar.*
import kotlinx.coroutines.launch
import org.jetbrains.anko.startActivity
class MyFragment : BaseFragment(R.layout.fragment_my_config) {
private val backupSelectRequestCode = 22
private val restoreSelectRequestCode = 33
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setSupportToolbar(toolbar)
@ -58,150 +46,14 @@ class MyFragment : BaseFragment(R.layout.fragment_my_config) {
override fun onCompatOptionsItemSelected(item: MenuItem) {
when (item.itemId) {
R.id.menu_help -> startActivity<AboutActivity>()
R.id.menu_backup -> backup()
R.id.menu_restore -> restore()
}
}
private fun backup() {
val backupPath = AppConfig.backupPath
if (backupPath.isNullOrEmpty()) {
selectBackupFolder()
} else {
if (backupPath.isContentPath()) {
val uri = Uri.parse(backupPath)
val doc = DocumentFile.fromTreeUri(requireContext(), uri)
if (doc?.canWrite() == true) {
launch {
Backup.backup(requireContext(), backupPath)
toast(R.string.backup_success)
}
} else {
selectBackupFolder()
}
} else {
backupUsePermission()
}
}
}
private fun backupUsePermission(path: String = Backup.legadoPath) {
PermissionsCompat.Builder(this)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
launch {
Backup.backup(requireContext(), path)
toast(R.string.backup_success)
}
}
.request()
}
private fun selectBackupFolder() {
alert {
titleResource = R.string.select_folder
items(arrayListOf("默认路径", "系统文件夹选择器", "自带文件夹选择器")) { _, index ->
when (index) {
0 -> PermissionsCompat.Builder(this@MyFragment)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
launch {
AppConfig.backupPath = Backup.legadoPath
backupUsePermission()
}
}
.request()
1 -> {
try {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivityForResult(intent, backupSelectRequestCode)
} catch (e: java.lang.Exception) {
e.printStackTrace()
toast(e.localizedMessage ?: "ERROR")
}
}
2 -> {
}
}
}
}.show()
}
fun restore() {
launch {
if (!WebDavHelp.showRestoreDialog(requireContext()) {
toast(R.string.restore_success)
}) {
val backupPath = getPrefString(PreferKey.backupPath)
if (backupPath?.isNotEmpty() == true) {
val uri = Uri.parse(backupPath)
val doc = DocumentFile.fromTreeUri(requireContext(), uri)
if (doc?.canWrite() == true) {
Restore.restore(requireContext(), uri)
toast(R.string.restore_success)
} else {
selectBackupFolder()
}
} else {
selectRestoreFolder()
}
}
}
}
private fun selectRestoreFolder() {
try {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivityForResult(intent, restoreSelectRequestCode)
} catch (e: java.lang.Exception) {
PermissionsCompat.Builder(this)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
launch {
Restore.restore(Backup.legadoPath)
toast(R.string.restore_success)
}
}
.request()
R.id.menu_backup -> BackupRestoreUi.backup(this)
R.id.menu_restore -> BackupRestoreUi.restore(this)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
backupSelectRequestCode -> if (resultCode == Activity.RESULT_OK) {
data?.data?.let { uri ->
requireContext().contentResolver.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
AppConfig.backupPath = uri.toString()
launch {
Backup.backup(requireContext(), uri.toString())
toast(R.string.backup_success)
}
}
}
restoreSelectRequestCode -> if (resultCode == Activity.RESULT_OK) {
data?.data?.let { uri ->
requireContext().contentResolver.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
AppConfig.backupPath = uri.toString()
launch {
Restore.restore(requireContext(), uri)
toast(R.string.restore_success)
}
}
}
}
BackupRestoreUi.onActivityResult(requestCode, resultCode, data)
}
class PreferenceFragment : PreferenceFragmentCompat(),