在Android 6上没有返回fileEntry结果 [英] No fileEntry results returned on Android 6

查看:218
本文介绍了在Android 6上没有返回fileEntry结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Cordova应用程序中似乎有文件读取权限问题,但是我无法终生正确地对其进行跟踪.在Android 5和Android 6之间,对于相同的fileEntry调用,我看到的结果完全不同. 有人知道是否需要更改才能在Android> 5中读取文件/目录?

I've got what appears to be a file read permissions issue in my Cordova app, but I can't for the life of me track it down properly. Between Android 5 and Android 6, I'm seeing completely different results to the same calls to fileEntry. Does anyone know whether there are needed changes to be able to read files/directories in Android > 5?

详细信息:我仅用cordova-plugin-file(调用cordova create hello)将代码复制到了helloWorld应用中,并获得了相同的结果.我的更改如下:

Gory details: I copied the code out to a helloWorld app with just cordova-plugin-file (calling cordova create hello), and am getting the same results. My changes are as follows:

我在index.html的正文中添加了一个元素:

I added a single element to the body of index.html:

        <div id="contents"></div>

我还更改了index.js中的stock receiveEvent方法,只是要遍历设备上的各个目录并返回cordova-plugin-file给我的内容:

I also changed the stock receivedEvent method in index.js, just to iterate through the various directories on the device and return what cordova-plugin-file gives me:

receivedEvent: function (id) {
    "use strict";

    var parentElement = document.getElementById(id),
        listeningElement = parentElement.querySelector('.listening'),
        receivedElement = parentElement.querySelector('.received'),
        localURLs    = [
            cordova.file.documentsDirectory,
            cordova.file.externalRootDirectory,
            cordova.file.sharedDirectory,
            cordova.file.syncedDataDirectory
        ],
        DirsRemaining = localURLs.length,
        i,
        contents = "",
        addFileEntry = function (entry) {
            var dirReader = entry.createReader();
            dirReader.readEntries(
                function (entries) {
                    var i;
                    for (i = 0; i < entries.length; i += 1) {
                        if (entries[i].isDirectory === true) {
                            contents += "<h2> Directory: " + entries[i].fullPath + "</h2>";
                            // Recursive -- call back into this subdirectory
                            DirsRemaining += 1;
                            addFileEntry(entries[i]);
                        } else {
                            contents += "<p> File: " + entries[i].fullPath + "</p>";
                        }
                    }
                    DirsRemaining -= 1;
                    if (DirsRemaining <= 0) {
                        if (contents.length > 0) {
                            document.getElementById("contents").innerHTML = contents;
                        } else {
                            // nothing to select -- inform the user
                            document.getElementById("contents").innerHTML = "No documents found";
                        }
                    }
                },
                function (error) {
                    console.log("readEntries error: " + error.code);
                    contents += "<p>readEntries error: " + error.code + "</p>";
                }
            );
        },
        addError = function (error) {
            // log the error and continue processing
            console.log("getDirectory error: " + error.code);
            DirsRemaining -= 1;
        };
    for (i = 0; i < localURLs.length; i += 1) {
        if (localURLs[i] === null || localURLs[i].length === 0) {
            DirsRemaining -= 1;
            continue; // skip blank / non-existent paths for this platform
        }
        window.resolveLocalFileSystemURL(localURLs[i], addFileEntry, addError);
    }

    listeningElement.setAttribute('style', 'display:none;');
    receivedElement.setAttribute('style', 'display:block;');

    console.log('Received Event: ' + id);
}

可能的安全配置:

我的platforms/android/AndroidManifest.xml文件包含适当的权限:

My platforms/android/AndroidManifest.xml file contains the appropriate permissions:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

这是我在index.html中的CSP(仅仅是股票):

Here's my CSP in index.html (it's just the stock one):

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">


以下是结果:

Android5.注意目录和文件(屏幕外还有其他文件)

Android 5. Note directories and a file (there are others offscreen)

Android6.请注意,在cordova.file.externalRootDirectory下的子目录中有一些文件应显示;它也应该显示子目录本身.

Android 6. Note that I have some files in the subdirectories under cordova.file.externalRootDirectory that should be displayed; it should also be displaying the subdirectories themselves.

推荐答案

@greenapps的提示提示-这种行为显然是由于Android 6中引入的运行时权限引起的.

Hat tip to @greenapps for the hint -- this behavior is apparently due to the runtime permissions introduced in Android 6.

对于Cordova,有一个插件可以解决该问题,直到完成cordova-android的清理为止(截至2017年11月6日,PhoneGap Build使用cordova-android 6.2.3,这取决于cordova-plugin-compat来处理有了这个).我目前的解决方法:

For Cordova, there's a plugin that can address the issue until cordova-android is cleaned up a bit (as of 11/6/2017, PhoneGap Build uses cordova-android 6.2.3, which depends on cordova-plugin-compat to deal with this). My fix for now:

cordova plugin add cordova.plugins.diagnostic

然后在例程中添加适当的运行时权限:

Then the routine to add the appropriate runtime permissions:

// request read access to the external storage if we don't have it

cordova.plugins.diagnostic.getExternalStorageAuthorizationStatus(function (status) {
    if (status === cordova.plugins.diagnostic.permissionStatus.GRANTED) {
        console.log("External storage use is authorized");
    } else {
        cordova.plugins.diagnostic.requestExternalStorageAuthorization(function (result) {
           console.log("Authorization request for external storage use was " + (result === cordova.plugins.diagnostic.permissionStatus.GRANTED ? "granted" : "denied"));
       }, function (error) {
           console.error(error);
       });
   }
}, function (error) {
   console.error("The following error occurred: " + error);
});

这篇关于在Android 6上没有返回fileEntry结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆