You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 01:09:29