To get all available storage folders (including SD cards), you first get the storage files:
File internalStorageFile=getFilesDir();
File[] externalStorageFiles=ContextCompat.getExternalFilesDirs(this,null);
Then you can get the available size of each of those.
There are 3 ways to do it:
API 8 and below:
StatFs stat=new StatFs(file.getPath());
long availableSizeInBytes=stat.getBlockSize()*stat.getAvailableBlocks();
API 9 and above:
long availableSizeInBytes=file.getFreeSpace();
API 18 and above (not needed if previous one is ok) :
long availableSizeInBytes=new StatFs(file.getPath()).getAvailableBytes(); 
To get a nice formatted string of what you got now, you can use:
String formattedResult=android.text.format.Formatter.formatShortFileSize(this,availableSizeInBytes);
or you can use this in case you wish to see exact bytes number but nicely:
NumberFormat.getInstance().format(availableSizeInBytes);
Do note that I think the internal storage could be the same as the first external storage, since the first one is the emulated one.
EDIT: Using StorageVolume on Android Q and above, I think it's possible to get the free space of each, using something like:
fun getStorageVolumesAccessState(context: Context) {
    val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
    val storageVolumes = storageManager.storageVolumes
    val storageStatsManager = context.getSystemService(Context.STORAGE_STATS_SERVICE) as StorageStatsManager
    for (storageVolume in storageVolumes) {
        var freeSpace: Long = 0L
        var totalSpace: Long = 0L
        val path = getPath(context, storageVolume)
        if (storageVolume.isPrimary) {
            totalSpace = storageStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT)
            freeSpace = storageStatsManager.getFreeBytes(StorageManager.UUID_DEFAULT)
        } else if (path != null) {
            val file = File(path)
            freeSpace = file.freeSpace
            totalSpace = file.totalSpace
        }
        val usedSpace = totalSpace - freeSpace
        val freeSpaceStr = Formatter.formatFileSize(context, freeSpace)
        val totalSpaceStr = Formatter.formatFileSize(context, totalSpace)
        val usedSpaceStr = Formatter.formatFileSize(context, usedSpace)
        Log.d("AppLog", "${storageVolume.getDescription(context)} - path:$path total:$totalSpaceStr used:$usedSpaceStr free:$freeSpaceStr")
    }
}
fun getPath(context: Context, storageVolume: StorageVolume): String? {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
        storageVolume.directory?.absolutePath?.let { return it }
    try {
        return storageVolume.javaClass.getMethod("getPath").invoke(storageVolume) as String
    } catch (e: Exception) {
    }
    try {
        return (storageVolume.javaClass.getMethod("getPathFile").invoke(storageVolume) as File).absolutePath
    } catch (e: Exception) {
    }
    val extDirs = context.getExternalFilesDirs(null)
    for (extDir in extDirs) {
        val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
        val fileStorageVolume: StorageVolume = storageManager.getStorageVolume(extDir)
                ?: continue
        if (fileStorageVolume == storageVolume) {
            var file = extDir
            while (true) {
                val parent = file.parentFile ?: return file.absolutePath
                val parentStorageVolume = storageManager.getStorageVolume(parent)
                        ?: return file.absolutePath
                if (parentStorageVolume != storageVolume)
                    return file.absolutePath
                file = parent
            }
        }
    }
    try {
        val parcel = Parcel.obtain()
        storageVolume.writeToParcel(parcel, 0)
        parcel.setDataPosition(0)
        parcel.readString()
        return parcel.readString()
    } catch (e: Exception) {
    }
    return null
}
Hopefully this can help.