Skip to content

Commit f8446dd

Browse files
add backup banner options
1 parent b89a37a commit f8446dd

1 file changed

Lines changed: 73 additions & 1 deletion

File tree

V2rayNG/app/src/main/java/com/v2ray/ang/ui/BackupActivity.kt

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.v2ray.ang.ui
22

33
import android.content.Intent
4+
import android.net.Uri
45
import android.os.Bundle
56
import androidx.core.content.FileProvider
67
import androidx.lifecycle.lifecycleScope
@@ -98,7 +99,7 @@ class BackupActivity : HelperBaseActivity() {
9899
}
99100

100101
/**
101-
* Backup configuration to cache directory
102+
* Backup configuration to cache directory.
102103
* Returns Pair<success, zipFilePath>
103104
*/
104105
private fun backupConfigurationToCache(): Pair<Boolean, String> {
@@ -115,13 +116,50 @@ class BackupActivity : HelperBaseActivity() {
115116
return Pair(false, "")
116117
}
117118

119+
// Backup custom banner image files alongside MMKV data
120+
backupBannerImages(backupDir)
121+
118122
return if (ZipUtil.zipFromFolder(backupDir, outputZipFilePath)) {
119123
Pair(true, outputZipFilePath)
120124
} else {
121125
Pair(false, "")
122126
}
123127
}
124128

129+
/**
130+
* Copy banner image files into the backup directory.
131+
* Each banner is saved as "banners/<key>.jpg" so restore can find them by key.
132+
*/
133+
private fun backupBannerImages(backupDir: String) {
134+
val bannerKeys = listOf(
135+
AppConfig.PREF_CUSTOM_HOME_BANNER_URI,
136+
AppConfig.PREF_CUSTOM_SHEET_BANNER_URI,
137+
AppConfig.PREF_PROFILE_BANNER_URI,
138+
)
139+
val bannersDir = java.io.File(backupDir, "banners").also { it.mkdirs() }
140+
for (key in bannerKeys) {
141+
val uriString = MmkvManager.decodeSettingsString(key) ?: continue
142+
if (uriString.isBlank()) continue
143+
try {
144+
val uri = Uri.parse(uriString)
145+
val srcFile = if (uri.scheme == "file") {
146+
java.io.File(uri.path!!)
147+
} else {
148+
val tmp = java.io.File(cacheDir, "banner_backup_tmp_${key}.jpg")
149+
contentResolver.openInputStream(uri)?.use { input ->
150+
tmp.outputStream().use { input.copyTo(it) }
151+
}
152+
tmp
153+
}
154+
if (srcFile.exists()) {
155+
srcFile.copyTo(java.io.File(bannersDir, "$key.jpg"), overwrite = true)
156+
}
157+
} catch (e: Exception) {
158+
LogUtil.e(AppConfig.TAG, "Failed to backup banner for key $key", e)
159+
}
160+
}
161+
}
162+
125163
private fun restoreConfiguration(zipFile: File): Boolean {
126164
val backupDir = this.cacheDir.absolutePath + "/${System.currentTimeMillis()}"
127165

@@ -133,10 +171,44 @@ class BackupActivity : HelperBaseActivity() {
133171
SettingsChangeManager.makeSetupGroupTab()
134172
SettingsChangeManager.makeRestartService()
135173

174+
// Restore custom banner image files and fix their paths in MMKV
175+
restoreBannerImages(backupDir)
176+
136177
SettingsManager.initApp(this)
137178
return count > 0
138179
}
139180

181+
/**
182+
* Copy banner image files from the backup dir into cacheDir,
183+
* then update each URI key in MMKV to the new path.
184+
*/
185+
private fun restoreBannerImages(backupDir: String) {
186+
val bannerKeys = listOf(
187+
AppConfig.PREF_CUSTOM_HOME_BANNER_URI,
188+
AppConfig.PREF_CUSTOM_SHEET_BANNER_URI,
189+
AppConfig.PREF_PROFILE_BANNER_URI,
190+
)
191+
val bannersDir = java.io.File(backupDir, "banners")
192+
if (!bannersDir.exists()) return
193+
194+
for (key in bannerKeys) {
195+
val srcFile = java.io.File(bannersDir, "$key.jpg")
196+
if (!srcFile.exists()) {
197+
// No backup for this banner — clear the stale URI so we don't point to a missing file
198+
MmkvManager.encodeSettings(key, "")
199+
continue
200+
}
201+
try {
202+
val destFile = java.io.File(cacheDir, "${key}_${System.currentTimeMillis()}.jpg")
203+
srcFile.copyTo(destFile, overwrite = true)
204+
MmkvManager.encodeSettings(key, Uri.fromFile(destFile).toString())
205+
} catch (e: Exception) {
206+
LogUtil.e(AppConfig.TAG, "Failed to restore banner for key $key", e)
207+
MmkvManager.encodeSettings(key, "")
208+
}
209+
}
210+
}
211+
140212
private fun showFileChooser() {
141213
launchFileChooser { uri ->
142214
if (uri == null) {

0 commit comments

Comments
 (0)