Androidスマホの場合、歩数カウンタに再起動時からの歩数が記録されている。 直接読み取ることはできず、カウンタの値が変わるごとに、イベントを受けることとなる。
前アプリでは、スマホの再起動時の処理に不備があった。
必ずしも頻繁に SQLiteデータベースの値を更新する必要はないが、現時点では、60歩または10分毎に 更新している。
歩いている途中でシャットダウンが起きた場合、1日の歩数に 60歩未満の誤差が起こり得る。 しかし、通常は、10分以上静止した状態でスマホをシャットダウン(再起動)しているので、誤差は生じない。 不測の自体でシャットダウンが起きた場合に備えて、変化があれば 60歩または10分後にデータベースを 更新している。
シャットダウンの前にはイベントが送られるはずなので、このイベントをキャッチして、その時点で データベースに書き込めばいいのであろうが、記録歩数に多少の誤差が生まれても問題はないので、このようにした。
今日の歩数は地図画面の最下部に表示している。日付更新イベントを受けて、その日の歩数をリセットする ことも可能であるが、今は、そうしていない。 朝一番では前日の歩数が表示されている。10歩以上歩いたとき、初めて changedイベントが連続して送られてくる。 これで、新しい日の歩数が表示されるようになる。
朝一番では昨日の歩数が分かる方がいいので、このようにしている。
日々の歩数や月別平均歩数グラフはデータベースから求める。
データベース自体には日々の歩数だけが記録されている。月別平均歩数は SQLの集計関数で求まるはずだが、 今はプログラムで算出している。
int lastCumSteps = -1;
long timeChanged = -1;
void changed(int cumSteps) {
long now = System.currentTimeMillis()/1000;
if (cumSteps > lastCumSteps + 60 ||
(now - timeChanged > 600 && cumSteps > lastCumSteps)) {
int date = dateNow();
int[][] cols = getRecordDesc(1);
int date0 = cols[0][0];
int steps0 = cols[0][1];
int cum_steps0 = cols[0][2];
int steps = (cumSteps - cum_steps0);
if (date > date0) { // 日付が変わった
if (cumSteps >= cum_steps0) {
insertOrUpdate(date, steps, cumSteps);
} else {
// shutdownがあった
insertOrUpdate(date, cumSteps, cumSteps);
}
} else {
if (cumSteps >= cum_steps0) {
steps = steps0 + (cumSteps - cum_steps0);
} else { // shutdownがあった
steps = steps0; // 2026.1.7
}
insertOrUpdate(date, steps, cumSteps);
}
app.setSteps(steps);
timeChanged = now;
}
}