From ba928150d5232abf958a672f8337ef92ff0b7ba6 Mon Sep 17 00:00:00 2001
From: ShirkNeko <2773800761@qq.com>
Date: Fri, 21 Mar 2025 03:03:27 +0800
Subject: [PATCH] -Optimize file permission requests, simplify backup and
restore logic, and directly process user-selected files
- This will fix an issue where some devices were unable to back up their app lists
---
manager/app/src/main/AndroidManifest.xml | 8 +-
.../zako/sukisu/ui/util/ModuleModify.kt | 77 +++++++------------
2 files changed, 31 insertions(+), 54 deletions(-)
diff --git a/manager/app/src/main/AndroidManifest.xml b/manager/app/src/main/AndroidManifest.xml
index 5bbdbd49..a893ed23 100644
--- a/manager/app/src/main/AndroidManifest.xml
+++ b/manager/app/src/main/AndroidManifest.xml
@@ -3,10 +3,9 @@
xmlns:tools="http://schemas.android.com/tools">
-
-
+
+
+
/proc/self/fd/1
""".trimIndent()
val process = Runtime.getRuntime().exec(arrayOf("su", "-c", command))
- process.waitFor()
+
+ // 直接将tar输出写入到用户选择的文件
+ context.contentResolver.openOutputStream(uri)?.use { output ->
+ process.inputStream.copyTo(output)
+ }
val error = BufferedReader(InputStreamReader(process.errorStream)).readText()
if (process.exitValue() != 0) {
throw IOException(context.getString(R.string.command_execution_failed, error))
}
- context.contentResolver.openOutputStream(uri)?.use { output ->
- tempFile.inputStream().use { input ->
- input.copyTo(output)
- }
- }
-
- tempFile.delete()
-
withContext(Dispatchers.Main) {
snackBarHost.showSnackbar(
context.getString(R.string.backup_success),
@@ -96,23 +90,15 @@ object ModuleModify {
try {
val busyboxPath = "/data/adb/ksu/bin/busybox"
val moduleDir = "/data/adb/modules"
- val tempFile = File(context.cacheDir, "temp_restore.tar.gz").apply {
- if (exists()) delete()
- }
+
+ // 直接从用户选择的文件读取并解压
+ val process = Runtime.getRuntime().exec(arrayOf("su", "-c", "$busyboxPath tar -xz -C $moduleDir"))
context.contentResolver.openInputStream(uri)?.use { input ->
- tempFile.outputStream().use { output ->
- input.copyTo(output)
- }
+ input.copyTo(process.outputStream)
}
+ process.outputStream.close()
- val command = """
- cd "$moduleDir" &&
- rm -rf * &&
- $busyboxPath tar -xzvf "${tempFile.absolutePath}"
- """.trimIndent()
-
- val process = Runtime.getRuntime().exec(arrayOf("su", "-c", command))
process.waitFor()
val error = BufferedReader(InputStreamReader(process.errorStream)).readText()
@@ -120,8 +106,6 @@ object ModuleModify {
throw IOException(context.getString(R.string.command_execution_failed, error))
}
- tempFile.delete()
-
withContext(Dispatchers.Main) {
val snackbarResult = snackBarHost.showSnackbar(
message = context.getString(R.string.restore_success),
@@ -166,25 +150,19 @@ object ModuleModify {
withContext(Dispatchers.IO) {
try {
val allowlistPath = "/data/adb/ksu/.allowlist"
- val tempFile = File(context.cacheDir, "allowlist_backup_${System.currentTimeMillis()}")
- val command = "cp $allowlistPath ${tempFile.absolutePath}"
- val process = Runtime.getRuntime().exec(arrayOf("su", "-c", command))
- process.waitFor()
+ // 直接复制文件到用户选择的位置
+ val process = Runtime.getRuntime().exec(arrayOf("su", "-c", "cat $allowlistPath"))
+
+ context.contentResolver.openOutputStream(uri)?.use { output ->
+ process.inputStream.copyTo(output)
+ }
val error = BufferedReader(InputStreamReader(process.errorStream)).readText()
if (process.exitValue() != 0) {
throw IOException(context.getString(R.string.command_execution_failed, error))
}
- context.contentResolver.openOutputStream(uri)?.use { output ->
- tempFile.inputStream().use { input ->
- input.copyTo(output)
- }
- }
-
- tempFile.delete()
-
withContext(Dispatchers.Main) {
snackBarHost.showSnackbar(
context.getString(R.string.allowlist_backup_success),
@@ -211,18 +189,15 @@ object ModuleModify {
withContext(Dispatchers.IO) {
try {
val allowlistPath = "/data/adb/ksu/.allowlist"
- val tempFile = File(context.cacheDir, "allowlist_restore_temp").apply {
- if (exists()) delete()
- }
+
+ // 直接从用户选择的文件读取并写入到目标位置
+ val process = Runtime.getRuntime().exec(arrayOf("su", "-c", "cat > $allowlistPath"))
context.contentResolver.openInputStream(uri)?.use { input ->
- tempFile.outputStream().use { output ->
- input.copyTo(output)
- }
+ input.copyTo(process.outputStream)
}
+ process.outputStream.close()
- val command = "cp ${tempFile.absolutePath} $allowlistPath"
- val process = Runtime.getRuntime().exec(arrayOf("su", "-c", command))
process.waitFor()
val error = BufferedReader(InputStreamReader(process.errorStream)).readText()
@@ -230,8 +205,6 @@ object ModuleModify {
throw IOException(context.getString(R.string.command_execution_failed, error))
}
- tempFile.delete()
-
withContext(Dispatchers.Main) {
snackBarHost.showSnackbar(
context.getString(R.string.allowlist_restore_success),
@@ -350,4 +323,8 @@ object ModuleModify {
type = "application/octet-stream"
}
}
+
+ private fun reboot() {
+ Runtime.getRuntime().exec(arrayOf("su", "-c", "reboot"))
+ }
}
\ No newline at end of file