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

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

Become a more social person