External Storage Path (SD card) for Android 5.1.1 and later with Cordova

From Android 5.0 onwards, the location of the external (removable) SD is no longer a fixed path. Instead, the serial number of the SD card is used in the path. For example, on my Samsung Galaxy S4 which is running Android 7.1.1, the physical external removable SD card path is /storage/4975-1401/.

In addition, the root of the external SD card (e.g. /storage/4975-1401/) is now read-only to Android apps. This means if your app needs to write to the SD card, it must do so in the application sandbox directory (e.g. /storage/4975-1401/Android/data/your.app.package.id/files).

cordova-plugin-file does not enable you to access the external (removable) SD card: for example cordova.file.externalRootDirectory returns file:///storage/emulated/0/.

However, you can use the getExternalSdCardDetails() of cordova-diagnostic-plugin to retrieve the filepaths to the external (removable) SD card, for example:

function getExternalSdLocation(done){
    cordova.plugins.diagnostic.getExternalSdCardDetails(function(details){
        details.forEach(function(detail){
            if(detail.type == "application"){
                cordova.file.externalSdCardApplicationDirectory = detail.filePath;
            }else if(detail.type == "root"){
                cordova.file.externalSdCardRootDirectory = detail.filePath;
            }
        });
        done();
    }, function(error){
        console.error(error);
        done();
    });
}

getExternalSdLocation(function(){
    // use cordova.file.externalSdCardApplicationDirectory to write to SD card
});

For Android 6.0 and above, run-time permission is required in order to access the external SD card. You can use requestRuntimePermission() in cordova-diagnostic-plugin to request this permission.

function requestExternalSdPermission(done){
    cordova.plugins.diagnostic.requestRuntimePermission(function(status){
        switch(status){
            case cordova.plugins.diagnostic.permissionStatus.GRANTED:
                console.log("Permission granted");
                getExternalSdLocation(done);
                break;
            case cordova.plugins.diagnostic.permissionStatus.DENIED:
                console.log("Permission denied");
                askAgain(done);
                break;
            case cordova.plugins.diagnostic.permissionStatus.DENIED_ALWAYS:
                console.log("Permission permanently denied");
                reportError(done);
                break;
        }
    }, function(error){
        console.error("The following error occurred: "+error);
        reportError(done);
    }, cordova.plugins.diagnostic.permission.WRITE_EXTERNAL_STORAGE);
}
  • Running this code on Android 5 and below will alwys result in "permission granted" without requesting permission from the user.
  • You also need to include <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> in the AndroidManifest.xml - see Android permissions.