Jetpack Compose で Quick Settings の開閉を検知する
はじめに
Quick Settings
は画面の上部を下にスワイプした時に出てくるメニュー画面のことです. [1]
Quick Settings
を使うとスマートフォンのどの画面からもインターネット接続や位置情報をはじめとしたした設定を変えたり通知を確認したりすることができます.
しかし Quick Settings
を開閉したとしても onResume()
や onPause()
等のライフサイクル コールバックは呼ばれることはありません.
そのため, Quick Settings
上で端末の位置情報の権限の許諾を変更した場合にすぐさま UI を更新したい場合などには別の方法を検討する必要があります.
そこで今回は Jetpack Compose
で Quick Settings
の開閉を検知する方法について調べてみました.
Activity における Quick Settings の開閉の検知
Jetpack Compose
の前に Activity
における Quick Settings
の開閉の検知の方法について調べてみます.
上述の通り, Quick Settings
の開閉で onResume()
や onPause()
等のライフサイクル コールバックは呼ばれることがありません.
Stack Overflow で探してみると Activity においては Activity の現在の Window がフォーカスを得たり失ったりする時に呼ばれる Activity.onWindowFocusChanged()
で検知が可能との投稿がありました. [2]
onWindowFocusChanged
のドキュメントをみると
As a general rule, however, a foreground activity will have window focus... unless it has displayed other dialogs or popups that take input focus, in which case the activity itself will not have focus when the other windows have it.
Likewise, the system may display system-level windows (such as the status bar notification panel or a system alert) which will temporarily take window input focus without pausing the foreground activity.
とあり,
- ダイアログやポップアップが表示された時は Activity のフォーカスが外れる
- (
Quick Settings
のような)システムレベルのウィンドウが表示された時は Activity のフォーカスが外れるが foreground activity は停止しない
という趣旨の文言が記載されています. [3]
確認をしてみるとダイアログが表示/非表示になったタイミングや Quick Settings
の開閉時, さらにアプリがフォアグラウンド/バックグラウンドに移動したタイミングで Activity.onWindowFocusChanged()
が呼び出されることがわかります.
そのため一部ライフサイクル コールバックの呼び出しと重複することがあることに注意する必要があるが, 基本的には Activity.onWindowFocusChanged()
で Quick Settings
の開閉を検知することができそうです.
Compose における Quick Settings の開閉の検知
次に Jetpack Compose
における Quick Settings
の開閉の検知の方法について調べてみます.
Activity の時と同様に onWindowFocusChanged()
に当たるものが Compose にないかどうか調べてみると androidx.compose.ui.platform
に WindowInfo.isWindowFocused
というものが用意されていました. [4] [5]
ドキュメントには
Indicates whether the window hosting this compose hierarchy is in focus.
とあり Compose をホストしている Window にフォーカスがあるかどうかを検知することができるとあります.
そして Compose で WindowInfo
は LocalWindowInfo.current
によって取得をすることができるので以上を踏まえると次のようなコードで Quick Settings
の開閉を検知することができます.
val windowInfo = LocalWindowInfo.current
LaunchedEffect(windowInfo.isWindowFocused) {
// windowInfo.isWindowFocused の値に応じて処理
}
上記のコードでも Activity.onWindowFocusChanged()
と同様にダイアログやポップアップに相当する Composable を表示した時やアプリがフォアグラウンド/バックグラウンドに移動したタイミングで windowInfo.isWindowFocused
の値が切り替わるので注意が必要です.
まとめ
WindowInfo.isWindowFocused
を用いることで Compose においても Quick Settings
を開閉を検知することができそうです.
また余力があれば LocalWindowInfo
を提供する Owner
についても記事にまとめてみたいなと思っています.
Discussion