Androidで標準センサーを使って歩数計アプリを作りたいけれどセンサーの種類やAPIレベルの扱いで迷ってしまうことが多いはずです。
この記事を読むと標準の歩数センサーからリアルタイムに歩数を取得する方法とセンサーがない端末での軽量な代替手法や実機でのテスト方法さらに省電力に配慮した実装のコツまで身に付きます。
| 項目 | 内容 |
|---|---|
| 独自コンテンツ1 | 実機で動くコピーアンドペースト可能なコード例と行ごとの実務的な解説。 |
| 独自コンテンツ2 | メーカー差を踏まえたセンサーデバッグの具体的手順とよくある落とし穴回避法。 |
| 独自コンテンツ3 | 標準センサー非搭載時の加速度ベース検出アルゴリズムとバッテリー節約の実践テクニック。 |
面倒に感じるポイントをやさしく噛み砕いて順を追って説明するので実機で動く状態まで一緒に進めていきましょう安心して読み進めてください。
Android博士初めてでも大丈夫です怖がらずに手を動かしてみてください一回でも実機で動かせば自信になりますし少しずつ改良していけますよ。
Androidで標準の歩数センサーから歩数をリアルタイム取得する方法


Android端末の標準センサーを使えば歩数をリアルタイムで取得できます。よく使うのはTYPE_STEP_DETECTORとTYPE_STEP_COUNTERの二つで、それぞれ得意な場面が違います。前者は歩いた瞬間にイベントが届くので瞬時の表示に向きますし、後者は累積値で長期的な集計に便利です。
この章ではActivityでSensorManagerを取得する手順から、onResumeでの登録、onPauseでの保存までを具体的に示します。初めてでも迷わないように実務で役立つコツや端末再起動時の扱いも分かりやすく説明します。



最初はセンサーの種類やイベントの扱いに戸惑うかもしれませんが、順を追えばシンプルに動きます。焦らず一つずつ試してみてくださいね。
TYPE_STEP_DETECTORで1歩ずつ受け取るやり方


TYPE_STEP_DETECTORは一歩ごとにイベントを送るセンサーです。SensorEventのvalues[0]が1.0で来ることが多いので、そのタイミングでローカルの歩数を増やします。反応が良くバッテリー負荷も小さいのでリアルタイム表示に向いています。
注意点として端末によってはサポートされていない場合やセンサーがバッチ配信される場合があります。必ずセンサーの存在チェックとイベントの重複防止を入れて、UI更新はメインスレッドで行ってください。
ActivityのonCreateでSensorManagerを取得する
ActivityのonCreateでgetSystemServiceでSensorManagerを取得して変数に保持します。
SensorManager.getDefaultSensorでTYPE_STEP_DETECTORを取得し、nullチェックを行ってから保存します。
取得できなければ代替処理を用意してユーザーに対応を促すメッセージを出します。
onResumeでTYPE_STEP_DETECTORを登録しonSensorChangedで歩数を増やす
onResumeでregisterListenerを呼んでTYPE_STEP_DETECTORを登録します。遅延はSENSOR_DELAY_NORMALで十分なことが多いです。
onSensorChangedでsensor.getTypeを確認し、values[0]が1相当ならローカルの歩数変数をインクリメントしてUIを更新します。
UI更新はrunOnUiThreadやHandlerで行い、イベントの重複を防ぐため簡単なデバウンス処理を入れると安定します。
onPauseでセンサー登録を解除してSharedPreferencesに現在カウントを保存する
onPauseで必ずunregisterListenerを呼んでセンサー登録を解除し、余計な電力消費を防ぎます。
SharedPreferencesに現在の歩数をputIntで保存してapplyで非同期保存します。復帰時に読み出せるようにしておきます。
保存は頻繁に行うと負荷になるので重要なタイミングでまとめて保存するか、画面遷移時に確実に保存する設計にします。
TYPE_STEP_COUNTERで累積値を差分として扱うやり方


TYPE_STEP_COUNTERは端末起動後からの累積歩数を返すセンサーです。SensorEventのvalues[0]に累積値が入るため、そのまま表示するとリセットや再起動で困ることがあります。初回読み取り時に基準値を取るのが定石です。
実装では初回の値をbaselineとして保存し、以降はcurrent-baselineを表示します。端末再起動やセンサーリセットで値が小さくなる可能性があるので、その場合はbaselineを現在値に更新する処理を入れてください。
初回読み取り値をbaselineとして保存し以降は差分を計算して表示する
SharedPreferencesにbaselineが無ければ現在のvalues[0]をbaselineとして保存します。これが以降の基準になります。
表示はcurrentValues-baselineで行います。負の値になったら再起動やリセットと判断してbaselineを現在値で上書きします。
baselineは永続化しておき、アプリ再起動時や端末再起動時に正しく差分が出るように設計します。
Androidで標準センサー未搭載端末向けに加速度で歩数を検出する方法


端末に標準の歩数センサーがない場合は、加速度センサーの生データから歩数を検出するのが実用的です。ここでは現場でよく使う手法をわかりやすくまとめますので、気楽に読み進めてください。
- シンプルなピーク検出法。加速度の山を数えて歩数にするため実装が素早く済みます。
- センサフュージョン。ジャイロや磁気センサーと組み合わせて誤検出を減らす方法です。
- 機械学習を使った判定。精度は高くなるが学習データの準備が必要になります。
まずはピーク検出で試してみるのがおすすめです。閾値と間隔を現場でチューニングすれば、多くの端末で安定して動きますので気軽に試してみてください。
ピーク検出でシンプルに歩数を判定するパターン


ピーク検出は加速度の局所的な山を見つけてそれを一歩としてカウントする方法です。重力成分を取り除いた線形加速度やベクトルの大きさを使うと分かりやすく動作します。
閾値と最小間隔で誤検出を抑えつつ、ローパスやハイパスでノイズを減らすのが定石です。実際の歩行データでテストを繰り返しながら値を調整すると安定します。
ActivityのonCreateで加速度センサーを取得してリスナーを用意する
onCreateでContextからSensorManagerを取得し、TYPE_ACCELEROMETERのSensorを取っておきます。ここでは参照を保持しておくと後で登録が簡単になります。
SensorEventListenerを実装してonSensorChangedとonAccuracyChangedを用意します。生データのバッファや時刻を保持する変数をここで初期化しておくと実装が楽になります。
onCreateで準備だけ行い、実際の登録はonResumeでregisterListener、onPauseでunregisterListenerするのが安全な使い方です。
onSensorChangedでローパス/ハイパスフィルタをかけてノイズを除去する
- ローパスフィルタで重力成分を推定する。単純な指数移動平均で十分効果があります。
- ハイパスフィルタで線形加速度だけ取り出す。重力を引いてからピーク検出する流れが扱いやすいです。
- 追加で移動平均や中央値フィルタを入れてスパイクをならすと誤検出が減ります。
ピーク検出の閾値と最小間隔を決めてピークで歩数をカウントする
| 項目 | 内容 |
|---|---|
| 閾値の目安 | 1.0〜2.0m/s^2が一般的。端末やポケット位置で変わるので実測で調整してください。 |
| 最小間隔の目安 | 250〜700msを設定すると歩行の速さによる重複カウントを防げます。ユーザの歩幅に合わせて調整しましょう。 |
| 運用上のコツ | 閾値を固定にせず歩行検出中は適応的に補正すると安定します。テストユーザで必ず確認してください。 |
Androidでバックグラウンドでも歩数を記録して日別集計する方法


バックグラウンドで歩数を記録して日別に集計するには、端末の標準センサーと長時間動く仕組みを組み合わせるのが現実的です。ここでは実際に動く手順を中心に、継続取得と日付ごとの保存までをわかりやすく伝えます。
使えるアプローチはいくつかあり、センサーイベントを逐次受け取って加算する方法と、累積値を差分で扱う方法があります。端末やAndroidバージョンで挙動が少し変わるので、まず小さなプロトタイプで挙動を確認すると安心です。
- ForegroundServiceでSensorListenerを常時登録して歩数イベントを受け取り、日ごとに加算保存するパターン。
- WorkManagerなどで定期起動してセンサーやAPIから値を取得し日次で集計するパターン。
- 端末センサーが未搭載の場合はGoogleFit等の外部APIと同期して日次データを取得するパターン。



まずは端末上で小さなサービスを立ち上げて、歩数イベントが正しく来るかを確認してみてください。動けば一気に応用できるので楽しみながら進めましょう。
Foreground Serviceで継続取得して日ごとに保存する実践パターン


ForegroundServiceを使うとシステムに終了されにくくなり、リアルタイムで歩数を拾いやすくなります。サービス内でSensorManagerにSensorEventListenerを登録し、通知を表示してフォアグラウンドにする流れが基本です。
実装時はACTIVITY_RECOGNITIONのパーミッション確認と、センサーの種類(STEP_DETECTORかSTEP_COUNTER)に応じた処理を分けておくと後で楽になります。イベントを受け取ったら日付に紐付けて保存するロジックを忘れず用意してください。
サービス内でSensorListenerを登録して通知付きForegroudServiceを起動する
IntentServiceではなくForeground Serviceを用意し、startForegroundで通知を出す準備をする。
ServiceのonCreateやonStartCommand内でSensorManagerを取得し、STEP_DETECTORかSTEP_COUNTERを登録する。
ユーザーに見える通知を作成してstartForegroundを呼び、サービスが継続して動くようにする。
歩数イベントを受けたらローカルDBやSharedPreferencesに日付キーで加算保存する
- イベント受信時にイベントのタイムスタンプを日付文字列(YYYY-MM-DD)に変換し、その日付キーで加算する。
- 単純な用途はSharedPreferencesにintを保存しても良いが、整合性や将来の拡張を考えるとRoomなどのローカルDBを推奨する。
- 深夜の切り替わりはタイムスタンプで判定し、日付が変わったら新しいキーに加算を始めるロジックを入れると正確に集計できる。
よくある質問


- センサーが見つからないや歩数が取れないときは
端末に標準の歩数センサーがないと取得できません。SensorManager.getDefaultSensorでnullか確認して、エミュレータは非対応なので実機で試してください。標準センサーがない場合は加速度センサーで歩数検出を行う代替実装を検討してください。
- 歩数がリセットされたように見えるのはなぜ
STEP_COUNTERは端末の起動以降の累計値を返します。日ごとに集計したいときはその日の開始時点の値を保存して差分を取る方法が扱いやすいです。再起動を検出した場合は基準値を更新してください。
- バッテリーが心配なときはどうすればいいですか
ハードウェアの歩数センサー(STEP_DETECTORやSTEP_COUNTER)は加速度を常時処理するより省電力です。これらを使い、SENSOR_DELAY_NORMALなど低頻度で登録し、不要時はlistenerを解除する運用が効果的です。
- テストやデバッグの効率的な方法はありますか
実機での歩行テストが最も確実です。繰り返し確認したいときはアプリ内にステップを模擬するボタンやモック実装を用意すると動作確認が楽になります。
まとめ


ここまででAndroidの標準センサーを使って歩数をリアルタイムに取得する基本の流れがつかめたはずです。主に使うのはTYPE_STEP_COUNTERとTYPE_STEP_DETECTORで、SensorManagerに登録してSensorEventで歩数を受け取るだけでシンプルに動きます。とはいえ端末の実装差やOSバージョンで挙動が変わるので、いくつかの安全策を入れておくと安心です。
実務的にはACTIVITY_RECOGNITION権限の確認と、ステップセンサー非搭載端末向けに加速度センサーを使ったフォールバック処理を用意しておくと実用性が高まります。電池を節約するためにセンサーバッチやサンプリング間隔を調整し、歩数はSharedPreferencesやRoomで永続化して再起動時はBootCompletedReceiverで整合させてください。これで想定外の挙動に強くなります。
テストは必ず実機で歩いて動きを確認し、ログを活用した擬似イベントでケースを埋めてください。まずは最小限の機能で安定させてからUIやバックグラウンド処理を追加すると開発が楽になります。気楽に試しながら、細かなズレはログで追う姿勢が一番の近道です。



焦らずやっていきましょう。センサーは端末ごとに性格が違うので、ログを取りながら少しずつ動きを確認すると安心です。
