Android WebViewのダークモード

# はじめに
AndroidはChromeで強制ダークモードが使えるため、
WebViewも可能だろうと思い調べてみたところ、
設定が思いのほか複雑だったので、まとめてみました

# 設定方法
SDK Versionとダークモードの適用方法(ダークモード対応サイトのみ、強制ダークモード)によって、設定を分類しています

## SDK Version 33

- [Theme_isLightTheme](https://developer.android.com/reference/android/R.styleable#Theme_isLightTheme)
- [setAlgorithmicDarkeningAllowed()](https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#setAlgorithmicDarkeningAllowed(android.webkit.WebSettings,%20boolean))
  - `androidx.webkit:webkit:1.5.0`のAPI
  - 初期値は`false`

### ダークモード対応サイトのみダークモードにする

WebViewもしくは、より上位のViewに[Theme_isLightTheme](https://developer.android.com/reference/android/R.styleable#Theme_isLightTheme)が定義されたThemeを設定する

```xml
<WebView
    android:id="@+id/web_view"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:theme="@style/Theme.MaterialComponents.DayNight"/>
```

### 全てのサイトをダークモードにする

[Theme_isLightTheme](https://developer.android.com/reference/android/R.styleable#Theme_isLightTheme)と[setAlgorithmicDarkeningAllowed()](https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#setAlgorithmicDarkeningAllowed(android.webkit.WebSettings,%20boolean)) を`true`に設定する
`true`に設定しても、ダークモード対応サイトはそのサイトで定義されたカラーで表示される

```kotlin
if(WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) {
    WebSettingsCompat.setAlgorithmicDarkeningAllowed(binding.webView.settings, true)
}
```

## SDK Version 29〜32

- [setForceDark()](https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#setForceDark(android.webkit.WebSettings,int))
  - [FORCE_DARK_AUTO]() (初期値)
    - Referenceに以下の記述があるため、ダークモード対応アプリでは使えない
        > If your app uses a dark theme, WebView will not be inverted. Similarly, if your app's theme inherits from a DayNight theme, WebView will not be inverted. In either of these cases, you should control the mode manually with FORCE_DARK_ON or FORCE_DARK_OFF.
  - [FORCE_DARK_ON]()
  - [FORCE_DARK_OFF]()
- [setForceDarkStrategy()]() ※ setForceDark()を呼び出すと値が変わるため注意
  - [DARK_STRATEGY_WEB_THEME_DARKENING_ONLY](https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#DARK_STRATEGY_WEB_THEME_DARKENING_ONLY()) (初期値)
  - [DARK_STRATEGY_USER_AGENT_DARKENING_ONLY](https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#DARK_STRATEGY_USER_AGENT_DARKENING_ONLY())
  - [DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING](https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#DARK_STRATEGY_WEB_THEME_DARKENING_ONLY())
    - Referenceにはダークモード対応サイトはそのサイトで定義された配色で表示されるような旨が記載されていますが、動作確認したところ強制ダークモードの配色になってしまいました
    （原因は現状不明です。。）

### ダークモード対応サイトのみダークモードにする
ダークON/OFF設定と[setForceDark()](https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#setForceDark(android.webkit.WebSettings,int))の値を同期させて、[setForceDarkStrategy()]()を[DARK_STRATEGY_WEB_THEME_DARKENING_ONLY]()に設定する

```kotlin
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK) && WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
    when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
        Configuration.UI_MODE_NIGHT_YES -> {
            WebSettingsCompat.setForceDark(binding.webView.settings, WebSettingsCompat.FORCE_DARK_ON)
        }

        Configuration.UI_MODE_NIGHT_NO, Configuration.UI_MODE_NIGHT_UNDEFINED -> {
            WebSettingsCompat.setForceDark(binding.webView.settings, WebSettingsCompat.FORCE_DARK_OFF)
        }
    }
    WebSettingsCompat.setForceDarkStrategy(binding.webView.settings, WebSettingsCompat.DARK_STRATEGY_WEB_THEME_DARKENING_ONLY)
}
```

### 全てのサイトをダークモードにする
ほぼ同じで、違いは[setForceDarkStrategy()]()の設定値を[DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING]()にする

```kotlin
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK) && WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
    when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
        Configuration.UI_MODE_NIGHT_YES -> {
            WebSettingsCompat.setForceDark(binding.webView.settings, WebSettingsCompat.FORCE_DARK_ON)
        }

        Configuration.UI_MODE_NIGHT_NO, Configuration.UI_MODE_NIGHT_UNDEFINED -> {
            WebSettingsCompat.setForceDark(binding.webView.settings, WebSettingsCompat.FORCE_DARK_OFF)
        }
    }
    WebSettingsCompat.setForceDarkStrategy(binding.webView.settings, WebSettingsCompat.DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING)
}
```

## SDK Version 〜28
ダークモードに対応していないため、ライトテーマでの表示となる



# おまけ : Chromeの強制ダークモード設定方法

chrome://flags
 -> Auto Dark Mode for Web Contents : Enabled

# 参考にさせていただいたリンク

https://developer.android.com/develop/ui/views/layout/webapps/dark-theme

https://developer.android.com/guide/topics/ui/look-and-feel/darktheme?hl=ja

https://qiita.com/ryo_mm2d/items/2211b4f3354a3166cba9