Android Dark-Mode could not be detected #1978
-
The Capacitor WebView is unable to detect the media query Try out the ionic example inside the browser and then with capacitor: https://ionicframework.com/docs/theming/dark-mode Steps to reproduce:
Link to sample project: https://ionicframework.com/docs/theming/dark-mode |
Beta Was this translation helpful? Give feedback.
Replies: 19 comments 37 replies
-
Hi. I'm also seeing this issue. Running the latest webview (v77) on Android 10 it doesn't seem to support the |
Beta Was this translation helpful? Give feedback.
-
Looks like it's a bug on Android or on the WebView, according to what I've read it should just work, but it doesn't.
But you need to target SDK 29, which might cause other issues. |
Beta Was this translation helpful? Give feedback.
-
Adding to @jcesarmobile answer, we have used this solution for our needs: Update MainActivity.java
Then in whatever implementation you are using prefers-color-scheme, add the following to handle detecting the appended user agent string:
We used user agent so we could share the same code across web and "native" platforms and avoid targeting SDK 29. |
Beta Was this translation helpful? Give feedback.
-
Is there ANY WAY of overriding prefers-color-scheme on the web view without targeting a recent SDK? |
Beta Was this translation helpful? Give feedback.
-
@sean-perkins Thank you for your solution, which works.
|
Beta Was this translation helpful? Give feedback.
-
If you want to dynamically listen to changes in the dark mode on android, you can use the plugin I've developed. In opposition to checking whether dark mode has been enabled during app launch, the plugin will allow you to listen to changes in the dark mode even while your app is running. Also, there is no need to target sdk 29. I've tested the plugin by targeting sdk 28 and it works fine. |
Beta Was this translation helpful? Give feedback.
-
To make this a bit more complete, could you guys also post your preferred solution to handle the navigationBarColor when using dark mode in a Capacitor app? On my Samsung test device, the webview app will still run with a light navigation bar (not status bar!) even though the dark mode is enabled. One workaround would be to set the navigationBarColor programmatically: if (nightModeFlags == Configuration.UI_MODE_NIGHT_YES) {
// ...
getWindow().setNavigationBarColor(ContextCompat.getColor(this, R.color.colorNavbarDark));
} How do you do it? Especially if the user disables the dark mode and you want to go back to the default system color? (cc @sean-perkins @jcesarmobile ) |
Beta Was this translation helpful? Give feedback.
-
The plugin I've written is only responsible for notifying the web app of system wide color scheme changes. The rest needs to be handled within the web app. For instance, if you're using my plugin, you can set the color of Status Bar inside the "darkModeStateChanged" listener. You can alter the color of the statusbar by using the following Capacitor API: Inside the web app: |
Beta Was this translation helpful? Give feedback.
-
@hinddeep Thanks, but I'm talking about the navigation bar (Home, Back, Recent), not the status bar. I think this can be set in the Android theme. I just wonder what the "proper" way to do this would be. |
Beta Was this translation helpful? Give feedback.
-
Would be outstanding if this was referenced somewhere in the theme documentation so that you don't need to bang your head against the wall for a few hours instead of just having this hypothetical documentation that doesn't actually work on Android. |
Beta Was this translation helpful? Give feedback.
-
Still facing this issue. Is there any workaround to dynamically change ionic theme from light to dark and vice versa? |
Beta Was this translation helpful? Give feedback.
-
due to problems with the FORCE_DARK_STRATEGY i have solved it as follows with
|
Beta Was this translation helpful? Give feedback.
-
There seems to be a plugin that addresses this issue now: https://github.com/timbru31/cordova-plugin-android-dark-mode-support Anyone tried it? |
Beta Was this translation helpful? Give feedback.
-
Here's the complete It combines the FORCE strategy (where supported) and a CSS class based fallback for pre Android 10. package io.github.eyecatchup.example;
import android.os.Bundle;
import android.content.res.Configuration;
import android.webkit.WebSettings;
import com.getcapacitor.BridgeActivity;
import com.getcapacitor.Plugin;
import java.util.ArrayList;
public class MainActivity extends BridgeActivity {
void setDarkMode() {
// Android "fix" for enabling dark mode
// @see: https://github.com/ionic-team/capacitor/discussions/1978
int nightModeFlags = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
WebSettings webSettings = this.bridge.getWebView().getSettings();
if (nightModeFlags == Configuration.UI_MODE_NIGHT_YES) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
// As of Android 10, you can simply force the dark mode
webSettings.setForceDark(WebSettings.FORCE_DARK_ON);
}
// Before Android 10, we need to use a CSS class based fallback
this.bridge.getWebView().evaluateJavascript("document.body.classList.toggle('dark', true);", null);
} else {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
webSettings.setForceDark(WebSettings.FORCE_DARK_OFF);
}
this.bridge.getWebView().evaluateJavascript("document.body.classList.toggle('dark', false);", null);
}
}
@Override
public void onStart() {
super.onStart();
setDarkMode();
}
@Override
public void onResume() {
super.onResume();
setDarkMode();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initializes the Bridge
this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{
// Additional plugins you've installed go here
// Ex: add(TotallyAwesomePlugin.class);
}});
}
} |
Beta Was this translation helpful? Give feedback.
-
Just the needs to perform such tweaks makes you feel sad :S |
Beta Was this translation helpful? Give feedback.
-
The MainActivity.java: package com.pulsegrow;
import android.content.res.Configuration;
import android.webkit.WebSettings;
import com.getcapacitor.BridgeActivity;
public class MainActivity extends BridgeActivity {
// Alternative for "prefers-color-scheme: dark" not working properly on Android
// Adds "AndroidDarkMode" to user agent
// @see: https://github.com/ionic-team/capacitor/discussions/1978
void detectDarkMode() {
int nightModeFlags = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
WebSettings webSettings = this.bridge.getWebView().getSettings();
String userAgent = webSettings.getUserAgentString();
Boolean hasDarkModeString = userAgent.contains(" AndroidDarkMode");
if (nightModeFlags == Configuration.UI_MODE_NIGHT_YES) {
// Dark mode detected, add string to user agent if it's not added already
if (!hasDarkModeString) {
userAgent = userAgent + " AndroidDarkMode";
}
} else {
// Light mode detected, remove string from user agent
userAgent = userAgent.replace(" AndroidDarkMode","");
}
webSettings.setUserAgentString(userAgent);
}
@Override
public void onResume() {
super.onResume();
detectDarkMode();
}
} JS: if (window.navigator.userAgent.includes('AndroidDarkMode')) {
// switch to dark mode
} |
Beta Was this translation helpful? Give feedback.
-
i created a PR to make it come to capacitor : #5483 |
Beta Was this translation helpful? Give feedback.
-
Another very simple solution:
And it works 🎉 |
Beta Was this translation helpful? Give feedback.
-
Having to install a plugin instead of fixing capacitor for android is kinda sad tho IMO. |
Beta Was this translation helpful? Give feedback.
Here's the complete
MainActivity.java
I came up with:It combines the FORCE strategy (where supported) and a CSS class based fallback for pre Android 10.
Also, the additional
onResume
takes care of applying system settings changes after resuming the app.