110

I'm using Androids built in day/night mode functionality and I'd like to add an option to my app for AppCompatDelegate.MODE_NIGHT_AUTO

I'm having a problem though because my app requires certain things to be colored programmatically, and I can't figure out how to check if the app considers itself in night or day mode. Without that, I can't set a flag to choose the right colors.

Calling AppCompatDelegate.getDefaultNightMode() just returns AppCompatDelegate.MODE_NIGHT_AUTO which is useless.

I don't see anything else that would tell me, but there must be something?

Ben987654
  • 3,280
  • 4
  • 27
  • 50
  • 1
    Possible duplicate of [How to get AppCompatDelegate current mode if default is auto](https://stackoverflow.com/questions/41391404/how-to-get-appcompatdelegate-current-mode-if-default-is-auto) – StarWind0 Oct 09 '17 at 17:51

11 Answers11

177
int nightModeFlags =
    getContext().getResources().getConfiguration().uiMode &
    Configuration.UI_MODE_NIGHT_MASK;
switch (nightModeFlags) {
    case Configuration.UI_MODE_NIGHT_YES:
         doStuff();
         break;

    case Configuration.UI_MODE_NIGHT_NO:
         doStuff();
         break;

    case Configuration.UI_MODE_NIGHT_UNDEFINED:
         doStuff();
         break;
}
ArghadipDasCEO
  • 177
  • 1
  • 12
ephemient
  • 198,619
  • 38
  • 280
  • 391
  • Thanks, that did the trick. I started going down the route of checking a colors string value to see which resource file it was coming from, but this is way better! – Ben987654 May 24 '17 at 23:54
  • 1
    Please cite your sources. https://stackoverflow.com/questions/41391404/how-to-get-appcompatdelegate-current-mode-if-default-is-auto – StarWind0 Oct 09 '17 at 17:50
  • 20
    @StarWind0 I did not find any other answers; this answer was derived purely from the API documentation. – ephemient Oct 09 '17 at 17:55
  • @ephemient So? "Please cite your sources" share the link to the API documentation... – Tigerrrrr Jul 27 '23 at 22:38
55

If you are kotlin developer then you can use below code to judge dark mode.

when (context.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK)) {
    Configuration.UI_MODE_NIGHT_YES -> {}
    Configuration.UI_MODE_NIGHT_NO -> {}
    Configuration.UI_MODE_NIGHT_UNDEFINED -> {}
}

For more about dark theme mode

https://github.com/android/user-interface-samples/tree/main/DarkTheme

Ethan Allen
  • 14,425
  • 24
  • 101
  • 194
Saurabh Khare
  • 1,227
  • 13
  • 24
19

A very simple solution is to add a string resource like this.

res/values/strings.xml

<string name="mode">Day</string>

res/values-night/strings.xml

<string name="mode">Night</string>

And then wherever you need to check it:

if (resources.getString(R.string.mode) == "Day") {
    // Do Day stuff here
} else {
    // Do night stuff here
}

But you CAN NOT call this before super.onCreate() in an activity's life-cycle. It will always return "Day" before onCreate.

just_user
  • 11,769
  • 19
  • 90
  • 135
13

The bitwise operator in Java (which is used in @ephemient 's answer) is different in kotlin so the code might not be easily convertible for beginners. Here is the kotlin version just in case someone needs it:

    private fun isUsingNightModeResources(): Boolean {
        return when (resources.configuration.uiMode and 
Configuration.UI_MODE_NIGHT_MASK) {
            Configuration.UI_MODE_NIGHT_YES -> true
            Configuration.UI_MODE_NIGHT_NO -> false
            Configuration.UI_MODE_NIGHT_UNDEFINED -> false
            else -> false
    }
}
Ali Nem
  • 5,252
  • 1
  • 42
  • 41
10

to check for night mode you can do as below:

public boolean isNightMode(Context context) {
    int nightModeFlags = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
    return nightModeFlags == Configuration.UI_MODE_NIGHT_YES;
}
Mustafa Poya
  • 2,615
  • 5
  • 22
  • 36
7

Kotlin Version :->

fun isDarkMode(context: Context): Boolean {
    val darkModeFlag = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
    return darkModeFlag == Configuration.UI_MODE_NIGHT_YES
}
abhi
  • 961
  • 9
  • 13
3

Maybe just a property that will actually tell you if you have Dark Mode ?

val Context.isDarkMode
    get() = if (getDefaultNightMode() == MODE_NIGHT_FOLLOW_SYSTEM)
        resources.configuration.uiMode and UI_MODE_NIGHT_MASK == UI_MODE_NIGHT_YES
    else getDefaultNightMode() == MODE_NIGHT_YES
Renetik
  • 5,887
  • 1
  • 47
  • 66
3

From Android Version R (30) there is provided a value in context.resources.configuration.isNightModeActive.

So you don't need to mask anymore.

Example in onConfigurationChanged:

private var _isNightModeActive: Boolean = false

override fun onConfigurationChanged(newConfig: Configuration) {
        _isNightModeActive =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                _resources.configuration.isNightModeActive
            } else {
                newConfig.uiMode and
                        Configuration.UI_MODE_NIGHT_MASK ==
                        Configuration.UI_MODE_NIGHT_YES
            }
    }
Carsten
  • 51
  • 3
1

For Xamarin.Android

if (Build.VERSION.SdkInt >= BuildVersionCodes.Froyo)
{
    var uiModeFlags = Application.Context.Resources.Configuration.UiMode & UiMode.NightMask;
    switch (uiModeFlags)
    {
        case UiMode.NightYes:
            // dark mode
            break;
        case UiMode.NightNo:
            // default mode
            break;
        default:
            // default mode
            break;
    }
}
else
{
// default mode
}
0

I had problems with my UI tests, when try to get current theme in every answer code. It every time return the same value.

So I create static variable in application class and get theme for UI tests throw it:

@Theme
fun Context.getAppTheme(): Int? {
    val theme = when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
        Configuration.UI_MODE_NIGHT_NO -> Theme.LIGHT
        Configuration.UI_MODE_NIGHT_YES -> Theme.DARK
        else -> null
    }

    Application.theme = theme

    return theme
}

In Application class:

companion object {
    @Theme
    @RunNone var theme: Int? = null
}

May be it will be usefull for someone!

SerjantArbuz
  • 982
  • 1
  • 12
  • 16
-1

I found nothing of this to be working after changing the the app to dark theme with

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);

Is there any way to know the system setting after changing the app with this method?
Thanks,
FF

FerFig
  • 113
  • 9
  • I have the answer to my question [here](https://stackoverflow.com/questions/66896942/cant-detect-if-dark-theme-is-active-or-not-after-changing-it-with-appcompatdeleg/66913308#66913308) for anyone with the same "issue". – FerFig Apr 02 '21 at 01:11