yasd yasd - 11 days ago 7
Android Question

What to listen for to detect do-not-disturb mode changes in Android?

I would like my application to show a notification when the phone has been set to do-not-disturb modes (alarms-only, priority-only or total-silence). This works pretty well by listening to

android.media.RINGER_MODE_CHANGED
when checking this mode in quick settings and choosing the mode in the already selected tab. But when selecting another tab it isn't fired again. So my application has the wrong mode information and displays a wrong notification.

I gave another try to
android.app.action.INTERRUPTION_FILTER_CHANGED
but it wasn't fired at all in the cases above.

As I want to be informed at once I don't want to use a polling observer. In my case I'd expect massive battery drain from that.

There's a similar question but no listener solution for it:

Android: Detect Do Not Disturb status?

In the hope there might be a solution in the meantime I wanted to ask this again: Has anybody a good idea or a hint what to listen for?

UPDATE:

This is the broadcast receiver definition in AndroidManifest.xml ... to be clear about this: the receiver is called on ring mode changes, flight mode and off hook are detected as well, but it is not called on all ring mode changes, especially switches between do-not-disturb mode changes by tabbing in quick settings or by volume keys:

<receiver android:name="UpdateStatusNotification" android:process=":remote">
<intent-filter>
<action android:name="android.app.action.INTERRUPTION_FILTER_CHANGED"/>
<action android:name="android.intent.action.AIRPLANE_MODE"/>
<action android:name="android.intent.action.PHONE_STATE"/>
<action android:name="android.media.RINGER_MODE_CHANGED"/>
</intent-filter>
</receiver>


UPDATE 2:

Please read my last comment to the accepted answer.

Answer

The broadcast receiver action is :

 NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED

IntentFilter intent = new IntentFilter();
intent.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);

The below code should be in receiver.

if(intetn.getAction().equals(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED) {
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
if(mNotificationManager.getCurrentInterruptionFilter() == NotificationManager.INTERRUPTION_FILTER_ALARMS) {
    //do your stuff
} else if (mNotificationManager.getCurrentInterruptionFilter() == NotificationManager.INTERRUPTION_FILTER_NON) {
    //....
} else if (mNotificationManager.getCurrentInterruptionFilter() == NotificationManager.INTERRUPTION_FILTER_ALL) {

} else if (mNotificationManager.getCurrentInterruptionFilter() == NotificationManager.INTERRUPTION_FILTER_PRIORUTY) {

} else if (mNotificationManager.getCurrentInterruptionFilter() == NotificationManager.INTERRUPTION_FILTER_UNKNOWN) {

}

}