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

Android物理SD卡写入问题求助:代码写入内置存储而非SD卡

解决Android写入物理SD卡的问题

嘿,我懂你现在的困扰——明明想把文件写到物理SD卡上,结果用Environment.getExternalStorageDirectory()拿到的却是内置存储,属实是Android存储命名的坑搞的鬼!先给你理清楚问题根源,再给你分版本的解决方案。

为什么当前代码不行?

Android里的getExternalStorageDirectory()这个方法的“external”是个历史遗留的命名误区:它指的是对外可访问的存储区域(比如手机厂商划分的、可以通过USB传输文件的内置分区),而非字面意义上的“可移除SD卡”。你看到isExternalStorageRemovable()返回false,就正好验证了这一点——当前拿到的是内置的“外部存储”。

分版本解决方案

Android不同版本的存储权限机制差异很大,得针对性处理:

Android 10及以上(API 29+):用存储访问框架(SAF)

从Android 10开始引入了Scoped Storage,禁止APP直接访问SD卡的任意路径,必须通过**存储访问框架(SAF)**让用户手动选择要操作的SD卡目录,才能进行读写。

  1. 发起请求让用户选择SD卡目录:
private static final int REQUEST_CODE_PICK_DIR = 1001;

// 触发目录选择
Intent pickDirIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(pickDirIntent, REQUEST_CODE_PICK_DIR);
  1. 处理用户选择后的回调,写入文件:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_PICK_DIR && resultCode == RESULT_OK && data != null) {
        Uri selectedDirUri = data.getData();
        // 持久化权限,避免下次打开APP还要重新选择
        getContentResolver().takePersistableUriPermission(selectedDirUri,
                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        
        // 创建要写入的文件
        DocumentFile targetDir = DocumentFile.fromTreeUri(this, selectedDirUri);
        DocumentFile newFile = targetDir.createFile("text/plain", "my_sd_file.txt");
        
        // 写入内容
        try (OutputStream outputStream = getContentResolver().openOutputStream(newFile.getUri())) {
            outputStream.write("终于写到物理SD卡啦!".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Android 9及以下(API 28及以下):直接获取SD卡路径

这个版本还允许直接访问SD卡的APP专属目录,你可以通过Context.getExternalFilesDirs()方法获取所有外部存储目录:

// 获取所有外部存储目录,数组第一个是内置外部存储,第二个是物理SD卡(如果存在)
File[] externalStorageDirs = getExternalFilesDirs(null);
if (externalStorageDirs.length > 1 && externalStorageDirs[1] != null) {
    File sdCardAppDir = externalStorageDirs[1];
    // 创建要写入的文件
    File targetFile = new File(sdCardAppDir, "my_sd_file.txt");
    // 写入内容
    try (FileWriter writer = new FileWriter(targetFile)) {
        writer.write("成功写入物理SD卡的APP专属目录!");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

注意:这个版本需要在Manifest中添加权限,并且针对API 23+要动态申请权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

额外提醒

  • 如果想访问SD卡上的非APP专属目录(比如SD卡根目录的自定义文件夹),Android 10之前需要WRITE_EXTERNAL_STORAGE权限;Android 10及以上只能通过SAF让用户手动选择,没办法直接硬编码路径访问。
  • 尽量优先使用APP专属目录,这样不需要额外的权限申请(Android 10+甚至不需要WRITE_EXTERNAL_STORAGE),也不会因为Scoped Storage的限制出问题。

内容的提问来源于stack exchange,提问作者AndyAndroid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:41:11