如何在PhoneGap将看到的android目录中获取文档

时间:2015-04-16 14:43:07

标签: android cordova cordova-plugins

我希望能够将一些文件复制到我的PhoneGap / Cordova的Documents目录中,以便在我使用cordova-plugin-file API列出该目录时显示它们。不幸的是,文件API与平板电脑存储上实际存在的内容之间似乎存在一些脱节。以下是File插件规范所说的系统目录结构应如下所示:

Android文件系统布局

  • file:///android_asset/ | cordova.file.applicationDirectory
  • file:///android_asset/data/data/<app-id>/ | cordova.file.applicationStorageDirectory
  • file:///android_asset/data/data/<app-id>/cache | cordova.file.cacheDirectory
  • file:///android_asset/data/data/<app-id>/files | cordova.file.dataDirectory
  • file:///android_asset/data/data/<app-id>/Documents | cordova.file.documents
  • <sdcard>/ | cordova.file.externalRootDirectory
  • <sdcard>/Android/data/<app-id>/ | cordova.file.externalApplicationStorageDirectory
  • <sdcard>/Android/data/<app-id>/cache | cordova.file.externalCacheDirectry
  • <sdcard>/Android/data/<app-id>/files | cordova.file.externalDataDirectory

不幸的是,当我将设备(4.4.2 /联想平板电脑)插入我的电脑或Mac时,我没有看到这一点。相反,我看到了:

- Internal Storage
|- .IdeaDesktopHD
|- .lelauncher
|- .magic
|- .powercenterhd
|- Alarms
|- Android
|- Audio
|- Bluetooth
|- Contact
|- data
|- DCIM
|- Document
|- Download
|- googleota
|- legc
|- LenovoReaper
|- LesyncDownload
|- Movies
|- MyFavorite
|- Notifications
|- Others
|- Pictures
|- Podcasts
|- powercenterhd
|- Ringtones
|- SHAREit

知道我应该在哪里复制文件以便我的应用可以看到它们吗?

2 个答案:

答案 0 :(得分:10)

现在好吧。我的部分问题是我对cordova上的filesystem / cordova-plugin-file API的异步性质有所了解。我不得不做一些代码重构以使文件列表正确显示,但是一旦我这样做,文件就会正常显示,无论它们在设备上的位置如何。

以下是适用的代码。请注意,您需要将cordova-plugin文件添加到Cordova / PhoneGap项目中,并且它不能在浏览器中工作。我实际上在另一个if / then块中有这个块 - 如果它在浏览器中运行,则显示html5 <input type=file>,如果它在移动设备中,则显示此块:

var localURLs    = [
    cordova.file.dataDirectory,
    cordova.file.documentsDirectory,
    cordova.file.externalApplicationStorageDirectory,
    cordova.file.externalCacheDirectory,
    cordova.file.externalRootDirectory,
    cordova.file.externalDataDirectory,
    cordova.file.sharedDirectory,
    cordova.file.syncedDataDirectory
];
var index = 0;
var i;
var statusStr = "";
var addFileEntry = function (entry) {
    var dirReader = entry.createReader();
    dirReader.readEntries(
        function (entries) {
            var fileStr = "";
            var i;
            for (i = 0; i < entries.length; i++) {
                if (entries[i].isDirectory === true) {
                    // Recursive -- call back into this subdirectory
                    addFileEntry(entries[i]);
                } else {
                   fileStr += (entries[i].fullPath + "<br>"); // << replace with something useful
                   index++;
                }
            }
            // add this directory's contents to the status
            statusStr += fileStr;
            // display the file list in #results
            if (statusStr.length > 0) {
                $("#results").html(statusStr);
            } 
        },
        function (error) {
            console.log("readEntries error: " + error.code);
            statusStr += "<p>readEntries error: " + error.code + "</p>";
        }
    );
};
var addError = function (error) {
    console.log("getDirectory error: " + error.code);
    statusStr += "<p>getDirectory error: " + error.code + ", " + error.message + "</p>";
};
for (i = 0; i < localURLs.length; i++) {
    if (localURLs[i] === null || localURLs[i].length === 0) {
        continue; // skip blank / non-existent paths for this platform
    }
    window.resolveLocalFileSystemURL(localURLs[i], addFileEntry, addError);
}

编辑(2018年2月)即使您可以在Android文件传输上看到文件,也可能无法以编程方式返回任何结果,即使您在Cordova应用程序中设置了构建时间权限。这是由于添加到Android的运行时权限检查(我相信&gt; 6.0)。有几个插件可以帮助解决这个问题;在某些时候,我猜测文件插件也会为它添加自动请求。以下是我在Cordova cli-7.0.1所做的事情:

在config.xml中,设置所需的应用程序权限。您需要READ_EXTERNAL_STORAGE(如果您打算这样做,也要写。)我还添加了下面引用的两个插件:

<plugin name="cordova-plugin-device" source="npm" spec="1.1.6" />
<plugin name="cordova.plugins.diagnostic" spec="^3.7.1" />

<config-file platform="android" parent="/manifest" mode="replace">
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</config-file>

然后,最好在应用程序的启动代码中的某个位置(即设备就绪事件的处理程序),检查运行时权限并在需要时添加它们:

if (device.platform === "Android") {
    // 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);
    });
}

答案 1 :(得分:1)

scan : function(url,fileType,callback)
        {
             var fileTypeCollection = [];
             var defer = $q.defer();


                url.forEach(function(element, index) 
                {
                //requestLocalFileSystemURL
                log(element);
                window.resolveLocalFileSystemURL(element,onRequestFileSystem, fail);


                log("Ends resolve");
                });


            function onRequestFileSystem(fileSystem) 
            {
                var directoryReader = fileSystem.createReader();
                directoryReader.readEntries(onReadEntries,fail);
            } /*onRequestFile Ends*/

            function onReadEntries(entries) 
            {


                if(entries.length==0)
                {
                     log("Entries Length....Resolving");
                     defer.resolve(fileTypeCollection);
                }
                else
                {   
                    entries.forEach( function(element, index) 
                    {

                        if (element.isDirectory === true) 
                        {
                        // Recursive -- call back into this subdirectory

                         onRequestFileSystem(element);
                        } 

                        if(element.isFile == true) 
                        {

                                fileType.forEach(function(type)
                                {
                                    if(element.name.indexOf(type) != -1)
                                    {
                                        fileTypeCollection.push(element);
                                    }
                                }); 
                        } /*is File ENds*/
                    });  /*Entries For Each Ends*/
                }   

            }  /*OnRead Ends*/

            function fail(resp)
            {
                log(resp);
                defer.reject();
            }  /*Fail Ends*/

        return defer.promise;

    }  //Scan Function Ends

我对Angularjs有这个。但是我遇到了这个问题。如果你运行这个,你会发现当我调用它时,输出会被多次重新提出,但是承诺似乎无法正常工作。但它适用于回调,但直到会返回多次,并且无法知道完整的文件遍历何时完成。