I have an android app where I want to display a webpage in dark mode, overlaid on top of other apps (using android draw over apps facility). I'm using a webview and windowmanager to create the floating view.
I want to target Android 9 / API 28, so that I can use the app with Amazon Fire TV.
The webpage in question is from Home Assistant. Dark mode can be set to auto, dark or light in home assistant. For the purposes of this post, i've set dark mode in the HA settings. When the HA page loads, it shows a "loading data" splash screen before showing the final screen. The issue I am experiencing is that the splash screen is shown light, whereas the final HA screen correctly displays in dark mode.
It has been suggested by the HA team that the splash screen is displayed as light or dark depending upon the browser setting. So, it seems that dark mode needs to be set on the webview.
However, in my test code, I have implemented a test where a webview is used but not floating, it's full screen. In this test, the splash screen is correctly dark. Here are the tests:
Working, but not floating
widget_web.xml
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadingEdge="vertical"
android:padding="8dp"
android:visibility="visible" />
MainActivity.kt
setContentView(R.layout.widget_web)
myWebView = findViewById<View>(R.id.web_view) as WebView
myWebView.settings.javaScriptEnabled = true
myWebView.setInitialScale(100)
myWebView.addJavascriptInterface(WebViewJavascriptInterface(applicationContext), "externalApp")
myWebView.loadUrl("http://192.168.1.73:8123/dashboard-studyonly?external_auth=1")
Splash screen (black, as I need it)
Black Home Assistant page:
Not working, but floating
MainActivity.kt
lateinit var windowManager: WindowManager
lateinit var floatView: ViewGroup
lateinit var mParentView: ViewGroup
lateinit var floatWindowLayoutParam: WindowManager.LayoutParams
setContentView(R.layout.widget_web)
floatWindowLayoutParam = WindowManager.LayoutParams(
1000,1000,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
)
windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
val inflater: LayoutInflater =
baseContext.getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater
mParentView = FrameLayout(this)
windowManager.addView(mParentView, floatWindowLayoutParam) //add mParentView to window with assigned parameters
floatView = inflater.inflate(R.layout.widget_web, null) as ViewGroup //floatView holds the webView
floatView.visibility = View.GONE
mParentView.addView(floatView) // add floatView (webView) as child to mParentView
myWebView = floatView.findViewById(R.id.web_view) as WebView
myWebView.settings.javaScriptEnabled = true
myWebView.settings.domStorageEnabled = true
myWebView.setInitialScale(100)
myWebView.addJavascriptInterface(WebViewJavascriptInterface(applicationContext), "externalApp")
myWebView.loadUrl("http://192.168.1.73:8123/dashboard-studyonly?external_auth=1")
myWebView.requestFocus()
myWebView.visibility = View.VISIBLE
finish() // hide the background of the app
Splash screen, white not black:
Black HA theme, as required (but driven by HA settings, not the webview):
Try this
floatWindowLayoutParam = WindowManager.LayoutParams(
1000, 1000,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
)
windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
val inflater: LayoutInflater = getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater
mParentView = FrameLayout(this)
windowManager.addView(mParentView, floatWindowLayoutParam)
floatView = inflater.inflate(R.layout.widget_web, mParentView, false) as ViewGroup
floatView.visibility = View.GONE
mParentView.addView(floatView)
myWebView = floatView.findViewById(R.id.web_view) as WebView
myWebView.settings.javaScriptEnabled = true
myWebView.settings.domStorageEnabled = true
myWebView.setInitialScale(100)
myWebView.addJavascriptInterface(WebViewJavascriptInterface(applicationContext), "externalApp")
myWebView.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
injectDarkModeCSS(view)
}
}
myWebView.loadUrl("http://192.168.1.73:8123/dashboard-studyonly?external_auth=1")
myWebView.requestFocus()
myWebView.visibility = View.VISIBLE
finish()
}
private fun injectDarkModeCSS(webView: WebView?) {
val css = "(function() {" +
"document.body.style.backgroundColor = 'black';" +
"document.body.style.color = 'white';" +
"})()"
webView?.evaluateJavascript("javascript:$css", null)
}
}