スリープ状態について

806 views
Skip to first unread message

karamu

unread,
Sep 4, 2014, 10:19:17 PM9/4/14
to android-g...@googlegroups.com
いつも勉強させていただいています。
宜しくお願いします。

端末がSleep時のonReceive時の処理について伺いたいです。
スリープ状態でもonReceiveが処理できるとは確認できたのですが、

下記サイト様などをみますと、下記のような記述がありました。
=====================
onReceive() メソッドが完了してすぐにスリープ状態になる場合があることを意味する
alarm receiver が Context.startService() を呼ぶ場合、service を起動するリクエストが完了するまえに電話がスリープ状態になる可能性がある
=====================
参考にさせていただいているサイト:http://y-anz-m.blogspot.jp/2011/03/alarmmanager.html

イメージとしては、
「スリープ状態でもonReceive()は起動するけど、その中でサービスの起動などを行った場合、
サービスの処理が中断することがあるよ」
な感じなのですが、この場合、スリープ状態というのは画面が真っ暗な状態、ということなのでしょうか?


上記のサイト様には解決策なども記載されており
owerManager.WakeLockをつかってスリープを解除させてあげればよいのだ!と勉強になったのですが、
SCREEN_BRIGHT_WAKE_LOCKはAPI level 13よりdeprecatedになっており、
ならば「PARTIAL_WAKE_LOCK」を使おう!とおもったものの
スリープの定義がわからなくなってしまいました。
SCREEN_BRIGHT_WAKE_LOCK」はスクリーンとCPUをONにしてあげるけど、
PARTIAL_WAKE_LOCK」はCPUのみON。

これは「スリープ状態」の解除にあたるのだろうか…と。。。

有識者の皆様、ご助言いただけると助かります。




Makoto Yamazaki

unread,
Sep 5, 2014, 3:56:03 AM9/5/14
to android-g...@googlegroups.com
zaki です。

参照先のページで言っている"電話がスリープ状態"というのは、
CPU を止めている状態のことです。

Receiver#onReceive() の中を実行している間はCPU が止まらないことが
保証されているのですがそこで startService を呼んでも、onReceive を抜けた瞬間に
CPU が止まってしまいサービスの起動処理がずっと後にならないと動かないということが
起こりえます。

support library に WakefulBroadcastReceiver というクラスがあって、これを使うと
サービスの実行が終わるまでCPU を止めないようにする処理が簡単にかけます。

Alarm のレシーバーをWakefulBroadcastReceiver のサブクラスにし、startWakefulService で
サービスの実行開始、サービス側からは処理が終わったら completeWakefulIntent で終了を通知
というような感じで実装します。

詳しくは WakefulBroadcastReceiver のリファレンスを見てください。




--
このメールは Google グループのグループ「日本Androidの会」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには android-group-j...@googlegroups.com にメールを送信してください。
このグループに投稿するには android-g...@googlegroups.com にメールを送信してください。
http://groups.google.com/group/android-group-japan からこのグループにアクセスしてください。
その他のオプションについては https://groups.google.com/d/optout にアクセスしてください。



--
YAMAZAKI Makoto

Takanori Sudo

unread,
Sep 5, 2014, 4:59:54 AM9/5/14
to android-g...@googlegroups.com
こんにちは。須藤と申します。

画面が点灯しているかどうかと、プログラムが動ける(aquire()されている)状態かは別の状態ですね。
画面はOFF・CPUがON、は、スリープ状態が解除されているという理解が正しいです。
実際にアプリがどう動くかをイメージすると、意味が分かってくるかと思います。たとえば…

アプリがネットワーク側からのプッシュを受け、「メッセージが来たよ」とユーザに通知したいケース。
ユーザが寝ている間枕元にスマホを置いていて、メッセージが来るたびに画面が点灯したら・・・私なら正直うざいと思いますし、電池も食います。
この場合は画面は消灯のまま、通知領域の機能を使ってLEDを点滅させるくらいがちょうどよいでしょう。
でも、実際画面は消灯したままでも、裏でメッセージを受信したり、通知領域の表示をするためにスマホは起きなければなりません。
なので、aquire()して処理を行い、その後release()してまたスマホが寝ても良い状態にします。

対してユーザにガンと主張しなければならないアプリもあります。目覚まし時計アプリなんかはその典型例でしょう。
この場合、画面を点灯させて、時間が来たよと自己主張すべきです。

ということで、アプリの趣旨とユーザへの見せ方、電池の消耗等ユーザへの配慮を総合的に勘案し、どうすべきかを考える必要があります。
アプリを作る側からするとどうしても自己主張する方に走りがちですが、そこはじっくり検討してください。

これがお答えになっているとよいですが・・・


2014年9月5日金曜日 11時19分17秒 UTC+9 karamu:

karamu

unread,
Sep 8, 2014, 6:35:08 AM9/8/14
to android-g...@googlegroups.com
zaki さま、Takanori Sudo さま、コメントありがとうございます。


zaki さま
WakefulBroadcastReceiver 
このようなクラスがあるのですね。初めて知りました。よい機会ですので勉強がてら触ってみたいと思います!



Takanori Sudo さま
わかりやすい例まで、本当にありがとうございます。とても納得できました。


お二方の回答でとてもすっきりしました。
さっそくいろいろと試してみたいと思います。ありがとうございました。

Reply all
Reply to author
Forward
0 new messages