You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Cordova Android应用中写入系统根目录而非应用数据目录?

如何在Cordova Android应用中写入系统公共目录(如Downloads)

嘿,我之前开发Cordova Android应用时也碰到过这个问题——默认的Persistent存储确实会把文件放到应用私有数据目录里,要写到系统级的公共目录(比如Downloads、Notifications)得换个思路来搞,下面给你一步步拆解可行的方案:

核心思路:切换到外部公共存储路径

cordova-plugin-file提供了一系列预定义的路径常量,对应Android的不同存储区域。要访问系统公共目录,我们需要用到cordova.file.externalRootDirectory(对应/storage/emulated/0/),然后拼接具体的子目录(比如Download/)。

步骤1:配置权限与兼容设置

1.1 添加必要权限

config.xml里添加相关权限配置,确保应用能访问外部存储:

<platform name="android">
    <!-- 针对Android 9及以下版本的读写权限 -->
    <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" />
    </config-file>
    <!-- 针对Android 10+的兼容设置(暂时适配旧存储逻辑) -->
    <config-file parent="/manifest/application" target="AndroidManifest.xml">
        <application android:requestLegacyExternalStorage="true" />
    </config-file>
    <!-- Android 13+细分权限示例(按需添加) -->
    <config-file parent="/manifest" target="AndroidManifest.xml">
        <uses-permission android:name="android.permission.WRITE_MEDIA_IMAGES" />
    </config-file>
</platform>

1.2 请求动态权限

Android 6+需要动态申请权限,你可以用cordova-plugin-android-permissions插件来处理:

cordova plugin add cordova-plugin-android-permissions

然后在代码里先请求权限,再执行文件写入操作:

var permissions = cordova.plugins.permissions;
permissions.checkPermission(permissions.WRITE_EXTERNAL_STORAGE, function(status) {
    if (status.hasPermission) {
        // 权限已获取,执行文件写入
        writeToDownloads();
    } else {
        // 请求权限
        permissions.requestPermission(permissions.WRITE_EXTERNAL_STORAGE, function(status) {
            status.hasPermission ? writeToDownloads() : console.error("写入权限被拒绝");
        }, function(error) {
            console.error("权限请求出错:", error);
        });
    }
}, function(error) {
    console.error("权限检查出错:", error);
});

步骤2:写入Downloads目录的代码实现

我们用resolveLocalFileSystemURL直接访问公共目录,而非默认指向私有存储的requestFileSystem

function writeToDownloads() {
    // 拼接Downloads目录的完整路径(也可用cordova.file.externalPublicDirectory('Download')获取标准化路径)
    var downloadsPath = cordova.file.externalRootDirectory + 'Download/';
    
    // 解析Downloads目录的FileEntry
    window.resolveLocalFileSystemURL(downloadsPath, function(dirEntry) {
        console.log('访问Downloads目录成功:' + dirEntry.fullPath);
        
        // 在Downloads目录下创建文件
        dirEntry.getFile("newPersistentFile.txt", { create: true, exclusive: false }, function(fileEntry) {
            console.log("文件创建成功:" + fileEntry.fullPath);
            // 调用你的写入函数
            writeFile(fileEntry, "自定义写入内容");
        }, onErrorCreateFile);
    }, function(error) {
        console.error("访问Downloads目录失败:", error);
    });
}

// 复用你的writeFile函数(可按需修改)
function writeFile(fileEntry, dataObj) {
    fileEntry.createWriter(function(fileWriter) {
        fileWriter.onwriteend = () => console.log("文件写入完成");
        fileWriter.onerror = e => console.log("写入失败:" + e.toString());
        
        // 处理空数据的默认情况
        if (!dataObj) {
            dataObj = new Blob(["默认测试内容"], { type: 'text/plain' });
        }
        fileWriter.write(dataObj);
    });
}

// 错误处理函数
function onErrorCreateFile(error) {
    console.error("创建文件出错:", error);
}

关于Notifications目录的说明

如果要写入Notifications目录,逻辑完全一致,只需调整路径即可。若目录不存在,需先创建:

// 检查并创建Notifications目录
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, function(rootDir) {
    rootDir.getDirectory("Notifications", { create: true, exclusive: false }, function(notifDir) {
        // 在Notifications目录下创建文件
        notifDir.getFile("notificationLog.txt", { create: true }, function(fileEntry) {
            writeFile(fileEntry, "通知相关日志内容");
        }, onErrorCreateFile);
    }, function(error) {
        console.error("创建Notifications目录失败:", error);
    });
}, function(error) {
    console.error("访问外部根目录失败:", error);
});

注意事项

  • Android 10+ Scoped Storage:若应用目标API≥30,requestLegacyExternalStorage会失效,此时需改用MediaStore API写入公共目录,cordova-plugin-file已支持相关操作,可参考插件文档配置。
  • 目录兼容性:部分设备公共目录名称可能有差异(如中文设备的下载),使用cordova.file.externalPublicDirectory('Download')可获取系统标准化路径,提升兼容性。

内容的提问来源于stack exchange,提问作者Joey Yi Zhao

火山引擎 最新活动