12

I'm building a mobile app for Android with JQM and PhoneGap. I need to upload a file (image) to remote server (from galery or take a picture with camera). Basically it can be done using phonegap file API, the problem is that the server was written to support simple POST submission.

What I need is to "simulate" in my app request exact as it would sent from the following html form. In addition I need to get the server response.

<form name="myWebForm" ENCTYPE="multipart/form-data" action="http://www.myurl.com/api/uploadImage "method="post">
    <input type="file" name="image" />
    <input type="submit" value="Submit"/>       
</form>

I tried to use phonegap file API but the structure of the retrieved data on the server side is different than it should be.

I tried to implement that form in my app but the "choose file" button was disabled...

How it can be achieved without making any changes on the server side?

Victor
  • 263
  • 1
  • 5
  • 13
  • See my answer for a simple full example. All you have to do is replicate http://stackoverflow.com/questions/11402937/phonegap-file-transfer-error-code-3-http-status-404-on-iphone/14376244#14376244 – iOSAndroidWindowsMobileAppsDev Jan 22 '13 at 08:35

2 Answers2

12

You can't use input file on Phonegap. It's not supported. You need make something like this:

    function onDeviceReady() {

        // Retrieve image file location from specified source
        navigator.camera.getPicture(uploadPhoto,
                                    function(message) { alert('get picture failed'); },
                                    { quality: 50, 
                                    destinationType: navigator.camera.DestinationType.FILE_URI,
                                    sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY }
                                    );

    }

    function uploadPhoto(imageURI) {
        var options = new FileUploadOptions();
        options.fileKey="file";
        options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1)+'.png';
        options.mimeType="text/plain";

        var params = new Object();

        options.params = params;

        var ft = new FileTransfer();
        ft.upload(imageURI, encodeURI("http://some.server.com/upload.php"), win, fail, options);
    }

    function win(r) {
        console.log("Code = " + r.responseCode);
        console.log("Response = " + r.response);
        console.log("Sent = " + r.bytesSent);
    }

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

On getPicture method you will choose what's your file source. See more info: http://docs.phonegap.com/en/2.1.0/cordova_file_file.md.html#FileTransfer

EDIT:

The fileName extension was needed specify as well as the mimeType is requested on 'text/plain' format to send image on text format. As for the params, if you don't need them why use them?

A. Magalhães
  • 1,511
  • 2
  • 22
  • 31
  • This is exactly the code that I used, but the structure of this code on the server side is not like it was submitted by form. That method pass an array called 'files', that has another array called 'file' (options.fileKey="file";) and the 'file' array has properties like name, type, size etc... the problem is that the server side looking for variable called "image" that holds the image... like in the form... any other suggestions? – Victor Dec 13 '12 at 14:55
  • See changes of mimeType to text/plain and to send empty params. – A. Magalhães Dec 13 '12 at 15:01
  • Still doesn't work... Is it possible to submit programmatically the returned object from navigator.camera.getPicture without phonegap? Using jquery or javascript only? – Victor Dec 13 '12 at 16:26
  • This is the only solution I found to upload. I forgot to tell that you need put the file extension on filename like options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1)+".png"; – A. Magalhães Dec 13 '12 at 16:48
  • Sorry. But I don't have more any options to you. – A. Magalhães Dec 13 '12 at 17:17
  • It's working now...... Thank you very much... You can post it as answer. Can you explain please the logic behind this solution? why it was important to change the mime type and send the params empty? – Victor Dec 13 '12 at 17:18
  • I think the EDIT answers to your questions. – A. Magalhães Dec 13 '12 at 18:35
  • Bro, you deserve a medal for this solution – Dan Green-Leipciger Dec 21 '13 at 15:56
  • I assume you need the FileTransfer and Camera plugins installed for the above code to work. – commonpike Sep 22 '14 at 12:06
  • As [PhoneGap API Documentation](http://docs.phonegap.com/en/2.1.0/guide_plugin-development_index.md.html#Plugin%20Development%20Guide) says: A Cordova plugin bridges a bit of functionality between the WebView powering a Cordova application and the native platform the Cordova application is running on. – A. Magalhães Sep 22 '14 at 21:22
  • how to upload multiple files using this? The HTML5 input tag supported multiple="multiple" attribute – Parth Doshi Oct 22 '16 at 13:34
  • i am also facing the similar issue but not able to fix it. can you please check this question stackoverflow.com/questions/40514847 – Roxx Nov 10 '16 at 10:55
0

You can't use input file on Phonegap. It's not supported. You need make something like this:

        <div ng-click="selectPicture()">selectPicture</div> // Put own HTML format but call the fuction

        // Angular fuction
             $scope.selectPicture = function () {
                var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
                var options = {
                    // Some common settings are 20, 50, and 100
                    quality: 50,
                    destinationType: Camera.DestinationType.FILE_URI,
                    // In this app, dynamically set the picture source, Camera or photo gallery
                    sourceType: srcType,
                    encodingType: Camera.EncodingType.JPEG,
                    mediaType: Camera.MediaType.PICTURE,
                    allowEdit: true,
                    correctOrientation: true  //Corrects Android orientation quirks
                }
                navigator.camera.getPicture(function cameraSuccess(imageUri) {
                    MobileUploadFile(imageUri);

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

            function MobileUploadFile(imageURI) {
                //console.log(imageURI);   
                var options = new FileUploadOptions();
                options.fileKey = "file";
                options.fileName = imageURI.substr(imageURI.lastIndexOf('/') + 1);
                options.mimeType="image/jpeg";
                options.chunkedMode = false;

                var ft = new FileTransfer();
                ft.upload(imageURI, encodeURI("http://www.example.com/upload.php"), function(result){
                    //console.log(JSON.stringify(result));
                }, function(error){
                    //console.log(JSON.stringify(error));
                }, options);
            };

     // php file
     <?php 
       // Directory where uploaded images are saved
        $dirname = "uploads/"; 
        // If uploading file
         if ($_FILES) {
             print_r($_FILES);
             mkdir ($dirname, 0777, true);
             move_uploaded_file($_FILES["file"]{"tmp_name"],$dirname."/".$_FILES["file"]["name"]);
        }
      ?>