切换至MODE_NIGHT_FOLLOW_SYSTEM未跟随系统,沿用最后模式求排查
你碰到的这个情况其实是AppCompat库在Android 10(API 29)以下设备上的预期行为。MODE_NIGHT_FOLLOW_SYSTEM这个模式是从Android 10开始才被系统原生支持的,在API 29之前的系统里,Android本身并没有提供系统级的夜间模式开关,AppCompat库没办法获取系统的夜间状态,只能沿用你最后一次手动设置的夜间模式(MODE_NIGHT_YES或MODE_NIGHT_NO)。
你的测试设备是Android 4.0.3(API 15)和6.0.1(API 23),都低于API 29,所以才会出现这种“切回跟随系统模式却保留之前手动设置”的现象。
根据你的需求,可以分两种场景处理:
1. 针对API 29及以上设备
你的原有代码完全没问题,在Android 10+的真机或模拟器上测试,MODE_NIGHT_FOLLOW_SYSTEM会正常跟随系统的深色模式设置,无需修改代码。
2. 针对API 29以下设备
如果需要在低版本设备上实现类似“跟随系统”的效果,得自己手动模拟逻辑(因为Android 10之前没有统一的系统深色模式,只能通过间接方式判断)。这里给你一个简单的实现示例:
private void changeNightMode(int nightMode) { if (nightMode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // API 29+ 直接使用系统原生模式 AppCompatDelegate.setDefaultNightMode(nightMode); } else { // 低版本设备:通过系统自动亮度模式模拟夜间判断(可根据需求调整逻辑) int brightnessMode = Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL); boolean isNight = brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTO; AppCompatDelegate.setDefaultNightMode(isNight ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO); } } else { AppCompatDelegate.setDefaultNightMode(nightMode); } recreate(); }
你也可以根据需求替换判断逻辑,比如根据当前时间(白天/黑夜)、用户自定义的规则来切换模式。另外,还可以在UI上给低版本设备的用户加个提示,说明“跟随系统模式仅在Android 10及以上设备生效”,避免用户困惑。
你可以找一台Android 10+的设备测试原有代码,会发现MODE_NIGHT_FOLLOW_SYSTEM能正常跟随系统设置,这就能确认问题根源是低版本系统的限制了。
内容的提问来源于stack exchange,提问作者Chmyaf

