12

In my application, I have registered a broadcast receiver to receive the system intent ACTION_DEVICE_STORAGE_LOW. I was expecting this to be broadcasted whenever the phone had low internal memory. So, I downloaded a few extra apps (my phone has a very small internal memory) which caused the OS to display the notification that the system memory is low. The phone had 10 - 15 MB remaining. However, my broadcast receiver never received that intent. Yet, the system notification stays in the notification bar, and I am not able to browse the internet because of low internal memory.

Should this intent be broadcasted whenever the low internal memory notification is displayed? Or is there some even lower threshold of memory that will send out this broadcast that I haven't hit yet on my phone? In the documentation it only says "Broadcast Action: A sticky broadcast that indicates low memory condition on the device." Since it doesn't actually define "low memory condition," I don't know if I am doing something wrong, or if I simply haven't hit that condition yet.

Here is the code for my BroadcastReceiver:

public class MemoryBroadcastReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();

        if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
            Log.isExternalStorageProblem = false;
            Log.clearNotification(Log.externalMemoryNotificationID);
        }

        if (action.equals(Intent.ACTION_DEVICE_STORAGE_OK)) {
            Log.isInternalStorageLow = false;
            Log.clearNotification(Log.internalMemoryNotificationID);
        }

        if (action.equals(Intent.ACTION_DEVICE_STORAGE_LOW)) {
            Log.isInternalStorageLow = true;
            Log.displayMemoryNotification("Internal Storage Low",
                    "The internal storage is low, Please fix this.",
                    "Please clear cache and/or uninstall apps.", Log.internalMemoryNotificationID);
        }
    }
}

I have a service that initializes the receiver, adds the intent filter and registers it (among other things):

private MemoryBroadcastReceiver memoryBroadcastReciever = new MemoryBroadcastReceiver();

public void registerBroadcastReceiver() {
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
    filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
    filter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW);
    filter.addDataScheme("file");
    
    this.getApplicationContext().registerReceiver(memoryBroadcastReciever, filter);
}

    @Override
    public void onCreate() {
        registerBroadcastReceiver();
}
mattgmg1990
  • 5,576
  • 4
  • 21
  • 26
  • I just posted my code. DallaRosa's answer is great and I think he's right about the broadcast being sent at 10% internal storage remaining, but I still haven't been able to receive the broadcast. – mattgmg1990 Nov 15 '11 at 02:50
  • 2
    In case anyone is interested, I found the answer to my problem receiving the broadcast. It turns out that this intent matches the default datascheme (meaning do not add any data scheme to the intent filter). Then it matches the action without a problem. I created two filters to match the three actions I was planning on receiving because ACTION_MEDIA_MOUNTED needs the file datascheme added. – mattgmg1990 Nov 19 '11 at 01:18

1 Answers1

27

TL;DR

As long as the device maker doesn't change the default settings, the intent will be broadcast when the free memory reaches 10% of the internal device memory.

Long Version

I grepped through the Android source code for that intent and I got to a class called DeviceStorageMonitorService

(located at: frameworks/base/services/java/com/android/server/DeviceStorageMonitorService.java)

From the javadoc:

This class implements a service to monitor the amount of disk
storage space on the device. If the free storage on device is less
than a tunable threshold value (a secure settings parameter; default 10%) a low memory notification is displayed to alert the user. If the user clicks on the low memory notification the Application Manager application gets launched to let the user free storage space.

So there you have it. As long as the device maker doesn't change that, it will be at 10%.

Checking out the source code a bit more, the DeviceStorageMonitor sends out a sticky Broadcast: (line 354)

mContext.sendStickyBroadcast(mStorageLowIntent);

Which means that even after the broadcast is finished you can catch the data by registering a receiver on that intent.

from Android Developer - Context :

Perform a sendBroadcast(Intent) that is "sticky," meaning the Intent you are sending stays around after the broadcast is complete, so that others can quickly retrieve that data through the return value of registerReceiver(BroadcastReceiver, IntentFilter). In all other ways, this behaves the same as sendBroadcast(Intent).

hope this helps.

DallaRosa
  • 5,737
  • 2
  • 35
  • 53
  • 1
    Thanks a lot! I've accepted your answer as you've absolutely answered the question I asked. You are definitely right about the notification/broadcast being sent when the phone has 10% available internal storage. I have verified that. However, I still am not sure why my application doesn't receive the intent as expected. I will try to utilize the fact that the broadcast is sticky by periodically checking the value as you mentioned, but I would love to also receive the broadcast when it happens so I can present my own notification to the user. – mattgmg1990 Nov 15 '11 at 02:54
  • Has anything changed since this answer was posted and accepted nearly a decade ago? – RockPaperLz- Mask it or Casket Jul 30 '21 at 00:08
  • @RockPaperLz-MaskitorCasket actually they have! Let me take some time later to update my answer. If you wanna check the latest source code find it here: https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java;l=1?q=DeviceStorageMonitorService.java&sq=&ss=androidhttps://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java;l=1?q=DeviceStorageMonitorService.java&sq=&ss=android – DallaRosa Jul 31 '21 at 11:52
  • Thank you for the link and I look forward to your updated answer! – RockPaperLz- Mask it or Casket Aug 01 '21 at 08:11