43

I wrote an jQuery Mobile app and packaged it with Phonegap to iOS and Android apps.

At this point I am using locally stored json files to read data.

I would like to update these json files from time to time by downloading newer json files from a server.

How can I get the json from the server and store the json files to the local file system of Android and iOS?

Cheers Johe

j7nn7k
  • 17,995
  • 19
  • 78
  • 88
  • We are fetching the data as string,then store in to byte array to form as pdf.I would be very glad if you can provide me the code snippet for saving the generated pdf in iPad,then viewing the same.Banging our heads since weeks to find a way for this.Although we were able to do with android,but not for ios :( – Eshwar Chaitanya Jan 03 '14 at 06:23

6 Answers6

93

Use FileTransfer.download, here is an example:

function downloadFile(){

window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, 
    function onFileSystemSuccess(fileSystem) {
        fileSystem.root.getFile(
        "dummy.html", {create: true, exclusive: false}, 
        function gotFileEntry(fileEntry) {
            var sPath = fileEntry.fullPath.replace("dummy.html","");
            var fileTransfer = new FileTransfer();
            fileEntry.remove();

            fileTransfer.download(
                "http://www.w3.org/2011/web-apps-ws/papers/Nitobi.pdf",
                sPath + "theFile.pdf",
                function(theFile) {
                    console.log("download complete: " + theFile.toURI());
                    showLink(theFile.toURI());
                },
                function(error) {
                    console.log("download error source " + error.source);
                    console.log("download error target " + error.target);
                    console.log("upload error code: " + error.code);
                }
            );
        }, fail);
    }, fail);
};
}
shashwat
  • 7,851
  • 9
  • 57
  • 90
justmoon
  • 1,311
  • 1
  • 10
  • 9
  • 4
    Thank you for this amazing piece of code. It had everything I needed .. well except for that fail variable refereneced at the end. If you are planning to use this just define fail as a function like: function fail(error) { console.log(error.code); } – dreamerkumar May 24 '13 at 18:19
  • 2
    how do i force it not to use external storage and store it in abc folder created under www directory? – beNerd Oct 23 '13 at 12:26
  • 1
    The above code was originally posted here: https://gist.github.com/nathanpc/2464060 as you can see a couple of extra functions (fail and showLink) are needed to make the code functional. – tayler Feb 13 '14 at 20:43
  • 5
    what is dummy.html here..?? – shashwat Mar 20 '14 at 10:42
  • 1
    ^+1, why you remove fileEntry? – Pahlevi Fikri Auliya May 26 '14 at 23:39
  • dummy.html is created to find out what full path is. – tarikakyol May 29 '14 at 10:49
  • In new version of transfer plugin use fileEntry.toURL().replace("dummy.html",""); – h0mayun Nov 21 '14 at 14:44
  • @justmoon: Where does this download to? Path? – shmuli Dec 09 '14 at 21:39
  • 3
    This code won't work anymore with the newer version of Cordova API. They changed it a bit, see this topic - http://stackoverflow.com/questions/21756274/phonegap-ios-why-when-i-get-the-full-path-of-the-filesystem-in-a-device-or-s Also, creating dummy is not really necessary, you can just go with fileSystem.root.toNativeURL() – Stranger Apr 26 '15 at 16:19
24

This is how I solved it. First set the file paths, wich are different for Android and iOS

var file_path;
function setFilePath() {
    if(detectAndroid()) {   
        file_path = "file:///android_asset/www/res/db/";
        //4 Android
    } else {
        file_path = "res//db//";
        //4 apache//iOS/desktop
    }
}

Then I load my JSON files, wich are prepackaged with the app, into the local browser storage. Like this:

localStorage["my_json_data"] = loadJSON(file_path + "my_json_data.json");

function loadJSON(url) {
    return jQuery.ajax({
        url : url,
        async : false,
        dataType : 'json'
    }).responseText;
}

If I wanna update my data. I get the new JSON Data from the server and push it into the local storage. If the server is on a different domain, which is the case most of the time, you have to make a JSONP call (check jQuery's docs on JSONP). I did it kinda like this:

$.getJSON(my_host + 'json.php?function=' + my_json_function + '&callback=?', function (json_data) {
    //write to local storage
    localStorage["my_json_data"] = JSON.stringify(json_data);

});
j7nn7k
  • 17,995
  • 19
  • 78
  • 88
  • Yes it does if you write/use an xml parser. – j7nn7k Feb 20 '12 at 15:46
  • 6
    This is a bad approach as it uses both async:false and cross domain requests. You should be using phonegaps FileTransfer.download instead http://docs.phonegap.com/en/2.0.0/cordova_file_file.md.html#FileTransfer – Blowsie Aug 14 '12 at 13:47
  • I agree with @Blowsie since you are working with a framework that implemented this functionality, you shouldn't have to do workarounds. – Mark Verkiel Oct 17 '12 at 08:28
  • Do you suggest to use the File API to make ajax calls with phonegap, I have been trying a while to understand, but is first time I see someone suggesting not using jQuery? Can you explain a little bit more please? – Lali Pali Jun 01 '13 at 11:01
8

You can do this in one line of code:

new FileManager().download_file('http://url','target_path',Log('downloaded success'));

target_path: can include directory (example: dira/dirb/file.html) and the directories will be created recursively.

You can find the library to do this here:

https://github.com/torrmal/cordova-simplefilemanagement

Jorge Torres
  • 271
  • 3
  • 2
2

Updated Answer for new Cordova

function downloadFile(url, filename, callback, callback_error) {
    var fileTransfer = new FileTransfer();
    fileTransfer.download(url,
        cordova.file.dataDirectory + "cache/" + filename,
        function (theFile) {
            console.log("download complete: " + theFile.toURL());
            if (callback)
                callback();
        },
        function (error) {
            console.log("download error source " + error.source);
            console.log("download error target " + error.target);
            console.log("upload error code: " + error.code);
            if (callback_error)
                callback_error();
        }
    );
}
2

My suggestion would be to look into PhoneGap's File API. I haven't used it myself, but it should do what you're after.

avoision
  • 1,235
  • 9
  • 14
0

For downloading and displaying a file, follow the sample code.

Include the given code just above the </head> tag in your index.html

< script type = "text/javascript" charset = "utf-8" >
  // Wait for Cordova to load
  document.addEventListener("deviceready", onDeviceReady, false);
// Cordova is ready
function onDeviceReady() {
  alert("Going to start download");
  downloadFile();
}

function downloadFile() {
  window.requestFileSystem(
    LocalFileSystem.PERSISTENT, 0,
    function onFileSystemSuccess(fileSystem) {
      fileSystem.root.getFile(
        "dummy.html", {
          create: true,
          exclusive: false
        },
        function gotFileEntry(fileEntry) {
          var sPath = fileEntry.fullPath.replace("dummy.html", "");
          var fileTransfer = new FileTransfer();
          fileEntry.remove();
          fileTransfer.download(
            "http://www.w3.org/2011/web-apps-ws/papers/Nitobi.pdf",
            sPath + "theFile.pdf",
            function(theFile) {
              console.log("download complete: " + theFile.toURI());
              showLink(theFile.toURI());
            },
            function(error) {
              console.log("download error source " + error.source);
              console.log("download error target " + error.target);
              console.log("upload error code: " + error.code);
            }
          );
        },
        fail);
    },
    fail);
}

function showLink(url) {
  alert(url);
  var divEl = document.getElementById("deviceready");
  var aElem = document.createElement("a");
  aElem.setAttribute("target", "_blank");
  aElem.setAttribute("href", url);
  aElem.appendChild(document.createTextNode("Ready! Click To Open."))
  divEl.appendChild(aElem);
}

function fail(evt) {
  console.log(evt.target.error.code);
}
</script>

Refer :- Blog Post

Mo.
  • 26,306
  • 36
  • 159
  • 225
Adarsh V C
  • 2,314
  • 1
  • 20
  • 37