Phonegap image file is not saved permanently iOS - ios

Hi i'm trying to capture a photo and save it permanently to the filesystem. Taking the photo works so far, but it seems it doesn't save it permanently to the filesystem. After i restart the app, the pictures are gone.
The path of the picture is saved to my WebSQL Database (which works without problems)
Here is the part of my code:
function capturePhoto() {
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50,
destinationType: destinationType.FILE_URI, saveToPhotoAlbum: true });
}
function onFail(message) {
console.log('Failed because: ' + message);
}
function onPhotoDataSuccess(imageURI) {
movePic(imageURI);
}
function movePic(file){
window.resolveLocalFileSystemURI(file, resolveOnSuccess, resOnError);
}
//Callback function when the file system uri has been resolved
function resolveOnSuccess(entry){
var d = new Date();
var n = d.getTime();
//new file name
var newFileName = n + ".jpg";
var myFolderApp = "LeadAppPhotos";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
//The folder is created if doesn't exist
fileSys.root.getDirectory( myFolderApp,
{create:true, exclusive: false},
function(directory) {
entry.moveTo(directory, newFileName, successMove, resOnError);
},
resOnError);
},
resOnError);
}
//Callback function when the file has been moved successfully
function successMove(entry) {
//put the path url in a div so i can save it later to my websql database
$('#hidden_photo').val(entry.fullPath);
}
function resOnError(error) {
alert(error.code);
}
What's my mistake?

Related

Cordova: What is the right location to store recorded Audio files in iOS?

I am using media plugin to record sounds.
var my_media = new Media('test.wav');
my_media.startRecord();
my_media.stopRecord() // after few seconds
my_media.release();
my_media.play();//works fine
// But when I try to Check if test.wav file exist I always get false as status.
//File name of our important data file we didn't ship with the app
var fileName = "test.wav";
function init() {
console.log("Checking for data file.");
//Check for the file.
window.resolveLocalFileSystemURL(fileName, onSuccess, onFail);
}
function onSuccess() {
console.log("Great! This file exists");
}
function onFail() {
console.log('Sorry! File not Found');
}
// I always get this message: Sorry! File not Found
What is right way to do this? After recording I want user to be able to see list of available recorded sounds and user should be able to play it. For that I need to check if file exists or not.
So how should we implement that?
You can display list of recorded files as:
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) {
fileSystem.root.getDirectory(YOUR_PATH, {
create: true
}, function(directory) {
root_path = fileSystem.root.toURL();
var directoryReader = directory.createReader();
directoryReader.readEntries(function(entries) {
var i;
for (i = 0; i < entries.length; i++) {
//Get file URL as: entries[i].toURL()); & display using creating dynamic tag.
}
}, function(error) {
alert(error.code);
});
});
}, function(error) {
alert("can't even get the file system: " + error.code);
});

Downloaded image not shown in iOS gallery while shown in android phone gallery

I used telerik app builder platform to create application. I created download image functionality. This functionality is working on android device, but not on iOS. I don't know why it is not working.
When the user downloads an image using application in android device, then cordova filesystem creates directory and saves image into that directory and image was also shown in gallery. While user performs same action in iOS then it does not create any directory and the image is not shown in gallery. I haven't found where to save this image.
Please give suggestion on how to save downloaded image in iOS gallery.
My code is below
function onDeviceReady() {
var that = this,
App = new downloadApp(),
fileName = "sample.png",
uri = encodeURI("http://www.telerik.com/sfimages/default-source/logos/app_builder.png"),
folderName = "test";
navigator.splashscreen.hide();
App.run(uri, fileName, folderName);
}
downloadApp.prototype = {
run: function (uri, fileName, folderName) {
var that = this,
filePath = "";
document.getElementById("download").addEventListener("click", function () {
that.getFilesystem(
function (fileSystem) {
console.log(fileSystem);
that.getFolder(fileSystem, folderName, function (folder) {
filePath = folder.toURL() + "\/" + fileName;
console.log(filePath);
that.transferFile(uri, filePath)
}, function () {
console.log("failed to get folder");
});
},
function () {
console.log("failed to get filesystem");
}
);
});
},
getFilesystem: function (success, fail) {
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, success, fail);
},
getFolder: function (fileSystem, folderName, success, fail) {
fileSystem.root.getDirectory(folderName, { create: true, exclusive: false }, success, fail)
},
transferFile: function (uri, filePath) {
var transfer = new FileTransfer();
transfer.download(
uri,
filePath,
function (entry) {
var targetPath = entry.toURL();
},
function (error) {
console.log(error)
}
);
},
Try to download by using https://www.npmjs.com/package/com-cordova-image-save-to-gallery plugin. It will download a picture from a given URL and save it to IOS Photo Gallery.
Cordova plugin add https://github.com/valwinjose007/cordova-image-save-to-gallery.git
How to use:
declare var CordovaImageSaveToGallery: any;
CordovaImageSaveToGallery.downloadFromUrl('https://picsum.photos/200/300',(res)=>{
//download success
},(err)=>{
//error on download
});

iOS callback not triggered after file upload from $cordovaCamera

I'm building a hybrid app in ionic, which runs over cordova. I use the $cordovaCamera plugin to capture images from the phone, either by selecting from the phone's gallery or by using the camera to take a picture.
I then send that image using Restangular to my server, and when that action finishes, I want to display a status message on the screen.
My problem: All of the above works perfectly on Android. On iOS, it is working only when the image is selected from the gallery, but not when the image is directly captured from the phone. In that case, the image is correctly transferred to the server, the request returns a 201 Created just as it should - but the then() callback function is never entered.
If anyone can explain this behavior, that would be awesome...my second best would be to capture the image on the iPhone, save to gallery, and then attempt to retrieve the last saved image, but I haven't been able to figure out how to yet and I'd rather just get this working.
Update: I've narrowed it down to the Restangular part - if instead of calling the Restangular upload function, I use $http, the callback is triggered as expected and all is good...so that's what I'm going to do, but if anyone can tell me what the problem was I'd be grateful.
Relevant code:
/** cameraService functions **/
//when the user chooses to snap a picture from the camera
takePicture: function(){
var options = {
quality: 50,
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions
};
return $cordovaCamera.getPicture(options).then(
function(imageData) {
return imageData;
},
function(err) {
console.log("error", err);
});
},
//when the user chooses to select image from the gallery
choosePicture: function(){
var options = {
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY
};
return $cordovaCamera.getPicture(options).then(
function(imageData) {
return imageData;
},
function(err) {
console.log("error", err);
});
},
uploadPicture: function(imageSource, caption, is_logo){
if (typeof is_logo == 'undefined') is_logo = false;
var upload_object = {
caption: caption,
source: imageSource,
is_logo: is_logo
};
//apiService is my wrapper for Restangular
return apiService.uploadFile(loadingService.getClientUrl('images'), upload_object);
},
/**apiService uploadFile - apparently the problem is here ***/
uploadFile: function(baseElem, object, route, path){
var headers = apiFunctions.setHeaders({'Content-Type': undefined});
//this DOES NOT WORK (on iPhone with image from camera) - request completes but callback not triggered
return Restangular.all(baseElem).customPOST(object, path, route, headers);
//this works fine:
return $http.post('https://api.mysite.dev/v1/clients/'+localStorageService.getValue('client_id')+'/images', JSON.stringify(object), {headers:headers}
);
},
/** controller functions **/
$scope.takePicture = function () {
cameraService.takePicture().then(function (imageData) {
$scope.data.imageSource = imageData;
});
};
$scope.choosePicture = function () {
cameraService.choosePicture().then(function (imageData) {
$scope.data.imageSource = imageData;
});
};
$scope.uploadPicture = function () {
cameraService.uploadPicture($scope.data.imageSource, $scope.data.caption)
.then(function (response) { //this is never entered if image is captured from camera on iPhone
$ionicScrollDelegate.scrollTop();
$scope.data.caption = '';
$scope.data.imageSource = '';
if (response.data.response.is_success.data_value == true) {
$scope.messages.success.push("Photo uploaded successfully");
} else {
$scope.messages.failure.push("Error uploading photo.");
}
});
}

Phonegap 3.5 File Download / Moving not working

I am busy upgrading a Phonegap app from 3.3 to 3.5 everything works so far but the file download, opening isn't working
function downloadFile(url, filename, fail, downloadDone) {
window.fail = fail;
window.downloadDone = downloadDone;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function onFileSystemSuccess(
fileSystem) {
var fileTransfer = new FileTransfer();
fileTransfer.download(url, window.filePath + filename, function(theFile) {
window.downloadDone();
}, function(error) {
window.fail(error);
});
}, window.fail);
}
function setupFilePath(callBack) {
window.callback = callBack;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function onFileSystemSuccess(
fileSystem) {
fileSystem.root.getFile("dummy.html", {
create: true,
exclusive: false
}, function gotFileEntry(fileEntry) {
var sPath = fileEntry.root.replace("dummy.html", "");
window.filePath = sPath;
var fileTransfer = new FileTransfer();
fileEntry.remove();
dataDir = fileSystem.root.getDirectory(sPath + 'cordapp', {
create: true
});
window.filePath = sPath + 'cordapp/';
console.log("FILE PATH IS: " + window.filePath)
callBack()
}, null);
}, null);
}
Getting the error that the app can't create the directory what am I doing wrong? Is there also a way to not letting it backup to iCloud?

Capturing and storing a picture taken with the Camera into a local database / PhoneGap / Cordova / iOS

I'm currently building an app for iOS using Phonegap/Cordova and jQuerymobile. The idea is to take photos with camera and store the captured image for future use. I would like to store the path/filename into my local database and to move the picture file to a persistent place in the iPhone.
Could someone provide me with an example ?
Ok, here is the solution.
in the Html file
I have an image tag for displaying the picture taken by the camera :
I have a button that runs a function for taking photo :
Capture Photo
The function to capture photo is (when the photo is taken, the scr of the 'smallImage' id is populated with the path of the photo)
function capturePhoto() {
// Take picture using device camera and retrieve image as base64-encoded string
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50 });
}
//Callback function when the picture has been successfully taken
function onPhotoDataSuccess(imageData) {
// Get image handle
var smallImage = document.getElementById('smallImage');
// Unhide image elements
smallImage.style.display = 'block';
smallImage.src = imageData;
}
//Callback function when the picture has not been successfully taken
function onFail(message) {
alert('Failed to load picture because: ' + message);
}
Now I want to move the picture in a permanent folder and then save the link into my database :
function movePic(file){
window.resolveLocalFileSystemURI(file, resolveOnSuccess, resOnError);
}
//Callback function when the file system uri has been resolved
function resolveOnSuccess(entry){
var d = new Date();
var n = d.getTime();
//new file name
var newFileName = n + ".jpg";
var myFolderApp = "EasyPacking";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
//The folder is created if doesn't exist
fileSys.root.getDirectory( myFolderApp,
{create:true, exclusive: false},
function(directory) {
entry.moveTo(directory, newFileName, successMove, resOnError);
},
resOnError);
},
resOnError);
}
//Callback function when the file has been moved successfully - inserting the complete path
function successMove(entry) {
//I do my insert with "entry.fullPath" as for the path
}
function resOnError(error) {
alert(error.code);
}
My file has been saved in the database to display it, i put "file://" front of the row that contains the image src
Hope this help.
J.
P.S. :
- many thanks to Simon Mac Donald (http://hi.im/simonmacdonald) for his post on googledocs.
Jerome's answer works like a charm.. the only thing to point out to people when they want to use the file don't use entry.fullPath as this can sometimes cause issues, use entry.toURL() as this will give you the full path without having to add "file://" to the path as well as bypassing issues such as SD card storage..
if (index == '0')
{
var options = {
quality: 50,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: false,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: false,
correctOrientation:true
};
$cordovaCamera.getPicture(options).then(movePic,function(imageData) {
$rootScope.imageUpload=imageData;
}, function(err) {
console.error(err);
});
function movePic(imageData){
console.log("move pic");
console.log(imageData);
window.resolveLocalFileSystemURL(imageData, resolveOnSuccess, resOnError);
}
function resolveOnSuccess(entry){
console.log("resolvetosuccess");
//new file name
var newFileName = itemID + ".jpg";
var myFolderApp = "ImgFolder";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
console.log("folder create");
//The folder is created if doesn't exist
fileSys.root.getDirectory( myFolderApp,
{create:true, exclusive: false},
function(directory) {
console.log("move to file..");
entry.moveTo(directory, newFileName, successMove, resOnError);
console.log("release");
},
resOnError);
},
resOnError);
}
function successMove(entry) {
//I do my insert with "entry.fullPath" as for the path
console.log("success");
//this is file path, customize your path
console.log(entry);
}
function resOnError(error) {
console.log("failed");
}
}
I just did a that works with promises, based on Jérôme's answer above:
function moveFile(file){
var deferred = $q.defer();
window.resolveLocalFileSystemURL(file,
function resolveOnSuccess(entry){
var dateTime = moment.utc(new Date).format('YYYYMMDD_HHmmss');
var newFileName = dateTime + ".jpg";
var newDirectory = "photos";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
//The folder is created if doesn't exist
fileSys.root.getDirectory( newDirectory,
{create:true, exclusive: false},
function(directory) {
entry.moveTo(directory, newFileName, function (entry) {
//Now we can use "entry.toURL()" for the img src
console.log(entry.toURL());
deferred.resolve(entry);
}, resOnError);
},
resOnError);
},
resOnError);
}, resOnError);
return deferred.promise;
}
function resOnError(error) {
console.log('Awwww shnap!: ' + error.code);
}
There are 3 steps:
Get the photo. Apple has a good example for this on the iPhone dev site
Get your Documents directory, like so:
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *docDir = [arrayPaths objectAtIndex:0];
And finally, storing the UIImage you got in step 1 out to disk:
NSString *filename = #"mypic.png";
NSString *fullpath = [docDir stringByAppendingPathComponent:filename];
[UIImagePNGRepresentation(image) writeToFile:fullpath atomically:YES];

Resources