3

This Cordova code works on iOS and most Android devices, but fails on some Samsung devices:

window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFileSystem, gotFileError); 

function gotFileSystem(fs) 
{   
    fs.root.getDirectory(
        'my_folder',
        {create: true}, 
        function (entry) { 
            // Yay! Got the directory,
            // unless running certain Samsung Android devices,
            // in which case the "gotFileError" function will
            // run with the error FileError.PATH_EXISTS_ERR
        }, 
        gotFileError
    );

});

What's up with Samsung?
Or, more importantly, how can I make this work on all Samsung devices too?

kris
  • 11,868
  • 9
  • 88
  • 110

1 Answers1

0

The problem

Apparently in Android 6.0.0 and onwards it has been determined that apps must explicitly ask permission to write to the file system (ref) and all existing apps can just break.
I checked the version of Android for the devices I had that were failing and both were 6.0.1.

The fix

1. Install the "cordova-diagnostic-plugin"
$ cordova plugin add cordova.plugins.diagnostic .

2. Add this logic in before calling fs.root.getDirectory()

function gotFileSystemButNowCheckForWritePermission(fs)
{
    cordova.plugins.diagnostic.requestRuntimePermission(
        function(status){
            switch(status){
                case cordova.plugins.diagnostic.permissionStatus.GRANTED:
                    console.log("Permission granted");
                    gotFileSystemAndAccessPermission(fs);
                    break;
                case cordova.plugins.diagnostic.permissionStatus.DENIED:
                    console.log("Permission denied");
                    alert('App needs access to the phones file storage in order to run');
                    gotFileSystemButNowCheckForWritePermission(fs);
                    break;
                case cordova.plugins.diagnostic.permissionStatus.DENIED_ALWAYS:
                    console.log("Permission permanently denied");
                    alert('Cannot run App without access to the phones file storage');
                    break;
            }
        }, 
        function(error){
            console.error("The following error occurred: "+error);
        }, 
        cordova.plugins.diagnostic.permission.WRITE_EXTERNAL_STORAGE
    );
}

(special thanks to this answer : https://stackoverflow.com/a/45779916/1290746 )


Further info

All apps, even Facebook and Twitter, need to do this now. In fact they are often adding an extra message before the Android system message for permission:

https://www.androidcentral.com/run-permissions-why-change-android-60-may-make-you-repeat-yourself

See also : http://www.androidpolice.com/2015/09/07/android-m-begins-locking-down-floating-apps-requires-users-to-grant-special-permission-to-draw-on-other-apps/

"Android M may soon earn a reputation for an overabundance of confirmation dialogs, at least that's how it will feel to anybody setting up a new device. Fortunately, we need only grant each permission to an app once, so things will never get as bad as Windows Vista."

Tech info : https://developer.android.com/training/permissions/requesting.html More info : https://www.captechconsulting.com/blogs/runtime-permissions-best-practices-and-how-to-gracefully-handle-permission-removal

According to this : https://medium.com/prodgasm/obtaining-app-permissions-the-right-way-and-humanizing-the-process-1c9e2d6d5818 : one could add some extra text to the prompts.

kris
  • 11,868
  • 9
  • 88
  • 110