Android - GmailやLINE等の通知 (+Dozeの無効化)

Android 6.0 以降には「Doze」と呼ばれる省電力機構が導入されました。

https://developer.android.com/about/versions/nougat/android-7.0-changes.html#doze

簡単に言うと画面がオフになって静止状態(端末を持ち運んでいない)で一定時間が立つとDoze(CPUとネットワーク制限)が有効になりバッテリー使用量を削減するというものです。Android 7以降では「深いDoze」(Deep Doze)が追加されて、段階的に省電力処理を行います。

これに伴いアプリの通知がこないという現象が起こるようになりました。

特にGmailアプリは「深いDoze」中にプッシュ通知は行われず、画面をオンにした時点でまとめて通知が来るためリアルタイムの通知が必要な場合には困ることになります。

このページではAndroid 7以降でもGmailやLINE等の通知がリアルタイムに来るよう設定する方法、またはDozeを無効化する方法について記しています。

プッシュ通知

Androidの通知にはアプリが起動していない状態でも外部サーバから送られるメッセージに反応する「プッシュ通知」と呼ばれる通知があります。

ところがDoze(Androidのスリープ省電力制御)中はAndroid側でリアルタイム性が必要と判断した高プライオリティのプッシュ通知の処理のみを行い、それ以外は一旦保留してDoze解除後に通知を表示するという処理を行います。

同様にDoze中はアラーム等のリアルタイム性が重要なアプリ以外は、定期的なチェックも行われなくなります。

このため画面をオンにした時や、スマホを手にもって移動を開始した瞬間などに通知がまとめて行われるということになります。

Androidの通信には通常のネットワーク接続の他にGCM(Google Cloud Messaging)という方式があります。

GCMは主にプッシュ通知に使用されていますが、GCMに対するプライオリティ(優先度)があって、プライオリティによりDozeモード中にプッシュ通知が行われるかどうかが決まります。(注 : 2019/04/11以降はFirebase Cloud Messagingへ切り替わりますが、ユーザから見た動作的にはさほど変わらない感じになると思われます)

このGCMに対するアプリのプライオリティが「高」である場合はDoze中でも即時に通知がなされますが、それ以外のアプリはDozeによって動作が制限されているので、Doze中にはプッシュ通知されず、画面がオンになった状態ではじめて通知されることになります。

Gmailアプリの通常のGCMに対するプライオリティは「ノーマル」なのでGoogleとしては端末が長時間「静止状態」の場合は就寝中などと想定して通知の必要なしとしているのかもしれません。

ただしGmailアプリでも重大なセキュリティ通知(不正アクセスがあった等)であれば「深いDoze」中でもリアルタイムで通知されるようです。

浅いDozeと深いDoze

Dozeには「浅いDoze」と「深いDoze」があり「深いDoze」ではごく限られたアプリのみ動作が許されます。

画面がオフになってからしばらくすると「浅いDoze」へ移行します。その後「2時間程度(機種によって異なる)の間、端末を未使用」かつ「静止状態 (持ち運びを行っていない)」である場合に「深いDoze」へ移行し、その後は一時的な「浅いDoze」と長時間の「深いDoze」を繰り返します。そして画面オフから6時間程度たった時点でずっと「深いDoze」のままになります。

「深いDoze」の挙動は使用している端末で違うことが多いので、プッシュ通知を確実に行うためには各端末に適した設定変更を行う必要があるようです。

ほとんどの通知遅延は「深いDoze」中におきますが、まずはDozeの状態を確認してみてください。

Dozeの状態確認

プッシュ通知が来ない場合、それがDoze中なのかどうかを確認する必要があります。

たとえば「GSam Battery Monitor」のようなアプリを使用することでDozeの状態を確認することができますので、まずはインストールしてみてください。

「Doze」の色の薄い部分が「浅いDoze」で濃い部分が「深いDoze」、白く抜けているのはリブートしたところです。

初級編

電池の最適化

Android端末の省電力機能が原因の場合は、通知が来ないアプリをAndroidの設定の「電池の最適化」の対象外にすることで、Doze中でも通常時と同様に動作し通知が行われるようになるはずです。

(ただしGmailアプリは「電池の最適化」で設定できないか、設定可能でも通知は行われない場合があります)

「電池の最適化」はほぼ全ての端末で設定可能なはずで、検索すればやり方は出てくると思いますので詳細は割愛します。

端末によって若干設定が違うものの概ね以下のようにしてアクセス可能なようです。

「設定」>「アプリ」> 歯車アイコン >「特別なアクセス」>「電池の最適化」

「設定」>「電池」>「電池の最適化」

アプリを「電池の最適化」(Doze)の対象外にすると、Doze中でもアプリは動作するため通知が来るようになりますが、このあたりの実装は各メーカーの電源管理に依存していて、同じアプリの同じ設定でも端末によって異なる動作をする場合があります。

機種によっては「電池の最適化」以外にも、独自のアプリ制御設定が存在する端末もあるので気をつける必要があります。

(たとえばHuawei機では「電池の最適化」だけでなく「電池」→「起動」も手動に設定する必要があります)

メールアプリ

Gmailアプリを「電池の最適化」の対象外にできない、あるいは対象外にしても効果がない場合は別の手段で通知を行う必要があります。

GmailについてはやはりGoogle純正のGmailアプリが最適ではあるので、Gmailアプリの通知のみが問題であれば、他のメールアプリを併用して通知させるという手もあります。プリインストールされているメールアプリやロック画面に通知が表示されるタイプのメールアプリでは「深いDoze」でも通知がなされることも多いようです。

Android側でGCM(FCM)を止められてしまえばメールアプリを「電池の最適化」の対象外にしても通知は来ないのですが、メールアプリによってIMAPを使用可能な場合はGCM(FCM)ではなくIMAP IDLEを利用してプッシュ通知を行うため「深いDoze」中でも通知が可能になります。

最近のメールアプリはたいていIMAP IDLEに対応しているので「電池の最適化」から外してやれば通知が届くようになるようですが、やはり相性はあるのでいくつか試してみてください。以下は個人的に試してみたメールアプリです。

CosmoSiaはUQモバイル推奨、K-9 mailはオープンソース、Microsoft OutlookはMicrosoft社製、ということで信頼しても問題なさそうです。Blue MailとmyMailについてはダウンロード数が多いのと評価が高いのでそれなりに安心して使えそうということで使用してみました。

通知音やLEDの色、バイブレーションを細かく設定可能なのはK-9 mailとBlue Mailでした。

まずは設定が簡単なのでCosmoSiaを使ってみるのが良いかもしれません。CosmoSiaを「電池の最適化」の対象外に設定するだけで「深いDoze」中でも通知が来るようになります。ただし通信関係のオプション設定はほとんどないので、デフォルトでうまくいかない場合は別のアプリを使うしかありません。

つぎにK-9 mailですが、認証方式が古い(後述)のと、見た目が前時代的なことを除けば、細かい設定が可能で機能的には十分だと言えます。
個人的にはGmailアプリは通知を切ってCosmoSiaで通知を行うという形に落ち着きました。

なおGmailアプリの通知は独自の重要度で通知する/しないを制御しています。サードパーティー製のメールアプリの場合、Outlook以外は基本的に全ての新着メールに対して通知を行うことになります。必要ならWeb上のGmailからフィルタを設定して、通知させたくないメールアドレス等に「受信トレイをスキップ」&「適当なラベルをつける」と良いでしょう。アプリによっては特定のアカウントやメールに対して通知を制御することができます。

余談ですがGmailは設定なしでname@gmail.comのアドレスに対してname+hoge@gmail.comのように+と好きな英数字を追加して使用することができます。

例えばamazon.co.jpの登録はname+amazon@gmail.comを使用しておけば、フィルタを作る際にアドレスに+amazonを含む場合は「受信トレイをスキップ」などのフィルタを作ることができます。

K-9 mail

K-9 mailで通知を行うために、まず「電池の最適化」の対象外に設定する必要があります。

デフォルト設定でDoze中に通知が来ない場合は

「グローバル設定」 > 「ネットワーク」 > 「バックグラウンド同期」

を「自動同期がチェックされた時」ではなく「常時利用」にすると通知されるようになるようです。

その他にIMAPのアイドル時間を短くすることが有効な場合もあります。

なおパスワードが正しいにも関わらず、メールを読み取れないことがあります。

これはK-9 mailがGoogleのセキュリティポリシーからは弱いセキュリティとみなされることがあり、その場合は2段階認証からアプリパスワードを発行しての認証が必要とされるからです。

https://support.google.com/mail/answer/185833?hl=ja

2段階認証を使用していない場合は「安全性の低いアプリによるアカウントの使用を許可」する必要があります。

Keep-Alive

MVNO(格安SIM)などではDozeとは関係なく一定時間の間ネットワーク通信が未使用であるとプロバイダ側からセッションを切断される場合があります。

セッションが切断されているので当然通知が来なくなるわけですが、この場合には定期的にネットワーク通信を行いセッションを維持するアプリが有効です。

セッションの切断が原因の場合は短時間で通知が来なくなるため、Dozeによる通知遅延とは切り分けが簡単なはずです。(格安SIMで30分以内に通知が行われなくなる場合などはセッションの切断が原因である可能性が高いと思われます)

頻度を高くしても電池を消費するだけなので一時的に3分以下に設定してみて、有効であれば問題なく動作する最長の間隔を選択すると良いでしょう。

改善されない場合は無意味なのでアンインストールしてください。

改善されても「深いDoze」中の通知が来なくなる場合は「電池の最適化」の対象外にする必要があります。

Microsoft flow

https://play.google.com/store/apps/details?id=com.microsoft.flow

Microsoft flowというアプリを使用するとGmailにメールが届いた場合に通知を行うことができます。



「Doze」の無効化

根本的な対策として「Doze」自体、または「深いDoze」のみを無効化する方法があります。

「Doze」は次節の「上級編」で説明するようにPCを使ったadbコマンド等で無効化可能です。

ちなみに筆者がAndroid 7.0の端末で「深いDoze」のみを禁止して一日放置した場合は一時間あたり0.3%程度増加しました。

使用アプリや端末の電池容量等で異なるもので許容範囲ではあるものの、やはり正攻法で対処したほうが良いかもしれません。

自動化アプリ

自動化アプリ(android端末のセンサー等と連携して様々なアクションを実行する)を利用してDozeを抑制する方法もあります。

端末によって動作は異なるので確実なわけではありませんが、自動化アプリを利用して一定時間ごとに画面を点灯させてDozeに入ることを阻止する、あるいは画面オフ時の一定時間ごとにGmailやLINEを起動する、などで通知の遅延に有効な場合があります。

代表的な自動化アプリ

上級編

もし「深いDoze」に入ったタイミングで通知が来なくなるようなら、「Deep Doze」を無効化することで通知が来るようになります。

Dozeを無効化したい場合はPCからadbコマンドを使用する必要があります。

PCからadbで権限を有効化する必要があるので、以下のいずれかからadbツールをPCへインストールします。

Androidアプリ開発環境を整えている場合は開発環境のadbコマンドを使用してください。

GSam Battery Monitor」は、adbで権限を付加することにより詳細なバッテリーの使用状況を表示することができます。

メニューの「Enable more stats」からMinimal ADBを使用して権限を有効にする方法が解説されているので、そちらを参照しても良いでしょう。

USBデバッグの有効化

まずはPCに接続して中身が見えるようなら、次に「開発者オプション」の「USBデバッグ」を有効にしてPCへ接続します。

このあたりの説明は適当に検索すると大量に出てきますので割愛します。

端末を接続して通知が出たらUSBデバッグを許可してください。

正常に接続されたらコマンドプロンプトから以下を実行してみてください。

adb devices

Windowsの場合はadb.exeのあるフォルダでアドレスバーにcmdと入力するとコマンドプロンプトが起動するので便利です。

Dozeの無効化

Doze自体を無効化するには以下を実行します。

adb -d shell dumpsys deviceidle disable

Android 7以降で通知が来ないのが「深いDoze」中のみであれば、以下のコマンドで「Deep Doze」のみを無効化できます。(バッテリー的には「深いDoze」のみ無効化するほうが有利です)

adb -d shell dumpsys deviceidle disable deep

なお、この設定は一度設定すれば再起動するまでは有効なままですが、端末を再起動した場合は、再設定を行う必要があります。

Android 6

Andriod 6の場合は以下の端末エミュレータアプリから設定が可能です。

Android Terminal Emulator改変版

一度だけアプリにandroid.permission.DUMP権限を付加します。

adb -d shell pm grant jackpal.androidterm android.permission.DUMP

再起動した場合は「Android Terminal Emulator改変版」を起動してコマンドを入力します。

dumpsys deviceidle disable

強制的に「深いDoze」へ移行

Greenify」を使って強制的に1分間程度で「深いDoze」へ移行させることができます。

「深いDoze」中の動作チェックをしたい場合は有用ですが、こちらもadbで権限を有効にする必要があります。

番外編:一日の待機消費電力

アプリの通知が鳴らないという問題が解決したとして、次に問題になるのは一日にバッテリーがどれくらい消費されるかということです。

これは使用機種と使用アプリで大きく異なるわけですが、ほぼ使用しない状態でのバッテリー消費が一時間につき1%程度が一つの目安で、それ以上は異常な消費とみなして対処する必要があるかもしれません。(大抵の場合、初期状態でのバッテリー消費は一時間あたり0.5%以下のようです)

実際問題としてスリープ時の消費電力が一時間につき1%であれば、全く使用しなくても4日でバッテリーが完全に無くなってしまうことになるのであまり良い状態とは言えない気がします。

上記の例は2700mAのバッテリー使用機種の場合で、大容量バッテリーの機種だと消費電力の数値的には小さくなります。自宅にWiFiがある場合はSIM(モバイル通信)を無効化してWiFiに接続し、10時間程度スリープした時の消費電力を調べて基準にすると良いかもしれません。(一般的にWiFi接続のみのほうが電力は消費しません)

バッテリーの異常消費には大きく分けて3種類あります。

アプリの異常

まれにアプリが暴走してバッテリーを異常消費することがあります。大抵はAndroidの「設定」からバッテリー消費量一覧がみられるので確認してみてください。

この場合は端末を再起動するのが正攻法ですが、それでも改善されない場合はAndroidの「アプリ設定」から該当アプリの「キャッシュを削除」、または一度「強制停止」してやることでおおむね対応可能です。

特に見当たらないが急にバッテリーの消費量が増えた場合は「Google Play開発者サービス」のデータ削除&再起動が有効な場合が多いようです。

アプリの仕様

一時話題になったFacebookのようにそもそも仕様として消費電力の高いアプリがあります。

Androidの設定やバッテリモニターアプリで「実行中のアプリ」を確認できるので待機状態で起動しているアプリで問題になりそうなアプリを停止させてみるというのが対処になります。Android 6.0以降であれば該当アプリに権限を付加しないことで消費電力が少なくなることもあります。

問題になるのは主に「位置情報を使用する」、「定期的に通信」するアプリです。

筆者はAndroid 5.1のSIM非対応タブレットも使用しているのですが、「Japan Connected-free Wi-Fi」というフリーWiFi接続アプリを入れてみたところ、(現在では修正されているのかもしれませんが)アプリを使用していないにも関わらずバッテリー消費量が劇的に上昇しました。Android 7.0の端末ではDozeによってバックグラウウンド動作を禁止されるのか、それほど問題にならなかったのですが、Doze以前のAndroidではアプリの出来がダイレクトに反映されるのかもしれません。

代替がなくどうしても使用しなければならないアプリは、使用後にAndroidの「アプリ設定」から毎回強制停止するという方法しかありません。なお強制停止してもすぐに動作を始めるいわゆるゾンビアプリであれば対処法はないということになります。バックグラウウンド動作を禁止する「Greenify」のような節電アプリ(機種によっては同じような機能がOSに組み込まれているものもあります)を使用する方法もありますが、そもそも対処したくなるような行儀の悪いアプリに対しては効果は余り望めないことが多いようです。

ハードウェア

意外と気がつかないのがハードウェアに起因するバッテリードレインです。

ハードウェア起因の問題と言っても、原因になるのはおおむねSIMカードかSDカードです。

SDカードは取り外して様子を見てみればよいのですが、SIMカードでは逆に「SIMを挿していない」か「SMSが使えないデータ通信専用SIM」の場合に「セルスタンバイ」問題が起きる機種があるので気をつける必要があります。

また契約会社の違うSIMを同じスマホに挿した場合、スリープ中のバッテリー消費が大幅に異なる事がありました。筆者の場合はdocomo系のBiglobeのSIMをdocomo系のNifmo、OCNのSIMに変更してみたところ同じスマホでのスリープ時の消費電力が倍(1時間で0.4%→0.8%)になりました。

OCNのSIMの場合は設定で解決した人もいるようです。

https://bike8615.blogspot.com/2020/06/ocn-one-sim.html

ただし全てのデバイスで”LTE only"に設定できるわけではありません。

また筆者はHuawei機で購入直後から機内モード(+Wi-Fi有効)で動作させるとバッテリードレインが起きず、データ通信を有効にするとバッテリードレインが起きるという状態になっていたことがありました。一度SIMカードを外して起動し、電源を落としてから再びSIMカードを挿して起動すると解決したのですが、初回起動前からSIMを挿してしまっていたため原因不明で相当悩んだ覚えがあります。(ソフト的な問題か接触不良だったのかは結局不明です)

同様にSDカードを挿しているとバッテリーを異常消費する問題があったとして、購入時からSDカードを挿していたりするとなかなか原因に気が付けないということになります。

スマホに限らずハードウェアの物理的な抜き差しや電源の抜き差しで改善することは割とあるので一度試してみるのもよいかもしれません。

その他にBluetoothでのハードウェア接続に起因する場合もありますが、こちらも一時的にBluetoothをオフにしてみることで確認できるはずです。