参考文章:http://www.jianshu.com/p/5d57f7fd84fa 本文对原文计步项目进行了精简,移除了进程服务和计时、守护进程、数据库保存等等,方便扩展功能。
本文源码:https://github.com/lioilwin/StepOrient Android4.4以上版本,有些手机有计步传感器可以直接使用, 而有些手机没有,但有加速度传感器,也可以实现计步功能(需要计算加速度波峰波谷来判断人走一步)!
一.调用
public class MainActivity extends AppCompatActivity implements StepSensorBase.StepCallBack{
.........
@Override
public void Step(int stepNum
) {
stepText
.setText("步数:" + stepNum
);
}
@Override
protected void onCreate(Bundle savedInstanceState
) {
super.onCreate(savedInstanceState
);
setContentView(R
.layout
.activity_main
);
stepText
= (TextView
) findViewById(R
.id
.step_text
);
stepSensor
= new StepSensorPedometer(this, this);
if (!stepSensor
.registerStep()) {
Toast
.makeText(this, "计步传传感器不可用!", Toast
.LENGTH_SHORT
).show();
stepSensor
= new StepSensorAcceleration(this, this);
if (!stepSensor
.registerStep()) {
Toast
.makeText(this, "加速度传感器不可用!", Toast
.LENGTH_SHORT
).show();
}
}
}
.......
}
public abstract class StepSensorBase implements SensorEventListener {
private Context context
;
protected StepCallBack stepCallBack
;
protected SensorManager sensorManager
;
protected static int CURRENT_SETP
= 0;
protected boolean isAvailable
= false;
public StepSensorBase(Context context
, StepCallBack stepCallBack
) {
this.context
= context
;
this.stepCallBack
= stepCallBack
;
}
public interface StepCallBack {
void Step(int stepNum
);
}
public boolean registerStep() {
if (sensorManager
!= null
) {
sensorManager
.unregisterListener(this);
sensorManager
= null
;
}
sensorManager
= SensorUtil
.getInstance().getSensorManager(context
);
registerStepListener();
return isAvailable
;
}
protected abstract void registerStepListener();
public abstract void unregisterStep();
}
二.直接使用计步传感器实现计步
public class StepSensorPedometer extends StepSensorBase {
private final String TAG
= "StepSensorPedometer";
private int lastStep
= -1;
private int liveStep
= 0;
private int increment
= 0;
private int sensorMode
= 0;
public StepSensorPedometer(Context context
, StepCallBack stepCallBack
) {
super(context
, stepCallBack
);
}
@Override
protected void registerStepListener() {
Sensor detectorSensor
= sensorManager
.getDefaultSensor(Sensor
.TYPE_STEP_DETECTOR
);
Sensor countSensor
= sensorManager
.getDefaultSensor(Sensor
.TYPE_STEP_COUNTER
);
if (sensorManager
.registerListener(this, detectorSensor
, SensorManager
.SENSOR_DELAY_GAME
)) {
isAvailable
= true;
sensorMode
= 0;
Log
.i(TAG
, "计步传感器Detector可用!");
} else if (sensorManager
.registerListener(this, countSensor
, SensorManager
.SENSOR_DELAY_GAME
)) {
isAvailable
= true;
sensorMode
= 1;
Log
.i(TAG
, "计步传感器Counter可用!");
} else {
isAvailable
= false;
Log
.i(TAG
, "计步传感器不可用!");
}
}
@Override
public void unregisterStep() {
sensorManager
.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent event
) {
liveStep
= (int) event
.values
[0];
if (sensorMode
== 0) {
Log
.i(TAG
, "Detector步数:"+liveStep
);
StepSensorBase
.CURRENT_SETP
+= liveStep
;
} else if (sensorMode
== 1) {
Log
.i(TAG
, "Counter步数:"+liveStep
);
StepSensorBase
.CURRENT_SETP
= liveStep
;
}
stepCallBack
.Step(StepSensorBase
.CURRENT_SETP
);
}
@Override
public void onAccuracyChanged(Sensor sensor
, int accuracy
) {
}
}
三.使用加速度传感器实现计步
public class StepSensorAcceleration extends StepSensorBase {
private final String TAG
= "StepSensorAcceleration";
final int valueNum
= 5;
float[] tempValue
= new float[valueNum
];
int tempCount
= 0;
boolean isDirectionUp
= false;
int continueUpCount
= 0;
int continueUpFormerCount
= 0;
boolean lastStatus
= false;
float peakOfWave
= 0;
float valleyOfWave
= 0;
long timeOfThisPeak
= 0;
long timeOfLastPeak
= 0;
long timeOfNow
= 0;
float gravityNew
= 0;
float gravityOld
= 0;
final float initialValue
= (float) 1.7;
float ThreadValue
= (float) 2.0;
float minValue
= 11f;
float maxValue
= 19.6f;
private int CountTimeState
= 0;
public static int TEMP_STEP
= 0;
private int lastStep
= -1;
public static float average
= 0;
private Timer timer
;
private long duration
= 3500;
private TimeCount time
;
public StepSensorAcceleration(Context context
, StepCallBack stepCallBack
) {
super(context
, stepCallBack
);
}
@Override
protected void registerStepListener() {
isAvailable
= sensorManager
.registerListener(this, sensorManager
.getDefaultSensor(Sensor
.TYPE_ACCELEROMETER
),
SensorManager
.SENSOR_DELAY_GAME
);
if (isAvailable
) {
Log
.i(TAG
, "加速度传感器可用!");
} else {
Log
.i(TAG
, "加速度传感器不可用!");
}
}
@Override
public void unregisterStep() {
sensorManager
.unregisterListener(this);
}
public void onAccuracyChanged(Sensor arg0
, int arg1
) {
}
public void onSensorChanged(SensorEvent event
) {
Sensor sensor
= event
.sensor
;
synchronized (this) {
if (sensor
.getType() == Sensor
.TYPE_ACCELEROMETER
) {
calc_step(event
);
}
}
}
synchronized private void calc_step(SensorEvent event
) {
average
= (float) Math
.sqrt(Math
.pow(event
.values
[0], 2)
+ Math
.pow(event
.values
[1], 2) + Math
.pow(event
.values
[2], 2));
detectorNewStep(average
);
}
public void detectorNewStep(float values
) {
if (gravityOld
== 0) {
gravityOld
= values
;
} else {
if (DetectorPeak(values
, gravityOld
)) {
timeOfLastPeak
= timeOfThisPeak
;
timeOfNow
= System
.currentTimeMillis();
if (timeOfNow
- timeOfLastPeak
>= 200
&& (peakOfWave
- valleyOfWave
>= ThreadValue
) && (timeOfNow
- timeOfLastPeak
) <= 2000) {
timeOfThisPeak
= timeOfNow
;
preStep();
}
if (timeOfNow
- timeOfLastPeak
>= 200
&& (peakOfWave
- valleyOfWave
>= initialValue
)) {
timeOfThisPeak
= timeOfNow
;
ThreadValue
= Peak_Valley_Thread(peakOfWave
- valleyOfWave
);
}
}
}
gravityOld
= values
;
}
private void preStep() {
StepSensorBase
.CURRENT_SETP
++;
stepCallBack
.Step(StepSensorBase
.CURRENT_SETP
);
}
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
>= minValue
&& oldValue
< maxValue
))) {
peakOfWave
= oldValue
;
return true;
} else if (!lastStatus
&& isDirectionUp
) {
valleyOfWave
= oldValue
;
return false;
} else {
return false;
}
}
public float Peak_Valley_Thread(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
;
}
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.7;
}
return ave
;
}
class TimeCount extends CountDownTimer {
public TimeCount(long millisInFuture
, long countDownInterval
) {
super(millisInFuture
, countDownInterval
);
}
@Override
public void onFinish() {
time
.cancel();
StepSensorBase
.CURRENT_SETP
+= TEMP_STEP
;
lastStep
= -1;
Log
.v(TAG
, "计时正常结束");
timer
= new Timer(true);
TimerTask task
= new TimerTask() {
public void run() {
if (lastStep
== StepSensorBase
.CURRENT_SETP
) {
timer
.cancel();
CountTimeState
= 0;
lastStep
= -1;
TEMP_STEP
= 0;
Log
.v(TAG
, "停止计步:" + StepSensorBase
.CURRENT_SETP
);
} else {
lastStep
= StepSensorBase
.CURRENT_SETP
;
}
}
};
timer
.schedule(task
, 0, 2000);
CountTimeState
= 2;
}
@Override
public void onTick(long millisUntilFinished
) {
if (lastStep
== TEMP_STEP
) {
Log
.v(TAG
, "onTick 计时停止:" + TEMP_STEP
);
time
.cancel();
CountTimeState
= 0;
lastStep
= -1;
TEMP_STEP
= 0;
} else {
lastStep
= TEMP_STEP
;
}
}
}
}
简书: http://www.jianshu.com/p/6b05b1b8603e 博客: http://blog.csdn.net/qq_32115439/article/details/61619644 GitHub博客:http://lioil.win/2017/03/12/Android-Step.html Coding博客:http://c.lioil.win/2017/03/12/Android-Step.html
转载请注明原文地址: https://ju.6miu.com/read-34658.html