Unable to switch Night mode - android

Changing night mode doesn't work on my mobile (it works in emulator)
night mode is set to my mobile's system mode(dark mode)
Since the new android studio there is default night mode theme in the starter code
I need to make a app with only Light mode
I've checked many solutions where we can change the theme using AppCompatDelegate method
example here, and docs

You could set the theme to light or dark mode via the activity file. Here is the snipit of code you need:
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.fcs.darktheme", appContext.packageName)
}
You can check out the video that I found this in. I persoanlly use Java and the principle worked for me. I commented in that video should you need the Java code. It is done with kotlin here:
https://www.youtube.com/watch?v=bWLnf2nqTl4&lc=UgximPI3XmiVgRa9k3N4AaABAg.9HePgMqRxF-9HeU3b16R-b&feature=em-comments

Related

Application of the system theme

Starting with Android 10, it became possible to change the device theme from settings (to dark and light), and the application by default grasps the theme that is set in the system. But I ran into a rather interesting problem. A device with Android 9 and in the settings there is also the possibility of changing the theme, but when I use a dark theme, nothing happens and my application remains in the light theme. I read on the Internet and found a way to get a theme(is light):
private fun foo(): Boolean {
return resources.configuration.uiMode and
Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_NO
}
, but this function always returns that a light theme has been applied (in Android 9 when a dark theme is enabled in the settings). As far as I understood, this is because this function returns the theme that is in the application and wanted to find out how, in this case, you can get the theme of the system.
The resources associated with the Activity will reflect the configuration of that Activity. That means that resources.configuration (or any context.resources.configuration) will have the uiMode of your Activity, not of the System.
When your application is starting, Android must create the Application instance for your app. At this moment your resources are not loaded yet, so Android attaches resources and configuration of the System to your Application instance. So you can access the uiMode of the System from the application Context. Also, you can access System resources and configuration using Resources.getSystem(), which is handy when you don't have access to any Context.
val activityIsLight =
resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_NO
val systemIsLight =
applicationContext.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_NO
// Or without using any Context
val systemIsLight =
Resources.getSystem().configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_NO

Android: Change correct to UI Mode dark in Android 10 and greater

I would like to apply the Dark mode to my app for Android 10 and greater.
Therefore I wrote following code on startup:
int modeNight;
int colorMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
if (colorMode == Configuration.UI_MODE_NIGHT_YES) {
modeNight = AppCompatDelegate.MODE_NIGHT_YES;
} else {
modeNight = AppCompatDelegate.MODE_NIGHT_NO;
}
AppCompatDelegate.setDefaultNightMode(modeNight);
This works in general. If I start the app, the correct mode gets set.
But, this does not work if the app is still in the background and I start it again.
If I start the app while it is not completely closed getResources().getConfiguration() does not get updated and it always returns the old value until I kill the app and start it again.
How can I force the app to reload the resources configuration? Or how else can I fix that problem?
Update:
I now replaced AppCompatDelegate.setDefaultNightMode(modeNight); with setTheme(R.style.Theme_ImmoFinder24);.
This works for the general Theme, but I still have a problem:
I've got some elements (Recycler Views) where the user can set the background color. One color for the normal mode and one for the Dark mode.
The theme changes, but the color listens to the value set in AppCompatDelegate.setDefaultNightMode(modeNight);.
If I keep both setDefaultNightMode() and setTheme(R.style.Theme_ImmoFinder24);, it does not change anything to the start of the problem (was without setTheme()).
You'll have to change your App's theme to DayNight
parent="Theme.AppCompat.DayNight"
You can also use MaterialComponents' dark theming:
parent="Theme.MaterialComponents.DayNight"
And use the system setting (Settings -> Display -> Theme) to enable Dark theme.
Please checkout this link for more information: https://developer.android.com/guide/topics/ui/look-and-feel/darktheme

How can I detect programmatically if the Android Device is in Dark Mode?

I'm trying to support the Android Q Dark theme for my Android app and I can't figure out how to import different assets based on the theme I'm currently in.
Im using the official DayNight theme for making the dark/light versions and for drawables is very easy to just point to the XML and it will choose the correct value either from values or values-night depending on what is enabled.
I wanted to do something similar where depending on the theme it would load either the asset "priceTag_light.png" or "priceTag_dark.png".
val inputStream = if(darkIsEnabled) {
assets.open("priceTag_dark.png")
} else {
assets.open("priceTag_light.png")
}
Is there a way I get that flag?
Okay finally found the solution I was looking for. As #deepak-s-gavkar points out the parameter that gives us that information is on the Configuration. So, after a small search I found this article that gives this example method that has worked perfectly for what I wanted:
fun isDarkTheme(activity: Activity): Boolean {
return activity.resources.configuration.uiMode and
Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
}
You first need to do this changes in manifest
<activity
android:name=".MyActivity"
android:configChanges="uiMode" />
then onConfigurationChanged of activity
val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
when (currentNightMode) {
Configuration.UI_MODE_NIGHT_NO -> {} // Night mode is not active, we're using the light theme
Configuration.UI_MODE_NIGHT_YES -> {} // Night mode is active, we're using dark theme
}
Use the following code:
boolean isDarkThemeOn = (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;

Android bug loading wrong colors in night mode

Disclaimer: I have already found a solution to this problem but wanted to post the question and answer for other people since it took me a long time to figure out why it was happening.
I ran into a strange issue where when opening my application in night mode, some of the UI was loaded in the correct night mode colors and some of the UI was loaded in the normal colors.
It turns out there is a strange bug where only the first time a WebView is created, it resets the UI mode. So for me, what was happening was:
-Application is initialized and night mode is set on
-Some of the UI is loaded in the initial activity with the proper colors
-Asynchronous call is made to fetch content
-WebView is created in a secondary fragment, resetting the UI mode
-Asynchronous call returns, loading UI elements in normal mode
The solution (which I found here), is to initialize a dummy WebView when the application starts up that isn't used anywhere before enabling night mode, so that the next time a WebView is used it won't reset the UI mode. So something like this:
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
val nightModeEnabled = //get value from shared prefs or wherever you are storing this flag
if (nightModeEnabled) {
Timber.d("Manually instantiating WebView to avoid night mode issue.");
try {
WebView(applicationContext)
} catch (e: Exception) {
Timber.e("Got exception while trying to instantiate WebView to avoid night mode issue. Ignoring problem.", e)
}
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}
}
}
Edit
Looks like they may have fixed this in Appcompat Version 1.1.0-alpha03 (haven't actually tried it though)
"Fixed WebView resets DayNight Resources (b/37124582)"

Activity Background change dynamic

I have just started developing an android weather app and I was wondering how to change activity background automatically. For example, in daytime it should show day time or in the night it should show night photos.
This is the app of Sony which has a feature (mentioned above)
Check the screenshots.
Okay Credit goes to SteD;so for you check this(beginner's guide)
Follow this
//set an ID for Relative Layout in content_main.xml(Android Studio)
RelativeLayout rlayout=(RelativeLayout)findViewById(R.id.rlayout);
if(something){Drawable drawble=getResource().getDrawable(R.drawable.your_image);rlayout.setBackgroundDrawable(drawable);}
//If it works,destroy the upvote
The only automatic way is the newly released (Day/Night theme for android app)
For finer control you check the condition yourself and call the normal Java methods, like this:
if(something) {
getWindow()
.setBackgroundDrawable(ContextCompat.getDrawable(this, R.drawable.image));
}
of if you don't care about the newly introduced context themed styling, you just call the deprecated method (which will keep working without issues for all the foreseeable future)
if(something) {
getWindow()
.setBackgroundDrawable(
getResources().getDrawable(R.drawable.image));
}

Categories

Resources