anyone got an Android code to detect OS-theme (dark/light?) ?
-
@JoeCFD sweet!
in the mean time I figured out the pure JNI code;
auto context = QJniObject(QNativeInterface::QAndroidApplication::context()); // In Java: // context.getResources().getConfiguration().uiMode auto resources = context.callObjectMethod("getResources", "()Landroid/content/res/Resources;"); auto config = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;"); auto uiMode = config.getField<jint>("uiMode"); constexpr int UI_MODE_NIGHT_MASK = 0x30; constexpr int UI_MODE_NIGHT_YES = 0x20; const bool dark = (uiMode & UI_MODE_NIGHT_MASK) == UI_MODE_NIGHT_YES;
-
@TomZ Try this out.
public static boolean isDarkTheme(Activity activity) { int currentNightMode = activity.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; return currentNightMode == Configuration.UI_MODE_NIGHT_YES; }
or
package com.yourpackage; import android.content.Context; import android.content.res.Configuration; public class ThemeDetector { public static String getSystemTheme(Context context) { int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; if (currentNightMode == Configuration.UI_MODE_NIGHT_YES) { return "dark"; } else { return "light"; } } }
-
@JoeCFD thank you!
I've been trying for a couple of hours anything I can to actually call this from C++, this is as far as I have come (the docs on the Android stuff is significantly lower quality than the rest of Qt).
But I can't figure it out. This doesn't compile. No clue what "Args" are as mentioned in the documentation.
auto context = QJniObject(QNativeInterface::QAndroidApplication::context()); QJniObject retStr = QJniObject::callStaticObjectMethod("org/flowee/ThemeDetector", "getSystemTheme", "()Lorg/flowee/ThemeDetector;", context);
yap, 2 lines. Still trying after 3 hours. [hair pulling emoti]
ps. using Qt 6.5.1
-
@TomZ said in anyone got an Android code to detect OS-theme (dark/light?) ?:
"()Lorg/flowee/ThemeDetector;"
I guess this one is wrong. Here you define the data type you pass into the func
"()Lorg/flowee/ThemeDetector;"
for example passing a string is like
"(Landorid/content/Context;)LJava/lang/String;"
read the doc carefully.
-
another attempt in a different direction, a little progress made, I guess...
auto context = QJniObject(QNativeInterface::QAndroidApplication::context()); auto resources = context.callObjectMethod("getResources", "()Landroid.content.res.Resources;");
Got stuck on using 'callMethod' which didn't work, but callObjectMethod' does. No clue what the difference is.
-
@TomZ In Qt5, the following is good enough. Have not tried Qt6
QAndroidJniObject::callStaticObjectMethod(...)
This does not exist in Qt6 anymore.
https://forum.qt.io/topic/138952/help-qt6-calling-android-java-from-c/2
A full and pretty new example for Qt6:
https://scythe-studio.com/de/blog/how-to-interface-qt-with-android-java-code-2023 -
@JoeCFD In Qt6 the calling of the class you pasted seems completely impossible by design.
You can't pass in non-trivial objects, is what clang tells me.
error: cannot pass object of non-trivial type 'QJniObject' through variadic function; call will abort at runtime [-Wnon-pod-varargs] "getSystemTheme", "(Landoroid/content/Context;)L;", context);
-
@JoeCFD said in anyone got an Android code to detect OS-theme (dark/light?) ?:
read the doc carefully.
maybe that changed between Qt5 and Qt6, but in the QJniObject docs it states:
Method signatures are written as "(ArgumentsTypes)ReturnType", see JNI Types.
-
@JoeCFD sweet!
in the mean time I figured out the pure JNI code;
auto context = QJniObject(QNativeInterface::QAndroidApplication::context()); // In Java: // context.getResources().getConfiguration().uiMode auto resources = context.callObjectMethod("getResources", "()Landroid/content/res/Resources;"); auto config = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;"); auto uiMode = config.getField<jint>("uiMode"); constexpr int UI_MODE_NIGHT_MASK = 0x30; constexpr int UI_MODE_NIGHT_YES = 0x20; const bool dark = (uiMode & UI_MODE_NIGHT_MASK) == UI_MODE_NIGHT_YES;
-