LoginSignup
3
5

More than 5 years have passed since last update.

Androidでバックグラウンドから位置情報を定期的に取得するには結局どうするか

Posted at

何かとバックグラウンドでできることの制限が多いAndroid。
バックグラウンドで定期的に位置情報を取得するときはどう実装するのが良いか考えました。

TL;DR

  1. Android 6系より前はBackground Service、Android6系以降はJobScheduler
  2. AlarmManagerで10分おきに位置情報取得
  3. どうしても正確に拾っていきたいときはForegroundServiceを使う

1の根拠

OnStartCommandSTART_STICKYSTART_REDELIVER_INTENTを指定すれば、Android 8より前であれば動くのではと思ったけど、こちらの記事によると

By default, if you want to run a service in the background forever, then you can return START_STICKY in the onStartCommand of service. The service will get recreated by the Android OS if this was destroyed for many reasons. But this will not work in devices which are running in Android version 6 and above due to Standby and Doze mode restrictions

とあり、ServiceもDozeモードにやられてしまうようなので、Android 6系以降はJobSchedulerで統一。
(ただこれは記事による伝聞ベースなので、検証端末さえあれば6系7系での挙動を確認したい)

とはいえ、JobSchedulerのほうもDozeモードにはやられてしまうのでこの判断に差異は特にないのですが、Android8以降BackgroundServiceが実行できなくなるので、JobSchedulerのほうを優先した、という感じです。

2の根拠

JobSchedulerに統一はしたものの、深いDozeに入ってしまえば、こちらの記事によれば何時間も位置情報が取得できなくなってしまう。
ということで、AlarmManagerで定期的に位置情報を取得します。
10分おきというところの根拠は、Android 8以降ではAlarmManagerが最大で9分に1回までしか発火できない、という情報を基にしています。

まあこれをしても、Android 8以降では、位置情報を取得できるのは1時間に数回のみのようなので、「10分ごとであれば正確な位置情報がとれます!」とも特には言えませんね。

3の根拠

とはいえ、サービスを運用していく上で、どうしてもここは正確に位置を取りたい!という要望があったときは、ForegroundServiceでやるしかないでしょう。
ただ、これもうまくやらないと、こちらから明示的にstopさせずともForegroundServiceが止まってしまうこともあるので、実装時は要注意。

まとめ

いろいろ調べてみてなんですが、ForegroundServiceを使わないという選択をする限り、正確な位置をベースとしたサービス設計にはしないほうが良いです。

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5