1
votes

In my phonegap app I take a picture with my camera and it works as expected.

Then, I'd like to send it to my server. I see that sending the base64 encoded string is a bad practice and I figured the best solution is using the file transfer plugin.

So, I added the plugin and I wrote this:

function onPhotoURISuccess(imageURI) {
    try{
        var url = "myserver/addPhoto";
        alert(url);
        var options = new FileUploadOptions();
        options.chunkedMode = false;
        options.fileKey = "recFile";
        var imagefilename = imageURI;
        options.fileName = imagefilename;
        options.mimeType = "image/jpeg";
        options.params = { "token": APP.TOKEN};
        var ft = new FileTransfer();
        alert(imagefilename);
        ft.upload(imageURI, url, win, fail, options); 
    }
    catch (err) {
        alert(err.message);
    }
}

In the last line in the try branch, I get the error FileTransferError.FILE_NOT_FOUND_ERR.

In the alert before this line, I show in the alert the path (imagefilename variable). If I try to go manually in that path in my Android device, I can't find it. The path is file:///storage/emulated/0/Android/data/com.My.App/cache/1505307795417.jpg

So, I tried to set the option

saveToPhotoAlbum: true

to check if the image is saved and I correctly see the photo in my album. I don't know why I get the error while sending it, can be the path wrong?

I don't think the problem is server side, since I can't even see the request in the server log.

UPDATE:

I also tried this after Anuj T suggestion, but the result is still the same:

function onPhotoURISuccess(imageURI) {
    var filepath;
    window.resolveLocalFileSystemURL(imageURI, function success(fileEntry) {

        // Do something with the FileEntry object, like write to it, upload it, etc.
        // writeFile(fileEntry, imageURI);
        filepath = fileEntry.fullPath;
        alert("got file: " + fileEntry.fullPath);
        // displayFileData(fileEntry.nativeURL, "Native URL");

        try {
            var url = "myUrl";
            alert(url);
            var options = new FileUploadOptions();
            options.chunkedMode = false;
            options.fileKey = "recFile";
            var imagefilename = filepath;
            options.fileName = imagefilename;
            options.mimeType = "image/jpeg";
            options.params = { "token": APP.TOKEN }; // if we need to send parameters to the server request
            var ft = new FileTransfer();
            alert(imagefilename);
            alert(imageURI);

            ft.upload(filepath, url, win, fail, options);
        }
        catch (err) {
            alert(err.message);
        }

    }, function () {
        // If don't get the FileEntry (which may happen when testing
        // on some emulators), copy to a new FileEntry.
        alert("file system fail");
        createNewFileEntry(imgUri);

    });


}

UPDATE 2:

This is my server side code.

internal GenericResponse AddChiusuraPhoto(string token)
    {
        Utility.Logger("AddChiusuraPhoto");
        var gr = new GenericResponse();
        if (CheckToken(token, out IS_UTENZE utente))
        {
            try
            {
                var md5 = new md5Manager();
                HttpPostedFile file = HttpContext.Current.Request.Files["recFile"];
                if (file == null)
                    return null;
                string targetFilePath = @"C:\ProgramData\" + file.FileName;
                file.SaveAs(targetFilePath);
                Utility.Logger("[AddChiusuraPhoto] Returning lista ");
                return gr;
            }
            catch (Exception ex)
            {
                gr.ESITO = "[KO]";
                gr.MESSAGGIO = ex.ToSafeString();
                Utility.Logger("AddChiusuraPhoto " + gr.MESSAGGIO);
            }
        }
        else
        {
            gr.ESITO = "[KO]";
            gr.MESSAGGIO = "Utente non loggato, impossibile effettuare il logout.";
            Utility.Logger("AddChiusuraPhoto " + gr.MESSAGGIO);
        }
        return gr;
    }

Note that this is a WCF. This is the addressing part:

[OperationContract]
[WebInvoke(UriTemplate = "chiusure/addPhoto", Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
GenericResponse AddChiusuraPhoto(string token);
1

1 Answers

1
votes

You need to take a picture and get a FileEntry Object

If you need to use a FileEntry object, set the destinationType to Camera.DestinationType.FILE_URI in your CameraOptions object

UPDATED CODE

function getPicture(){

      var srcType = Camera.PictureSourceType.CAMERA;
      var options = setOptions(srcType);
      //var func = createNewFileEntry;

      navigator.camera.getPicture(function cameraSuccess(imageUri) {

          //displayImage(imageUri);
          // You may choose to copy the picture, save it somewhere, or upload.
          //func(imageUri);
          var filename = imageUri.substr(imageUri.lastIndexOf('/') + 1);
          window.resolveLocalFileSystemURL(cordova.file.cacheDirectory, function success(dirEntry) {

              // Do something with the FileEntry object, like write to it, upload it, etc.
              // writeFile(fileEntry, imgUri);
              console.log("got file: " + dirEntry.fullPath);

              console.log("file name " + filename);
              // JPEG file
              dirEntry.getFile(filename, { create: true, exclusive: false }, function (fileEntry) {

                      // Do something with it, like write to it, upload it, etc.
                      // writeFile(fileEntry, imgUri);
                      console.log("got file: " + fileEntry.fullPath);
                      // displayFileData(fileEntry.fullPath, "File copied to");
                      upload(fileEntry);

                  }, onErrorCreateFile);                      
              // displayFileData(fileEntry.nativeURL, "Native URL");
          }, function () {
            // If don't get the FileEntry (which may happen when testing
            // on some emulators), copy to a new FileEntry.
              //createNewFileEntry(imgUri);
          });
          //console.log(imageUri);

      }, function cameraError(error) {
          console.debug("Unable to obtain picture: " + error, "app");

      }, options);
 };

set option function.

function setOptions(srcType) {
  var options = {
      // Some common settings are 20, 50, and 100
      quality: 50,
      destinationType: Camera.DestinationType.NATIVE_URI ,
      // In this app, dynamically set the picture source, Camera or photo gallery
      sourceType: srcType,
      encodingType: Camera.EncodingType.JPEG,
      mediaType: Camera.MediaType.PICTURE,
      allowEdit: false,
      saveToPhotoAlbum:false,
      correctOrientation: true  //Corrects Android orientation quirks
  };
  return options;
}

See the detail explanation here.

To Upload the file to the server

function upload(fileEntry) {

 var fileURL = fileEntry.toURL();

 var success = function (r) {
     console.log("Successful upload..." + JSON.stringify(r));
     console.log("Code = " + JSON.stringify(r.responseCode));
     alert(JSON.stringify(r.response));
     // displayFileData(fileEntry.fullPath + " (content uploaded to server)");
 };

 var fail = function (error) {
     alert("An error has occurred: Code = " + error.code);
     console.log("Error= " + error);
 };

 var options = new FileUploadOptions();
  options.fileKey = "file";
  options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
  options.mimeType = "text/plain";

var params = {};
 params.value1 = "test";
 params.value2 = "param";

 options.params = params;

 var SERVER = "http://posttestserver.com/post.php";

 var ft = new FileTransfer();
 // SERVER must be a URL that can handle the request, like
 // http://some.server.com/upload.php
 ft.upload(fileURL, encodeURI(SERVER), success, fail, options);
}

when you get the success alert you can also check your params uploaded to the server or not, you will receive the link in success.

enter image description here

Hope this help.