mirror of
https://github.com/mihonapp/mihon.git
synced 2025-11-15 13:37:29 +01:00
Refactor backup service
This commit is contained in:
@@ -4,10 +4,7 @@ import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
@@ -16,7 +13,6 @@ import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.list.listItemsMultiChoice
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.backup.BackupConst
|
||||
import eu.kanade.tachiyomi.data.backup.BackupCreateService
|
||||
import eu.kanade.tachiyomi.data.backup.BackupCreatorJob
|
||||
import eu.kanade.tachiyomi.data.backup.BackupRestoreService
|
||||
@@ -24,7 +20,6 @@ import eu.kanade.tachiyomi.data.backup.models.Backup
|
||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.requestPermissionsSafe
|
||||
import eu.kanade.tachiyomi.ui.setting.backup.BackupNotifier
|
||||
import eu.kanade.tachiyomi.util.preference.defaultValue
|
||||
import eu.kanade.tachiyomi.util.preference.entriesRes
|
||||
import eu.kanade.tachiyomi.util.preference.intListPreference
|
||||
@@ -35,9 +30,7 @@ import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
||||
import eu.kanade.tachiyomi.util.preference.summaryRes
|
||||
import eu.kanade.tachiyomi.util.preference.titleRes
|
||||
import eu.kanade.tachiyomi.util.system.getFilePicker
|
||||
import eu.kanade.tachiyomi.util.system.registerLocalReceiver
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.util.system.unregisterLocalReceiver
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
@@ -48,24 +41,11 @@ class SettingsBackupController : SettingsController() {
|
||||
*/
|
||||
private var backupFlags = 0
|
||||
|
||||
private val notifier by lazy { BackupNotifier(preferences.context) }
|
||||
|
||||
private val receiver = BackupBroadcastReceiver()
|
||||
|
||||
init {
|
||||
preferences.context.registerLocalReceiver(receiver, IntentFilter(BackupConst.INTENT_FILTER))
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 500)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
preferences.context.unregisterLocalReceiver(receiver)
|
||||
}
|
||||
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
|
||||
titleRes = R.string.backup
|
||||
|
||||
@@ -74,7 +54,7 @@ class SettingsBackupController : SettingsController() {
|
||||
summaryRes = R.string.pref_create_backup_summ
|
||||
|
||||
onClick {
|
||||
if (!isBackupStarted) {
|
||||
if (!BackupCreateService.isRunning(context)) {
|
||||
val ctrl = CreateBackupDialog()
|
||||
ctrl.targetController = this@SettingsBackupController
|
||||
ctrl.showDialog(router)
|
||||
@@ -193,11 +173,8 @@ class SettingsBackupController : SettingsController() {
|
||||
val file = UniFile.fromUri(activity, uri)
|
||||
|
||||
activity.toast(R.string.creating_backup)
|
||||
notifier.showBackupProgress()
|
||||
|
||||
BackupCreateService.makeBackup(activity, file.uri, backupFlags)
|
||||
|
||||
isBackupStarted = true
|
||||
BackupCreateService.start(activity, file.uri, backupFlags)
|
||||
}
|
||||
CODE_BACKUP_RESTORE -> if (data != null && resultCode == Activity.RESULT_OK) {
|
||||
val uri = data.data
|
||||
@@ -286,30 +263,9 @@ class SettingsBackupController : SettingsController() {
|
||||
}
|
||||
}
|
||||
|
||||
inner class BackupBroadcastReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
when (intent.getStringExtra(BackupConst.ACTION)) {
|
||||
BackupConst.ACTION_BACKUP_COMPLETED -> {
|
||||
isBackupStarted = false
|
||||
|
||||
val uri = Uri.parse(intent.getStringExtra(BackupConst.EXTRA_URI))
|
||||
val unifile = UniFile.fromUri(activity, uri)
|
||||
notifier.showBackupComplete(unifile)
|
||||
}
|
||||
BackupConst.ACTION_BACKUP_ERROR -> {
|
||||
isBackupStarted = false
|
||||
|
||||
notifier.showBackupError(intent.getStringExtra(BackupConst.EXTRA_ERROR_MESSAGE))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val CODE_BACKUP_CREATE = 501
|
||||
const val CODE_BACKUP_RESTORE = 502
|
||||
const val CODE_BACKUP_DIR = 503
|
||||
|
||||
var isBackupStarted = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
package eu.kanade.tachiyomi.ui.setting.backup
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.BitmapFactory
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import eu.kanade.tachiyomi.util.system.notificationBuilder
|
||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||
import java.io.File
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
internal class BackupNotifier(private val context: Context) {
|
||||
|
||||
private val notificationBuilder = context.notificationBuilder(Notifications.CHANNEL_BACKUP_RESTORE) {
|
||||
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
|
||||
setSmallIcon(R.drawable.ic_tachi)
|
||||
setAutoCancel(false)
|
||||
}
|
||||
|
||||
private fun NotificationCompat.Builder.show(id: Int) {
|
||||
context.notificationManager.notify(id, build())
|
||||
}
|
||||
|
||||
fun showBackupProgress() {
|
||||
with(notificationBuilder) {
|
||||
setContentTitle(context.getString(R.string.backup))
|
||||
setContentText(context.getString(R.string.creating_backup))
|
||||
|
||||
setProgress(0, 0, true)
|
||||
setOngoing(true)
|
||||
}
|
||||
|
||||
notificationBuilder.show(Notifications.ID_BACKUP_PROGRESS)
|
||||
}
|
||||
|
||||
fun showBackupError(error: String?) {
|
||||
context.notificationManager.cancel(Notifications.ID_BACKUP_PROGRESS)
|
||||
|
||||
with(notificationBuilder) {
|
||||
setContentTitle(context.getString(R.string.creating_backup_error))
|
||||
setContentText(error)
|
||||
|
||||
// Remove progress bar
|
||||
setProgress(0, 0, false)
|
||||
setOngoing(false)
|
||||
}
|
||||
|
||||
notificationBuilder.show(Notifications.ID_BACKUP_COMPLETE)
|
||||
}
|
||||
|
||||
fun showBackupComplete(unifile: UniFile) {
|
||||
context.notificationManager.cancel(Notifications.ID_BACKUP_PROGRESS)
|
||||
|
||||
with(notificationBuilder) {
|
||||
setContentTitle(context.getString(R.string.backup_created))
|
||||
|
||||
if (unifile.filePath != null) {
|
||||
setContentText(context.getString(R.string.file_saved, unifile.filePath))
|
||||
}
|
||||
|
||||
// Remove progress bar
|
||||
setProgress(0, 0, false)
|
||||
setOngoing(false)
|
||||
|
||||
// Clear old actions if they exist
|
||||
if (mActions.isNotEmpty()) {
|
||||
mActions.clear()
|
||||
}
|
||||
|
||||
addAction(
|
||||
R.drawable.ic_share_24dp,
|
||||
context.getString(R.string.action_share),
|
||||
NotificationReceiver.shareBackupPendingBroadcast(context, unifile.uri, Notifications.ID_BACKUP_COMPLETE)
|
||||
)
|
||||
}
|
||||
|
||||
notificationBuilder.show(Notifications.ID_BACKUP_COMPLETE)
|
||||
}
|
||||
|
||||
fun showRestoreProgress(content: String = "", progress: Int = 0, maxAmount: Int = 100): NotificationCompat.Builder {
|
||||
val builder = with(notificationBuilder) {
|
||||
setContentTitle(context.getString(R.string.restoring_backup))
|
||||
setContentText(content)
|
||||
|
||||
setProgress(maxAmount, progress, false)
|
||||
setOngoing(true)
|
||||
|
||||
// Clear old actions if they exist
|
||||
if (mActions.isNotEmpty()) {
|
||||
mActions.clear()
|
||||
}
|
||||
|
||||
addAction(
|
||||
R.drawable.ic_close_24dp,
|
||||
context.getString(R.string.action_stop),
|
||||
NotificationReceiver.cancelRestorePendingBroadcast(context, Notifications.ID_RESTORE_PROGRESS)
|
||||
)
|
||||
}
|
||||
|
||||
builder.show(Notifications.ID_RESTORE_PROGRESS)
|
||||
|
||||
return builder
|
||||
}
|
||||
|
||||
fun showRestoreError(error: String?) {
|
||||
context.notificationManager.cancel(Notifications.ID_RESTORE_PROGRESS)
|
||||
|
||||
with(notificationBuilder) {
|
||||
setContentTitle(context.getString(R.string.restoring_backup_error))
|
||||
setContentText(error)
|
||||
|
||||
// Remove progress bar
|
||||
setProgress(0, 0, false)
|
||||
setOngoing(false)
|
||||
}
|
||||
|
||||
notificationBuilder.show(Notifications.ID_RESTORE_COMPLETE)
|
||||
}
|
||||
|
||||
fun showRestoreComplete(time: Long, errorCount: Int, path: String?, file: String?) {
|
||||
context.notificationManager.cancel(Notifications.ID_RESTORE_PROGRESS)
|
||||
|
||||
val timeString = context.getString(
|
||||
R.string.restore_duration,
|
||||
TimeUnit.MILLISECONDS.toMinutes(time),
|
||||
TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(
|
||||
TimeUnit.MILLISECONDS.toMinutes(time)
|
||||
)
|
||||
)
|
||||
|
||||
with(notificationBuilder) {
|
||||
setSmallIcon(R.drawable.ic_tachi)
|
||||
setAutoCancel(false)
|
||||
|
||||
setContentTitle(context.getString(R.string.restore_completed))
|
||||
setContentText(context.getString(R.string.restore_completed_content, timeString, errorCount))
|
||||
|
||||
// Remove progress bar
|
||||
setProgress(0, 0, false)
|
||||
setOngoing(false)
|
||||
|
||||
// Clear old actions if they exist
|
||||
if (mActions.isNotEmpty()) {
|
||||
mActions.clear()
|
||||
}
|
||||
|
||||
if (errorCount > 0 && !path.isNullOrEmpty() && !file.isNullOrEmpty()) {
|
||||
val destFile = File(path, file)
|
||||
val uri = destFile.getUriCompat(context)
|
||||
|
||||
addAction(
|
||||
R.drawable.nnf_ic_file_folder,
|
||||
context.getString(R.string.action_open_log),
|
||||
NotificationReceiver.openErrorLogPendingActivity(context, uri)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
notificationBuilder.show(Notifications.ID_RESTORE_COMPLETE)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user