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

后端 未结 1 492
无人共我
无人共我 2020-11-30 10:25

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

相关标签:
1条回答
  • 2020-11-30 11:12

    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);
        });
    }
    
    0 讨论(0)
提交回复
热议问题