【问题标题】:Android: Detect if night mode is set to FOLLOW_SYSTEM with AppCompatDelegateAndroid:使用 AppCompatDelegate 检测夜间模式是否设置为 FOLLOW_SYSTEM
【发布时间】:2020-07-02 04:53:56
【问题描述】:

我正在尝试创建一个设置选项,允许用户选择应用程序是处于夜间模式、白天模式还是遵循系统默认设置。为了向用户显示当前设置,我需要从系统中获取它。但是我在下面使用的代码总是返回MODE_NIGHT_UNSPECIFIED。我在这里做错了吗?

我有以下代码:

val x = AppCompatDelegate.getDefaultNightMode()
        when (x) {
            AppCompatDelegate.MODE_NIGHT_NO -> {"testsadflke-  MODE_NIGHT_NO".log()}
            AppCompatDelegate.MODE_NIGHT_YES -> {"testsadflke-  MODE_NIGHT_YES".log()}
            AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY -> {"testsadflke-  MODE_NIGHT_AUTO_BATTERY".log()}
            AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM -> {"testsadflke-  MODE_NIGHT_FOLLOW_SYSTEM".log()}
            AppCompatDelegate.MODE_NIGHT_UNSPECIFIED -> {"testsadflke-  MODE_NIGHT_UNSPECIFIED".log()}
        }

日志输出为:

2020-07-01 21:47:08.751 6783-6783/com.example.macrotracker D/(AnyExt.kt:6)log(): Object: testsadflke-  MODE_NIGHT_UNSPECIFIED

但是我认为这是不正确的,因为我的 appTheme 扩展了 Material DayNight 主题。此外,当我启用或禁用夜间模式时,我的应用会更改主题,因此它必须遵循系统模式。任何帮助将不胜感激!

【问题讨论】:

  • 你自己打电话给AppCompatDelegate.setDefaultNightMode吗?
  • 我在调用 AppCompatDelegate.setDefaultNightMode 之前调用了这个。我想,由于我的应用正在根据设备日/夜主题更改主题,getDefaultNightMode 应该返回 MODE_NIGHT_FOLLOW_SYSTEM

标签: android android-appcompat android-theme android-dark-theme android-night-mode


【解决方案1】:

AppCompat 的夜间模式支持分为两层:

  • “默认”层 - 由setDefaultNightMode() 控制,通过getDefaultNightMode() 读取
  • “本地”层 - 由setLocalNightMode() 控制,通过getLocalNightMode() 读取

“默认”层仅在您没有通过显式调用具有不同值的 setLocalNightMode() 来设置本地模式(即 getLocalNightMode() 返回 MODE_NIGHT_UNSPECIFIED)时适用。

出于类似的原因,如果您从未调用过setDefaultNightMode(),那么getDefaultNightMode() 应该会返回MODE_NIGHT_UNSPECIFIED - 未指定意味着您没有将其设置为任何特定值。

重要的是要注意AppCompatDelegate 不会保留您设置的任何值 - 您需要在每次创建应用程序时调用setDefaultNightMode()(即,在进程死亡后恢复您想要/之前保存的任何值) 和 setLocalNightMode()(如果您在特定的 Activity/Dialog 上使用它)创建该组件时。

根据MODE_NIGHT_UNSPECIFIED documentation

如果默认和本地夜间模式都设置为此值 [MODE_NIGHT_UNSPECIFIED],则应用默认值 MODE_NIGHT_FOLLOW_SYSTEM

因此,如果您根本不使用本地模式,那么您可以将 MODE_NIGHT_UNSPECIFIED 视为与 MODE_NIGHT_FOLLOW_SYSTEM 相同,因为这正是 AppCompat 在两者都是 MODE_NIGHT_UNSPECIFIED 的情况下所做的。

【讨论】:

  • 哦,我明白了,但是localdefault 有什么区别? default 是否由设备设置(如在设备夜间模式设置中)? local 是否仅适用于您的应用?
  • 它们都只适用于您的应用程序。您的应用程序的默认模式适用于未设置本地模式的任何时候 - 因此它被称为默认模式。将默认视为适用于应用程序中的每个活动和每个对话框的选项,将本地视为您在特定活动或特定对话框上设置的选项以强制其进入特定模式。
  • 啊,我明白了,感谢您澄清这一点。因此,在这个问题的基础上,调用setDefaultlNightMode(MODE_NIGHT_UNSPECIFIED) 是否将Android 10+ 设备设置为MODE_NIGHT_FOLLOW_SYSTEM,将Android 9- 设备设置为MODE_NIGHT_AUTO_BATTERY?如果是这种情况,这是否意味着使用.._UNSPECIFIED 是让应用遵循设备夜间模式设置的最佳/最方便的方式,而不管安卓版本如何?
  • 根据我特别引用的文档,如果默认模式和本地模式都是UNSPECIFIED,它使用FOLLOW_SYSTEM。对于每个 API 级别都是如此。除非您专门将模式设置为AUTO_BATTERY,否则它将永远不会使用AUTO_BATTERY。您可以考虑reading the guidance on Night mode,它特别指出了您应该如何跨 API 级别处理夜间模式。
猜你喜欢
  • 1970-01-01
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多