android手機計步器功能
在市面上瀏覽過眾多的計步軟件,可惜沒有開源的代碼,而github上的幾個開源的計步代碼,要么就是記得不準,要么就是功能不完善,不穩定,于是決心自己寫一個,分享給大家使用,希望大家一起來完善。
已上傳github:https://github.com/xfmax/BasePedo
流程圖:
核心代碼如下:
package com.base.basepedo.service; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.util.Log; import com.base.basepedo.utils.CountDownTimer; import java.util.Timer; import java.util.TimerTask; public class StepDcretor implements SensorEventListener { private final String TAG = "StepDcretor"; // alpha 由 t / (t + dT)計算得來,其中 t 是低通濾波器的時間常數,dT 是事件報送頻率 private final float alpha = 0.8f; private long perCalTime = 0; private final float minValue = 8.8f; private final float maxValue = 10.5f; private final float verminValue = 9.5f; private final float vermaxValue = 10.0f; private final float minTime = 150; private final float maxTime = 2000; /** * 0-準備計時 1-計時中 2-準備為正常計步計時 3-正常計步中 */ private int CountTimeState = 0; public static int CURRENT_SETP = 0; public static int TEMP_STEP = 0; private int lastStep = -1; // 加速計的三個維度數值 public static float[] gravity = new float[3]; public static float[] linear_acceleration = new float[3]; //用三個維度算出的平均值 public static float average = 0; private Timer timer; // 倒計時8秒,8秒內不會顯示計步,用于屏蔽細微波動 private long duration = 8000; private TimeCount time; OnSensorChangeListener onSensorChangeListener; public StepDcretor(Context context) { super(); } public void onSensorChanged(SensorEvent event) { Sensor sensor = event.sensor; synchronized (this) { if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) { // 用低通濾波器分離出重力加速度 gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0]; gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1]; gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2]; average = (float) Math.sqrt(Math.pow(gravity[0], 2) + Math.pow(gravity[1], 2) + Math.pow(gravity[2], 2)); if (average <= verminValue) { if (average <= minValue) { perCalTime = System.currentTimeMillis(); } } else if (average >= vermaxValue) { if (average >= maxValue) { float betweentime = System.currentTimeMillis() - perCalTime; if (betweentime >= minTime && betweentime < maxTime) { perCalTime = 0; if (CountTimeState == 0) { // 開啟計時器 time = new TimeCount(duration, 1000); time.start(); CountTimeState = 1; Log.v(TAG, "開啟計時器"); } else if (CountTimeState == 1) { TEMP_STEP++; Log.v(TAG, "計步中 TEMP_STEP:" + TEMP_STEP); } else if (CountTimeState == 2) { timer = new Timer(true); TimerTask task = new TimerTask() { public void run() { if (lastStep == CURRENT_SETP) { timer.cancel(); CountTimeState = 0; lastStep = -1; TEMP_STEP = 0; Log.v(TAG, "停止計步:" + CURRENT_SETP); } else { lastStep = CURRENT_SETP; } } }; timer.schedule(task, 0, 2000); CountTimeState = 3; } else if (CountTimeState == 3) { CURRENT_SETP++; } } } } if (onSensorChangeListener != null) { onSensorChangeListener.onChange(); } } } } public void onAccuracyChanged(Sensor arg0, int arg1) { } public interface OnSensorChangeListener { void onChange(); } public OnSensorChangeListener getOnSensorChangeListener() { return onSensorChangeListener; } public void setOnSensorChangeListener( OnSensorChangeListener onSensorChangeListener) { this.onSensorChangeListener = onSensorChangeListener; } class TimeCount extends CountDownTimer { public TimeCount(long millisInFuture, long countDownInterval) { super(millisInFuture, countDownInterval); } @Override public void onFinish() { // 如果計時器正常結束,則開始計步 time.cancel(); CURRENT_SETP += TEMP_STEP; lastStep = -1; CountTimeState = 2; Log.v(TAG, "計時正常結束"); } @Override public void onTick(long millisUntilFinished) { if (lastStep == TEMP_STEP) { Log.v(TAG, "onTick 計時停止"); time.cancel(); CountTimeState = 0; lastStep = -1; TEMP_STEP = 0; } else { lastStep = TEMP_STEP; } } } }
來自: http://blog.csdn.net/xf396191344/article/details/50467570
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!