android高分段进阶攻略(2)传感器

  一开始,先对昨晚在昆明市火车站遇难的同胞表示默哀,并对恶势力进行谴责,你们如果有再大的冤情也不要对平民下手,所谓冤有头债有主,该弄谁弄谁去啊,欺负百姓算是怎么回事,所以在遇到突发情况下,首先要有泰山崩于前而面不改色的镇定,其次要么能像成龙大哥那样以一抵十的身手,要么就是跑得快,第一项技能好像普通人是无法学会的,那我们只能学习第二项技能——跑得快,当然冰冻三尺非一日寒,这就需要大家平时多多锻炼,怎么记录提醒自己锻炼了,就和我们今天要说这个计步器APP有关了。

上次我已经和大家基本介绍了下各种传感器,今天就是传感器的实际应用,由于商业运作的原因,还暂时不能开源我做的app,文章末尾会有上传个pedometer计步器,供大家学习

首先问下大家觉得计步器应该是用什么传感器了,其实就是利用方向传感器,根据上次说的Value的那个值进行判断,计步器原理就是人拿着手机走,走一步会产生振荡,从而方向传感获得参数Value,通过两次Value[1]的变化值之差来判断人是否走路,从而达到计步效果。核心代码如下:

public void onSensorChanged(SensorEvent event)   
{  
    //  当两个values[1]值之差的绝对值大于8时认为走了一步  
  
    if (Math.abs(event.values[1] - lastPoint) > 8)  
    {    
 lastPoint = event.values[1];  
count++;
    }  
}  
然后如何完整的实现这个APP了,首先我们应该构思用户界面上这个功能需要些什么,下图是我设计的主要界面:

界面看起来很复杂,其实很简单,需要一张表记录用户的记录,然后显示出来,点击开始启动service,每一分钟刷新下界面,画出一个心电图,点击结束关闭service。

首先我们来写service,第一个service从最简单刷新界面service开始,这个service很简单,当接收到广播的时候,获得相关参数进行刷新。

public class StepUpdateReceiver extends BroadcastReceiver{  
  
public void onReceive(Context context, Intent intent) {  
  
Bundle bundle = intent.getExtras();//获得Bundle  
  
int steps = bundle.getInt("step");//读取步数  
  
view1.stepsPerMin = steps+PerMin;//view1是读取了MainActivity里面的view,PerMin是记录每分钟走了几步 

view1.stepsToday = steps+Today;//Today是记录今天走了几步  
   
view1.isMoving = true;//表示用户走路  
  
view1.updateView(); //刷新界面,重画界面  
  
}  
  
} 
然后我们来写一个ManagerSerivce,用户通过点击按钮传过来广播消息,通过这个类去判断用户是进行启动还是结束,代码如下:

class ManagerReceiver extends BroadcastReceiver{  
  
public void onReceive(Context context, Intent intent) {  
  
int result = intent.getIntExtra("result");  
switch(result){  
case WalkingService.CMD_STOP://停止服务  
stopSelf();  
break;  
case WalkingService.CMD_START: //SERVICE启动
isActivityOn = true;  
Intent i = new Intent();  
i.setAction("MainActivity");i.putExtra("step", steps);  
sendBroadcast(i);  
break;   
}    
}    
}  
写完ManagerService我们开始写最关键的WalkingService:

public class WalkingService extends Service{  
	    
SensorManagerSimulator mySensorManager;  
WalkingListener wl;  //这里自己写了个接听类
int steps=0;  
boolean isActivityOn = false; //Activity 是否运行  
boolean isServiceOn = false;  
NotificationManager nm;//声明NotificationManager  
long timeInterval = 60*1000;  
final static int CMD_STOP = 0;  
final static int CMD_START = 1;  
ManagerReceiver receiver; //声明BroadcastReceiver  
Handler myHandler = new Handler(){//定时上传数据  
public void handleMessage(Message msg) {  
uploadData();  
super.handleMessage(msg);  
}  
};  
public void onCreate() {  
super.onCreate();  
wl = new WalkingListener(this); //创建监听器类  
//初始化传感器  
mySensorManager = SensorManagerSimulator.getSystemService(this, SENSOR_SERVICE);  
mySensorManager.connectSimulator();    
//注册监听器  
mySensorManager.registerListener(wl,SensorManager.SENSOR_ACCELEROMETER,SensorManager.SENSOR_DELAY_UI);  
nm = (NotificationManager)  
getSystemService(NOTIFICATION_SERVICE);    
}  
public void onStart(Intent intent, int startId) {  
super.onStart(intent, startId);  
isServiceOn = true;  
showNotification();//添加Notification  
receiver = new ManagerReceiver();  
IntentFilter filter1 = new IntentFilter();  
filter1.addAction("WalkingService");  
registerReceiver(receiver, filter1);  
//每分钟刷新一次界面
if(isServiceOn){  
Message msg =myHandler.obtainMessage();  
myHandler.sendMessageDelayed(msg,  
timeInterval);  
}    
}  
public void onDestroy() {  
mySensorManager.unregisterListener(wl);  
wl = null;  
mySensorManager = null;  
nm.cancel(0);  
unregisterReceiver(receiver);  
super.onDestroy();  
}    
private void showNotification() {  
Intent intent = new Intent(this,WalkingActivity.class);  
PendingIntent pi = PendingIntent.getActivity(this,  
0, intent, 0);  
Notification myNotification = new Notification();  
myNotification.icon = R.drawable.icon;  
myNotification.defaults = otification.DEFAULT_ALL;  
myNotification.setLatestEventInfo(this,  
"计步器运行中", "点击查看", pi);  
nm.notify(0,myNotification);  
}  
public void uploadData(){  
对数据库进行操作,并发送广播给StepUpdateSerivce 
}  
}  
这里主要有几个重点,第一在oncreate里面初始化传感器,和上一节的方法一致,第二在onstart注册接听器,第三在ondestory方法里面取消接听器,有些细节需要的解释的,什么是NotificatonMangager,这是一个公用类,用于在android通知栏显示app信息和手机状态信息,自己写了一个show方法用于,最小化APP的时候,用户可以在通知栏里面看到该app;为什么不时时刷新,太吃机子性能,用户体验性不好,只能改成每分钟刷新,因为需要画图。

最后我们在把核心代码写在WalkingListener里面就可以了。

public class WalkingListener implements SensorListener  
  
{  
  
WalkingService father; // WalkingService 引用  
float [] preCoordinate;  
double currentTime=0,lastTime=0; //记录时间  
float WALKING_THRESHOLD = 20;  
public WalkingListener(WalkingService father){  
this.father = father;  
}  
public void onAccuracyChanged(int arg0, int arg1) {}  
//传感器发生变化后调用该方法  
public void onSensorChanged(int sensor, float[] values) {  
if(sensor ==SensorManager.SENSOR_ACCELEROMETER){  
analyseData(values);//调用方法分析数据  
}  
}  
public void analyseData(float[] values){  
currentTime=System.currentTimeMillis();  
//每隔200MS 取加速度力和前一个进行比较  
if(currentTime - lastTime >200){  
if(preCoordinate == null){//还未存过数据  
preCoordinate = new float[3];  
for(int i=0;i<3;i++){  
preCoordinate = values;  
}  
}
else{ //进行比较  
int angle= calculateAngle(values,preCoordinate);  
if(angle >=WALKING_THRESHOLD){  
father.steps++; //步数增加  
updateData(); //更新步数,并且向walkingService发送消息  
}  
for(int i=0;i<3;i++){  
preCoordinate=values;  
}}  
lastTime = currentTime;//重新计时  
}  
}    
public void updateData(){ 
Intent intent = new Intent(); //创建Intent 对象 
intent.setAction("MainActivity"); 
intent.putExtra("step", father.steps);//添加步数 
father.sendBroadcast(intent); //发出广播 
} 
public int calculateAngle(float[] newPoints,float[] oldPoints){  
int angle=0;  
float vectorProduct=0; //向量积  
float newMold=0; //新向量的模  
float oldMold=0; //旧向量的模  
for(int i=0;i<3;i++){  
vectorProduct +=newPoints*oldPoints;  
newMold += newPoints*newPoints;  
oldMold += oldPoints*oldPoints;  
}  
newMold = (float)Math.sqrt(newMold);  
oldMold = (float)Math.sqrt(oldMold);  
//计算夹角的余弦  
float cosineAngle=(float)(vectorProduct/(newMold*oldMold));  
//通过余弦值求角度  
float fangle = (float)  
Math.toDegrees(Math.acos(cosineAngle));  
angle = (int)fangle;  
return angle; //返回向量的夹角  
}
关于算法,因为需要精确,所以我进行的是向量夹角的判断,当夹角大于20的时候就证明用户走了一步,其实算法多样,你可以自己选择,这也是我百度到的算法,至此一个计步器就完成了。

最后希望大家能踊跃评论,大家可以说下自己想实现什么app,我先去试试,然后做成教程来写出,不然我一个人做过的app也很少,下面是网上开源的demo,我的demo等后续再上传。

源码下载


android高分段进阶攻略(2)传感器,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。