Phonegap - Retrieve photo from Camera Roll via path

后端 未结 4 1161
梦谈多话
梦谈多话 2020-12-29 05:49

In my PhoneGap/jQuery Mobile app, I\'m currently using PhoneGaps\' Camera API to allow the user to take a photo, which is also stored in the Camera Roll. I\'m setting Destin

相关标签:
4条回答
  • 2020-12-29 06:12

    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

    0 讨论(0)
  • 2020-12-29 06:21

    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.

    0 讨论(0)
  • 2020-12-29 06:23

    As of Cordova 1.8 this is working well, see:

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

    0 讨论(0)
  • 2020-12-29 06:28

    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.

    0 讨论(0)
提交回复
热议问题