Android存储权限异常:Android 9无法保存文本至外部存储问题排查
问题分析与修复方案
嘿,我仔细看了你的代码和遇到的问题,核心问题其实是权限请求的逻辑完全写反了,另外还有几个小细节需要调整——和你担心的手动创建"My Files"文件夹没关系,你的文件夹创建逻辑是没问题的。
1. 最致命的错误:权限判断逻辑搞反了!
看你onCreate里的这段权限判断代码:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){ String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE}; requestPermissions(permissions,WRITE_EXTERNAL_STORAGE_CODE); }else { saveToTxtFile(mText); } }
这段代码的逻辑完全颠倒了:已经有存储权限的时候,你反而去请求权限;没有权限的时候,却直接执行保存操作——这就导致在Android 9(API28)上,因为没有正确请求权限,直接触发了权限拒绝的问题。
修正后的正确逻辑应该是:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ // 检查是否没有权限,没有的话才去请求 if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE}; requestPermissions(permissions,WRITE_EXTERNAL_STORAGE_CODE); }else { // 已经有权限,直接保存文件 saveToTxtFile(mText); } }
2. Android 9(API28)的存储权限细节
虽然Android 9还没强制分区存储,但你需要确保:
- 你已经在
AndroidManifest.xml里正确声明了读写权限,这部分你做的没问题 - 别忘了定义
WRITE_EXTERNAL_STORAGE_CODE常量,比如在MainActivity里加一行:
否则请求权限的回调会识别不了请求码。private static final int WRITE_EXTERNAL_STORAGE_CODE = 100;
3. 关于"My Files"文件夹的创建
你的文件夹创建逻辑是对的:dir.mkdirs()会自动创建所有不存在的父目录,不管"My Files"之前有没有,都会帮你建好。不过可以优化一下路径拼接的方式,避免硬编码斜杠的问题:
// 用File的构造方法来拼接路径,更安全 File dir = new File(path, "My Files");
这样能适配不同系统的文件路径分隔符,不容易出错。
4. 额外的优化建议
- 在
saveToTxtFile方法里,建议用try-with-resources语法,它会自动帮你关闭流,避免资源泄漏:try (FileWriter fw = new FileWriter(file.getAbsoluteFile()); BufferedWriter bw = new BufferedWriter(fw)) { bw.write(mText); Toast.makeText(this, fileName+" is saved to\n" + dir, Toast.LENGTH_SHORT).show(); } catch (Exception e) { Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show(); } - 如果之后要适配Android 10(API29)及以上版本,建议改用媒体存储API或者应用专属外部存储,因为
Environment.getExternalStorageDirectory()从API29开始被弃用,而且分区存储会限制对公共目录的直接写入。
内容的提问来源于stack exchange,提问作者Ishak Benaissa




