cordova-plugin-file
cordova-plugin-file copied to clipboard
Not seeing files that are stored on the Android device
The issue has been described in this question: https://stackoverflow.com/questions/42490558/not-seeing-files-that-are-store-on-the-android-device-using-cordova-file-plugin
I'm facing the same issue and was only able to solve it by downgrading to Android API 22 as the author in the Stackoverflow question did.
When looping through all directories on the phone, it will only see files in the directory where the app is stored, but not files stored for example in the download folder of the SD Card.
This is my function:
var localURLs = [
this.file.cacheDirectory,
this.file.applicationDirectory,
this.file.applicationStorageDirectory,
this.file.dataDirectory,
this.file.documentsDirectory,
this.file.externalApplicationStorageDirectory,
this.file.externalCacheDirectory,
this.file.externalRootDirectory,
this.file.externalDataDirectory,
this.file.sharedDirectory,
this.file.syncedDataDirectory
];
loopThroughDirectories(localURLs, function(){
});
function loopThroughDirectories(localURLs, callback) {
for (i = 0; i < localURLs.length; i++) {
console.log("directory: " + localURLs[i]);
if(i == (localURLs.length - 1))
{
loading.dismiss();
callback();
}
if (localURLs[i] === null || localURLs[i].length === 0) {
continue; // skip blank / non-existent paths for this platform
}
window.resolveLocalFileSystemURL(localURLs[i], addFileEntry, addError);
}
}
var that = this;
var addFileEntry = function (entry) {
console.log("addFileEntry");
var dirReader = entry.createReader();
dirReader.readEntries(
function (entries) {
console.log("nr of entries: " + entries.length);
var i;
for (i = 0; i < entries.length; i++) {
console.log(entries[i].fullPath);
if (entries[i].isDirectory === true) {
// Recursive -- call back into this subdirectory
addFileEntry(entries[i]);
} else {
if(entries[i].fullPath.endsWith(".apkg") && entries[i].fullPath.search("/AnkiDroid/") == -1)
{
console.log(i + ": " + entries[i].fullPath);
that.arrFiles.push({nr: i, fullPath: entries[i].fullPath, nativeURL: entries[i].nativeURL});
}
}
}
},
function (error) {
console.error("readEntries error: " + error.code);
}
);
};
var addError = function (error) {
console.error("getDirectory error: " + error.code);
};
It's used in this project for finding all files on a phone with the apkg extension: https://github.com/phil4literacy/TeachMeWords
So API level <= 22 could see all files, API level >22 can only see application files?
Yes, mostly. For example with API 28 it found files here: file:///storage/emulated/0/Android/data/com.sil.teachmewords/files/
and also under the plugin folders:
/www/plugins/cordova-plugin-zip/ /www/plugins/cordova-plugin-file/www/browser/
but none under any of the folders that are not related to the app, e.g. /Download
BTW, new apps created with API 22 are no longer allowed to be uploaded to Google Play, so I'm currently stuck...
I am having the same issue.. Did you find a solution?
@premtemp1 : Sadly no. Still waiting and hoping somebody will work on fixing this. Looks like the plugin has been abandoned though, as if people no longer use files but do everything in the cloud... But apparently I'm not the only one who needs access to the filesystem.
It has not been abandoned, there is just a pretty massive backlog of stuff in general regarding Cordova core plugins that has to be taken care of. I am currently working through all the testing issues for example: https://github.com/apache/cordova/issues/28
@janpio : That's good to know. Thanks for all your hard work!
8.1.2 ([email protected]), API level 27 android 5.0 is OK. android 8.1 dirReader.readEntries is not seeing files in directory.
Hey all, has there been any movement on this? 6 months later I can confirm this is still an issue. I need to be able to access users files on both iOS and android, but I also need the ability to restrict by mime types and choose whether multi-select is enabled or not, depending on the scenario. There seems to be a lack of plugins that are able to do this, file-chooser and file-picker both seem to be limited to one file at a time. I have written a component in Ionic but obviously I need the android users folders to be accessible to be able to use it. Any information or work around to gain access to file.externalRootDirectory would be massively appreciated.
Thanks Marc
Edit: Looking into this further it is a permissions issue. If I also install the camera plugin and approve it's permissions to take a photo, I can then use my file manager component to access file.externalRootDirectory.
Hi everybody,
Any news? I have exactly the same problem. I'm programming an hybrid Ionic 3 app, that works perfectly except in Android 9.0(API Level 28) that asks for permissions (and I accept) but when I try to access local files, the device returns no folders. In Android 8 and less there is no problem. I use cordova-file.
I will much appreciate if anyone could answer me.
Thanks in advance.
Yours faithfully,
GSDiama
`
cordova info
Collecting Data...
Node version: v8.11.3
Cordova version: 8.0.0
Config.xml file:
<widget android-versionCode="20003" id="com.XXXXXX.YYYYYYYY" version="2.0.0"
xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0
">
<icon height="50" src="resources/ios/icon/icon-50.png" width="50" />
<icon height="100" src="resources/ios/icon/[email protected]" width="100" /
<icon height="60" src="resources/ios/icon/icon-60.png" width="60" />
<icon height="120" src="resources/ios/icon/[email protected]" width="120" /
<icon height="180" src="resources/ios/icon/[email protected]" width="180" /
<icon height="72" src="resources/ios/icon/icon-72.png" width="72" />
<icon height="144" src="resources/ios/icon/[email protected]" width="144" /
<icon height="76" src="resources/ios/icon/icon-76.png" width="76" />
<icon height="152" src="resources/ios/icon/[email protected]" width="152" /
<icon height="167" src="resources/ios/icon/[email protected]" width="167"
/>
Plugins:
cordova-android-support-gradle-release,cordova-plugin-actionsheet,cordova-plugin -camera,cordova-plugin-device,cordova-plugin-fcm,cordova-plugin-file,cordova-plu gin-file-opener2,cordova-plugin-file-transfer,cordova-plugin-ionic-webview,cordo va-plugin-network-information,cordova-plugin-splashscreen,cordova-plugin-whiteli st,cordova-sqlite-storage,ionic-plugin-keyboard
Android platform:
Available Android targets:
id: 1 or "android-23" Name: Android 6.0 Type: Platform API level: 23 Revision: 3 Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, W XGA720, WXGA800, WXGA800-7in Tag/ABIs : no ABIs.
id: 2 or "android-24" Name: Android 7.0 Type: Platform API level: 24 Revision: 2 Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, W XGA720, WXGA800, WXGA800-7in Tag/ABIs : android-tv/x86, default/x86, default/x86_64
id: 3 or "android-25" Name: Android 7.1.1 Type: Platform API level: 25 Revision: 3 Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, W XGA720, WXGA800, WXGA800-7in Tag/ABIs : no ABIs.
id: 4 or "android-26" Name: Android 8.0.0 Type: Platform API level: 26 Revision: 2 Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, W XGA720, WXGA800, WXGA800-7in Tag/ABIs : no ABIs.
id: 5 or "android-27" Name: Android 8.1.0 Type: Platform API level: 27 Revision: 3 Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, W XGA720, WXGA800, WXGA800-7in Tag/ABIs : no ABIs.
id: 6 or "android-28" Name: Android 9 Type: Platform API level: 28 Revision: 6 Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, W XGA720, WXGA800, WXGA800-7in, AndroidWearRound, AndroidWearRound360x360, Android WearRound390x390, AndroidWearRound400x400, AndroidWearRound454x454, AndroidWearR ound480x480, AndroidWearRoundChin320x290, AndroidWearRoundChin320x300, AndroidWe arRoundChin360x325, AndroidWearRoundChin360x326, AndroidWearRoundChin360x330, An droidWearSquare, AndroidWearSquare240x240, AndroidWearSquare320x320 Tag/ABIs : android-wear/x86, google_apis_playstore/x86, google_apis_playstore/x 86_64
id: 7 or "android-Q" Name: Android 10 (Preview) Type: Platform API level: Q Revision: 3 Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, W XGA720, WXGA800, WXGA800-7in Tag/ABIs : google_apis_playstore/x86, google_apis_playstore/x86_64
ionic info
Ionic:
ionic (Ionic CLI) : 4.12.0 (C:\Users\jc\AppData\Roaming\npm\node_mod ules\ionic) Ionic Framework : ionic-angular 3.9.2 @ionic/app-scripts : 3.0.1
Cordova:
cordova (Cordova CLI) : not installed Cordova Platforms : android 6.4.0 Cordova Plugins : not available
System:
(C:\Program Files (x86)\Android\android-sdk) NodeJS : v8.11.3 (C:\Program Files\nodejs\node.exe) npm : 6.4.1 OS : Windows 7`
I think I have got this working in initial testing.
I added
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
to the AndroidManifest.xml. I also added the cordova-plugin-android-permissions aswell. So I am not completely sure which one might have made it work.
I can now see the Downloads off of cordova.file.externalRootDirectory and when doing 'file:///sdcard' (device root internal directory for shared files) I can now see everything.
I am using API level 26 currently. I added a view from Chrome remote console.
It looks like the cordova-pluging-android-permissions is doing something the Manifest.xml is not checking for. I removed the permissions from the Manifest and did the checking via the pluging, everything works now.
@fragatak how did you do the checking via the plugin. I am currently trying to store an image file as shown in the documentation, but like everyone else I am unable to locate the files created (as the code shows no error, i assume the works)
@Zi1989 did you find anything? The permissions plugin says that is has the PERMISSION.READ_EXTERNAL_STORAGE
This is the code that is used with the app first starts up to check permission.
`function androidPermissions() { let permissions = cordova.plugins.permissions; let list = [ permissions.WRITE_EXTERNAL_STORAGE, permissions.READ_EXTERNAL_STORAGE ];
function error() {
console.warn('External Read or Write permission is not turned on');
}
permissions.checkPermission(list, function (status) {
if (!status.hasPermission) {
permissions.requestPermissions(
list,
function(status) {
if (!status.hasPermission) error();
},
error
);
}
}, null);
}
document.addEventListener("deviceready", androidPermissions, null);`
Just adding to the manifest.xml wasn't working so I ended up checking and requesting it directly for the user through the plugin.
and to read
`function Fail(evt) { console.log(evt.target.error.code); }
function error(e)
{
console.error("error in " + e);
}
function readConfig(entry)
{
entry.file((file) =>
{
var reader = new FileReader();
reader.onloadend = () =>
{
// do whatever you need to do for reading the file.
};
reader.readAsText(file);
}, () =>
{
console.error("error loading config file.")
});
}
let cordova = window.cordova || null;
if (cordova)
{
document.addEventListener("deviceready", () =>
{
window.requestFileSystem(1, 0, null, Fail);
window.resolveLocalFileSystemURL('file:///sdcard/{whatever file here]', readConfig.bind(this), error);
});
}`
You might have to startup android studio to see how the local file system looks for you.
@fragatak thanks! I've the permissions for the storage, but the file content is just "null". Do you have any idea?
With Android's Scoped Storage model (enforced in API 30 and later), the external storage is no longer discoverable. Some directories are simply not readable (they will give a File not Found error, even if they do exists, such as the externalRootDirectory
), and other directories will only list files that have been created by your app, but not files created by other apps.
Closing as not a bug.