Android写入外部存储报错net::ERR_ACCESS_DENIED,权限配置存疑
Hey there! That net::ERR_ACCESS_DENIED error when trying to access your text file is super common with Android's storage changes over the years—let's break down what's going wrong and how to fix it.
1. Address Android 10+ Scoped Storage Restrictions
Starting with Android 10 (API level 29), Google introduced Scoped Storage, which blocks direct access to arbitrary folders in external storage (like storage/emulated/0/Notifications/TestFolder/) even if you have the old WRITE_EXTERNAL_STORAGE permission.
Fix Options:
Option A: Use App-Specific Directories (Recommended)
For non-media files, the safest approach is to use your app's dedicated external storage folder—no special permissions required, and files are cleaned up when your app is uninstalled:// Get the app-specific external directory File appDir = new File(getExternalFilesDir(null), "TestFolder"); if (!appDir.exists()) { appDir.mkdirs(); } File testFile = new File(appDir, "test.txt"); // Now write to testFile without permission headachesOption B: Opt Out of Scoped Storage (Legacy Only)
If you absolutely need to access that specificNotifications/TestFolderpath (not recommended for new apps), add this to yourAndroidManifest.xmlunder the<application>tag (works for API 29-32 only):android:requestLegacyExternalStorage="true"Note: This won't work on Android 13+ for most public folders, and Google discourages this long-term.
2. Verify Runtime Permission Requests
Even if you've declared permissions in the manifest, Android 6.0 (API 23+) requires you to request them dynamically at runtime.
Step 1: Declare Permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- For Android 13+, use media-specific permissions if needed: --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
Step 2: Request Permissions Before Writing
Add this code to check and request permissions when the button is clicked:
private static final int STORAGE_PERMISSION_REQUEST = 1; private void checkAndWriteFile() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST); } else { // Permission granted—proceed to write writeToTargetFile(); } } // Handle permission request result @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == STORAGE_PERMISSION_REQUEST) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { writeToTargetFile(); } else { Toast.makeText(this, "Storage permission is required to save the file", Toast.LENGTH_SHORT).show(); } } }
3. Ensure the Target Folder Exists
Even with permissions, writing will fail if the Notifications/TestFolder directory doesn't exist. Add this check before writing:
private void writeToTargetFile() { File targetDir = new File(Environment.getExternalStorageDirectory(), "Notifications/TestFolder"); if (!targetDir.exists()) { boolean folderCreated = targetDir.mkdirs(); if (!folderCreated) { Toast.makeText(this, "Failed to create target directory", Toast.LENGTH_SHORT).show(); return; } } File testFile = new File(targetDir, "test.txt"); // Proceed to write content to testFile }
4. Fix WebView File Access Issues
If you're loading the file in a WebView, using file:// URLs can trigger security blocks. Instead, read the file content and load it directly:
// Read file content into a string String fileContent = new String(Files.readAllBytes(testFile.toPath())); // Load content into WebView webView.loadData(fileContent, "text/plain", "UTF-8");
Sticking with app-specific directories is the most reliable long-term solution—it avoids permission friction and aligns with Google's modern storage guidelines.
内容的提问来源于stack exchange,提问作者Kunal Shah

