pull/94/head
kunfei 5 years ago
parent 61c4a3f242
commit 7de6d4ad4f
  1. 23
      app/src/main/java/io/legado/app/help/storage/Restore.kt
  2. 6
      app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt
  3. 90
      app/src/main/java/io/legado/app/ui/config/BackupRestoreUi.kt
  4. 28
      app/src/main/java/io/legado/app/ui/filechooser/FileChooserDialog.kt
  5. 7
      app/src/main/java/io/legado/app/ui/main/my/MyFragment.kt

@ -11,10 +11,7 @@ import io.legado.app.App
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.entities.* import io.legado.app.data.entities.*
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.utils.DocumentUtils import io.legado.app.utils.*
import io.legado.app.utils.FileUtils
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
@ -33,17 +30,21 @@ object Restore {
) )
} }
suspend fun restore(context: Context, uri: Uri) { suspend fun restore(context: Context, path: String) {
withContext(IO) { withContext(IO) {
DocumentFile.fromTreeUri(context, uri)?.listFiles()?.forEach { doc -> if (path.isContentPath()) {
for (fileName in Backup.backupFileNames) { DocumentFile.fromTreeUri(context, Uri.parse(path))?.listFiles()?.forEach { doc ->
if (doc.name == fileName) { for (fileName in Backup.backupFileNames) {
DocumentUtils.readText(context, doc.uri)?.let { if (doc.name == fileName) {
FileUtils.createFileIfNotExist(Backup.backupPath + File.separator + fileName) DocumentUtils.readText(context, doc.uri)?.let {
.writeText(it) FileUtils.createFileIfNotExist(Backup.backupPath + File.separator + fileName)
.writeText(it)
}
} }
} }
} }
} else {
} }
} }
restore(Backup.backupPath) restore(Backup.backupPath)

@ -24,6 +24,7 @@ import io.legado.app.lib.dialogs.noButton
import io.legado.app.lib.dialogs.yesButton import io.legado.app.lib.dialogs.yesButton
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.filechooser.FileChooserDialog
import io.legado.app.utils.DocumentUtils import io.legado.app.utils.DocumentUtils
import io.legado.app.utils.LogUtils import io.legado.app.utils.LogUtils
import io.legado.app.utils.applyTint import io.legado.app.utils.applyTint
@ -35,6 +36,7 @@ import kotlin.coroutines.CoroutineContext
class BackupConfigFragment : PreferenceFragmentCompat(), class BackupConfigFragment : PreferenceFragmentCompat(),
SharedPreferences.OnSharedPreferenceChangeListener, SharedPreferences.OnSharedPreferenceChangeListener,
FileChooserDialog.CallBack,
CoroutineScope { CoroutineScope {
private lateinit var job: Job private lateinit var job: Job
private val oldDataRequestCode = 11 private val oldDataRequestCode = 11
@ -231,6 +233,10 @@ class BackupConfigFragment : PreferenceFragmentCompat(),
} }
} }
override fun onFilePicked(requestCode: Int, currentPath: String) {
BackupRestoreUi.onFilePicked(requestCode, currentPath)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
BackupRestoreUi.onActivityResult(requestCode, resultCode, data) BackupRestoreUi.onActivityResult(requestCode, resultCode, data)

@ -16,6 +16,7 @@ import io.legado.app.help.storage.Backup
import io.legado.app.help.storage.Restore import io.legado.app.help.storage.Restore
import io.legado.app.help.storage.WebDavHelp import io.legado.app.help.storage.WebDavHelp
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.ui.filechooser.FileChooserDialog
import io.legado.app.utils.getPrefString import io.legado.app.utils.getPrefString
import io.legado.app.utils.isContentPath import io.legado.app.utils.isContentPath
import io.legado.app.utils.toast import io.legado.app.utils.toast
@ -56,6 +57,7 @@ object BackupRestoreUi {
.rationale(R.string.tip_perm_request_storage) .rationale(R.string.tip_perm_request_storage)
.onGranted { .onGranted {
Coroutine.async { Coroutine.async {
AppConfig.backupPath = Backup.legadoPath
Backup.backup(fragment.requireContext(), path) Backup.backup(fragment.requireContext(), path)
}.onSuccess { }.onSuccess {
fragment.toast(R.string.backup_success) fragment.toast(R.string.backup_success)
@ -69,14 +71,7 @@ object BackupRestoreUi {
titleResource = R.string.select_folder titleResource = R.string.select_folder
items(fragment.resources.getStringArray(R.array.select_folder).toList()) { _, index -> items(fragment.resources.getStringArray(R.array.select_folder).toList()) { _, index ->
when (index) { when (index) {
0 -> PermissionsCompat.Builder(fragment) 0 -> backupUsePermission(fragment)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
AppConfig.backupPath = Backup.legadoPath
backupUsePermission(fragment)
}
.request()
1 -> { 1 -> {
try { try {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
@ -88,7 +83,11 @@ object BackupRestoreUi {
} }
} }
2 -> { 2 -> {
FileChooserDialog.show(
fragment.childFragmentManager,
backupSelectRequestCode,
mode = FileChooserDialog.DIRECTORY
)
} }
} }
} }
@ -102,13 +101,17 @@ object BackupRestoreUi {
}) { }) {
val backupPath = fragment.getPrefString(PreferKey.backupPath) val backupPath = fragment.getPrefString(PreferKey.backupPath)
if (backupPath?.isNotEmpty() == true) { if (backupPath?.isNotEmpty() == true) {
val uri = Uri.parse(backupPath) if (backupPath.isContentPath()) {
val doc = DocumentFile.fromTreeUri(fragment.requireContext(), uri) val uri = Uri.parse(backupPath)
if (doc?.canWrite() == true) { val doc = DocumentFile.fromTreeUri(fragment.requireContext(), uri)
Restore.restore(fragment.requireContext(), uri) if (doc?.canWrite() == true) {
fragment.toast(R.string.restore_success) Restore.restore(fragment.requireContext(), backupPath)
fragment.toast(R.string.restore_success)
} else {
selectRestoreFolder(fragment)
}
} else { } else {
selectRestoreFolder(fragment) restoreUsePermission(fragment, backupPath)
} }
} else { } else {
selectRestoreFolder(fragment) selectRestoreFolder(fragment)
@ -117,23 +120,27 @@ object BackupRestoreUi {
} }
} }
private fun restoreUsePermission(fragment: Fragment, path: String = Backup.legadoPath) {
PermissionsCompat.Builder(fragment)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
Coroutine.async {
AppConfig.backupPath = path
Restore.restore(path)
}.onSuccess {
fragment.toast(R.string.restore_success)
}
}
.request()
}
private fun selectRestoreFolder(fragment: Fragment) { private fun selectRestoreFolder(fragment: Fragment) {
fragment.alert { fragment.alert {
titleResource = R.string.select_folder titleResource = R.string.select_folder
items(fragment.resources.getStringArray(R.array.select_folder).toList()) { _, index -> items(fragment.resources.getStringArray(R.array.select_folder).toList()) { _, index ->
when (index) { when (index) {
0 -> PermissionsCompat.Builder(fragment) 0 -> restoreUsePermission(fragment)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
Coroutine.async {
AppConfig.backupPath = Backup.legadoPath
Restore.restore(Backup.legadoPath)
}.onSuccess {
fragment.toast(R.string.restore_success)
}
}
.request()
1 -> { 1 -> {
try { try {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
@ -145,13 +152,38 @@ object BackupRestoreUi {
} }
} }
2 -> { 2 -> {
FileChooserDialog.show(
fragment.childFragmentManager,
restoreSelectRequestCode,
mode = FileChooserDialog.DIRECTORY
)
} }
} }
} }
}.show() }.show()
} }
fun onFilePicked(requestCode: Int, currentPath: String) {
when (requestCode) {
backupSelectRequestCode -> {
AppConfig.backupPath = currentPath
Coroutine.async {
Backup.backup(App.INSTANCE, currentPath)
}.onSuccess {
App.INSTANCE.toast(R.string.backup_success)
}
}
restoreSelectRequestCode -> {
AppConfig.backupPath = currentPath
Coroutine.async {
Restore.restore(App.INSTANCE, currentPath)
}.onSuccess {
App.INSTANCE.toast(R.string.restore_success)
}
}
}
}
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) { when (requestCode) {
backupSelectRequestCode -> if (resultCode == RESULT_OK) { backupSelectRequestCode -> if (resultCode == RESULT_OK) {
@ -176,7 +208,7 @@ object BackupRestoreUi {
) )
AppConfig.backupPath = uri.toString() AppConfig.backupPath = uri.toString()
Coroutine.async { Coroutine.async {
Restore.restore(App.INSTANCE, uri) Restore.restore(App.INSTANCE, uri.toString())
}.onSuccess { }.onSuccess {
App.INSTANCE.toast(R.string.restore_success) App.INSTANCE.toast(R.string.restore_success)
} }

@ -42,21 +42,19 @@ class FileChooserDialog : DialogFragment(),
allowExtensions: Array<String?>? = null, allowExtensions: Array<String?>? = null,
menus: Array<String>? = null menus: Array<String>? = null
) { ) {
val fragment = (manager.findFragmentByTag(tag) as? FileChooserDialog) FileChooserDialog().apply {
?: FileChooserDialog().apply { val bundle = Bundle()
val bundle = Bundle() bundle.putInt("mode", mode)
bundle.putInt("mode", mode) bundle.putInt("requestCode", requestCode)
bundle.putInt("requestCode", requestCode) bundle.putString("title", title)
bundle.putString("title", title) bundle.putBoolean("isShowHomeDir", isShowHomeDir)
bundle.putBoolean("isShowHomeDir", isShowHomeDir) bundle.putBoolean("isShowUpDir", isShowUpDir)
bundle.putBoolean("isShowUpDir", isShowUpDir) bundle.putBoolean("isShowHideDir", isShowHideDir)
bundle.putBoolean("isShowHideDir", isShowHideDir) bundle.putString("initPath", initPath)
bundle.putString("initPath", initPath) bundle.putStringArray("allowExtensions", allowExtensions)
bundle.putStringArray("allowExtensions", allowExtensions) bundle.putStringArray("menus", menus)
bundle.putStringArray("menus", menus) arguments = bundle
arguments = bundle }.show(manager, tag)
}
fragment.show(manager, tag)
} }
} }

@ -23,12 +23,13 @@ import io.legado.app.ui.book.source.manage.BookSourceActivity
import io.legado.app.ui.config.BackupRestoreUi import io.legado.app.ui.config.BackupRestoreUi
import io.legado.app.ui.config.ConfigActivity import io.legado.app.ui.config.ConfigActivity
import io.legado.app.ui.config.ConfigViewModel import io.legado.app.ui.config.ConfigViewModel
import io.legado.app.ui.filechooser.FileChooserDialog
import io.legado.app.ui.replacerule.ReplaceRuleActivity import io.legado.app.ui.replacerule.ReplaceRuleActivity
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.view_title_bar.* import kotlinx.android.synthetic.main.view_title_bar.*
import org.jetbrains.anko.startActivity import org.jetbrains.anko.startActivity
class MyFragment : BaseFragment(R.layout.fragment_my_config) { class MyFragment : BaseFragment(R.layout.fragment_my_config), FileChooserDialog.CallBack {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setSupportToolbar(toolbar) setSupportToolbar(toolbar)
@ -51,6 +52,10 @@ class MyFragment : BaseFragment(R.layout.fragment_my_config) {
} }
} }
override fun onFilePicked(requestCode: Int, currentPath: String) {
BackupRestoreUi.onFilePicked(requestCode, currentPath)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
BackupRestoreUi.onActivityResult(requestCode, resultCode, data) BackupRestoreUi.onActivityResult(requestCode, resultCode, data)

Loading…
Cancel
Save