Android精准计步器
生活随笔
收集整理的這篇文章主要介紹了
Android精准计步器
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
demo鏈接:https://download.csdn.net/download/meixi_android/10690974
工具類(lèi):
public class StepDetector implements SensorEventListener {//存放三軸數(shù)據(jù)float[] oriValues = new float[3];final int ValueNum = 4;//用于存放計(jì)算閾值的波峰波谷差值float[] tempValue = new float[ValueNum];int tempCount = 0;//是否上升的標(biāo)志位boolean isDirectionUp = false;//持續(xù)上升次數(shù)int continueUpCount = 0;//上一點(diǎn)的持續(xù)上升的次數(shù),為了記錄波峰的上升次數(shù)int continueUpFormerCount = 0;//上一點(diǎn)的狀態(tài),上升還是下降boolean lastStatus = false;//波峰值float peakOfWave = 0;//波谷值float valleyOfWave = 0;//此次波峰的時(shí)間long timeOfThisPeak = 0;//上次波峰的時(shí)間long timeOfLastPeak = 0;//當(dāng)前的時(shí)間long timeOfNow = 0;//當(dāng)前傳感器的值float gravityNew = 0;//上次傳感器的值float gravityOld = 0;//動(dòng)態(tài)閾值需要?jiǎng)討B(tài)的數(shù)據(jù),這個(gè)值用于這些動(dòng)態(tài)數(shù)據(jù)的閾值final float InitialValue = (float) 1.3;//初始閾值float ThreadValue = (float) 2.0;//波峰波谷時(shí)間差int TimeInterval = 250;private StepCountListener mStepListeners;@Overridepublic void onSensorChanged(SensorEvent event) {for (int i = 0; i < 3; i++) {oriValues[i] = event.values[i];}gravityNew = (float) Math.sqrt(oriValues[0] * oriValues[0]+ oriValues[1] * oriValues[1] + oriValues[2] * oriValues[2]);detectorNewStep(gravityNew);}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {//}public void initListener(StepCountListener listener) {this.mStepListeners = listener;}/** 檢測(cè)步子,并開(kāi)始計(jì)步* 1.傳入sersor中的數(shù)據(jù)* 2.如果檢測(cè)到了波峰,并且符合時(shí)間差以及閾值的條件,則判定為1步* 3.符合時(shí)間差條件,波峰波谷差值大于initialValue,則將該差值納入閾值的計(jì)算中* */public void detectorNewStep(float values) {if (gravityOld == 0) {gravityOld = values;} else {if (detectorPeak(values, gravityOld)) {timeOfLastPeak = timeOfThisPeak;timeOfNow = System.currentTimeMillis();if (timeOfNow - timeOfLastPeak >= TimeInterval&& (peakOfWave - valleyOfWave >= ThreadValue)) {timeOfThisPeak = timeOfNow;/** 更新界面的處理,不涉及到算法* 一般在通知更新界面之前,增加下面處理,為了處理無(wú)效運(yùn)動(dòng):* 1.連續(xù)記錄10才開(kāi)始計(jì)步* 2.例如記錄的9步用戶停住超過(guò)3秒,則前面的記錄失效,下次從頭開(kāi)始* 3.連續(xù)記錄了9步用戶還在運(yùn)動(dòng),之前的數(shù)據(jù)才有效* */mStepListeners.countStep();}if (timeOfNow - timeOfLastPeak >= TimeInterval&& (peakOfWave - valleyOfWave >= InitialValue)) {timeOfThisPeak = timeOfNow;ThreadValue = peakValleyThread(peakOfWave - valleyOfWave);}}}gravityOld = values;}/** 檢測(cè)波峰* 以下四個(gè)條件判斷為波峰:* 1.目前點(diǎn)為下降的趨勢(shì):isDirectionUp為false* 2.之前的點(diǎn)為上升的趨勢(shì):lastStatus為true* 3.到波峰為止,持續(xù)上升大于等于2次* 4.波峰值大于20* 記錄波谷值* 1.觀察波形圖,可以發(fā)現(xiàn)在出現(xiàn)步子的地方,波谷的下一個(gè)就是波峰,有比較明顯的特征以及差值* 2.所以要記錄每次的波谷值,為了和下次的波峰做對(duì)比* */public boolean detectorPeak(float newValue, float oldValue) {lastStatus = isDirectionUp;if (newValue >= oldValue) {isDirectionUp = true;continueUpCount++;} else {continueUpFormerCount = continueUpCount;continueUpCount = 0;isDirectionUp = false;}if (!isDirectionUp && lastStatus&& (continueUpFormerCount >= 2 || oldValue >= 20)) {peakOfWave = oldValue;return true;} else if (!lastStatus && isDirectionUp) {valleyOfWave = oldValue;return false;} else {return false;}}/** 閾值的計(jì)算* 1.通過(guò)波峰波谷的差值計(jì)算閾值* 2.記錄4個(gè)值,存入tempValue[]數(shù)組中* 3.在將數(shù)組傳入函數(shù)averageValue中計(jì)算閾值* */public float peakValleyThread(float value) {float tempThread = ThreadValue;if (tempCount < ValueNum) {tempValue[tempCount] = value;tempCount++;} else {tempThread = averageValue(tempValue, ValueNum);for (int i = 1; i < ValueNum; i++) {tempValue[i - 1] = tempValue[i];}tempValue[ValueNum - 1] = value;}return tempThread;}/** 梯度化閾值* 1.計(jì)算數(shù)組的均值* 2.通過(guò)均值將閾值梯度化在一個(gè)范圍里* */public float averageValue(float value[], int n) {float ave = 0;for (int i = 0; i < n; i++) {ave += value[i];}ave = ave / ValueNum;if (ave >= 8)ave = (float) 4.3;else if (ave >= 7 && ave < 8)ave = (float) 3.3;else if (ave >= 4 && ave < 7)ave = (float) 2.3;else if (ave >= 3 && ave < 4)ave = (float) 2.0;else {ave = (float) 1.3;}return ave;}}?
?
總結(jié)
以上是生活随笔為你收集整理的Android精准计步器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android PopupWindow使
- 下一篇: Android 起调第三方导航,百度地图