歩数計センサーは、最終再起動以降、センサーがアクティベートされている間にユーザーが歩いた歩数を提供する。
ネットで見つけた事例を真似てみた。動作することは確かであるが、イベントで逐一、歩数を受け取るのは 電池の無駄である。例えば、ボタンをタップしたときにその時点の歩数カウント値を読み取るだけで十分である。
しかし、今のところその方法が見つからない。 リスナーを登録して、onSensorChanged で受け取る方法しか見つからない。
スマホは滅多にシャットダウンしないが、その時点の歩数カウンターの値をセーブする必要がある。 常時動かしているマイ地図の位置情報取得サービスでシャットダウン処理を行いたい。
毎日、日付が変わったときおよびシャットダウン時の日時と歩数カウンターの値を ストレージに書き込んでおく。そうすれば、日中にシャットダウンがあっても、日々の歩数を計算できる。
private SensorManager sensorManager;
private Sensor mStepCounter;
@Override
protected void onCreate(Bundle savedInstanceState) {
// 省略
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_DENIED){
//ask for permission
requestPermissions(new String[]{Manifest.permission.ACTIVITY_RECOGNITION}, 0x05);
//PHYISCAL_ACTIVITY); 0x05 は適当な値とした。
}
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mStepCounter = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
}
@Override
protected void onResume() {
// 省略
sensorManager.registerListener(this, mStepCounter,SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
// 省略
sensorManager.unregisterListener(this,mStepCounter) ;
}
@Override
public void onSensorChanged(SensorEvent event) {
int StepCount = (int) event.values[0];
Utils.toast("StepCount: " + StepCount, this);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
次のプログラムも試したが、カウンタの値が1となった。
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
sensorManager.registerListener(new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
int StepCount = (int) event.values[0];
Utils.toast("StepCount: " + StepCount, MainActivity.this);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, sensor, SensorManager.SENSOR_DELAY_UI);
歩数計としては Activity にリスナーを登録して、onSensorChangedで受け取ればよいが、 例えば、24時間稼働の位置情報取得 Service でセンサー情報を受け取り、移動がないと判断したときは、 GPS取得を止め、移動を検出したとき再開するには、Serviceへの実装が必要になる。Kotlinでの例が記事[5]にある。
Javaでプログラムを書いてみたが、Activity でも Service でも大体同じでよかった。
現在の地図アプリMapでは、Activity と Service にリスナーを実装している。 Service の方は 24時間稼働であるが、Activityの場合、onResume でリスナーを登録、onPause でリスナを削除するので、 稼働時間は極めて短い。地図の下部に、その日の歩数を表示する。
現在位置が自宅の時、Serviceの方は 30秒~1分間隔で、歩数をチェックする。