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

使用Kotlin在Android中无法创建.txt文件的问题求助

解决Android中创建.txt文件权限被拒的问题

核心问题分析

你遇到的Permission denied主要源于三个问题:

  1. 直接操作系统根目录/,普通APP无权限访问该系统分区
  2. 仅在清单文件声明权限,未完成动态权限申请(危险权限需运行时用户授权)
  3. Android 10(API 29)及以上版本对外部存储实施了更严格的分区存储限制

具体解决步骤

1. 选择合法的文件存储目录

不要直接操作根目录,根据需求选择以下合规目录:

  • APP内部存储:仅当前APP可访问,无需额外权限,卸载APP时文件会被自动删除
  • APP专属外部存储目录:仅当前APP可访问,Android 10+无需权限,卸载时文件被删除
  • 外部存储公共目录:如Downloads,需动态申请权限,Android 10+需适配分区存储规则

2. 动态申请危险权限

WRITE_EXTERNAL_STORAGE属于危险权限,API 23及以上版本必须在运行时请求用户授权:

private val REQUEST_STORAGE_PERMISSION = 100

fun checkStoragePermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_STORAGE_PERMISSION)
    } else {
        // 权限已授予,执行文件创建逻辑
        createTxtFile()
    }
}

// 处理权限申请结果
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == REQUEST_STORAGE_PERMISSION) {
        if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            createTxtFile()
        } else {
            Toast.makeText(this, "需要存储权限才能创建文件", Toast.LENGTH_SHORT).show()
        }
    }
}

3. 不同场景的文件创建代码示例

示例1:使用APP内部存储创建文件
fun createTxtFile() {
    val fileName = "documento.txt"
    // 获取内部存储的文件目录
    val file = File(filesDir, fileName)
    if (!file.exists()) {
        try {
            file.createNewFile()
            Toast.makeText(this, "文件创建成功", Toast.LENGTH_SHORT).show()
        } catch (e: IOException) {
            e.printStackTrace()
            Toast.makeText(this, "创建失败:${e.message}", Toast.LENGTH_SHORT).show()
        }
    } else {
        Toast.makeText(this, "文件已存在", Toast.LENGTH_SHORT).show()
    }
}
示例2:使用APP专属外部存储目录(Android 10+推荐)
fun createTxtFile() {
    val fileName = "documento.txt"
    // 获取APP专属外部存储目录,无需权限
    val externalDir = getExternalFilesDir(null)
    externalDir?.let {
        val file = File(it, fileName)
        if (!file.exists()) {
            try {
                file.createNewFile()
                Toast.makeText(this, "文件创建成功", Toast.LENGTH_SHORT).show()
            } catch (e: IOException) {
                e.printStackTrace()
                Toast.makeText(this, "创建失败:${e.message}", Toast.LENGTH_SHORT).show()
            }
        } else {
            Toast.makeText(this, "文件已存在", Toast.LENGTH_SHORT).show()
        }
    }
}
示例3:使用外部公共目录(如Downloads,需动态权限)
fun createTxtFile() {
    val fileName = "documento.txt"
    // 获取Downloads公共目录
    val downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
    val file = File(downloadsDir, fileName)
    if (!file.exists()) {
        try {
            file.createNewFile()
            Toast.makeText(this, "文件创建成功", Toast.LENGTH_SHORT).show()
        } catch (e: IOException) {
            e.printStackTrace()
            Toast.makeText(this, "创建失败:${e.message}", Toast.LENGTH_SHORT).show()
        }
    } else {
        Toast.makeText(this, "文件已存在", Toast.LENGTH_SHORT).show()
    }
}

4. Android 10+额外适配

如果目标SDK版本为29及以上,需在清单文件的application标签中添加临时兼容配置:

<application
    ...
    android:requestLegacyExternalStorage="true">

若要完全适配分区存储规则,建议使用MediaStore API操作公共目录文件。


内容的提问来源于stack exchange,提问作者Looking for a answer ...

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:57:21