定期処理するアプリを作っていてハマりまくりました。
その経緯と最終的に行った対処法のメモです。
結論を言ってしまうと、自分の端末(ZTE の AXON MINI)のせい。
どのようなアプリか
普段利用している英単語学習アプリの学習忘れを通知するアプリが欲しくて自作しました。
画面に英単語学習アプリの起動ボタンを配置して、その日に起動していなかったらプッシュ通知されるアプリです。https://play.google.com/store/apps/details?id=com.ozanote.iknownotification
SQLiteに最後に起動した時間を持っていて、定期処理でチェックして通知する感じです。
端末が再起動すると定期処理が動かなくなる
定期処理の仕組みに WorkManager を使用しています。
概ね思った通りの動作をするのですが、端末の再起動後に通知が来ないことに気づきました。
対策として Firebase の Cloud Functions(処理) と Cloud Messaging(通知) を使うことを思いつきました。
単純に Cloud Functions を使ってみたかったのもありますが、クラウド上で処理すれば端末の再起動に左右されないと思ったからです(が間違いでした)。
アプリが終了していると Cloud Messaging の通知が来ない
正確には通知は来るけど端末が拾ってくれないって感じでしょうか。
ここでいう「アプリが終了」は、起動中のアプリ一覧(右下辺りの□)から削除した状態の事です。
WorkManager を使用していた時はアプリが終了していても通知されていたので、余計に悪くなっただけでした。
クラウドと通信するから動作も遅くなって良いこと無し。。。
レシーバーを使う
初心に帰って WorkManager でどうにかすることにしました。
要するに、端末起動時に WorkManager を再設定してあげればいいよねってことで、起動時のレシーバ(android.intent.action.BOOT_COMPLETED)を作成し再設定するようにしました。
これで解決しただろうと動作確認してみる…
が、端末起動時にレシーバーに処理が来ない。。。
何故だー!
もう、お手上げ。
端末のせい
上記でいろいろ調べている間にひとつだけ解決できる方法がありましたが、できれば別の方法で解決したかった。
しかしこれ以上はどうしようもなさそうなので、最後の手段です。
どういうことかと言うと、実はエミュレータではちゃんと動くのです。。。
そもそもWorkManager は再起動しても動作すると公式ドキュメントに書いてあります。
Cloud Messaging に関しても、アプリを終了していたら通知できないなんて書いていないし、それだと使い勝手が悪すぎます。
なんと、一部のメーカーの端末はバッテリーの持ちをよくするため、バックグラウンドで動作していないといけないアプリまで勝手に終了してしまうそうです。
↓こんなサイトがありました(悪質なメーカー一覧と対処法も書いてあります。)
https://dontkillmyapp.com/
そのせいで定期処理が動かなかったり通知が表示されなかったりしていたのです。
対処方法
端末によって方法が違いますが、自動起動の設定をすると勝手に終了されなくなるようです。
私の端末(ZTE の AXON MINI)の場合【設定】→【電源管理】→【自動管理】と進み、アプリのトグルをONにすると再起動しても定期処理が動くようになりました。
何故この方法を最後の手段にしていたかというと、端末によって対処方法が違う上にユーザーが自ら設定しないといけないからです。
アプリは不特定多数の人が使うものなので、自力では設定できない人もいると思いますし、
この対処が必要なことを知らずに動かないアプリだと思ってアンインストールする人もいるでしょう。
(まぁ、このアプリは私しか使ってないですがw)
なんとかアプリ側でどうにかしたかったのですが無理でした。。。残念。
バッテリーの持ちは確かに大事ですが、最低限、公式ドキュメント通りに動くようにしてほしいですね。
2020/10/18 追記:
スマホを Pixel3a に変えました。再起動すると通知が来ませんでした。。。
純正androidでもこのような動作になることから、バッテリー対策として使用頻度の低いバックグラウンドアプリを停止するのは定番になっているようですね。
いい対策があれば誰か教えてください。