Monday, February 18, 2013

PhoneGap Android XhrFileReader

The FileReader API works great as long as the file you want to read is on the device's file system. However if you want to read a file you've packed in the Android assets folder you would need to use XHR to read the file. I'm providing an interface that follows the same API as the regular FileReader. Of course the XhrFileReader is not limited to only reading files from the assets folder, it can also read files from the file system and over HTTP.

Adding the plugin to your project 

To install the plugin, move XhrFileReader.js to your project's www folder and include a reference to it in your html files.

Using the plugin 

To instantiate a new reader use the folling code:
var reader = cordova.require("cordova/plugin/xhrfilereader"); 
Setup your event handlers:
// called once the reader begins
reader.onloadstart = function() {
    console.log("load start");
};
// called when the file has been completely read
reader.onloadend = function(evt) {
    console.log("File read");
    console.log(evt.target.result);
}; 
Unfortunately, you will only get an error on files read over HTTP. When you specify a file:// path the request status is always 0. There is no way to tell between a successful read or an error. So if you specify a file that does not exist like "file:///does.not.exist.txt" you will get an empty evt.target.result in your onloadend handler.
// called if the reader encounters an error
reader.onerror = function(error) {
    console.log("Error: " + error.code);
}; 
Progress events are fired but are not very useful as they don't contain partial results.
// called while the file is being read
reader.onprogress = function(evt) {
    console.log("progress");
}; 
Finally call your read method, for instance:
reader.readAsText("http://www.google.com"); reader.readAsText("file:///android_asset/www/config.json"); reader.readAsText("file:///sdcard/error.log");
and that's about it. Obviously, this plugin is most useful when you need to read a text file from the assets folder.

6 comments:

Raymond Camden said...

Err... respectfully... why? Why not just $.get?

Simon MacDonald said...

@Raymond Camden

Well....

1) That assumes you are using jQuery.
2) It doesn't follow the W3C FileReader spec.

but there is no reason why you couldn't use your own XHR (jQuery, Dojo, Sencha) to do exactly the same thing I did.

This is also a stealth feature for Cordova. If people like it I'll merge the changes into the FileReader code so that it will be able to handle files in the assets as well.

Raymond Camden said...

1) Heh, well, it works in Zepto too. ;)

2) Well, ok.

"This is also a stealth feature for Cordova. If people like it I'll merge the changes into the FileReader code so that it will be able to handle files in the assets as well."

Fair enough. ColdFusion supports this as well.

Gabriele said...

Hello everybody,
I think this is a great improvement to the FileReader API so i think it should be integrated in the cordova code.
I agree with Raymond when he tells that a simple $.get call (or whatever the framework you use gives) is simple and effective, but neverthelessI think this is very useful especially for reading files in the asset directory. With this plugin the user will be able to read filesystem and asset files using the same API and this will result in a simpler coding.
What do you think?

Farid Hidayat said...

i try to install , but fail.
could you please tell me how to install with example.
thanks.

Simon MacDonald said...

@Farid Hidayat

What's to install? You just need to use the .js file in your project.