TL;DR
1 | import { startActivityAsync, ActivityAction } from 'expo-intent-launcher'; |
でAPPLICATION_DETAILS_SETTINGS
を開くことができる。下の画像のような画面。
cf: Opening Device Settings on Android using Linking - Expo Forum
まえがき
ReactNativeで使用するフレームワーク(React codebase)であるExpoを便利に使用してはいるが、先週リリースされたAndroid 13で使用すると問題が発生する。
Android 13ではiOSと同じように通知を要求するときにダイアログを表示するようになったが、これと2022年8月20日時点のExpo(SDK 46)とは相性が良くないらしい。
まず、Notifications.requestPermissionsAsync()
で権限を要求することができない。何も表示されないまま即座にstatusがdeniedとしてresolveされてしまう。
そもそもターゲットがAPI level 32以上じゃないと任意の場所で通知権限を呼び出せない気がするし、それならExpo SDKのバージョン待ちということになりそうだ。
だからと言ってAPI level 31以下の場合と同じように最初のアクティビティでダイアログが出ることもないから困ってしまった。
この場合、UX的な解決策としては通知がdeniedされた場合に設定画面に飛ばしてやるのが最善だろう。現にiOSで一回通知を拒否してしまった場合二度とアプリ側からリクエストすることはできないから、Linking.openURL('app-settings://notification/YOUR_BUILD_IDENTIFY')
して通知の許可画面に飛ばしている。
IntentLauncherを使う
AndroidでiOSのURLスキームのようなことをするのが、IntentLauncherであり、Expoでもexpo-intent-launcherが用意されている。Exampleにはこう書かれている。
1 | import { startActivityAsync, ActivityAction } from 'expo-intent-launcher'; |
そしてその下にはActivityActionの一覧が記載されていて、その中にはAPPLICATION_DETAILS_SETTINGS
やAPP_NOTIFICATION_SETTINGS
など「まえがき」の解決策となりうる定数が記載されている。
しかし、ExampleのLOCATION_SOURCE_SETTINGS
をこれらに入れ替えてもうまく行かない。アプリ特有の設定だからパッケージ名が要るような気がするが、ドキュメントには何も書かれていない。
expo-intent-launcherはAndroid限定だしマイナー扱いなのだろうが、ドキュメントも雑だし先人たちの情報も見当たらない。
とりあえずparamsとしてIntentLauncherParamsを見ると、packageNameってのがあるのでそのまま指定してみるが何も動かない。
迷いまくった結果、Expo ForumのOpening Device Settings on Android using Linkingってトピックにちゃんと書いてあった。(が、2019年のものなのでこのままコピペしても動かない。)つまり、{ data: 'package:' + YOUR_PACKAGE_NAME }
をすれば良いらしく、実際にそれで動いた。
しかしこれで動いたのはAPPLICATION_DETAILS_SETTINGS
であり、APP_NOTIFICATION_SETTINGS
の方は動かなかった。というか、ActivityActionに記載されているやつのうちいくつかは最低でも書くだけじゃ動かないものがある。初心者お断り設計である。