<span style="white-space: pre;">
</span><span style="color:#ff0000;">自己研究加上网上查资料基本上能实现加速器记步功能,下来把代码贴上。
</span>
<span style="color:#ff0000;">第一个包是后台服务Service</span>
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
//service负责后台的需要长期运行的任务
// 计步器服务
// 运行在后台的服务程序,完成了界面部分的开发后
// 就可以开发后台的服务类StepService
// 注册或注销传感器监听器,在手机屏幕状态栏显示通知,与StepActivity进行通信,走过的步数记到哪里了
public class StepService extends Service {
public static Boolean FLAG = false;// 服务运行标志
private SensorManager mSensorManager;// 传感器服务
private StepDetector detector;// 传感器监听对象
private PowerManager mPowerManager;// 电源管理服务
private WakeLock mWakeLock;// 屏幕灯
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
FLAG = true;// 标记为服务正在运行
// 创建监听器类,实例化监听对象
detector = new StepDetector(this);
// 获取传感器的服务,初始化传感器
mSensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
// 注册传感器,注册监听器
mSensorManager.registerListener(detector,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_FASTEST);
// 电源管理服务
mPowerManager = (PowerManager) this
.getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP, "Jackie");
mWakeLock.acquire();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
FLAG = false;// 服务停止
if (detector != null) {
mSensorManager.unregisterListener(detector);
}
if (mWakeLock != null) {
mWakeLock.release();
}
}
}
<span style="color:#ff0000;">然后是计算步数的算法,这段代码是从github上截取下来的。</span>
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;
//走步检测器,用于检测走步并计数
/**
* 具体算法不太清楚。
*
*/
public class StepDetector implements SensorEventListener {
public static int CURRENT_SETP = 0;
public static float SENSITIVITY = 0; // SENSITIVITY灵敏度
private float mLastValues[] = new float[3 * 2];
private float mScale[] = new float[2];
private float mYOffset;
private static long end = 0;
private static long start = 0;
/**
* 最后加速度方向
*/
private float mLastDirections[] = new float[3 * 2];
private float mLastExtremes[][] = { new float[3 * 2], new float[3 * 2] };
private float mLastDiff[] = new float[3 * 2];
private int mLastMatch = -1;
/**
* 传入上下文的构造函数
*
* @param context
*/
public StepDetector(Context context) {
// TODO Auto-generated constructor stub
super();
int h = 480;
mYOffset = h * 0.5f;
mScale[0] = -(h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));
mScale[1] = -(h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));
SENSITIVITY = 10;
}
@Override
public void onSensorChanged(SensorEvent event) {
Sensor sensor = event.sensor;
synchronized (this) {
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
float vSum = 0;
for (int i = 0; i < 3; i++) {
final float v = mYOffset + event.values[i] * mScale[1];
vSum += v;
}
int k = 0;
float v = vSum / 3;
float direction = (v > mLastValues[k] ? 1
: (v < mLastValues[k] ? -1 : 0));
if (direction == -mLastDirections[k]) {
// Direction changed
int extType = (direction > 0 ? 0 : 1); // minumum or
// maximum?
mLastExtremes[extType][k] = mLastValues[k];
float diff = Math.abs(mLastExtremes[extType][k]
- mLastExtremes[1 - extType][k]);
if (diff > SENSITIVITY) {
boolean isAlmostAsLargeAsPrevious = diff > (mLastDiff[k] * 2 / 3);
boolean isPreviousLargeEnough = mLastDiff[k] > (diff / 3);
boolean isNotContra = (mLastMatch != 1 - extType);
if (isAlmostAsLargeAsPrevious
&& isPreviousLargeEnough && isNotContra) {
end = System.currentTimeMillis();
if (end - start > 500) {// 此时判断为走了一步
Log.i("StepDetector", "CURRENT_SETP:"
+ CURRENT_SETP);
CURRENT_SETP++;
mLastMatch = extType;
start = end;
}
} else {
mLastMatch = -1;
}
}
mLastDiff[k] = diff;
}
mLastDirections[k] = direction;
mLastValues[k] = v;
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
}
<span style="color:#ff0000;">最后一个是实现记步和卡路里计算的Activity</span>
import java.text.DecimalFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView tv_show_step;// 步数
private TextView tv_calories;// 卡路里
private Button btn_start;// 开始按钮
private Button btn_stop;// 停止按钮
private Double distance = 0.0;// 路程:米
private Double calories = 0.0;// 热量:卡路里
private int step_length = 0; // 步长
private int weight = 0; // 体重
private int total_step = 0; // 走的总步数
private Thread thread; // 定义线程对象
Handler handler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg); // 此处可以更新UI
countDistance(); // 调用距离方法,看一下走了多远
if (distance != 0.0) {
// 体重、距离
// 跑步热量(kcal)=体重(kg)×距离(公里)×1.036
calories = weight * distance * 0.01;
} else {
calories = 0.0;
}
countStep(); // 调用步数方法
tv_show_step.setText(total_step + "");// 显示当前步数
tv_calories.setText(formatDouble(calories));// 显示卡路里
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (thread == null) {
thread = new Thread() {// 子线程用于监听当前步数的变化
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
int temp = 0;
while (true) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (StepService.flag) {
Message msg = new Message();
if (temp != StepDetector.CURRENT_SETP) {
temp = StepDetector.CURRENT_SETP;
}
handler.sendMessage(msg);
}
}
}
};
thread.start();
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
tv_calories = (TextView) findViewById(R.id.calories);
tv_show_step = (TextView) findViewById(R.id.step);
btn_start = (Button) findViewById(R.id.button1);
btn_stop = (Button) findViewById(R.id.button2);
step_length = 50;
weight = 65;
countDistance();
countStep();
if (distance != 0.0) {
calories = weight * distance * 0.001;
} else {
calories = 0.0;
}
tv_calories.setText(formatDouble(calories));
tv_show_step.setText(total_step + "");
btn_start.setEnabled(!StepService.flag);
btn_stop.setEnabled(StepService.flag);
if (StepService.flag) {
btn_stop.setText("停止");
} else if (StepDetector.CURRENT_SETP > 0) {
btn_stop.setEnabled(true);
btn_stop.setText("暂停");
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private CharSequence formatDouble(Double doubles) {
DecimalFormat format = new DecimalFormat("####.##");
String distanceStr = format.format(doubles);
return distanceStr.equals("0") ? "0.0" : distanceStr;
}
public void onClick(View view) {
Intent service = new Intent(this, StepService.class);
switch (view.getId()) {
case R.id.button1:
startService(service);
btn_start.setEnabled(false);
btn_stop.setEnabled(true);
btn_stop.setText("暂停");
break;
case R.id.button2:
stopService(service);
if (StepService.flag && StepDetector.CURRENT_SETP > 0) {
btn_stop.setText("清零");
} else {
StepDetector.CURRENT_SETP = 0;
btn_stop.setText("暂停");
btn_stop.setEnabled(false);
tv_show_step.setText("0");
tv_calories.setText(formatDouble(0.0));
// tv_velocity.setText(formatDouble(0.0));
handler.removeCallbacks(thread);
}
btn_start.setEnabled(true);
break;
}
}
private void countStep() {
if (StepDetector.CURRENT_SETP % 2 == 0) {
total_step = StepDetector.CURRENT_SETP / 2 * 3;
} else {
total_step = StepDetector.CURRENT_SETP / 2 * 3 + 1;
}
}
private void countDistance() {
if (StepDetector.CURRENT_SETP % 2 == 0) {
distance = (StepDetector.CURRENT_SETP / 2) * 3 * step_length * 0.01;
} else {
distance = ((StepDetector.CURRENT_SETP / 2) * 3 + 1) * step_length
* 0.01;
}
}
}