暑假里做了一个安卓计步器,不依靠GPS,也不用联网,只依靠重力加速度传感器和三轴磁力传感器,就可以实现记录步数和记录行走轨迹。我还加入了摇一摇切歌的功能,享受运动的乐趣~~
发布的apk可以在这里下载:pan.baidu.com/s/1i3gw3sh (打算以后完备了再发布到应用市场,所以欢迎大家吐槽评论)
这个项目只用了三天时间(作为自己的第一个安卓作品,我觉得还是很快的~~),当时完全是被deadline给逼出来的。老师对这个项目赞不绝口,觉得我一个正在上预科的孩子,学校里C语言还没有开课,就能自己做得这么好,于是果断给99分,哈哈~~不过,我觉得这个项目有很多地方可以改进和完善,因此在这里把这个项目总结一下,以备查询,也欢迎大家给出意见。以后有时间,再推出2.0、3.0等版本咯咯~~
计步器的原理是基本的物理知识,不再赘述,以后有时间可以单独写一篇,说明我是如何推导的。下面是所有代码:
第一部分:manifest
第二部分:mainActivity
package com.example.pedometre;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.util.ArrayList;
import com.example.pedometre.StepDetector;
import com.example.pedometre.StepCounterService;
import android.support.v4.widget.DrawerLayout;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout = null;
private ListView mylistview;
private ArrayList list = new ArrayList();
private TextView tv_step;
private TextView sy_dis;
private TextView sy_cal;
private TextView sy_vit;
private Button btn_start;
private Button btn_stop;
private Thread mThread;
private Chronometer timer;
public static int total_step = 0;
private int total_step1=0;
private float pep_weight=60;
private float per_step=0.5f;
private float last_time=0;
private float kaluli=0;
private float x=0;
private float st_x=0;
private float st_y=0;
private String inputName="";
private SensorManager sm1;
private SensorManager sm2;
float[] accelerometerValues = new float[3];
float[] magneticFieldValues = new float[3];
public static float[]da_st=new float[10000];
public static float max_width=0f,max_height=0f;
@SuppressLint("HandlerLeak") Handler mHandler = new Handler(){
@Override
public void handleMessage(android.os.Message msg) {
super.handleMessage(msg);
if(msg.what == 0x00){
countStep();
tv_step.setText(total_step+"");
last_time=last_time/1000/3600;
kaluli=pep_weight*last_time*30/(last_time/per_step/total_step*400*60);
DecimalFormat decimalFormat=new DecimalFormat("0.00");
sy_cal.setText(decimalFormat.format(kaluli)+"kcal");
float[] values = new float[3];
float[] R = new float[9];
SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticFieldValues);
SensorManager.getOrientation(R, values);
da_st[total_step]=values[0];
/* st_x=(float) (st_x+Math.cos(values[0]));
st_y=(float) (st_y+Math.sin(values[0]));
if (Math.abs(st_x)>max_height){
max_height=Math.abs(st_x);
}
if (Math.abs(st_y)>max_width){
max_width=Math.abs(st_y);
}
*/
sy_dis.setText(decimalFormat.format(total_step*per_step/1000)+"km");
sy_vit.setText(decimalFormat.format(total_step*per_step/1000/last_time)+"km/h");
}
}
};
private void countStep() {
if(StepDetector.CURRENT_SETP % 2 == 0){
total_step = StepDetector.CURRENT_SETP;
}else{
total_step = StepDetector.CURRENT_SETP + 1;
}
Log.i("total_step", StepDetector.CURRENT_SETP+"");
total_step = StepDetector.CURRENT_SETP;
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sm1 = (SensorManager) getSystemService(SENSOR_SERVICE);
sm2 = (SensorManager) getSystemService(SENSOR_SERVICE);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
forceShowOverflowMenu();
tv_step = (TextView) findViewById(R.id.tv_step);
sy_dis = (TextView) findViewById(R.id.sy_distance);
sy_cal = (TextView) findViewById(R.id.sy_caluli);
sy_vit = (TextView) findViewById(R.id.sy_vitesse);
btn_start = (Button) findViewById(R.id.btn_start);
btn_stop = (Button) findViewById(R.id.btn_stop);
timer = (Chronometer) findViewById(R.id.chronometer);
mylistview = (ListView)findViewById(R.id.left_drawer);
list.add("Poids(kg): (60kg par défaut)");
list.add("Longueur de chaque étape(cm): (50cm par défaut)");
list.add("La sensibilité du capteur: (3 par défaut)");
list.add("Intervalle temporel entre deux étapes(ms): (500 par défaut)");
ArrayAdapter myArrayAdapter = new ArrayAdapter
(this,android.R.layout.simple_list_item_1,list);
mylistview.setAdapter(myArrayAdapter);
mylistview.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView> arg0, View arg1, int arg2,long arg3) {
if(list.get(arg2).contains("Poids")){
inputTitleDialog();
int t=0;
try{
t=Integer.parseInt(inputName);
}catch(Exception e){}
if (t>0){
list.set(arg2,"Poids(kg): ("+inputName+"kg par défaut)");
pep_weight=t;
}
}
if(list.get(arg2).contains("Longueur")){
inputTitleDialog();
int t=0;
try{
t=Integer.parseInt(inputName);
}catch(Exception e){}
if (t>0){
list.set(arg2,"Longueur de chaque étape(cm): ("+inputName+"cm par défaut)");
per_step=(float) (t*1.0/100);
}
}
if(list.get(arg2).contains("sensibilité")){
inputTitleDialog();
int t=0;
try{
t=Integer.parseInt(inputName);
}catch(Exception e){}
if (t>0){
list.set(arg2,"La sensibilité du capteur: ("+inputName+" par défaut)");
StepDetector.SENSITIVITY=t;
}
}
if(list.get(arg2).contains("Intervalle")){
inputTitleDialog();
int t=0;
try{
t=Integer.parseInt(inputName);
}catch(Exception e){}
if (t>0){
list.set(arg2,"Intervalle temporel entre deux étapes(ms): ("+inputName+" par défaut)");
StepDetector.time_jg=t;
}
}
}
});
}