Просмотр исходного кода

修复恢复备份用的zip库不支持5.0,6.0的问题

kunfei 3 лет назад
Родитель
Сommit
6b7fc0033a

+ 5 - 4
app/src/main/java/io/legado/app/help/storage/Restore.kt

@@ -44,12 +44,13 @@ object Restore {
             } else {
                 ZipUtils.unZipToPath(File(uri.path!!), Backup.backupPath)
             }
+        }.onSuccess {
+            restoreDatabase()
+            restoreConfig()
+            LocalConfig.lastBackup = System.currentTimeMillis()
         }.onFailure {
-            AppLog.put("恢复复制文件出错\n${it.localizedMessage}", it)
+            AppLog.put("复制解压文件出错\n${it.localizedMessage}", it)
         }
-        restoreDatabase()
-        restoreConfig()
-        LocalConfig.lastBackup = System.currentTimeMillis()
     }
 
     suspend fun restoreDatabase(path: String = Backup.backupPath) {

+ 4 - 3
app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt

@@ -78,17 +78,18 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
         execute {
             importSource(text)
         }.onSuccess {
-            it?.let(finally) ?: context.toastOnUi("格式不对")
+            finally.invoke(it)
         }.onError {
             context.toastOnUi(it.localizedMessage ?: "Error")
+            it.printOnDebug()
         }
     }
 
-    suspend fun importSource(text: String): BookSource? {
+    suspend fun importSource(text: String): BookSource {
         return when {
             text.isAbsUrl() -> {
                 val text1 = okHttpClient.newCallStrResponse { url(text) }.body
-                text1?.let { importSource(text1) }
+                importSource(text1!!)
             }
             text.isJsonArray() -> {
                 if (text.contains("ruleSearchUrl") || text.contains("ruleFindUrl")) {

+ 66 - 7
app/src/main/java/io/legado/app/utils/compress/ZipUtils.kt

@@ -1,5 +1,6 @@
 package io.legado.app.utils.compress
 
+import android.os.Build
 import io.legado.app.utils.DebugLog
 import io.legado.app.utils.printOnDebug
 import kotlinx.coroutines.Dispatchers.IO
@@ -193,16 +194,36 @@ object ZipUtils {
     }
 
     @Throws(SecurityException::class)
-    fun unZipToPath(inputStream: InputStream, path: String, filter: ((String) -> Boolean)? = null): List<File> {
-        return ZipArchiveInputStream(inputStream).use {
-            unZipToPath(it, File(path), filter)
+    fun unZipToPath(
+        inputStream: InputStream,
+        path: String,
+        filter: ((String) -> Boolean)? = null
+    ): List<File> {
+        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            ZipArchiveInputStream(inputStream).use {
+                unZipToPath(it, File(path), filter)
+            }
+        } else {
+            ZipInputStream(inputStream).use {
+                unZipToPath(it, File(path), filter)
+            }
         }
     }
 
     @Throws(SecurityException::class)
-    fun unZipToPath(inputStream: InputStream, dir: File, filter: ((String) -> Boolean)? = null): List<File> {
-        return ZipArchiveInputStream(inputStream).use {
-            unZipToPath(it, dir, filter)
+    fun unZipToPath(
+        inputStream: InputStream,
+        dir: File,
+        filter: ((String) -> Boolean)? = null
+    ): List<File> {
+        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            ZipArchiveInputStream(inputStream).use {
+                unZipToPath(it, dir, filter)
+            }
+        } else {
+            ZipInputStream(inputStream).use {
+                unZipToPath(it, dir, filter)
+            }
         }
     }
 
@@ -243,6 +264,44 @@ object ZipUtils {
         return files
     }
 
+
+    @Throws(SecurityException::class)
+    private fun unZipToPath(
+        zipInputStream: ZipInputStream,
+        dir: File,
+        filter: ((String) -> Boolean)? = null
+    ): List<File> {
+        val files = arrayListOf<File>()
+        var entry: ZipEntry?
+        while (zipInputStream.nextEntry.also { entry = it } != null) {
+            val entryName = entry!!.name
+            val entryFile = File(dir, entryName)
+            if (!entryFile.canonicalPath.startsWith(dir.canonicalPath)) {
+                throw SecurityException("压缩文件只能解压到指定路径")
+            }
+            if (entry!!.isDirectory) {
+                if (!entryFile.exists()) {
+                    entryFile.mkdirs()
+                }
+                continue
+            }
+            if (entryFile.parentFile?.exists() != true) {
+                entryFile.parentFile?.mkdirs()
+            }
+            if (filter != null && !filter.invoke(entryName)) continue
+            if (!entryFile.exists()) {
+                entryFile.createNewFile()
+                entryFile.setReadable(true)
+                entryFile.setExecutable(true)
+            }
+            FileOutputStream(entryFile).use {
+                zipInputStream.copyTo(it)
+                files.add(entryFile)
+            }
+        }
+        return files
+    }
+
     /* 遍历目录获取所有文件名 */
     @Throws(SecurityException::class)
     fun getFilesName(
@@ -267,7 +326,7 @@ object ZipUtils {
             }
             val fileName = entry!!.name
             if (filter != null && filter.invoke(fileName))
-            fileNames.add(fileName)
+                fileNames.add(fileName)
         }
         return fileNames
     }