大学生跑步管理(三)
一:计步器的实现
(1):我自己本人也没有做过计步,在网上看了一些别人写的一些程序代码,但比较复杂,注释太少,有的地方看的不是太明白,但是自己还是想试试写一点东西。计步器的思路是在主Activity中开启一个服务,在服务中注册一个广播用来监听保存数据,建立一个新的子线程,在子线程开启记步检测,之后更新跳转到新的界面。现在市场上的计步传感器有两种一种是Google内置计步器,另一种是加速度传感器。
(2):计步器实现流程图
(3):主要代码说明
MainActivity:
在onCreate方法中初始化Handler,onStart方法中通过setupService方法开启一个服务StepService,程序后台再到前台时也能开启服务。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text_step = (TextView) findViewById(R.id.main_text_step);
delayHandler = new Handler(this);
}
@Override
public void onStart() {
super.onStart();
setupService();
}
/**
* 开启服务
*/
private void setupService() {
Intent intent = new Intent(this, StepService.class);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
startService(intent);
}
开启服务,使用了bind形式、用ServiceConnection接收回调。使用onServiceConnected方法发送消息。
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
try {
messenger = new Messenger(service);
Message msg = Message.obtain(null, Constant.MSG_FROM_CLIENT);
msg.replyTo = mGetReplyMessenger;
messenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {}
};
在handleMessage中接收从服务端回调的步数,并显示在界面上:
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case Constant.MSG_FROM_SERVER:
//更新步数
text_step.setText(msg.getData().getInt("step") + "");
delayHandler.sendEmptyMessageDelayed(Constant.REQUEST_SERVER, TIME_INTERVAL);
break;
case Constant.REQUEST_SERVER:
try {
Message msgl = Message.obtain(null, Constant.MSG_FROM_CLIENT);
msgl.replyTo = mGetReplyMessenger;
messenger.send(msgl);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
return false;
}
Handler进行消息发送、通讯。
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg){
switch (msg.what){
case Constant.MSG_FROM_CLIENT:
try{
Messenger messenger=msg.replyTo;
Message replyMsg=Message.obtain(null,Constant.MSG_FROM_SERVER);
Bundle bundle=new Bundle();
//将现在的步数以消息的形式进行发送
bundle.putInt("step",StepDetector.CURRENT_STEP);
replyMsg.setData(bundle);
messenger.send(replyMsg);//发送要返回的消息
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
}
开启计时器,并向数据库中写入数据。
启动数据监测器
@Override
public void onCreate(){
super.onCreate();
initBroadcastReceiver();
new Thread(new Runnable() {
@Override
public void run() {
//启动步数监测器
startStepDetector();
}
}).start();
startTimeCount();
}
广播的初始化
/**
*初始化广播
*/
mBatInfoReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
if(Intent.ACTION_SCREEN_ON.equals(action)){
Log.v(TAG,"screen on");
}else if(Intent.ACTION_SCREEN_OFF.equals(action)){
Log.v(TAG,"screen off");
save();
//改为60秒一存储
duration=60000;
}else if(Intent.ACTION_USER_PRESENT.equals(action)){
Log.v(TAG,"screen unlock");
save();
//改为30秒一存储
duration=30000;
}else if(Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())){
Log.v(TAG,"receive Intent.ACTION_CLOSE_SYSTEM_DIALOGS");
//保存一次
save();
}else if(Intent.ACTION_SHUTDOWN.equals(intent.getAction())){
Log.v(TAG,"receive ACTION_SHUTDOWN");
save();
}else if(Intent.ACTION_TIME_CHANGED.equals(intent.getAction())){
Log.v(TAG,"receive ACTION_TIME_CHANGED");
initTodayData();
}
}
};
registerReceiver(mBatInfoReceiver,filter);
}
在网上查看了别的计步器使用的传感器的写法,下面是我参考别人传感器的写法。
@Override
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);
}
以上代码是我参考一些网上的代码,加上自己的理解,自己写的一些东西,有很多不完善的地方,以后在加以改善。
posted on 2017-05-31 18:25 shixianchao 阅读(253) 评论(0) 编辑 收藏 举报