@@ -3,6 +3,7 @@ package com.simplemobiletools.filemanager.pro.activities
33import android.annotation.SuppressLint
44import android.net.Uri
55import android.os.Bundle
6+ import com.simplemobiletools.commons.dialogs.EnterPasswordDialog
67import com.simplemobiletools.commons.dialogs.FilePickerDialog
78import com.simplemobiletools.commons.extensions.*
89import com.simplemobiletools.commons.helpers.NavigationIcon
@@ -13,14 +14,22 @@ import com.simplemobiletools.filemanager.pro.adapters.DecompressItemsAdapter
1314import com.simplemobiletools.filemanager.pro.extensions.config
1415import com.simplemobiletools.filemanager.pro.models.ListItem
1516import kotlinx.android.synthetic.main.activity_decompress.*
17+ import net.lingala.zip4j.exception.ZipException
18+ import net.lingala.zip4j.exception.ZipException.Type
19+ import net.lingala.zip4j.io.inputstream.ZipInputStream
20+ import net.lingala.zip4j.model.LocalFileHeader
1621import java.io.BufferedInputStream
17- import java.util.zip.ZipEntry
18- import java.util.zip.ZipInputStream
1922
2023class DecompressActivity : SimpleActivity () {
24+ companion object {
25+ private const val PASSWORD = " password"
26+ }
27+
2128 private val allFiles = ArrayList <ListItem >()
2229 private var currentPath = " "
2330 private var uri: Uri ? = null
31+ private var password: String? = null
32+ private var passwordDialog: EnterPasswordDialog ? = null
2433
2534 override fun onCreate (savedInstanceState : Bundle ? ) {
2635 isMaterialActivity = true
@@ -36,17 +45,23 @@ class DecompressActivity : SimpleActivity() {
3645 return
3746 }
3847
48+ password = savedInstanceState?.getString(PASSWORD , null )
49+
3950 val realPath = getRealPathFromURI(uri!! )
4051 decompress_toolbar.title = realPath?.getFilenameFromPath() ? : Uri .decode(uri.toString().getFilenameFromPath())
41- fillAllListItems(uri!! )
42- updateCurrentPath(" " )
52+ setupFilesList()
4353 }
4454
4555 override fun onResume () {
4656 super .onResume()
4757 setupToolbar(decompress_toolbar, NavigationIcon .Arrow )
4858 }
4959
60+ override fun onSaveInstanceState (outState : Bundle ) {
61+ super .onSaveInstanceState(outState)
62+ outState.putString(PASSWORD , password)
63+ }
64+
5065 private fun setupOptionsMenu () {
5166 decompress_toolbar.setOnMenuItemClickListener { menuItem ->
5267 when (menuItem.itemId) {
@@ -57,6 +72,11 @@ class DecompressActivity : SimpleActivity() {
5772 }
5873 }
5974
75+ private fun setupFilesList () {
76+ fillAllListItems(uri!! )
77+ updateCurrentPath(" " )
78+ }
79+
6080 override fun onBackPressed () {
6181 if (currentPath.isEmpty()) {
6282 super .onBackPressed()
@@ -99,14 +119,17 @@ class DecompressActivity : SimpleActivity() {
99119 try {
100120 val inputStream = contentResolver.openInputStream(uri!! )
101121 val zipInputStream = ZipInputStream (BufferedInputStream (inputStream!! ))
122+ if (password != null ) {
123+ zipInputStream.setPassword(password?.toCharArray())
124+ }
102125 val buffer = ByteArray (1024 )
103126
104127 zipInputStream.use {
105128 while (true ) {
106129 val entry = zipInputStream.nextEntry ? : break
107130 val filename = title.toString().substringBeforeLast(" ." )
108131 val parent = " $destination /$filename "
109- val newPath = " $parent /${entry.name .trimEnd(' /' )} "
132+ val newPath = " $parent /${entry.fileName .trimEnd(' /' )} "
110133
111134 if (! getDoesFilePathExist(parent)) {
112135 if (! createDirectorySync(parent)) {
@@ -161,10 +184,25 @@ class DecompressActivity : SimpleActivity() {
161184 }
162185
163186 val zipInputStream = ZipInputStream (BufferedInputStream (inputStream))
164- var zipEntry: ZipEntry ?
187+ if (password != null ) {
188+ zipInputStream.setPassword(password?.toCharArray())
189+ }
190+ var zipEntry: LocalFileHeader ?
165191 while (true ) {
166192 try {
167193 zipEntry = zipInputStream.nextEntry
194+ } catch (passwordException: ZipException ) {
195+ if (passwordException.type == Type .WRONG_PASSWORD ) {
196+ if (password != null ) {
197+ toast(getString(R .string.invalid_password))
198+ passwordDialog?.clearPassword()
199+ } else {
200+ askForPassword()
201+ }
202+ return
203+ } else {
204+ break
205+ }
168206 } catch (ignored: Exception ) {
169207 break
170208 }
@@ -173,10 +211,24 @@ class DecompressActivity : SimpleActivity() {
173211 break
174212 }
175213
176- val lastModified = if (isOreoPlus()) zipEntry.lastModifiedTime.toMillis() else 0
177- val filename = zipEntry.name .removeSuffix(" /" )
214+ val lastModified = if (isOreoPlus()) zipEntry.lastModifiedTime else 0
215+ val filename = zipEntry.fileName .removeSuffix(" /" )
178216 val listItem = ListItem (filename, filename.getFilenameFromPath(), zipEntry.isDirectory, 0 , 0L , lastModified, false , false )
179217 allFiles.add(listItem)
180218 }
219+ passwordDialog?.dismiss(notify = false )
220+ }
221+
222+ private fun askForPassword () {
223+ passwordDialog = EnterPasswordDialog (
224+ this ,
225+ callback = { newPassword ->
226+ password = newPassword
227+ setupFilesList()
228+ },
229+ cancelCallback = {
230+ finish()
231+ }
232+ )
181233 }
182234}
0 commit comments