とにかくやるブログ

とにかくやるブログ

プログラムの備忘録とその他雑記を適当にやるブログ

【Androidプログラム】ロック画面からPUSH通知でアプリを着信的な感じで無理やり起動しようとしたら色々気をつけることがあった備忘録

f:id:tewow:20190419225915j:plain
※関係ないアイキャッチ


表題の通りです。

FirebaseのPUSH通知を使います。
EsFirebase~のonMessageReceive()に入ってきたらトバしたいActivityのIntentをcreateIntentしてstartActivityするって寸法です。

ロック画面からでも強制的に起動できるようにしたかったので色々調べると
どうやら"WindowManager"というものを使うといいらしい。


"WindowManager"には設定可能なフラグがいくつかあるが
今回必要なのは以下の3つ

・FLAG_SHOW_WHEN_LOCKED
・FLAG_DISMISS_KEYGUARD
・FLAG_TURN_SCREEN_ON

こいつを設定してやると以下。

val window = this.getWindow()

window.addFlags(
           WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                   or  WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                   or  WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON ) 

ただ、Androidディベロッパーサイトでこのフラグを確認すると
”FLAG_DISMISS_KEYGUARD”はAPI LEVEL26まで
”FLAG_SHOW_WHEN_LOCKED”と”FLAG_TURN_SCREEN_ON ”は27までのようで
Oreo以上に対応させようとすると別の処理が必要。

developer.android.com



ただ、ディベロッパーサイトは便利なもので代替案はすぐに見つかった。

val window = this.getWindow()

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
   setShowWhenLocked(true)
   setTurnScreenOn(true)

   val keyguard = getSystemService(android.content.Context.KEYGUARD_SERVICE) as? KeyguardManager
   keyguard?.requestDismissKeyguard(this,null)

}else{

 window.addFlags(
           WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                   or  WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                   or  WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON ) 
}

setShowWhenLocked(true) は FLAG_SHOW_WHEN_LOCKED
setTurnScreenOn(true) は FLAG_TURN_SCREEN_ON
keyguard~ は FLAG_TURN_SCREEN_ON

にそれぞれ相当している。

これで一度動かしてみたところ、問題なく動作してめでたしめでたし・・・


と、思いきや、、


端末をPCから切り離した状態で試してみると、動作せず・・・!


どうやら端末がPCにつながった状態でのスリープと
繋がっていないスリープでは状態が違うらしく
もう一押し必要だったらしい。




そうして、ここでは”PowerManager”という端末の電源状態を管理するマネージャーを使うことに

val pm = getSystemService(Context.POWER_SERVICE) as PowerManager
val wakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP or PowerManager.ON_AFTER_RELEASE,TAG)
wakelock.acquire(10000)//タイムアウト:10秒


なお、今回はWindowManagerは起動させたいActivityのonCreate()で
PowerManagerはEsFirebase~のonMessageReceive()でそれぞれ処理を行っている。


また、PowerManagerのWakeLocks は端末の電源に大きな影響を与えるので
使ったあとには必ず開放するのを忘れないように。