Is it possible to list the files inside the www PhoneGap folder? And recursively?
I need it because I would like to preload all the images inside it.
The official documentation for working with files in phonegap can be rather hard to get started with.
Here's a working example of listing the files in a folder other than the root (in this case one called Downloads).
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) {
fileSystem.root.getDirectory("Downloads", {
create: true
}, function(directory) {
var directoryReader = directory.createReader();
directoryReader.readEntries(function(entries) {
var i;
for (i=0; i<entries.length; i++) {
log(entries[i].name);
}
}, function (error) {
alert(error.code);
});
} );
}, function(error) {
alert("can't even get the file system: " + error.code);
});
Note this will give you a directory in the writable area (Documents on iOS, sdcard on Android, so may not help that much).
here's a PhoneGap app that does just that, even if written for BlackBerry, the jscript/html code is the same and should work in your iOS app as well.
Hope this helps
Related
I know this is a very old issue but honestly I did not find a single complete piece of code for dropzonejs which is working as described.
I am trying to implement dropzonejs for file uploading. What I need is upload file to the server when it is dragged, and remove the file from the server when Remove file url is clicked.
I saw many solutions, for me, uploading just works fine. But when I try to implement the remove, I found no sample.
for the upload process, I configured my dropzone like below:
Dropzone.options.dropzoneForm = {
addRemoveLinks: true,
init: function() {
//upload process
}
};
It shows the addRemoveLink like "Remove file" just under the uploaded file.
I have seen someone to use another property like
Dropzone.options.dropzoneForm = {
addRemoveLinks: true,
removedFiles: function() {
//remove process
}
};
I am not sure how to implement this. Should I implement this like below? :
Dropzone.options.dropzoneForm = {
addRemoveLinks: true,
init: function(){
//upload process
}
removedFiles: function() {
//remove process
}
};
Please NB. I am expecting a full working example with server side upload and file delete.
I need a "support" mode for my Cordova app currently running on Windows Mobile and iOS. For this purpose, I need to compress an sqlite database file and upload it to a server. The database has to be compressed as it might grow over 250MB and the upload has to work without a wifi connection.
Searching the web brought up different approaches but all of them were outdated or did only solve my problem for either iOS or Windows Mobile. For example, when using the Cordova file plug-in I've encountered this in the plug-in documentation:
Supported Platforms
Android iOS OS X Windows* Browser
These platforms do not support FileReader.readAsArrayBuffer nor FileWriter.write(blob).
This was my approach: Cordova - Zip files and folders on iOS
Any ideas?
I would suggest you to give FileReader() a second chance.
In my case wich may be very similar to yours, I read a file using FilerReader.readAsArrayBuffer and after that, compress it using the JSZip library: http://stuartk.com/jszip
In opposition to the cordova-file-plugin's API documentation (https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/)
"Windows*"->"These platforms do not support FileReader.readAsArrayBuffer nor FileWriter.write(blob))"
I experienced that readAsArrayBuffer works under Windows UWP platform, but slower.
So in my case, with a file of approx. 50M I had to wait for nearly 2min for the whole process to finish!
Try following this example:
You'll need to adapt to your paths but this runs for WINDOWS UWP and IOS (didn't test it with Android but that was not your question).
Also, you'll need to implement your own error handler (errorHandler).
This solution uses Promises since you'll have to wait for the file beeing read and compressed.
PS1: Always be sure your "device ready's event" as been fired in order to access plugins.
PS2: You may encouter no access permission on the database file, this may be related to the fact, that it's being used by another process.
Be sure the database is closed.
SQLITE:
var sqlite = window.sqlitePlugin.openDatabase({ name: 'yourdb.db', location: 'default' });
sqlite.close(function () {
console.log("DONE closing db");
}, function (error) {
console.log("ERROR closing db");
console.log(JSON.stringify(error));
});
"ZIP" function:
function zipFile(sourceFileName, targetFileName) {
return new Promise(function (resolve, reject) {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
fs.root.getFile(sourceFileName, { create: false, exclusive: false }, function (fe) {
fe.file(function (file) {
var reader = new FileReader();
reader.onloadend = function (data) {
var zip = new JSZip();
zip.file(sourceFileName, data.target.result);
zip.generateAsync({
type: "blob",
compression: "DEFLATE",
compressionOptions: {
level: 9
}
// level 9 means max. compression
// this may also take some time depending on the size of your file
// I tested it with a 50M file, it took about 65 sec.
}).then(
// following is post-zip in order to transfer the file to a server
function (blob) {
fs.root.getFile(targetFileName, { create: true, exclusive: false }, function (newzip) {
writeFile(newzip, blob, "application/zip").then(function () {
var f = blob;
var zipReader = new FileReader();
zipReader.onloadend = function (theFile) {
var base64 = window.btoa(theFile.target.result);
resolve(base64);
};
// need to "resolve" the zipped file as base64 in order to incluse it in my REST post (server-upload)
zipReader.readAsBinaryString(f);
});
});
}
)
};
reader.readAsArrayBuffer(file);
// this may take some time depending on the size of your file
// I tested it with a 50M file, it took about 72 sec.
}, errorHandler);
}, errorHandler);
});
});
}
ex call:
if (window.cordova) {
document.addEventListener('deviceready', function () {
zipFile("yourDatabaseFileName.db","compressedDatabaseFile.zip");
});
}
Why not use sqlite ".dump" command as query and get result via steam and then compress the output. Even though text dump will be larger it will get reasonable size when you compress it. I think there are some very good text only compression algorithms as well,
In my react native app i am showing several images in <Image> tags and i load those images from local folder.
<Image source={require('./src/images/image1.jpg')} />
I want to save image when the user tapped on it.
I can get which image user tapped and pass it to the function. But i put a single image path to it.
_onPressButton(imgName) {
CameraRoll.saveToCameraRoll( './src/images/image1.jpg' , 'photo').then(function(result) {
alert(result);
}).catch(function(error) {
alert(error);
});
}
But this gives me an error in iOS emulator saying it cant find the image in the path.
When i give as,
CameraRoll.saveToCameraRoll( 'https://i.imgur.com/JnrwMpZ.jpg' , 'photo')
It works.
But i want to save these files in my src/images folder.
How can i get a path of this image file OR get this done..?
I appreciate any help regarding this.
Thanks
Here is my solution with Expo, worked in android and should work on ios too
onSave = async () => {
const asset = Asset.fromModule(require('./src/images/image1.jpg'))
if (!asset.localUri) {
await asset.downloadAsync();
}
const uri = asset.localUri;
CameraRoll.saveToCameraRoll(uri, 'photo')
}
My setup:
local packages:
Cordova Platforms : android 6.1.2 ios 4.4.0
Ionic Framework : ionic1 1.3.2
Cordova CLI 7.0.1 and latest ionic as of today
I have an Ionic 1 app that downloads a set of images and stores them via the Cordova file plugin here: cordova.file.dataDirectory. I am then trying to show those images, but having some trouble. I am using a MacBook Pro, Xcode 8, and iOS 10 in a WKWebView (for performance), although I switched to a UIWebView with the same result.
sharedSvc.getDetails($stateParams.id).then(function (data) {
angular.forEach(imgData, function (value, key) {
$cordovaFile.checkFile(cordova.file.dataDirectory+data.state+'/'+data.image_id+'/', value.image).then(function (success) {
$scope.imgArr.push({src: cordova.file.dataDirectory+data.state+'/'+data.image_id+'/'+value.image});
console.log('PUSHING - '+imgSrc);
}, function(error) {
console.log('Check for file bad1: '+cordova.file.dataDirectory+data.state+'/'+data.image_id+'/'+value.image);
//console.log(JSON.stringify(error));
});
});
});
Then I am trying to show the images:
<img ng-repeat="image in imgArr" src="{{image.src}}" />
For reference, I have the following items in my config.xml file:
<access allows-arbitrary-loads-in-media="true" allows-arbitrary-loads-in-web-content="true" allows-local-networking="true" origin="*" />
<access allows-arbitrary-loads-in-media="true" allows-arbitrary-loads-in-web-content="true" allows-local-networking="true" origin="file:///*" />
<allow-navigation href="file://*/*" />
<allow-intent href="file://*/*" />
Some of those may be unnecessary, but they have been added while I was looking for possible answers. Some pointed me towards issues with whitelisting, hence the additions.
I can verify the images are there, as shown in the checkFile call in the top code block. When I navigate to those images manually, they are there and the correct size. Also, the console logs are showing proper path to the files. However, when the app runs in the simulator (and on my physical device), the images are blank.
After searching all day for a solution, I am asking for some assistance from the code pros here. Thanks!
WKWebView blocks access to files outside of the directory in which the source page is located, i.e. www where index.html resides.
When you download data to cordova.file.dataDirectory, the filepath is on a different subtree so WKWebView is unable to access the files.
One solution, as outlined here, is to load the images using cordova-plugin-file as blobs which can be turned into a URL which WKWebView will accept:
function fetchLocalFileViaCordovaAsArrayBuffer(filename, successCallback, errorCallback)
{
fetchLocalFileViaCordova(filename, function (file)
{
var reader = new FileReader();
reader.onload = function (e)
{
successCallback(e.target.result);
};
reader.readAsArrayBuffer(file);
}, errorCallback);
};
function fetchLocalFileViaCordovaAsURL(filename, successCallback, errorCallback)
{
// Convert fake Cordova file to a real Blob object, which we can create a URL to.
fetchLocalFileViaCordovaAsArrayBuffer(filename, function (arrayBuffer)
{
var blob = new Blob([arrayBuffer]);
var url = URL.createObjectURL(blob);
successCallback(url);
}, errorCallback);
};
sharedSvc.getDetails($stateParams.id).then(function (data) {
angular.forEach(imgData, function (value, key) {
$cordovaFile.checkFile(cordova.file.dataDirectory+data.state+'/'+data.image_id+'/', value.image).then(function (success) {
fetchLocalFileViaCordovaAsURL(cordova.file.dataDirectory+data.state+'/'+data.image_id+'/'+value.image, function(url){
$scope.imgArr.push({src: url});
console.log('PUSHING - '+imgSrc);
});
}, function(error) {
console.log('Check for file bad1: '+cordova.file.dataDirectory+data.state+'/'+data.image_id+'/'+value.image);
//console.log(JSON.stringify(error));
});
});
});
I am building an app that lets the user download a PDF file when he clicks on a button.
I use the library react-native-fetch-blob for this purpose.
It works well on Android.
On iOS, the console log tells me the download has worked well, but:
I don't see anything happening on screen (on Android, there is a notification that tells me the download is complete)
I cannot find the file anywhere on the iPad. There is no "My files" folder or equivalent.
What is the right way to achieve what I want?
The solution thats worked for me in iOS was use RNFetchBlob.ios.openDocument function inside the then of fetch. This function open the file on the device file explorer where you have the option to download. Here is the code example:
downloadPDFiOS (uri) {
let uriSplitted = uri.split("/");
const fileName = uriSplitted.pop();
const dirs = RNFetchBlob.fs.dirs;
RNFetchBlob
.config({
path: dirs.DocumentDir + '/' + fileName,
fileCache: true,
})
.fetch('GET', uri, {
//some headers ..
})
.then((res) => {
RNFetchBlob.ios.openDocument(res.data);
})
.catch((e) => {
console.log('Error en el fetch: ', e);
})
}