This problem happens on Android version > 5 when you select a file from the native file chooser using cordava or phonegap, learn how to deal with this issue !

Solve native path of android (content://) if resolveLocalFileSystemURL doesn't work

In cordova you can actually read an android file with a given path easily (file://storage/etc/etc.txt) using the cordova file plugin ,for example:

var path = "file:///path/to/myfile/";

window.resolveLocalFileSystemURL(path, success, fail);
            
function fail(e) {
      console.error(e);
}

function success(fileEntry) {
   fileEntry.file(function(file) {
           var reader = new FileReader();
           reader.onloadend = function(e) {
           var content = this.result;
           console.log(content);
       };
       reader.readAsText(file); // or the way you want to read it
   });
}

However, with android version >= 4.4 was introduced the MediaStore. The Media provider contains meta data for all available media on both internal and external storage devices and returns a content:// URI.

Then if your filebrowser provides a native uri content of android, something like : content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F63131  instead of file:///path/to/myfile/ ,  you will be unable to retrieve a file entry of the previous path as the cordova file plugin expects an absolute file path.

This is a well known problem of the paths with android >= 4.4, therefore someone just wrote a plugin to solve this issue, you can use the following solution.

Download the cordova-plugin-filepath using the following command in your command prompt :

$ cordova plugin add cordova-plugin-filepath 

Then use the following code to solve :

  var uripath = 'content://com.google.android.apps.photos.contentprovider/0/1/content......';

  window.FilePath.resolveNativePath(uripath, successNative, failNative);
            
  function failNative(e) {
        console.error('Houston, we have a big problem :(');
  }

  function successNative(finalPath) {
        var path = 'file://'+ finalPath;
        
        window.resolveLocalFileSystemURL(path, success, fail);
            
        function fail(e) {
              console.error(e);
        }

        function success(fileEntry) {
           fileEntry.file(function(file) {
                   var reader = new FileReader();
                   reader.onloadend = function(e) {
                   var content = this.result;
                   console.log(content);
               };
               reader.readAsText(file); // Finally !
           });
        }
  } 

The content uri will be resolved by this plugin using window.FilePath.resolveNativePath and a native filepath will be retrieved, with this you can use then resolveLocalFileSystemURL to read the file without any problem.

You can read more about this plugin here.

Option 2

Use a plugin that generates file:// path style instead of an URI. The ourcodeworld-cordova-filebrowser plugin is a cordova implementation of NoNonsense-FilePicker for Android. This plugin allow you to select folder and files, and at the same time create folders and create files (not a file is created actually, but it will return the filepath and name of the "choosen path").

Add this plugin into your project executing the following command in the command prompt:

cordova plugin add https://github.com/ourcodeworld/cordova-ourcodeworld-filebrowser.git

And start a single filepicker to test the plugin:

// Single file selector
window.OurCodeWorld.Filebrowser.filePicker.single({
    success: function(data){
        if(!data.length){
            // No file selected
            return;
        }

        // Array with filepaths
        // ["file:///storage/emulated/0/360/security/file.txt", "file:///storage/emulated/0/360/security/another-file.txt"]
    },
    error: function(err){
        console.log(err);
    }
});

Note that the plugin works both in vertical and horizontal orientation and the filepath will be readable by the file-plugin of cordova.

Read more about this plugin in the official documentation or in the github repository here.

Have fun


Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.

Sponsors