How to get documents in an android directory that PhoneGap will see

人走茶凉 提交于 2019-11-26 12:46:30

问题


I\'d like to be able to copy some files into my PhoneGap / Cordova\'s Documents directory, so that they show up when I use the cordova-plugin-file API to list that directory. Unfortunately, there seems to be some disconnect between the file API and what\'s actually laid out on the tablet\'s storage. Here\'s what the File plugin spec says the system directory structure should look like:

Android File System Layout

  • 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

Unfortunately, I\'m not seeing this when I plug my device (4.4.2 / Lenovo tablet) into my PC or Mac. Instead, I see:

- 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

Any idea where I should be copying the files so that my app can see them?


回答1:


Well now. Part of my problem was that I got bit by the asynchronous nature of the filesystem / cordova-plugin-file API on cordova. I had to do some code refactoring to get the file list to show up properly, but once I did, the files displayed properly regardless of where they were on the device.

Here's the applicable code. Note that you'll need the cordova-plugin-file added to your Cordova/PhoneGap project, and that it won't work in the browser. I actually have this block inside another if/then block -- if it's running in a browser, show the html5 <input type=file>, if it's in a mobile device, show this block:

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);
}

EDIT (Feb 2018): even if you can see the files on Android File Transfer, you might not get any results back programmatically, even if you have build time permissions set in your Cordova app. This is due to runtime permission checks added to Android (I believe > 6.0). There are a couple plugins that can help get around this; at some point, I'm guessing the file plugin will add automatic requests for it as well. Here's what I've done as of Cordova cli-7.0.1:

In your config.xml, set the needed app permissions. You'll need READ_EXTERNAL_STORAGE (and write as well, if you are going to do that). I'm also adding two plugins that are referenced below:

<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>

Then, preferably somewhere in your app's startup code (i.e., the handler for the device ready event), check for the runtime permissions and add them if needed:

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);
    });
}


来源:https://stackoverflow.com/questions/29678186/how-to-get-documents-in-an-android-directory-that-phonegap-will-see

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!