How to check if the device has Low Storage on Android Oreo API 26 and Above

Viewed 5141

How can I check if the device has low storage on Android 8 Oreo. I saw in the Android Documentation that the Intent.ACTION_DEVICE_STORAGE_LOW is deprecated in API 26.

This constant was deprecated in API level 26. if your app targets O or above, this broadcast will no longer be delivered to any BroadcastReceiver defined in your manifest. Instead, apps are strongly encouraged to use the improved getCacheDir() behavior so the system can automatically free up storage when needed. - Android Documentation

They are encouraging me use getCacheDir() instead.

But I don't understand much of it, as getCacheDir() seems to return the system cache directory path as a FILE object, which can only be used to clear cache or some such.

But I need to check whether the device is running low on device storage. I hope someone will help me in this

2 Answers

After digging into the code of android excatlty the class that release the Low storage notification called DeviceStorageMonitorService

Here's what i found, Some phones use the sys_storage_threshold_percentage and some use sys_storage_threshold_max_bytes so to test the storage you should get the real value from the Settings.Secure using both keys and then compare between sys_storage_threshold_percentage * Total memory size of data system folder and sys_storage_threshold_max_bytes and then take the small value and compare it to the available storage space of data system folder, here's the code of how to do it

    private void checkForLowStorage() {

        long mFreeMem = getDeviceCurrentStorage();
        float deviceLowStorageThreshold = getDeviceLowStorageThreshold();
        if (mFreeMem <= deviceLowStorageThreshold) {
            Toast.makeText(this, R.string.low_storage_error_message, Toast.LENGTH_LONG).show();
            // Handle storage low state
        } else {
            // Handle storage ok state
        }
    }

    private long getDeviceCurrentStorage() {

        long mFreeMem = 0;
        try {
            StatFs mDataFileStats = new StatFs("/data");
            mDataFileStats.restat("/data");
            mFreeMem = (long) mDataFileStats.getAvailableBlocksLong() *
                    mDataFileStats.getBlockSizeLong();
        } catch (IllegalArgumentException e) {
            // use the old value of mFreeMem
        }
        return mFreeMem;
    }

    private long getDeviceLowStorageThreshold() {

        long value = Settings.Secure.getInt(
                getContentResolver(),
                "sys_storage_threshold_percentage",
                10);
        StatFs mDataFileStats = new StatFs("/data");
        long mTotalMemory = ((long) mDataFileStats.getBlockCountLong() *
                mDataFileStats.getBlockSizeLong()) / 100L;
        value *= mTotalMemory;
        long maxValue = Settings.Secure.getInt(
                getContentResolver(),
                "sys_storage_threshold_max_bytes",
                500*1024*1024);
        return Math.min(value, maxValue);
    }

I'm still testing it, Dunno if it's not going to work on some devices

Related