Android Kotlin实现按钮点击解压Zip至internal storage/android/data目录
实现多级Zip文件解压到Android/data目录的详细步骤
1. 核心前提说明
- Android 10+ 采用Scoped Storage,访问自己应用的
Android/data/[你的包名]目录无需动态权限,直接通过系统API获取即可。 - 解压属于IO操作,必须放在子线程执行,不能阻塞主线程。
2. 获取目标解压目录
先拿到Android/data/[你的包名]对应的File对象,确保目录存在:
// 在Activity/Fragment中获取 val targetDir = context.getExternalFilesDir(null)?.parentFile // getExternalFilesDir(null) 返回 Android/data/包名/files,parentFile就是 Android/data/包名 // 若需解压到files子目录,直接用getExternalFilesDir(null)即可 // 确保目录存在 targetDir?.let { if (!it.exists()) { it.mkdirs() } }
3. 实现Zip解压工具函数
编写通用解压函数,自动处理多级文件夹结构:
import java.io.* import java.util.zip.ZipEntry import java.util.zip.ZipInputStream fun unzip(zipInputStream: InputStream, targetDir: File) { ZipInputStream(zipInputStream).use { zis -> var entry: ZipEntry? = zis.nextEntry while (entry != null) { val entryFile = File(targetDir, entry.name) // 处理目录:先创建多级目录 if (entry.isDirectory) { entryFile.mkdirs() } else { // 处理文件:先创建父目录(应对嵌套文件夹下的文件) entryFile.parentFile?.mkdirs() // 写入文件内容 FileOutputStream(entryFile).use { fos -> zis.copyTo(fos) } } zis.closeEntry() entry = zis.nextEntry } } }
4. 获取Zip文件的输入流
假设你的Zip文件放在assets目录下(如果是其他来源,比如下载的文件,替换成对应输入流即可):
// 从assets目录获取Zip文件输入流 val zipInputStream = context.assets.open("your_file.zip")
5. 按钮点击事件绑定+异步执行
在Activity中绑定按钮点击事件,用Kotlin协程完成异步解压(避免主线程阻塞):
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.Toast import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val unzipBtn = findViewById<Button>(R.id.btn_unzip) unzipBtn.setOnClickListener { val targetDir = getExternalFilesDir(null)?.parentFile ?: run { Toast.makeText(this, "无法获取目标目录", Toast.LENGTH_SHORT).show() return@setOnClickListener } // 开启IO线程执行解压 CoroutineScope(Dispatchers.IO).launch { var isSuccess = true try { assets.open("your_file.zip").use { zipStream -> unzip(zipStream, targetDir) } } catch (e: IOException) { e.printStackTrace() isSuccess = false } // 回到主线程提示结果 withContext(Dispatchers.Main) { Toast.makeText( this@MainActivity, if (isSuccess) "解压完成" else "解压失败", Toast.LENGTH_SHORT ).show() } } } } }
6. 额外注意事项
- 替换代码中的
your_file.zip为你实际的Zip文件名(若放在assets中,需确保文件已添加到assets目录)。 - 如果Zip文件来自外部存储(比如Download目录),需通过
ACTION_OPEN_DOCUMENT获取文件Uri,再用contentResolver.openInputStream(uri)获取输入流。 - 测试时可通过Android Studio的Device File Explorer查看
Android/data/[你的包名]目录下的解压结果。
内容的提问来源于stack exchange,提问作者Arun Goenka
相关产品推荐
相关产品推荐

