Android如何将文件保存到SD卡指定自定义文件夹而非应用专属目录
Got it, let's break down how to save files directly to a custom folder like /storage/9016-4EF8/MyFolder on your SD card—since the default getExternalFilesDir() locks you into the app-specific Android/data directory, we need to work within Android's storage rules based on the OS version.
Android 9 (API 28) and Below
On older Android versions, you can directly access the SD card root directory with standard storage permissions:
- Add permissions to your Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- Request dynamic permissions (for API 23+):
You'll need to prompt the user to grant storage access at runtime (since Android 6.0, dangerous permissions require explicit user approval). - Create the custom folder and write files:
// First, check if the SD card is mounted and writable String sdCardPath = Environment.getExternalStorageDirectory().getAbsolutePath(); File myFolder = new File(sdCardPath, "MyFolder"); // Create the folder if it doesn't exist if (!myFolder.exists()) { boolean folderCreated = myFolder.mkdirs(); if (!folderCreated) { // Handle folder creation failure (e.g., log error, show toast) return; } } // Create and write to your target file File targetFile = new File(myFolder, "my_file.txt"); try (FileOutputStream fos = new FileOutputStream(targetFile)) { fos.write("Your content here".getBytes()); } catch (IOException e) { e.printStackTrace(); // Handle write error }
Android 10 (API 29)
Android 10 introduced Scoped Storage, which restricts direct access to non-app-specific directories. You have two options here:
Option 1: Temporary Legacy Compatibility (Not Recommended Long-Term)
If your app targets API 28 or lower, you can add this to your AndroidManifest.xml to bypass Scoped Storage temporarily:
<application ... android:requestLegacyExternalStorage="true"> </application>
This lets you use the Android 9 code above, but it's not a permanent solution—Google will phase out this flag for newer API levels.
Option 2: Use Storage Access Framework (SAF) (Recommended)
SAF lets users manually select the target folder, which complies with Scoped Storage rules:
- Launch the folder picker:
private static final int REQUEST_PICK_FOLDER = 100; private void openCustomFolderPicker() { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); // Grant persistent read/write permissions to the selected folder intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); startActivityForResult(intent, REQUEST_PICK_FOLDER); }
- Handle the selected folder and write files:
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_PICK_FOLDER && resultCode == RESULT_OK && data != null) { Uri selectedFolderUri = data.getData(); if (selectedFolderUri != null) { // Persist the permission so you don't need to re-select the folder later getContentResolver().takePersistableUriPermission( selectedFolderUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION ); // Create "MyFolder" inside the selected directory (e.g., SD card root) DocumentFile rootFolder = DocumentFile.fromTreeUri(this, selectedFolderUri); DocumentFile myCustomFolder = rootFolder.findFile("MyFolder"); if (myCustomFolder == null) { myCustomFolder = rootFolder.createDirectory("MyFolder"); } // Create and write to your file DocumentFile targetFile = myCustomFolder.createFile("text/plain", "my_file.txt"); if (targetFile != null) { try (OutputStream os = getContentResolver().openOutputStream(targetFile.getUri())) { os.write("Your content here".getBytes()); } catch (IOException e) { e.printStackTrace(); } } } } }
Android 11 (API 30) and Above
Scoped Storage is enforced more strictly here. The only ways to access custom non-app directories are:
1. Storage Access Framework (SAF) (Most Recommended)
Use the same SAF code as Android 10—this is the most compliant approach and doesn't require special permissions.
2. MANAGE_EXTERNAL_STORAGE Permission (For Specialized Apps Only)
If your app is a file manager, backup tool, or another type that needs broad storage access, you can request this special permission:
- Add to Manifest:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
- Guide users to enable the permission:
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); Uri appUri = Uri.fromParts("package", getPackageName(), null); intent.setData(appUri); startActivity(intent);
Important: Google Play has strict policies for this permission—only apps that meet specific use cases will be approved. Avoid using this unless absolutely necessary.
内容的提问来源于stack exchange,提问作者Young King

