使用Cordova在Android虚拟外部存储写入文件遇错误求助
Hey there! Let's figure out why you're hitting error codes 5 or 9 when trying to write files to BitWebServer's www directory (that virtual SD card location) with Cordova. I’ve tackled this exact scenario before, so let’s break down the fixes step by step:
- Error 5 (
PERMISSION_DENIED): This means your app doesn’t have the right access permissions to write to that directory. It’s the most common culprit here. - Error 9 (
INVALID_PATH): Cordova can’t recognize the path you’re targeting—either it’s wrong, or the directory doesn’t exist (or isn’t accessible).
1. Fix Permission Configurations
Cordova needs explicit storage permissions, especially on Android 10+ (API 29) where storage rules changed:
- Add these permissions to your
config.xmlto ensure they’re included in the Android manifest:<platform name="android"> <config-file parent="/manifest" target="AndroidManifest.xml"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- For Android 13+, add these media-specific permissions too --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> </config-file> </platform> - Don’t just rely on config—request permissions actively in your code before trying to write files:
document.addEventListener("deviceready", onDeviceReady, false); function onDeviceReady() { // Request storage permissions first cordova.plugins.permissions.requestPermissions( [cordova.plugins.permissions.WRITE_EXTERNAL_STORAGE, cordova.plugins.permissions.READ_EXTERNAL_STORAGE], function(status) { if (status.hasPermission) { // Permissions granted—proceed with file write writeToBitWebServerDir(); } else { console.error("Storage permissions denied!"); } }, function(error) { console.error("Error requesting permissions: ", error); } ); }
2. Verify the Target Path is Correct
Error 9 almost always comes from a bad path. BitWebServer’s www directory is usually at /storage/emulated/0/bitwebserver/www/, but don’t hardcode it—use Cordova’s built-in path constants to avoid device-specific issues:
- Use
cordova.file.externalRootDirectoryto get the external storage root, then build the path dynamically:function writeToBitWebServerDir() { const externalRoot = cordova.file.externalRootDirectory; const targetDir = externalRoot + "bitwebserver/www/"; const fileName = "test_file.txt"; const fileContent = "Hello from Cordova!"; // First check if the directory exists; create it if not window.resolveLocalFileSystemURL(targetDir, function(dir) { // Directory exists—create/write the file dir.getFile(fileName, {create: true, exclusive: false}, function(file) { file.createWriter(function(writer) { writer.onwriteend = () => console.log("File written successfully!"); writer.onerror = (e) => console.error("Write failed: ", e); const blob = new Blob([fileContent], {type: 'text/plain'}); writer.write(blob); }, err => console.error("Failed to create writer: ", err)); }, err => console.error("Failed to access file: ", err)); }, function() { // Directory doesn't exist—create it first window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) { fs.root.getDirectory(targetDir, {create: true, exclusive: false}, function(newDir) { // Now create the file in the new directory newDir.getFile(fileName, {create: true, exclusive: false}, function(file) { // Repeat the write logic here file.createWriter(function(writer) { writer.onwriteend = () => console.log("File written after creating directory!"); writer.onerror = (e) => console.error("Write failed: ", e); const blob = new Blob([fileContent], {type: 'text/plain'}); writer.write(blob); }, err => console.error("Failed to create writer: ", err)); }, err => console.error("Failed to access file post-directory-creation: ", err)); }, err => console.error("Failed to create directory: ", err)); }, err => console.error("Failed to access file system: ", err)); }); }
3. Adapt to Android 10+ Scoped Storage
Android 10 (API 29) introduced Scoped Storage, which restricts direct access to external storage by default. To get around this for BitWebServer’s directory:
- Add
android:requestLegacyExternalStorage="true"to yourAndroidManifest.xmlunder the<application>tag to use the old storage model (a quick fix for compatibility):<application android:requestLegacyExternalStorage="true" ...> <!-- Your other app config --> </application> - Note: For Android 11+, you could use the
MANAGE_EXTERNAL_STORAGEpermission, but this requires users to manually enable it in settings and is heavily scrutinized by Google Play—only use it if your app is a file manager.
4. Check BitWebServer’s Directory Permissions
BitWebServer might set restrictive permissions on its www directory, preventing other apps from writing to it:
- Use your Android file manager to navigate to
/storage/emulated/0/bitwebserver/, long-press thewwwfolder, and check its permissions—ensure "Write" access is enabled for other apps. - Or use adb to verify permissions:
Look for permissions likeadb shell ls -l /storage/emulated/0/bitwebserver/drwxrwxrwx(read/write/execute for all users)—if it’s anything less, you’ll need to adjust the directory’s permissions (either via the file manager or adb).
- Double-check that storage permissions are enabled for your app in Android’s Settings > Apps > [Your App] > Permissions.
- Test with a simple text file first to rule out complex content issues.
- Use
console.logto print the full target path before writing—make sure it matches the actual location of BitWebServer’s www directory.
内容的提问来源于stack exchange,提问作者Disco Fever

