How to toggle Android device between silent mode and DND programmatically

295 Views Asked by At

I'm trying to make the phone toggle between silent mode , DND mode an both .

The only code I found for this is:

AudioManager.ringerMode = AudioManager.RINGER_MODE_SILENT

By it's name I expected it to toggle silent mode but it actually toggles DND.

The documentation is practically useless and I couldn't find any question addressing this issue on newer Android versions.

How can I toggle between these states on Android 21+?

3

There are 3 best solutions below

3
On
import android.app.NotificationManager;
import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
import android.provider.Settings;

public class SoundControl {

    // Constants for different modes
    private static final int MODE_SILENT = 0;
    private static final int MODE_VIBRATE = 1;
    private static final int MODE_NORMAL = 2;

    private final Context context;
    private final AudioManager audioManager;
    private final NotificationManager notificationManager;

    public SoundControl(Context context) {
        this.context = context;
        this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        this.notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    }

    // Toggle between silent, vibrate, and normal modes
    public void toggleSoundMode() {
        int currentMode = getCurrentSoundMode();

        switch (currentMode) {
            case MODE_SILENT:
                setSoundMode(AudioManager.RINGER_MODE_VIBRATE);
                break;
            case MODE_VIBRATE:
                setSoundMode(AudioManager.RINGER_MODE_NORMAL);
                break;
            case MODE_NORMAL:
                setSoundMode(AudioManager.RINGER_MODE_SILENT);
                break;
        }
    }

    // Set the Sound Mode
    private void setSoundMode(int mode) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            // For Android versions 7.0 (Nougat) to 8.1 (Oreo)
            audioManager.setRingerMode(mode);
        } else {
            // For Android versions 9 (Pie) and above
            Settings.Global.putInt(context.getContentResolver(), "zen_mode", mode);
        }
    }

    // Get the current sound mode
    private int getCurrentSoundMode() {
        int ringerMode = audioManager.getRingerMode();

        switch (ringerMode) {
            case AudioManager.RINGER_MODE_SILENT:
                return MODE_SILENT;
            case AudioManager.RINGER_MODE_VIBRATE:
                return MODE_VIBRATE;
            case AudioManager.RINGER_MODE_NORMAL:
                return MODE_NORMAL;
            default:
                return MODE_NORMAL;
        }
    }
}

[Note that the behavior of sound modes and DND settings may vary across Android versions and device manufacturers. This code provides a general approach and may need adjustments based on your specific use case and testing on different devices]

Hope it helps!

3
On

To toggle between silent mode and Do Not Disturb (DND) mode, follow these steps:

Ensure that your AndroidManifest.xml includes the necessary permission.

Add the following line inside the <manifest> tag:

<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />

Then, check if the app has been granted notification policy access:

if (!notificationManager.isNotificationPolicyAccessGranted) {
    // If not granted, prompt the user to give permission.
    val intent = Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS)
    startActivity(intent)
}

Then, we need to obtain instances of AudioManager and NotificationManager. Here's how you can get them:

val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
val notificationManager =
    getSystemService(NOTIFICATION_SERVICE) as NotificationManager

To toggle to silent mode:

private fun setSilentMode() {
    // Disable Do Not Disturb (DND) mode.
    notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL)
    // Set the device to silent mode.
    audioManager.ringerMode = AudioManager.RINGER_MODE_SILENT
}

To set DND mode:

private fun setDNDMode() {
    // Enable Do Not Disturb (DND) mode.
    notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE)
    // Set the device to normal ringer mode.
    audioManager.ringerMode = AudioManager.RINGER_MODE_NORMAL
}

To set both DND mode and silent mode simultaneously:

private fun setBothModes() {
    // Set the device to silent mode.
    audioManager.ringerMode = AudioManager.RINGER_MODE_SILENT
    // Enable Do Not Disturb (DND) mode.
    notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE)
}
1
On

You can try this code for AudioManager:

import android.content.Context
import android.media.AudioManager
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class SoundActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_sound)

    //use for silent mode and DND mode
    switchSilentMode()
    switchDNDMode()
}

private fun switchSilentMode() {
    val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        // For devices running Android Marshmallow (API 23) and above
        audioManager.ringerMode = AudioManager.RINGER_MODE_SILENT
        audioManager.adjustStreamVolume(
            AudioManager.STREAM_ALARM,
            AudioManager.ADJUST_UNMUTE,
            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        )
        audioManager.adjustStreamVolume(
            AudioManager.STREAM_MUSIC,
            AudioManager.ADJUST_UNMUTE,
            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        )
        audioManager.adjustStreamVolume(
            AudioManager.STREAM_NOTIFICATION,
            AudioManager.ADJUST_UNMUTE,
            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        )
        audioManager.adjustStreamVolume(
            AudioManager.STREAM_RING,
            AudioManager.ADJUST_UNMUTE,
            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        )
        audioManager.adjustStreamVolume(
            AudioManager.STREAM_SYSTEM,
            AudioManager.ADJUST_UNMUTE,
            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        )
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            audioManager.adjustStreamVolume(
                AudioManager.STREAM_ACCESSIBILITY,
                AudioManager.ADJUST_UNMUTE,
                AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
            )
        }
    } else {
        // For devices running versions below Android Marshmallow
        audioManager.ringerMode = AudioManager.RINGER_MODE_SILENT
    }
}

 private fun switchDNDMode() {
    val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        // For devices running Android Marshmallow (API 23) and above
        audioManager.ringerMode = AudioManager.RINGER_MODE_SILENT
        audioManager.adjustStreamVolume(
            AudioManager.STREAM_ALARM,
            AudioManager.ADJUST_MUTE,
            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        )
        audioManager.adjustStreamVolume(
            AudioManager.STREAM_MUSIC,
            AudioManager.ADJUST_MUTE,
            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        )
        audioManager.adjustStreamVolume(
            AudioManager.STREAM_NOTIFICATION,
            AudioManager.ADJUST_MUTE,
            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        )
        audioManager.adjustStreamVolume(
            AudioManager.STREAM_RING,
            AudioManager.ADJUST_MUTE,
            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        )
        audioManager.adjustStreamVolume(
            AudioManager.STREAM_SYSTEM,
            AudioManager.ADJUST_MUTE,
            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        )
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            audioManager.adjustStreamVolume(
                AudioManager.STREAM_ACCESSIBILITY,
                AudioManager.ADJUST_MUTE,
                AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
            )
        }
    } else {
        // For devices running versions below Android Marshmallow
        audioManager.ringerMode = AudioManager.RINGER_MODE_SILENT
    }
}

}