I have downloaded a PDF file as Base64 String in my phone as described in this SO Thread but I am not getting how can I render it to actual PDF so that end user can see it? I have written following code to write on the file:
var tempResponse = null;
function downloadFileOK(response){
var invocationResult = response['invocationResult'];
tempResponse = invocationResult;
var size = parseInt(invocationResult["responseHeaders"]["Content-Length"]);
window.requestFileSystem(LocalFileSystem.PERSISTENT, size, onSuccessFileHandler, onErrorFileHandler);
}
//Success
function onSuccessFileHandler(fileSystem) {
alert("inside onSuccessFileHandler START");
fileSystem.root.getFile("test2.pdf", {create: true, exclusive: false}, fileWriter, fail);
alert("inside onSuccessHandler END");
}
// Failure
function onErrorFileHandler(error) {
alert("inside onErrorFileHandler");
}
function fileWriter(entry){
alert("inside fileWriter START");
entry.createWriter(function(writer){
writer.onwriteend = function(evt) {
console.log("done written pdf :: test1.pdf");
alert("Inside onwriteend : START");
};
var temp = atob(tempResponse["text"]);
alert(temp);
writer.write(temp);
},fail);
alert("inside fileWriter END");
}
function fail(error) {
alert("inside fail");
console.log(error.code);
}
Am I doing it wrong? How can I open the PDF from my app in iOS/Android OS using javascript/jquery/cordova ?
Once you have download the base64 encoded file, you should decode it and save it to the file system so that it can be viewed later. You should not save the base in it's base64 encoded form.
You can use the utility function below to accomplish that. BTW you should take a look a the previous answer on Download PDF file from through MobileFirst Adapter since I made an update to it, it wasn't encoding the PDF properly.
var AppUtils = (function(){
// get the application directory. in this case only checking for Android and iOS
function localFilePath(filename) {
if(device.platform.toLowerCase() === 'android') {
return cordova.file.externalDataDirectory + filename;
} else if(device.platform.toLowerCase() == 'ios') {
return cordova.file.dataDirectory + filename;
}
}
// FileWritter class
function FileWritter(filename) {
this.fileName = filename;
this.filePath = localFilePath(filename);
}
// decode base64 encoded data and save it to file
FileWritter.prototype.saveBase64ToBinary = function(data, ok, fail) {
var byteData = atob(data);
var byteArray = new Array(byteData.length);
for (var i = 0; i < byteData.length; i++) {
byteArray[i] = byteData.charCodeAt(i);
}
var binaryData = (new Uint8Array(byteArray)).buffer;
this.saveFile(binaryData, ok, fail);
}
// save file to storage using cordova
FileWritter.prototype.saveFile = function(data, ok, fail) {
this.fileData = data;
var path = this.filePath.substring(0, this.filePath.lastIndexOf('/'));
var that = this;
// Write file on local system
window.resolveLocalFileSystemURL(path, function(directoryEntry) {
var options = {create: true, exclusive: false};
directoryEntry.getFile(that.fileName, options, function(file) {
file.createWriter(function(writer) {
writer.onwriteend = function(event) {
if(typeof ok === 'function') {
ok(event);
}
};
writer.write(that.fileData);
}, fail);
}, fail);
}, fail);
};
// open InApp Browser to view file
function viewFile(filename) {
var path = localFilePath(filename);
window.open(path, "_blank", "location=yes,hidden=no,closebuttoncaption=Close");
}
return {
FileWritter: FileWritter,
localFilePath: localFilePath,
viewFile: viewFile
}
})();
Your downloadFileOK should look as follow:
function downloadFileOK(response){
var pdfData = response['invocationResult']['text'];
var fileWritter = new AppUtils.FileWritter('YOUR-PDF-NAME.pdf');
fileWritter.saveBase64ToBinary(pdfData, function(r){
// file was saved
}, function(e){
// error file was not saved
});
}
If you want to open the file then you can use AppUtils.viewFile('YOUR-FILE-NAME.pdf')
Related
using cordova media-capture and file-transfer plugin I try to make an app to record video and upload on server. After recording video I call the upload function and it showing the success message in success callback function. But no file uploaded in server. Here my code.
$(document).ready(function(){
document.addEventListener("deviceready", onDeviceReady, false);
});
function onDeviceReady() {
navigator.device.capture.captureVideo(captureSuccess, captureError, {limit:1});
}
var captureSuccess = function(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
uploadFile(mediaFiles[i]);
}
};
var captureError = function(error) {
alert('error');
console.log(error);
};
/********* File Upload **********/
// Upload files to server
function uploadFile(mediaFile) {
var ft = new FileTransfer(),
path = mediaFile.fullPath,
name = mediaFile.name;
ft.upload(path,
"http://myserver.com/test.php",
function(result) {
alert('success');
},
function(error) {
alert('error');
},
{ fileName: name, fileKey: "file" });
}
My php code is
<?php
if($_FILES['file']['size'] > 0) {
$path = $_SERVER['DOCUMENT_ROOT']."/audior/app/";
$tmpname1 = $_FILES['file']['tmp_name'];
$ptname1 = $_FILES['file']['name'];
move_uploaded_file($tmpname1, $path . $ptname1);
echo 'success';
}
?>
You have to create a FileUploadOptions object
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = name;
then use it on the upload function
ft.upload(path,
"http://myserver.com/test.php",
function(result) {
alert('success');
},
function(error) {
alert('error');
},
options);
You can also change the
function(result) {
alert('success');
}
to
function(result) {
alert(result);
}
Just to check if the server is telling you something.
If you are getting the success callback the problem should be on the PHP script.
I use this one that returns the url of the uploaded file
<?php
$target_dir = "upload/";
$target_file = $target_dir . basename($_FILES["file"]["name"]);
move_uploaded_file($_FILES["file"]["tmp_name"], "./" . $_FILES["file"]["name"]);
echo "http://" . $_SERVER['SERVER_NAME'] . "/" . $target_file;
?>
Currently i am working in hybrid application. i received base 64 string which i want to get downloaded as pdf and open it when user clicks on download button. I managed to convert to pdf refering to the below link
It is getting stored in local storage of the device.
In android file getting stored in internal storage.But for ios pdf is not accessibe inside local storage and ibooks is not identifying the file. how to make pdf available in download folder in android and ibooks for ios for better user experience and make pdf open when download is done?.
convert base 64 to pdf blob
function b64toBlob(b64Data, contentType, sliceSize) {
var input = b64Data.replace(/\s/g, ''),
byteCharacters = atob(input),
byteArrays = [],
offset, slice, byteNumbers, i, byteArray, blob;
contentType = contentType || '';
sliceSize = sliceSize || 512;
for (offset = 0; offset < byteCharacters.length; offset += sliceSize) {
slice = byteCharacters.slice(offset, offset + sliceSize);
byteNumbers = new Array(slice.length);
for (i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
//Convert to blob.
try {
blob = new Blob(byteArrays, { type: contentType });
}
catch (e) {
// TypeError old chrome, FF and Android browser
window.BlobBuilder = window.BlobBuilder ||
window.WebKitBlobBuilder ||
window.MozBlobBuilder ||
window.MSBlobBuilder;
if (e.name == 'TypeError' && window.BlobBuilder) {
var bb = new BlobBuilder();
for (offset = 0; offset < byteArrays.length; offset += 1) {
bb.append(byteArrays[offset].buffer);
}
blob = bb.getBlob(contentType);
}
else if (e.name == "InvalidStateError") {
blob = new Blob(byteArrays, {
type: contentType
});
}
else {
return null;
}
}
return blob;
};
And then the downloading itself we need the cordova-file plugin:
function pdfConversion(){
alert("The paragraph was clicked.");
var fileName="test.pdf";
var fileToSave= b64toBlob(encodedString, 'application/pdf');
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, onFileSystemFail);
}
function gotFS(fileSystem) {
fileSystem.root.getFile(fileName, {create: true}, onFileEntryRetrieved, onFileSystemFail);
}
function onFileEntryRetrieved(fileEntry) {
console.log("file entry retrieved");
fileEntry.createWriter(gotFileWriter, onFileSystemFail);
}
function gotFileWriter (writer) {
console.log("inside local file system"+JSON.stringify(writer));
alert("JSON.stringify(writer)"+JSON.stringify(writer));
console.log("contents of file now 'some sample text'");
//writer.truncate(11);
writer.onwriteend = function(evt) {
writer.write(fileToSave);
writer.seek(4);
}
writer.onerror = function (e) {
// you could hook this up with our global error handler, or pass in an error callback
console.log('Write failed: ' + e.toString());
};
writer.write(fileToSave);
window.open(fileName, '_blank');
};
function onFileSystemFail(error) {
console.log(error.code);
}
};
In Android, we have access to write and read PDF. But in IOS, Sandbox access has certain restriction to read.
I managed to open PDF using encoded string as follows
window.open("data:application/pdf;base64,"+encodedString, "_blank","location=no,hidden=no,closebuttoncaption=Close");
Hi I am getting device db file and storing in server to make the backup of database of my app the requirement is that if device lost or broke or theft then in that case the user can download the backup of the database from server and can restore it into their device. I believe below code gives me a device db file with specified path with file name.
function doBackup(){
var defered = $.Deferred();
var version = parseFloat(window.device.version);
dbPath = cordova.file.applicationStorageDirectory
+'/app_webview/databases/file__0/1';
if(version < 4.4) {
dbPath = cordova.file.applicationStorageDirector+'/app_database
/file__0/0000000000000001.db';
}
var fileName = 'Backup_' + new Date().getTime();
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
fs.root.getDirectory(backupFolder, {
create : true,
exclusive : false
}, function(dir) {
window.resolveLocalFileSystemURL(dbPath, function(db) {
db.copyTo(dir, fileName, function() {
if(online) {
console.log("Im online - "+dbPath);
readFile(fileName);
//checkIfDBFileExists(backupFolder+'/log1.txt');
} else {
var data = new BackupData();
data.FileName = fileName;
data.BackupDate = new Date().getTime();
SaveBackupData(data, GetBackupData);
}
}, onfail)
});
}, onfail);
}, onfail);
function onfail(err){
return defered.reject(err);
}
return defered.promise();
}
For replacing I am trying below code BUT there is no luck
function copyFileToDB(fName){
var defered = $.Deferred();
// request for file system
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs){
//request for directory Entry
//backup folder name in dd mm yyyy format
var today = new Date();
//var fileName = today.getDate()+" " + (today.getMonth()+1) + " "+today.getFullYear();
var fileName = fName;
fs.root.getDirectory("Download/SMU/Backup/", {
create: false,
exclusive: false
}, function(destDirectoryEntry)
{window.resolveLocalFileSystemURL(cordova.file.applicationStorageDirectory
+"app_webview/databases/file__0/1",function(fileEntry){
fileEntry.copyTo(destDirectoryEntry, fileEntry.name, function(){
alert("success - "+JSON.stringify(destDirectoryEntry));
}, onfail);
},onfail)
}, onfail);
}, onfail);
function onfail(err){
return defered.reject(err);
}
return defered.promise();
}
Please anybody help me to resolve this..
so I am trying to use the phonegap file API to save and later load a file in the app. The save seems to be working, but reading the file throws this error:
processMessage failed: Stack: TypeError: Object #<an Object> has no method 'readAsText'
at [object Object].readAsText (file:///android_asset/www/plugins/org.apache.cordova.file/www/FileReader.js:130:33)
at file:///android_asset/www/index.html:3843:15
at file:///android_asset/www/plugins/org.apache.cordova.file/www/DirectoryEntry.js:100:9
at Object.callbackFromNative (file:///android_asset/www/phonegap.js:292:54)
at processMessage (file:///android_asset/www/phonegap.js:1029:21)
at Function.processMessages (file:///android_asset/www/phonegap.js:1063:13)
at pollOnce (file:///android_asset/www/phonegap.js:933:17)
at pollOnceFromOnlineEvent (file:///android_asset/www/phonegap.js:928:5)
No matter what I do, it always seems to throw this error. I printed out the fileReader object to the console and inspected it using weinre. It had the prototype with the readAsText() function on it, so I'm really at a loss why it's not working...
This is how I am saving the file:
var request = window.requestFileSystem;
if(typeof request != 'undefined') {
var fileSystem;
var writer;
request(LocalFileSystem.PERSISTENT, 0, function (FS) {
fileSystem = FS;
fileSystem.root.getFile("offlineData.txt", {create: true, exclusive: false}, function(fileEntry) {
fileEntry.createWriter(function(w) {
writer = w;
writer.write('This is some text yo');
}, function(e) {console.log(e);});},
function(e) {console.log(e); console.log('There was an error getting the file to write')});} ,
function(e) {\console.log('There was an error getting the file system');});}
Later in the flow, I will do something like this:
request(LocalFileSystem.PERSISTENT, 0, function(FS) {
fileSystem = FS;
fileSystem.root.getFile("offlineData.txt", null, function(_file) {
var reader = new FileReader();
reader.onloadend = function (evt) {
console.log("read success");
console.log(evt.target.result);
};
reader.onerror = function(evt) {
console.log("Error read text");
console.log("Error"+evt.error.code);
};
reader.onabort = function(evt) {
console.log("aborted read text");
console.log(evt.target.result);
};
reader.onloadstart = function(evt) {
console.log("started reading");
};
console.log(reader);
reader.readAsText(_file);
});
}, function(e) {console.log(e); console.log('There was an error getting the file.')});
In your sample, _file is a fileEntry and not file content. Can you try this :
fileSystem.root.getFile("offlineData.txt", null,
function (fileEntry) {
fileEntry.file(function (_file) {
var reader = new FileReader();
reader.onloadend = function () {
console.log("read success");
console.log(evt.target.result);
};
reader.readAsText(_file);
});
}
);
I am developing hybrid using phonegap 3.3. I am using camera plugin to capture image and store into photo album which working fine. Later, I have to read image file from the device storage.
I am using the following code.
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, failFS);
function gotFS(fileSystem){
fileSystem.root.getFile(imageData, {create: true}, gotFileEntry, fail);
}
function gotFileEntry(){
fileEntry.file(gotFile,fail);
}
function gotFile(file){
alert(file.getParent().fullPath);
}
I am getting error in the first line. It is giving
FileError.ENCODING_ERR
I am not sure what I am doing wrong here. After, I have to move to another directory with new name. Could anyone help me to fix.
I am using camera plugin for capture images and file plugin to read files and directory.
--Sridhar
You can try with below code to capture and copy image
var pictureSource;
var destinationType;
var FileFolder = "";
var FileName = "";
var obj_imageCapture = {
capturePicture:function(imgFolder,imgName)
{
var image = imgFolder + imgName;
FileFolder = imgFolder;
FileName = imgName;
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
navigator.camera.getPicture(obj_imageCapture.onPhotoDataSuccess1, obj_imageCapture.onFail, {quality: 50, destinationType: destinationType.FILE_URI , saveToPhotoAlbum: true });
},
onPhotoDataSuccess1:function(imageData){
obj_imageCapture.createFileEntry(imageData);
},
createFileEntry:function(imageURI) {
window.resolveLocalFileSystemURI(imageURI, obj_imageCapture.copyPhoto, obj_imageCapture.onFFail);
},
copyPhoto:function(fileEntry) {
try
{
var ext = fileEntry.fullPath.substr(fileEntry.fullPath.lastIndexOf('.'));
var imageN = "";
if(FileName.indexOf('.') > 0)
{
imageN = FileName.substr(0,FileName.lastIndexOf('.')) + ext;
}
else
{
imageN = FileName + ext;
}
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
fileSys.root.getDirectory(FileFolder, {create: true, exclusive: false}, function(dir) {
fileEntry.copyTo(dir, imageN, obj_imageCapture.onCopySuccess, obj_imageCapture.onFFail);
}, obj_imageCapture.onFFail);
}, obj_imageCapture.onFFail);
}
catch(ex)
{
alert(ex.message);
}
},
onCopySuccess:function(entry) {
var smallimage = document.getElementById("myimage");
smallimage.style.display = "block";
smallimage.src = entry.fullPath + "?rand=" + Math.random();
},
onFFail:function(message)
{
alert("Error in photo : " + message.message);
}
};
Above code might helpful to you