Phonegap - Retrieve photo from Camera Roll via path

半城伤御伤魂 提交于 2019-11-30 04:46:07

After you retrieve the file using the FILE_URI method you should use the File API to copy the image from the temp folder to the Documents folder and store the new path in your DB.

So you would take the result of your getPicture() pass it to window.resolveLocalFileSystemURI() to get a FileEntry. Then you can call FileEntry.copyTo() method to back up your file.

As of Cordova 1.8 this is working well, see:

http://docs.phonegap.com/en/1.8.0/cordova_camera_camera.md.html#Camera

Sorry that I had to create a separate post because I have not enough reputation to comment.

Thank you Simon for the advice and Casey for the solution.

I was working on a Cordova app that requires me to take a picture on iOS, save it in a directory and the link on local storage to be accessed later. After user submits the picture, the app needs to delete it from the directory.

Here are add on codes on how you can do that and also how you can view the project Documents folder.

You can get the full directory of the picture you want to delete by using $('#pictureid').attr('src').

function deletePic(file){
    console.log("deleting: "+file+"...");
    var file = "photos/"+file.toString().split('/').slice(-1)[0]; //gets photo name

    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys){
    fileSys.root.getFile(file, 
                {create:false}, 
                function(entry){
                    entry.remove();
                }, resOnErrorDelete);
                },
    resOnErrorDelete);          
}

function resOnErrorDelete(error) {
    console.log("resOnErrorDelete: "+error.code);
}

Alternatively if you have a form with multiple photo attachments, you may want to give the Documents folder you created to store the photos a unique name. This way, you can delete the whole folder after you submit the batch of photos instead of deleting them one by one.

function deleteFolder(folder){  
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys){
    fileSys.root.getDirectory(folder, 
                {create:true, exclusive: false}, 
                function(entry){
                    entry.removeRecursively();
                }, resOnErrorDelete);
                },
    resOnErrorDelete);          
}

function resOnErrorDelete(error) {
    console.log("resOnErrorDelete: "+error.code);
}

As for accessing the project Documents folder, you need to edit the plist to enable iTunes File Sharing

Go to [project_folder]/platforms/ios/[project_name]/[project_name]-Info.plist. Right-click and open with XCode.

You will see a table of keys. Right-click anywhere below the table and Add Row. A new row will be created. Double-click on the key and type UIFileSharingEnabled. It will automatically change to Application supports iTunes file sharing, put that key value to YES.

Now if you go to iTunes under your iOS's device's applications, scroll all the way down to see the File Sharing area where you can see your folder. However, it is just there for you to 'Save to' but no editing.

Hope all these additional information helps. It took me 2 days of research to find out.

Sharing my version which uses promises and resolveLocalFileSystemURL except resolveLocalFileSystemURI because second one is deprecated. It also uses original file name in new created one.

function copyPhotoToAppDir(imageURI) {
  if(!imageURI){
    console.warn("You need to pass imageURI");
    return;
  }

  var fileNameSplit = imageURI.split("/"),
    fileName = fileNameSplit[fileNameSplit.length - 1],
    deferred = $q.defer();

  var copyPhoto = function(fileEntry) {
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
      fileSys.root.getDirectory("photos", {create: true, exclusive: false}, function(dir) {
        fileEntry.copyTo(dir, fileName, onCopySuccess, onFileFail);
      }, onFileFail);
    }, onFileFail);
  };

  var onCopySuccess = function onCopySuccess(entry) {
    console.log("NEW PATH", entry.fullPath);
    deferred.resolve(entry.fullPath);
  };

  var onFileFail = function (error) {
    console.log("COPY FAIL", error);
    deferred.reject();
  };

  window.resolveLocalFileSystemURL(imageURI, copyPhoto, onFileFail);

  return deferred.promise;
}

Usage:

var uri = "path1";
copyPhotoToAppDir(uri).then(function(newURI){
  console.log(newURI);
});

Multiple URIs usage:

var uriArr = ["path1", "path2"]; 
  copyPhotoPromises = [];

uriArr.forEach(function(val){
  copyPhotoPromises.push(copyPhotoToAppDir(val));
});
$q.all(copyPhotoPromises).then(function(values){
  console.log("Array with new paths", values);
});

New file URIs will be saved as "/photos/fileName.jpg". To get the absolute path, you can use:

cordova.file.documentsDirectory + newFileUri.substring(1);

I'm using $q from angular here to handle promises but it can be easily changed to jQuery one.

deferred = $q.defer();

would need to be changed to:

deferred = jQuery.Deferred();

Cheers

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!