当前位置: 首页 > 科技观察

Android传感器编程实例

时间:2023-03-17 20:53:36 科技观察

1.前言我很喜欢电脑,但是笔记本还是太大了。再小的笔记本电脑,我也得弄个小包来装。智能手机是不同的。将它放在一个口袋里。所以2002年前后最喜欢玩的设备是戴尔的PDA,2007年的N73,2010年的Milestone。眼看着手机的功能越来越强,如今的智能手机在某些方面甚至已经超越了台式机和笔记本.本课是关于智能手机胜过台式机和笔记本电脑的地方:传感器。2008年,我非常喜欢我的小白笔记本Macbook。我喜欢在上面玩一个小软件。我一拍桌子,笔记本感觉到震动,变成了桌面,让我像个孩子一样拍照。拍桌子。此功能要归功于Apple笔记本电脑中的内置传感器。我不知道iPhone是不是第一个在手机上使用各种传感器,但我知道iPhone是第一个在手机上使用传感器最成功的。随后的安卓系统也内置了大量的传感器,使得安卓系统手机比普通的诺基亚智能手机和WindowsCE智能手机要强大不少。拥有Milestone之后,我的N73还在抽屉的角落里。从Android1.5开始,系统内置支持多达8个传感器,它们是:加速度传感器(accelerometer)、陀螺仪(gyroscope)、环境光传感器(light)、磁传感器(magneticfield)、方向传感器(orientation))、压力传感器(pressure)、距离传感器(proximity)和温度传感器(temperature)。  使用这些传感器,我们可以制作各种有趣的应用程序和游戏。例如,摇一摇放在口袋里的手机,手机就会在无人察觉的情况下开始录音。别担心,这很容易做到。我们将在本文最后一起制作这个小应用程序。本讲的学习方法是在实战中学习。需要提醒的是,传感器无法在模拟器中进行模拟,所以需要准备一台真实的Android设备来运行本讲中的例子。2、例子:手机传感器列表,先看程序再解释。1、创建工程Lesson37_HelloSensor,主Activity名称为mainActivity.java。2、UI发布文件main.xml的内容如下:XML/HTML代码3、mainActivity.java的内容如下:代码packagebasic.android.lesson37;importjava.util.List;importandroid.app.Activity;importandroid.content.Context;importandroid.hardware.Sensor;importandroid.hardware.SensorManager;importandroid.os.Bundle;importandroid.widget.TextView;publicclassMainActivityextendsActivity{/**在活动首次创建时调用。*/@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);//设置显示信息的UIfinalTextViewtx1=(TextView)findViewById(R.id.TextView01);//从系统服务中获取传感器管理器SensorManagersm=(SensorManager)getSystemService(Context.SENSOR_SERVICE);//从传感器管理器中获取所有传感器列表ListallSensors=sm.getSensorList(Sensor.TYPE_ALL);//显示有多少个传感器tx1.setText("检测到手机"+allSensors.size()+"sensors,theyare:\n");//显示每个传感器的具体信息for(Sensors:allSensors){StringtempString="\n"+"Devicename:"+s.getName()+"\n"+"设备版本:"+s.getVersion()+"\n"+"供应商:"+s.getVendor()+"\n";switch(s.getType()){caseSensor.TYPE_ACCELEROMETER:tx1.setText(tx1.getText().toString()+s.getType()+"加速度计"+tempString);break;caseSensor.TYPE_GYROSCOPE:tx1.setText(tx1.getText().toString()+s.getType()+"陀螺仪传感器陀螺仪"+tempString);break;caseSensor.TYPE_LIGHT:tx1.setText(tx1.getText().toString()+s.getType()+"环境光t传感器灯"+tempString);break;caseSensor.TYPE_MAGNETIC_FIELD:tx1.setText(tx1.getText().toString()+s.getType()+"电磁场传感器磁场"+tempString);break;caseSensor.TYPE_ORIENTATION:tx1.setText(tx1.getText().toString()+s.getType()+"orientation"+tempString);break;caseSensor.TYPE_PRESSURE:tx1.setText(tx1.getText().toString()+s.getType()+"压力传感器压力"+tempString);break;caseSensor.TYPE_PROXIMITY:tx1.setText(tx1.getText().toString()+s.getType()+"距离传感器接近度"+tempString);break;caseSensor.TYPE_TEMPERATURE:tx1.setText(tx1.getText().toString()+s.getType()+"温度传感器温度"+tempString);break;default:tx1.setText(tx1.getText().toString()+s.getType()+"未知传感器"+tempString);break;}}}}4.将Milestone连接到真机,编译运行程序,显示结果如下:5.结合上面的程序做一些说明1)Android中所有的传感器都由传感器管理器SensorManager管理。获取传感器管理器的方法很简单:Stringservice_name=Context.SENSOR_SERVICE;SensorManagersensorManager=(SensorManager)getSystemService(service_name);2)Android现阶段支持的传感器有:8种,分别是:3)从传感器管理器中获取一个或部分传感器的方式有以下三种:第一种方式:获取某个传感器的默认传感器SensordefaultGyroscope=sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);第二种:获取某个传感器的列表ListpressureSensors=sensorManager.getSensorList(Sensor.TYPE_PRESSURE);第三种:获取所有传感器的列表,第三种List<我们在本例中使用的Sensor>allSensors=sensorManager.getSensorList(Sensor.TYPE_ALL);4)对于某个传感器,它的具体信息获取方式见下表:3.例子:yyyy记录器通过上面的例子,我们学会了如何获取传感器有几种类型,下面我用一个例子来说明了解如何使用某种类型的传感器。这里我们使用加速度传感器来实现这样一个功能:打开我们的录音程序放在口袋或者包里,需要录音的时候整理一下衣服,或者把包移动到一个位置,手机就会感觉到变化这一次这开始记录。这样就达到了悄无声息的录音效果。说起来有点神奇,其实做起来很简单,让我们开始吧。简单的录音程序在第28讲已经做好了,我们在第28讲程序的基础上编写本讲的代码。1、新建工程Lesson37_YYRecorder,主文件为MainActivity.java。2、这里只列出28讲不同MainActivity.java的代码。请注意注释:Java代码包basic.android.lesson37;importjava.io.File;importjava.io.IOException;importjava.util.Calendar;importjava。util.Locale;importandroid.app.Activity;importandroid.content.Context;importandroid.hardware.Sensor;importandroid.hardware.SensorEvent;importandroid.hardware.SensorEventListener;importandroid.hardware.SensorManager;importandroid.media.MediaRecorder;importandroid.os。Bundle;importandroid.text.format.DateFormat;importandroid.view.View;importandroid.widget.Button;importandroid.widget.TextView;importandroid.widget.Toast;publicclassMainActivityextendsActivity{//录制和停止按钮privateButtonrecordButton;privateButtonstopButton;//检测晃动相关变量privatelonginitTime=0;privatelonglastTime=0;privatelongcurTime=0;privatelongduration=0;privatefloatlast_x=0.0f;privatefloatlast_y=0.0f;privatefloatlast_z=0.0f;privatefloatshake=0.0f;privatefloattotalShake=0.0fprivateMediarecorderobject;//正在录制私有布尔值Recoding=false;@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);//UI组件recordButton=(Button)this.findViewById(R.id.Button01);stopButton=(Button)this.findViewById(R.id.Button02);finalTextViewtx1=(TextView)this.findViewById(R.id.TextView01);//记录按钮点击事件recordButton.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){//如果不录制,点击按钮开始录制if(!isRecoding){startRecord();}}});//停止按钮点击事件stopButton.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){initShake();//如果正在录音,可以停止录音if(mr!=null){mr.stop();mr.release();mr=null;recordButton.setText("recording");Toast.makeText(getApplicationContext(),"Recordingiscomplete",Toast.LENGTH_LONG).show();isRecoding=false;}}});//获取传感器管理器SensorManagersm=(SensorManager)getSystemService(Context.SENSOR_SERVICE);//得到加速度传感器SensoracceleromerSensor=sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//定义传感器事件监听器SensorEventListeneraccelomerListener=newSensorEventListener(){@OverridepublicvoidonAccuracyChanged(Sensorsensor,intaccuracy){//什么都不做}//传感器数据变化事件@OverridepublicvoidonSensorChanged(SensorEventevent){//如果没有开始录制,可以监听是否有晃动事件,如果有晃动事件可以开始记录if(!isRecoding){//获取加速度传感器的三个参数floatx=event.values[SensorManager.DATA_X];floaty=event.values[SensorManager.DATA_Y];floatz=event.values[SensorManager.DATA_Z];//获取当前时刻的毫秒数curTime=System.currentTimeMillis();//100毫秒检测一次if((curTime-lastTime)>100){duration=(curTime-lastTime);//看是否刚开始Shakeif(last_x==0.0f&&last_y==0.0f&&last_z==0.0f){//当last_x,last_y,last_z同时为0时,表示录音有刚刚开始initTime=System.currentTimeMillis();}else{//单次摇动幅度shake=(Math.abs(x-last_x)+Math.abs(y-last_y)+Math.abs(z-last_z))/duration*100;}//将每个抖动幅度相加得到整体的Shake范围totalShake+=shake;//判断是否抖动,这是一个标准自己写的,不准确,只是作为教学例子,不要误会^_^if(totalShake>10&&totalShake/(curTime-initTime)*1000>10){startRecord();initShake();}tx1.setText("整体抖动率="+totalShake+"\nAverageshakingamplitude="+totalShake/(curTime-initTime)*1000);}last_x=x;last_y=y;last_z=z;lastTime=curTime;}}};//在传感器管理器中注册Listenersm.registerListener(acceleromerListener,acceleromerSensor,SensorManager.SENSOR_DELAY_NORMAL);}//开始录音publicvoidstartRecord(){//设置录音标志为trueisRecoding=true;//存储文件Filefile=newFile("/sdcard/"+"YY"+newDateFormat().format("yyyyMMdd_hhmmss",Calendar.getInstance(Locale.CHINA))+".amr");Toast.makeText(getApplicationContext(),"录音,录音文件在"+file.getAbsolutePath(),Toast.LENGTH_LONG).show();//创建录音对象mr=newMediaRecorder();//从麦克风源录音mr.setAudioSource(MediaRecorder.AudioSource.DEFAULT);//设置输出格式mr.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);//设置编码格式mr.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);//设置输出文件mr.setOutputFile(file.getAbsolutePath());try{//创建文件file.createNewFile();//准备记录mr.prepare();}catch(IllegalStateExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}//开始录音mr.start();recordButton.setText("Recording...");}//Shake初始化publicvoidinitShake(){lastTime=0;duration=0;curTime=0;initTime=0;last_x=0.0f;last_y=0.0f;last_z=0.0f;shake=0.0f;totalShake=0.0f;}}4.总结一下:直到Android2.2版本,系统才提供了很多对于开发人员可用的封装传感器信息仅提供传感器发送的原始数据。这些原始数据存储在event.values数组中。开发人员需要从这些原始数据中发现有用的信息,例如来自加速度传感器的3D数据。原始数据得到的抖动判断(我的抖动判断很好,有时间再改。。。)好了,本讲先到这里,有机会再说传感器,下次见。