Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cordova fileTransfer works perfect on iOS, throws error code = 1 on Android

I'm developing a mobile app for iOS and Android using Cordova and Ionic Framework. There needs to be 'Send Photo' and related functionality, and I'm using Cordova's FileTransfer to do this.

It works perfectly on iOS simulator, but throws "error code = 1" on Android device.

I know this means file_not_found or similar.

Note it happens if I take a picture from camera, or choose one from gallery.

Here is my code:

$scope.takePic = function() {
        var options =   {
            quality: 50,
            destinationType: navigator.camera.DestinationType.FILE_URI,
            sourceType: 0,      // 0:Photo Library, 1=Camera, 2=Saved Photo Album
            encodingType: 0     // 0=JPG 1=PNG
        }
        navigator.camera.getPicture(onSuccess, onFail, options);
    }
    var onSuccess = function(FILE_URI) {
        window.resolveLocalFileSystemURL(FILE_URI, function(fileEntry) {
            alert("full: " + JSON.stringify(fileEntry));
            var realUrl = fileEntry.toURL();
            $scope.picData = realUrl;
            $scope.$apply();
            console.log("real URL", realUrl);
        });
    };
    var onFail = function(e) {
        console.log("On fail " + e);
    }
    function win(r) {
        console.log("Code = " + r.responseCode);
        console.log("Response = " + r.response);
        console.log("Sent = " + r.bytesSent);
        Flash.success("Wysłano");
        var response = JSON.parse(r.response);
        $scope.attachment_id = response.data;
        $scope.$apply();
        $http.post($rootScope.baseServerUrl + 'Members/changeAvatar', {attachment_id: response.data}).success( function (response){
            console.log(response);
        });
    }

    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);
    }
    $scope.send = function() {
        Flash.warning('wysyłam');
        var myImg = $scope.picData;
        alert(myImg);
        var options = new FileUploadOptions();

        options.headers = {
            Accept: "application/json",
            Connection: "close"
        }
        options.fileKey="file";
        options.fileName=$scope.picData.substr($scope.picData.lastIndexOf('/')+1);
        options.mimeType="image/jpeg";
        options.chunkedMode = false;
        var ft = new FileTransfer();
        ft.upload(myImg, encodeURI($rootScope.baseServerUrl + 'media/Attachments/add'), win, fail, options);
    }

$scope.takePic and send are called by button clicks. There are a lot of alerts and console because I'm trying to find why its not working.

After picking a picture from the gallery on android I get:

file:///storage/sdcard0/download/file-name.jpg

on iOS simulator:

file:///Users//Library/Application%20Support/iPhone%20Simulator/7.1/Applications/B5FB2081-54E7-4335-8856-84C6499E6B07/tmp/cdv_photo_038.jpg

and by using this path I can show this picture by using <img src="{{picData}}"> this works on both platforms.

But if I try to send it on an Android device I get error Code = 1. On iOS sim it sends, photo, gets proper response, changes avatar...everything.

Both Cordova and plugins File and FileTransfer are up to date.

like image 733
asvid Avatar asked Oct 31 '22 19:10

asvid


2 Answers

It looks like you might have a path error, file:///storage.sdcard0/download/file-name.jpg should be file:///storage/sdcard0/download/file-name.jpg if I'm not mistaken.

From perusing your code, it doesn't appear that you are parsing anything incorrectly. Maybe you want to try using an older more stable version of the file plugin if it is returning the wrong URI (and maybe file a bug report)? I haven't used the file plugin since they released 1.0, but from personal experience there have been bugs/regressions in the bleeding edge releases before.

You can target specific plugin versions from the cordova-cli using @ like cordova plugin add [email protected]

As well as specific tags/releases from github using # like cordova plugin add https://github.com/apache/cordova-plugin-file-transfer#r0.4.2

like image 118
user1234 Avatar answered Nov 09 '22 04:11

user1234


Maybe late but I've kinda fixed it.

In my view file I use:

<input id="file" name="file" type="file" onchange="angular.element(this).scope().addFile(this)" class="upload" accept="image/*" capture="camera"/>

so it fires $scope.addFile() from my controller as soon as you pick up file from galery:

$scope.addFile = function(item){

        function uploadComplete(evt) {
            /* This event is raised when the server send back a response */
            $scope.imgId = JSON.parse(evt.target.responseText).data;
            $scope.$apply();
            $http.post($rootScope.baseServerUrl + 'Members/changeAvatar', {attachment_id: $scope.imgId}).success( function (response){
                console.log(response);
                $scope.User.attachment_id = $scope.imgId;
                $scope.$apply();
            });
        }
        function uploadFailed(evt) {
            alert("There was an error attempting to upload the file.")
        };
        var updateImage = function (element) {
            $scope.$apply(function() {
                $scope.theFile = element.files[0];

                var formData = new FormData();
                formData.append("file", $scope.theFile);

                var xhr = new XMLHttpRequest()

                xhr.addEventListener("load", uploadComplete, false)
                xhr.addEventListener("error", uploadFailed, false)
                xhr.open("POST", $scope.baseServerUrl + "media/Attachments/add")
                xhr.setRequestHeader("Accept","application/json")
                $scope.progressVisible = true

                xhr.send(formData);
            });
        };
        updateImage(item)
    }

Works for all Android devices I tested, above 4.0 excluding 4.4 because of input type="file" bug, works on iOS simulator and devices with 8.1 system (should also on older but I didn't test it).

It's not a perfect solution, because you can use only pictures you already got on your phone. I couldnt figure it out how to use Cordova FileTransfer with our server authentication way: I was always getting "please log in" in response, even when I tried adding all needed headers, tokens, anything...

So even though this solution is far from what I wanted to achieve - it works. Hope it helps anyone.

like image 44
asvid Avatar answered Nov 09 '22 03:11

asvid