Cordova File Plugin Has Wrong Directory - angularjs

So I am building a cordova/phonegap app in angularjs 1 and I'm trying to save and read from a file called calendar.txt in the app's private directory/sandbox and can't.
My console logs while debugging show that there are no errors and the file is being created if it doesn't exist, and is being read correctly. However that is not the case. When I build and run on my device, the data is not saved. Also no file is created in the location specified.
I console logged the path it was trying to use and this is it:
file:///data/data/com.adobe.phonegap.app/files/calendar.txt
Here is the code I am using to open the file:
$rootScope.openFile = function(){
var pathToFile = cordova.file.dataDirectory + "calendar.txt";
console.log('path = ' + pathToFile);
window.resolveLocalFileSystemURL(pathToFile,
function(fileEntry){
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function (e) {
$rootScope.calendar = JSON.parse(this.result);
console.log('file opened');
console.log(JSON.parse(this.result));
};
reader.readAsText(file);
}, function(error){});
}, function(error){
if(error.code == FileError.NOT_FOUND_ERR){
$rootScope.calendar = new Year();
console.log('no file found so it was created');
$rootScope.saveFile();
}
else{
console.log(error);
}
});
};
And here is the code for my save the file:
$rootScope.saveFile = function(){
var data = JSON.stringify($rootScope.calendar, null, '\t');
var fileName = "calendar.txt"
window.resolveLocalFileSystemURL(cordova.file.dataDirectory,
function(directoryEntry){
directoryEntry.getFile(fileName, { create: true },
function (fileEntry) {
fileEntry.createWriter(
function (fileWriter) {
var blob = new Blob([data], { type: 'text/plain' });
fileWriter.write(blob);
console.log('file saved');
},
function (error){});
},
function (error){}
);
},
function(error){
console.log("Saving Error: Error during finding directory", error.message);
}
);
};
I have used this tutorial to get this far: Cordova File Plugin Tutorial
What am I doing wrong?

I assume that you are facing this issue in Android as i too faced the same. As per my understanding and googling, in android (atleast in android 5) you cant write in application data directory unless the phone is rooted. So you may have to use externalRootDirectory instead.
eg: window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory,successCallback, errorCallback);
Hope it helps.

Related

save video files in iOS gallery using Cordova plugin

I am trying to save a video from a URL in my iOS device using a ionic Cordova file transfer .
var fileTransfer = new FileTransfer();
var uri = "https:xyz.abc/demo.mp4";
var fileURL = cordova.file.documentsDirectory + 'demoRename.mp4';
fileTransfer.download(
uri, fileURL, function (entry) {
console.log("download complete: " + entry.toURL());
},
function (error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("download error code" + error.code);
}
);
I can see the downloaded path as below using console log.
[Log] download complete: file:///var/mobile/Containers/Data/Application/EB4C2F9A-9C4D-4CA6-BED0-D83B7D4CBDE1/Documents/demoRename.mp4
But I can not see the downloaded video file in my gallery or in photos ,Where can I find them or am I doing it right?
you will need to save the video to gallery then you will able to see the downloaded video in the gallery.
please use the photo library plugin and follow the below link.
https://github.com/terikon/cordova-plugin-photo-library
use the below code may be it will helpful to you.
//based on device type choosing the location to save the video
if (ionic.Platform.isIOS()) {
var path = cordova.file.documentsDirectory;
var filename = "preview.mp4";
} else {
var path = cordova.file.externalRootDirectory;
var filename = "preview" + $filter('date')(new Date(), "yyyy-MM-dd HH:mm:ss") + ".mp4";
}
//Creating directory to save video in the device
$cordovaFile.createDir(path, "dir", true).then(function(success) {
var targetPath = path + "dir/" + filename;
var trustHosts = true;
var options = {};
//Downloading the file from URL.
$cordovaFileTransfer.download("video URL", targetPath, options, trustHosts).then(function(result) {
//Once downloaded the file calling function to add the video to photo library
if (ionic.Platform.isIOS()) {
function savelibrery() {
cordova.plugins.photoLibrary.saveVideo(targetPath, album, function(success) {}, function(err) {
if (err.startsWith('Permission')) {
cordova.plugins.photoLibrary.requestAuthorization(function() {
savelibrery();
}, function(err) {
$ionicLoading.hide();
$cordovaToast.show("Oops! unable to save video, please try after sometime.", "long", "center");
// User denied the access
}, // if options not provided, defaults to {read: true}.
{
read: true,
write: true
});
}
});
}
savelibrery()
} else {
//add refresh media plug in for refresh the gallery for android to see the downloaded video.
refreshMedia.refresh(targetPath);
}
$ionicLoading.hide();
$cordovaToast.show("Vidoe saved successfully", "long", "center");
}, function(error) {
$ionicLoading.hide();
$cordovaToast.show("Oops! unable to save video, please try after sometime.", "long", "center");
}, function(progress) {
$scope.downloadProgress = (progress.loaded / progress.total) * 100;
$cordovaToast.show("In progress", "short", "center");
});
}, function(error) {
//alert(JSON.stringify(error));
$ionicLoading.hide();
$cordovaToast.show("Oops! unable to save video, please try after sometime.", "long", "center");
});

Video capture to not show in my gallery on phone

I am using ng-cordova's plugin capture to capture (https://github.com/apache/cordova-plugin-media-capture) videos inside of the ionic framework from a mobile phone.
$scope.captureVideo = function() {
var options = { limit: 1, duration: 10 };
$cordovaCapture.captureVideo(options).then(function(videoData) {
var i, path, len;
for (i = 0, len = videoData.length; i < len; i += 1) {
path = videoData[i].fullPath;
console.log("Path of the video is = " + path.toString());
}
}, function(err) {
// An error occurred. Show a message to the user
});
}
The problem is every video capture I take saves to my phones gallery which I do not want. If I capture an image it does NOT save to my phone's gallery which is what I would like with video capture. Is there a way to stop videos from being saved?
I tried deleting the file but apparently the video file is not saved
in cordovafile directories.
function DeleteFile() {
var filename = "20161024_095758.mp4";
var relativeFilePath = "file:/storage/C8F0-1207/DCIM/Camera";
console.log('data directory: '+cordova.file.dataDirectory);
window.resolveLocalFileSystemURL(relativeFilePath, function(dir) {
dir.getFile(filename, {create:false}, function(fileEntry) {
fileEntry.remove(function(){
alert('file removed');
// The file has been removed succesfully
},function(error){
alert('error'+JSON.stringify(error));
// Error deleting the file
},function(){
alert('file doesnt exist');
// The file doesn't exist
});
});
});
The code above to delete file results in Error Code:6. No modification allowed
Well, apparently WE CANNOT DELETE AND WRITE FILES FROM MICRO SD-CARD SINCE VERSION 4.4. It is read only now.. And, when the user deletes the file from the gallery, it would not be available for the project. Here is what i came up with.
I copied the video file to cordova's external directory from where i could read the file when wanted and delete as per the need. Plugins required are cordova-file-plugin and cordova-plugin-file-transfer
.controller('yourCtrl', function($scope,$cordovaCapture,$sce,$cordovaFile, $cordovaFileTransfer, $timeout) {
$cordovaCapture.captureVideo(options).then(function(videoData) {
console.log(JSON.stringify(videoData[0]));
console.log(cordova.file.externalDataDirectory);
$cordovaFileTransfer.download(videoData[0].fullPath, cordova.file.externalDataDirectory + 'my-video.mp4', {}, true).then(
function(result)
{
console.log('success: '+ result);
},
function (error)
{
console.log('error: '+ JSON.stringify(error));
},function (progress) {
$timeout(function () {
$scope.downloadProgress = (progress.loaded / progress.total) * 100;
});
},false);
$scope.clipSrc = $sce.trustAsResourceUrl(videoData[0].fullPath);
//$scope.videoSrc = videoData[0].fullPath;
}, function(err) {
alert('Err: <br />'+ JSON.stringify(videoData));
});
//delete the file according to filename.
$scope.deleteVideo= function(){
$cordovaFile.removeFile(cordova.file.externalDataDirectory, "my-video.mp4")
.then(function (result) {
console.log('Success: deleting videoData file' + JSON.stringify(result));
}, function (err) {
console.log('Error: deleting videoData file' + JSON.stringify(err));
});
}
})

Failed to load pdf document, NodeJs

I am trying to download a pdf without prompt using the pdf which is already present under mocked test data. And I am able to do the above task using the below code.But when I try to open the downloaded pdf I am getting 'Failed to load pdf document' what am I missing here.Kindly help.
fs.readFile('./src/test-data/service/print/notes.pdf', function(error, content) {
if (error) {
res.writeHead(500);
res.end();
}
else {
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-Disposition': 'attachment; filename=notes.pdf'
});
res.end(content, 'utf-8');
}
});
you must use res.download
function fileExist(fullpath) {
try {
return fs.statSync(fullpath).isFile();
} catch (e) {
return false;
}
}
var name = 'notes.pdf';
var filePath = './src/test-data/service/print/' + name;
if (!Files.Exist(filePath)) {
console.log("file does't exist");
} else {
res.download(filePath, name, function(err) {
fs.unlink(filePath);
});
}
if you want keep your file after download replace the line
res.download(filePath, name, function(err) {
fs.unlink(filePath);
});
by
res.download(filePath, name);
in the angular application use $window.open(url, '_self');
This is working perfectly.
var file = fs.createReadStream('./src/test-data/service/print/notes.pdf');
var stat = fs.statSync('./src/test-data/service/print/notes.pdf');
res.setHeader('Content-Length', stat.size);
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=agreement.pdf');
file.pipe(res);
If the above solutions do not solve your problem, and your using nginx + express, the problem might be with nginx buffering the response. You can disable that using the following:
proxy_buffering off;

Download only new files on an Ionic app?

I want to download a file from a server only if the file is new. For example, by checking the file modified date. I am using the below code to download the file, but I am stuck where I need to compare the files before downloading. Can anyone please give me a solution for this.
.factory('fileDownloadService',['$cordovaFileTransfer', function($cordovaFileTransfer){
return{
fileDownload:function(){
// File for download
var url = "http://www.xxxxx/file-to-download.json";
// Get file name only
var filename = url.split("/").pop();
// Save location
var targetPath = cordova.file.externalRootDirectory + filename;
$cordovaFileTransfer.download(url, targetPath, {}, true).then(function (result) {
console.log('Download Successful');
}, function (error) {
console.log('Download Error');
}, function (progress) {
// Progress handling
});
}
}}])
Appreciate your help. Thank you

Zip generated by EasyZip is not working properly

I have generated a zip file using Easyzip. I can open it directly from download folder.But when try to open it after downloading, I am getting this error:- 'error occurred while extracting files'.
This my backend code :-
var zip2 = new EasyZip();
zip2.zipFolder('./downloads/'+application._id,function(){
zip2.writeToFile('./downloads/'+application._id+'.zip');
res.setHeader('Content-disposition', 'attachment; filename='+application._id+'.zip');
res.setHeader('Content-type', 'application/zip');
var fs = require('fs');
var filestream = fs.createReadStream('./downloads/'+application._id+'.zip');
filestream.pipe(res);
});
});
My angular.js code
$http.post('/download/archive/' + stateParams._id, {year: year}).success(function (data) {
var file = new Blob([data], {type: 'application/zip'});
console.log(file)
saveAs(file, 'application.zip');
});
Please help me to solve these. Thanks in advance.
I had the same problem and was able to solve it by using:
{responseType:'arraybuffer'} in the $http.post() request.
For more details check: how to download a zip file using angular as well as AngularJS: Display blob (.pdf) in an angular app
Solved issue by using node-native-zip module.
Here is my backend code
var zip = require("node-native-zip");
var files = []
files.push({name:application._id+'.pdf',path:'./downloads/'+vetting_id+application._id+'.pdf'}); //push all the files along with its name and path
var archive = new zip();
archive.addFiles(files, function (err) {
if (err) return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
var buff = archive.toBuffer();
var fs = require('fs');
fs.writeFile('./downloads/'+ vetting._id+'.zip', buff, function () {
console.log("Finished");
var filestream = fs.createReadStream('./downloads/'+vetting._id+'.zip');
filestream.pipe(res);
});

Resources