You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cordova应用升级Android API 26后存储权限失效问题排查

问题分析与解决方案

我帮你排查了代码里的几个关键问题,这应该就是权限弹窗不出现、文件复制失效的核心原因:

1. 权限请求的错误回调写法错误

你在Permission.has和Permission.request的错误回调里直接写了alert("permission failed"),这会导致代码执行到这里时立刻弹出提示,而不是在权限请求失败时才触发回调。正确的写法应该是传递一个函数,而不是直接执行alert语句。

2. 文件复制操作没有等待权限申请完成

asset2sd.copyDir是在权限请求还没完成的时候就执行了——权限请求是异步操作,这时候应用还没拿到存储权限,所以复制逻辑会直接失败。你需要把文件复制的代码放到权限申请成功的回调里,确保只有拿到权限后才执行复制。

3. 权限判断后的逻辑顺序混乱

你的代码里,在Permission.has判断没有权限后,执行请求,但之后立刻弹出了alert("permission granted failed"),这会不管用户是否同意权限都弹出这个提示,逻辑顺序完全错误。


修正后的完整代码

var app = {
    // Application Constructor
    initialize: function() {
        this.bindEvents();
    },
    // Bind Event Listeners
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    //deviceready Event Handler
    onDeviceReady: function() {
        app.receivedEvent('deviceready');
        // **修正后的权限处理代码**
        var Permission = cordova.plugins.Permission;
        var storagePermission = 'android.permission.WRITE_EXTERNAL_STORAGE';

        // 先检查是否已有存储权限
        Permission.has(storagePermission, function(results){
            if(results[storagePermission]) {
                // 已有权限,直接执行文件复制
                app.copyPdfFiles();
            } else {
                // 无权限,发起权限申请
                Permission.request(storagePermission, function(results){
                    if(results[storagePermission]){
                        alert("权限已授予");
                        // 权限申请成功后执行文件复制
                        app.copyPdfFiles();
                    } else {
                        alert("权限申请失败,无法完成文件复制");
                    }
                }, function() {
                    alert("权限请求过程中出错");
                });
            }
        }, function() {
            alert("权限状态检查出错");
        });
    },

    // 封装文件复制逻辑,便于复用
    copyPdfFiles: function() {
        asset2sd.copyDir({
            asset_directory: "www/pdf",
            destination_directory: "crisispdf",
        }, function () {
            alert('文件复制成功');
        }, function () {
            alert('文件复制失败');
        });
    },

    // Update DOM on a Received Event
    receivedEvent: function(id) {
        var parentElement = document.getElementById(id);
        var listeningElement = parentElement.querySelector('.listening');
        var receivedElement = parentElement.querySelector('.received');
        console.log('Received Event: ' + id);
    }
};
app.initialize();

额外注意事项

  • 确认cordova-plugin-permission插件是否正确安装,可执行cordova plugin list查看插件状态。如果该插件存在兼容性问题,建议改用更主流的cordova-plugin-android-permissions(用法类似,维护更活跃)。
  • 检查asset2sd插件是否适配Android 6.0+的运行时权限机制,确保它不会在无权限时直接报错。
  • 你的AndroidManifest中targetSdkVersion是27,但config.xml里的权限设置了maxSdkVersion="26",建议移除maxSdkVersion属性,避免权限在更高版本系统上失效。

内容的提问来源于stack exchange,提问作者Pravin Maske

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:57:36