多设备SD卡文件创建/跨存储复制及file.mkdir()失败问题咨询
Hey there, let's break down your two questions and fix that frustrating mkdir() issue you're facing!
1. 如何在多设备的SD卡路径下创建文件
First off, forget about getExternalStorageDirectory() — it's pretty much deprecated (since API 29) and often points to the internal shared storage (not the removable SD card) on many modern devices. Here's the proper way to target the removable SD card across different devices:
For API 24+ (Android 7.0 and above)
Use the StorageManager API to get all available storage volumes, then filter for the removable one:
StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE); List<StorageVolume> storageVolumes = storageManager.getStorageVolumes(); for (StorageVolume volume : storageVolumes) { // Check if this is the removable SD card if (volume.isRemovable()) { // Get the root directory of the SD card (requires API 24+) File sdCardRoot = volume.getDirectory(); if (sdCardRoot != null && sdCardRoot.canWrite()) { // Create your target directory/file here File targetDir = new File(sdCardRoot, "MyAppFiles"); if (!targetDir.exists()) { boolean created = targetDir.mkdirs(); // Use mkdirs() to create parent dirs too if (created) { // Success! Now create a file inside File newFile = new File(targetDir, "test.txt"); boolean fileCreated = newFile.createNewFile(); } } } } }
For older devices (API 19 to 23)
Use getExternalFilesDirs(null) — this returns an array where the second element (index 1) is usually the SD card's app-specific directory:
File[] externalDirs = getExternalFilesDirs(null); // The first element is internal shared storage, second is removable SD card (if exists) if (externalDirs.length > 1 && externalDirs[1] != null) { File sdCardAppDir = externalDirs[1]; File targetFile = new File(sdCardAppDir, "test.txt"); try { boolean created = targetFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } }
Important: For API 23 and below, you need to request the
WRITE_EXTERNAL_STORAGEpermission dynamically (not just in the manifest).
2. 是否可在SD卡中创建文件/复制内部存储到SD卡?
Absolutely — but it depends on which part of the SD card you're targeting:
应用专属目录(推荐)
- You can create files directly here without special permissions (API 29+). This is the safest approach because the files are tied to your app and get deleted when your app is uninstalled.
- To copy a file from internal storage to the SD card's app directory:
// Internal storage file (example: files saved in getFilesDir()) File internalFile = new File(getFilesDir(), "source.txt"); // SD card app directory File[] externalDirs = getExternalFilesDirs(null); if (externalDirs.length > 1 && externalDirs[1] != null) { File sdCardFile = new File(externalDirs[1], "copied_source.txt"); // Copy the file try (FileInputStream in = new FileInputStream(internalFile); FileOutputStream out = new FileOutputStream(sdCardFile)) { byte[] buffer = new byte[1024]; int length; while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); } } catch (IOException e) { e.printStackTrace(); } }
公共目录(如SD卡根目录、Downloads等)
- For API 29 and above, you need the
MANAGE_EXTERNAL_STORAGEpermission, which requires users to manually enable it in Settings (Google Play also restricts apps using this permission unless they meet specific criteria). - For API 28 and below, you need the
WRITE_EXTERNAL_STORAGEpermission.
Why mkdir() keeps returning false?
Here are the most common fixes:
- Use
mkdirs()instead ofmkdir(): If you're creating a nested directory,mkdir()fails if parent directories don't exist.mkdirs()creates all parent directories needed. - Check permissions: Make sure you've requested the necessary permissions (dynamic request for API 23+).
- Verify the path is correct: Don't hardcode paths like
/sdcard/— always use system APIs to get the SD card path. - Check if the SD card is mounted: Use
Environment.getExternalStorageState(sdCardRoot).equals(Environment.MEDIA_MOUNTED)to ensure the SD card is accessible and writable. - Avoid restricted directories: Some devices block writes to the SD card root or system directories — stick to app-specific or public directories you have access to.
内容的提问来源于stack exchange,提问作者Sahana Prabhakar

