Android Question How to get Exact Internal Memory and External Left on Android Phone

omo

Active Member
Licensed User
Longtime User
I like to show internal/external memory left on android. I use this code, i am not actually getting real size left or total storage capacity. Instead of showing 1GB left out of 16GB with 15.07GB used on phone it was tested as indicated below:
r2.jpg


Marked with red is what i got when code below was used:
r3.jpg

To determine memory left:
''to determine memory left
            Dim r As Reflector
            ''manifest: SetApplicationAttribute(android:largeHeap,"true")
            r.Target = r.RunStaticMethod("java.lang.Runtime", "getRuntime", Null, Null)
            FreeMemorypublic1 =  (r.RunMethod("freeMemory")/(1024*1024)) '& " MB"
            MaxMemorypublic =  (r.RunMethod("maxMemory")/(1024*1024)) '& " MB"
            availableMemorypublic =  ((r.RunMethod("maxMemory") - r.RunMethod("totalMemory"))/(1024*1024)) '& "MB"

Please , i want someone to please help me with correct code to show internal/external memory left on android.
 
Last edited:

omo

Active Member
Licensed User
Longtime User
Please, i am still searching solution for this. I need code that will give me accurate internal/external as stated above
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
Find Java code that returns it and we can help you translate it to B4A.
Ok, thank you Erel. I actually need it in B4A and B4I. Even though me and Java are not friends, i found these:

SOLUTION1 @



SOLUTION2
https://stackoverflow.com/questions/8133417/android-get-free-size-of-internal-external-memory

Code:
public static boolean externalMemoryAvailable() {
        return android.os.Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED);
    }

    public static String getAvailableInternalMemorySize() {
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSizeLong();
        long availableBlocks = stat.getAvailableBlocksLong();
        return formatSize(availableBlocks * blockSize);
    }

    public static String getTotalInternalMemorySize() {
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSizeLong();
        long totalBlocks = stat.getBlockCountLong();
        return formatSize(totalBlocks * blockSize);
    }

    public static String getAvailableExternalMemorySize() {
        if (externalMemoryAvailable()) {
            File path = Environment.getExternalStorageDirectory();
            StatFs stat = new StatFs(path.getPath());
            long blockSize = stat.getBlockSizeLong();
            long availableBlocks = stat.getAvailableBlocksLong();
            return formatSize(availableBlocks * blockSize);

 } else {
            return ERROR;
        }
    }

    public static String getTotalExternalMemorySize() {
        if (externalMemoryAvailable()) {
            File path = Environment.getExternalStorageDirectory();
            StatFs stat = new StatFs(path.getPath());
            long blockSize = stat.getBlockSizeLong();
            long totalBlocks = stat.getBlockCountLong();
            return formatSize(totalBlocks * blockSize);
        } else {
            return ERROR;
        }
    }

    public static String formatSize(long size) {
        String suffix = null;

        if (size >= 1024) {
            suffix = "KB";
            size /= 1024;
            if (size >= 1024) {
                suffix = "MB";
                size /= 1024;
            }
        }

StringBuilder resultBuffer = new StringBuilder(Long.toString(size));

        int commaOffset = resultBuffer.length() - 3;
        while (commaOffset > 0) {
            resultBuffer.insert(commaOffset, ',');
            commaOffset -= 3;
        }

        if (suffix != null) resultBuffer.append(suffix);
        return resultBuffer.toString();
    }
Get RAM Size

ActivityManager actManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
MemoryInfo memInfo = new ActivityManager.MemoryInfo();
actManager.getMemoryInfo(memInfo);
long totalMemory = memInfo.totalMem;

SOLUTION3:
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
}


Another Java/Kotlin Function Here
https://www.geeksforgeeks.org/how-t...torage-space-in-android-programmatically/amp/
 
Last edited:
Upvote 0

MarcoRome

Expert
Licensed User
Longtime User
I tested the code you found, it doesn't seem to return precise data.


I also tried the following code and the results are quite accurate. In particular the space still free on the device.
The getTotalBytes should be the total space minus the space occupied by system files.


"...That is the amount of space on the partition that contains Environment.getExternalStorageDirectory(). There will be other partitions on the device, for which you will not have access..."
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
It is quite simple to add this code an inline java. See the attached project. Whether it returns the correct values is a different question.

It is quite simple to add this code an inline java. See the attached project. Whether it returns the correct values is a different question.
@Erel, thank you so much. It actually works accurately for me on this phone i used at moment to confirm only internal storage for now. Image two was captured after use of 0.1, after first accurate response was confirmed. Please don't forget its conversion to B4I. Yes, i know i will use Native object, but since i dont have B4I now and the app is B4X, please, help me with it for reliability conversion sake from you. I will learn from it to solve more related future problems
r5.jpg


r4.jpg
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
I tested the code you found, it doesn't seem to return precise data.



I also tried the following code and the results are quite accurate. In particular the space still free on the device.
The getTotalBytes should be the total space minus the space occupied by system files.



"...That is the amount of space on the partition that contains Environment.getExternalStorageDirectory(). There will be other partitions on the device, for which you will not have access..."
@MarcoRome, i will look at your suggested solution too, but Erel solution actually worked on my phone. Proberbly some phones will have problem with it so i will whether to combine the two solution. Please can i get your phone info and android version?
 
Upvote 0

MarcoRome

Expert
Licensed User
Longtime User
@MarcoRome, i will look at your suggested solution too, but Erel solution actually worked on my phone. Proberbly some phones will have problem with it so i will whether to combine the two solution. Please can i get your phone info and android version?
Sure.
I tried the code on:
A Samsung S21 with Android 13.
Result:
1701866832527.png

With the code you found and converted by Erel I have the following result:
108 GB Total e 16 GB Free ( difference 3 GB )


A Samsung S7 Android 8.
Result:
1701867386517.png

With the code you found and converted by Erel I have the following result:
25 GB Total e 2.1 GB Free ( difference 3 GB )

So, the Free space is right for all device. The GB Total no, but i think space occupied by system files
 
  • Like
Reactions: omo
Upvote 0

omo

Active Member
Licensed User
Longtime User
Sure.
I tried the code on:
A Samsung S21 with Android 13.
Result:
View attachment 148405
With the code you found and converted by Erel I have the following result:
108 GB Total e 16 GB Free ( difference 3 GB )


A Samsung S7 Android 8.
Result:
View attachment 148406
With the code you found and converted by Erel I have the following result:
25 GB Total e 2.1 GB Free ( difference 3 GB )

So, the Free space is right for all device. The GB Total no, but i think space occupied by system files
Whaoo! Thank you for this detail info, it will be useful to see if only Samsung reports this in my further findings. Although, high-accuracy is not mandatory for me in this application context; since "Free space" is majorly what should be close to accurate
 
Upvote 0
Top