feat(settings): #180 支持备份全部数据

This commit is contained in:
Super12138 2025-03-22 08:15:42 +08:00
parent 4f5a97aef2
commit 60927892c4
5 changed files with 28 additions and 15 deletions

View file

@ -34,7 +34,7 @@ android {
applicationId = "cn.super12138.todo"
minSdk = 24
targetSdk = 36
versionCode = 603
versionCode = 605
versionName = "2.1.2"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

View file

@ -57,7 +57,7 @@ fun SettingsData(
contract = ActivityResultContracts.CreateDocument("application/zip"),
onResult = {
if (it != null) {
viewModel.backupDatabase(
viewModel.backupAppData(
uri = it,
context = context,
onResult = { success ->
@ -84,7 +84,7 @@ fun SettingsData(
contract = ActivityResultContracts.OpenDocument(),
onResult = {
if (it != null) {
viewModel.restoreDatabase(
viewModel.restoreAppData(
uri = it,
context = context,
onResult = { success ->

View file

@ -177,19 +177,21 @@ class MainViewModel : ViewModel() {
appSecureMode = enabled
}
fun backupDatabase(uri: Uri, context: Context, onResult: (completed: Boolean) -> Unit) {
fun backupAppData(uri: Uri, context: Context, onResult: (completed: Boolean) -> Unit) {
viewModelScope.launch(Dispatchers.IO) {
try {
// 获取数据库文件路径
val dbPath = TodoApp.db.openHelper.writableDatabase.path
val prefPath = "${context.filesDir.parent}/shared_prefs"
// 开启输出文件流输出位置为用户选取的文件夹URI
context.contentResolver.openOutputStream(uri)?.use { outputStream ->
ZipOutputStream(BufferedOutputStream(outputStream)).use { zipOutStream ->
listOf(
context.getDatabasePath(Constants.DB_NAME),
File("$dbPath-wal"),
File("$dbPath-shm")
).forEach { file ->
context.getDatabasePath(Constants.DB_NAME), // 数据库
File("$dbPath-wal"), // 数据库-wal
File("$dbPath-shm"), // 数据库-shm
File("$prefPath/${Constants.SP_NAME}.xml") // SharedPreferences
).filter { it.exists() }.forEach { file ->
FileUtils.addFileToZip(file, file.name, zipOutStream)
}
}
@ -204,19 +206,30 @@ class MainViewModel : ViewModel() {
}
}
fun restoreDatabase(uri: Uri, context: Context, onResult: (completed: Boolean) -> Unit) {
fun restoreAppData(uri: Uri, context: Context, onResult: (completed: Boolean) -> Unit) {
viewModelScope.launch(Dispatchers.IO) {
try {
// 获取数据库文件夹
val outputPath = context.getDatabasePath(Constants.DB_NAME).parent
val dbPath = context.getDatabasePath(Constants.DB_NAME).parent
val prefPath = "${context.filesDir.parent}/shared_prefs/"
// 开启输入文件流输入位置为用户选取的文件URI
context.contentResolver.openInputStream(uri)?.use { inputStream ->
ZipInputStream(BufferedInputStream(inputStream)).use { zipInputStream ->
generateSequence { zipInputStream.nextEntry }.forEach { zipEntry ->
val outputFile = File(outputPath, zipEntry.name)
// 判断是否为 SharedPreferences 设置文件
val outputFile = if (zipEntry.name.endsWith(".xml")) {
File(prefPath, zipEntry.name)
} else {
File(dbPath, zipEntry.name)
}
// 输出文件
if (zipEntry.isDirectory) {
// 如果是文件夹则创建文件夹
outputFile.mkdirs()
} else {
// 父文件夹为空就创建父文件夹
outputFile.parentFile?.mkdirs()
// 输出文件
FileOutputStream(outputFile).use { zipInputStream.copyTo(it) }
}
zipInputStream.closeEntry()

View file

@ -97,9 +97,9 @@
<string name="pref_data">数据</string>
<string name="pref_data_desc">备份与恢复、管理数据</string>
<string name="pref_backup">备份数据</string>
<string name="pref_backup_desc">将待办数据保存在你的设备上</string>
<string name="pref_backup_desc">将待办的应用数据保存在你的设备上</string>
<string name="pref_restore">恢复数据</string>
<string name="pref_restore_desc">从你的设备上恢复待办数据</string>
<string name="pref_restore_desc">从你的设备上恢复待办的应用数据</string>
<string name="tip_backup_success">备份成功</string>
<string name="tip_backup_failed">备份失败</string>
<string name="tip_restore_success">数据恢复成功,需要重启应用以加载数据</string>

View file

@ -98,9 +98,9 @@
<string name="pref_data">Data</string>
<string name="pref_data_desc">Backup and Restore, Manage Data</string>
<string name="pref_backup">Backup</string>
<string name="pref_backup_desc">Save the to-do database on your device</string>
<string name="pref_backup_desc">Save the To Do app data on your device</string>
<string name="pref_restore">Restore</string>
<string name="pref_restore_desc">Restore the to-do database from your device</string>
<string name="pref_restore_desc">Restore the To Do app data from your device</string>
<string name="tip_backup_success">Backup successful</string>
<string name="tip_backup_failed">Backup failed</string>
<string name="tip_restore_success">Restore successful, restart the app to load data</string>