传感器的应用/SurfaceView/制作简单的指南针
傳感器的簡(jiǎn)單應(yīng)用之光照傳感器
1.手機(jī)上傳感器的使用首先需要得到系統(tǒng)服務(wù)
private SensorManager mSensorManager; mSensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);2.然后得到在得到服務(wù)的類型,即選用哪種傳感器
Sensor sensor=mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);3.需要注冊(cè)監(jiān)聽(tīng)傳感器的使用
//注冊(cè)監(jiān)聽(tīng)事件,第一個(gè)參數(shù)是SensorEventListener,第二個(gè)參數(shù)是傳感器的類型,第三個(gè)參數(shù)是刷新頻率,mSensorManager.registerListener(listener,sensor,SensorManager.SENSOR_DELAY_NORMAL);4.注冊(cè)監(jiān)聽(tīng)事件是:
//當(dāng)傳感器精度發(fā)生變化時(shí),會(huì)調(diào)用onAccuracyChanged方法,當(dāng)傳感器檢測(cè)到的數(shù)值發(fā)生變化時(shí),就會(huì)調(diào)用onSensorChanged方法//在光照強(qiáng)度監(jiān)聽(tīng)住event數(shù)組中目前只有一個(gè)值,即光照強(qiáng)度private SensorEventListener listener=new SensorEventListener() {@Overridepublic void onSensorChanged(SensorEvent event) {float values=event.values[0];mTextView.setText("當(dāng)前關(guān)照強(qiáng)度為"+values+"lx");}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};5.最后在onDestory中注銷該監(jiān)聽(tīng)事件,釋放資源
if (mSensorManager!=null){mSensorManager.unregisterListener(listener);//注銷監(jiān)聽(tīng)事件,釋放資源}傳感器的簡(jiǎn)單應(yīng)用之加速度傳感器
1.加速度傳感器的使用基本和光照傳感器類似,只不過(guò)是將得到的傳感器的類型改變?yōu)門(mén)YPE_ACCELEROMETER
private SensorManager mSensorManager; mSensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);Sensor sensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);mSensorManager.registerListener(listener,sensor,SensorManager.SENSOR_DELAY_NORMAL);2.在注冊(cè)監(jiān)聽(tīng)事件中SensorEvent的values數(shù)組存放了3個(gè)值
//加速度傳感器的監(jiān)聽(tīng)事件,在values數(shù)組中會(huì)存放3個(gè)值,分別代表手機(jī)在X軸Y軸Z軸方向上的加速度信息//由于地心引力的存在,初始的加速度的值大約為9.8m/s*s,當(dāng)手機(jī)平放的時(shí)候這個(gè)加速度是在Z軸方向上的//當(dāng)手機(jī)豎起來(lái)的時(shí)候這個(gè)加速度是在Y軸上的,當(dāng)手機(jī)橫立起來(lái)的時(shí)候這個(gè)加速度方向是在X軸上的private SensorEventListener listener=new SensorEventListener() {@Overridepublic void onSensorChanged(SensorEvent event) {float xValues=event.values[0];float yValues=event.values[1];float zValues=event.values[2];//模仿微信搖一搖功能if(xValues>15.0||yValues>15.0||zValues>15.0){//如果某一個(gè)方向上的加速度值大于15.0就彈出一個(gè)ToastToast.makeText(AccelerometerActivity.this, "恭喜獲獎(jiǎng)", Toast.LENGTH_SHORT).show();}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};3.最后在onDestroy()方法中注銷監(jiān)聽(tīng)事件,釋放資源
@Overrideprotected void onDestroy() {super.onDestroy();if (mSensorManager!=null){mSensorManager.unregisterListener(listener);}}傳感器的綜合引用,加速度傳感器和地磁傳感器的結(jié)合,以及SurfaceView繪畫(huà)來(lái)制作一個(gè)簡(jiǎn)單的指南針
1.首先是得到這兩個(gè)傳感器,然后進(jìn)行注冊(cè)監(jiān)聽(tīng)。
private SensorManager mSensorManager;mSensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);//得到傳感器服務(wù)Sensor sensorAcc=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//得到加速度傳感器Sensor sensorMagn=mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);//得到地磁傳感器mSensorManager.registerListener(listener,sensorAcc,SensorManager.SENSOR_DELAY_GAME);//注冊(cè)加速度傳感器監(jiān)聽(tīng)事件mSensorManager.registerListener(listener,sensorMagn,SensorManager.SENSOR_DELAY_GAME);//注冊(cè)地磁傳感器監(jiān)聽(tīng)事件2.然后在監(jiān)聽(tīng)事件中得到加速度傳感器和地磁傳感器的值,并將值進(jìn)行計(jì)算得到旋轉(zhuǎn)的弧度,然后轉(zhuǎn)換成旋轉(zhuǎn)的角度,最后將得到的角度傳遞給SurfaceView上
private SensorEventListener listener=new SensorEventListener() {float[] accValues=new float[3];float[] magnValues=new float[3];@Overridepublic void onSensorChanged(SensorEvent event) {//加速度傳感器上有3個(gè)值分別代表X軸Y軸和Z軸上的值,因此需要將其賦值到一個(gè)float數(shù)組中if (event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){accValues=event.values.clone();}//地磁傳感器上的event上也有3個(gè)值,分別代表X軸Y軸Z軸方向上的磁力分量else if (event.sensor.getType()== Sensor.TYPE_MAGNETIC_FIELD){magnValues=event.values.clone();}float[] R=new float[9];float[] values=new float[3];//調(diào)用getRotationMatrix()方法會(huì)得到一個(gè)包含旋轉(zhuǎn)矩陣的R數(shù)組//第一個(gè)參數(shù)是一個(gè)長(zhǎng)度為9的float數(shù)組,getRotationMatrix()方法計(jì)算出來(lái)的旋轉(zhuǎn)數(shù)據(jù)就會(huì)賦值到這個(gè)數(shù)組中去,//第二個(gè)參數(shù)是一個(gè)用于將地磁向量轉(zhuǎn)換成重力坐標(biāo)的旋轉(zhuǎn)矩陣,通常指定為null即可//第三個(gè)和第四個(gè)參數(shù)分別傳入加速度傳感器和地磁傳感器的輸出值SensorManager.getRotationMatrix(R,null,accValues,magnValues);//getOrientation()該方法就可以計(jì)算手機(jī)的旋轉(zhuǎn)數(shù)據(jù)了//R是getRotationMatrix方法得到的旋轉(zhuǎn)矩陣,values是一個(gè)長(zhǎng)度為3的float數(shù)組,手機(jī)在各個(gè)方向上的旋轉(zhuǎn)數(shù)據(jù)都會(huì)被存放到這個(gè)數(shù)組中//values[0]表示手機(jī)圍Z軸的旋轉(zhuǎn)角度,values[1]表示手機(jī)圍繞X軸的旋轉(zhuǎn)角度,values[2]表示手機(jī)圍繞Y軸的旋轉(zhuǎn)角度SensorManager.getOrientation(R,values);//將得到的數(shù)據(jù)轉(zhuǎn)換(弧度)成角度//將得到的角度傳入到Message中然后通過(guò)Handler發(fā)送到SurfaceView上去float roateDegree=- (float) Math.toDegrees(values[0]);Message msg=new Message();msg.obj=roateDegree;msg.what=Config.DEGREE;handler.sendMessage(msg); // Log.d("degree","value[0]的值為"+Math.toDegrees(values[0])); // Log.d("degree","value[1]的值為"+Math.toDegrees(values[1])); // Log.d("degree","value[2]的值為"+Math.toDegrees(values[2]));}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};3.在SurfaceView中繪制指南針
因?yàn)镾urfaceView不像View一樣UI主線程會(huì)調(diào)用View的OnDraw方法,而SurfaceView中和 主線程沒(méi)有任何關(guān)系,因此在SurfaceView中進(jìn)行要實(shí)現(xiàn)CallBack方法,然后實(shí)現(xiàn)在surfaceCreated方法中創(chuàng)建一個(gè)線程,然后利用Handler進(jìn)行通訊
(1)首先得到SurfaceHolder,得到這個(gè)View的持有者
(2)然后繼承SurfaceHolder.Callback接口,復(fù)寫(xiě)里面的方法surfaceCreated、surfaceChanged、surfaceDestroyed這三個(gè)方法,
(3)在surfaceCreated方法中創(chuàng)建一個(gè)線程進(jìn)行繪制操作
@Overridepublic void surfaceCreated(final SurfaceHolder holder) {thread=new Thread(new Runnable() {@Overridepublic void run() {while (isRun){mCanvas=holder.lockCanvas();//首先是鎖定畫(huà)布mCanvas.drawColor(Color.WHITE);//添加一個(gè)背景為白色的畫(huà)布mCanvas.drawCircle(width/2,height/2,200,mPaintCircle);mCanvas.drawPoint(width/2,height/2,mPaintPoint);mPathRed.reset();mPathRed.moveTo(width/2-20,height/2);mPathRed.lineTo(width/2+20,height/2);mPathRed.lineTo(width/2,height/2-40);mPathRed.close();mCanvas.drawPath(mPathRed,mPaintRed);mPathBlue.reset();mPathBlue.moveTo(width/2-20,height/2);mPathBlue.lineTo(width/2+20,height/2);mPathBlue.lineTo(width/2,height/2+40);mPathBlue.close();mCanvas.drawPath(mPathBlue,mPaintBule);for (int i=1;i<=12;i++){mCanvas.save();mCanvas.rotate(degree+360/12*i,width/2,height/2);//將從主線程傳遞過(guò)來(lái)的角度添加上去重新繪制mCanvas.drawLine(width/2,height/2-200,width/2,height/2-180,mPaintCircle);mCanvas.restore();}for (int i=1;i<=4;i++){mCanvas.save();mCanvas.rotate(degree+360/4*i,width/2,height/2);//將從主線程傳遞過(guò)來(lái)的角度添加上去重新繪制mCanvas.drawText(array[i-1],width/2,height/2-120,mPaintText);mCanvas.restore();}holder.unlockCanvasAndPost(mCanvas);//最后將所畫(huà)的內(nèi)容提交上去,與lockCanvas配合使用try {//因?yàn)锳ndroid手機(jī)的刷新頻率一般為每秒25幀到30幀,因此延時(shí)一個(gè)來(lái)減少刷新頻率以及減少無(wú)用功Thread.sleep(40);} catch (InterruptedException e) {e.printStackTrace();}}}});thread.start();}public class MagneticAcitvity extends AppCompatActivity {private Compass mCompassView;private SensorManager mSensorManager;private Handler handler=new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what){case Config.DEGREE:float degree= (float) msg.obj;mCompassView.setDegree(degree);break;}}};private SensorEventListener listener=new SensorEventListener() {float[] accValues=new float[3];float[] magnValues=new float[3];@Overridepublic void onSensorChanged(SensorEvent event) {//加速度傳感器上有3個(gè)值分別代表X軸Y軸和Z軸上的值,因此需要將其賦值到一個(gè)float數(shù)組中if (event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){accValues=event.values.clone();}//地磁傳感器上的event上也有3個(gè)值,分別代表X軸Y軸Z軸方向上的磁力分量else if (event.sensor.getType()== Sensor.TYPE_MAGNETIC_FIELD){magnValues=event.values.clone();}float[] R=new float[9];float[] values=new float[3];//調(diào)用getRotationMatrix()方法會(huì)得到一個(gè)包含旋轉(zhuǎn)矩陣的R數(shù)組//第一個(gè)參數(shù)是一個(gè)長(zhǎng)度為9的float數(shù)組,getRotationMatrix()方法計(jì)算出來(lái)的旋轉(zhuǎn)數(shù)據(jù)就會(huì)賦值到這個(gè)數(shù)組中去,//第二個(gè)參數(shù)是一個(gè)用于將地磁向量轉(zhuǎn)換成重力坐標(biāo)的旋轉(zhuǎn)矩陣,通常指定為null即可//第三個(gè)和第四個(gè)參數(shù)分別傳入加速度傳感器和地磁傳感器的輸出值SensorManager.getRotationMatrix(R,null,accValues,magnValues);//getOrientation()該方法就可以計(jì)算手機(jī)的旋轉(zhuǎn)數(shù)據(jù)了//R是getRotationMatrix方法得到的旋轉(zhuǎn)矩陣,values是一個(gè)長(zhǎng)度為3的float數(shù)組,手機(jī)在各個(gè)方向上的旋轉(zhuǎn)數(shù)據(jù)都會(huì)被存放到這個(gè)數(shù)組中//values[0]表示手機(jī)圍Z軸的旋轉(zhuǎn)角度,values[1]表示手機(jī)圍繞X軸的旋轉(zhuǎn)角度,values[2]表示手機(jī)圍繞Y軸的旋轉(zhuǎn)角度SensorManager.getOrientation(R,values);//將得到的數(shù)據(jù)轉(zhuǎn)換(弧度)成角度//將得到的角度傳入到Message中然后通過(guò)Handler發(fā)送到SurfaceView上去float roateDegree=- (float) Math.toDegrees(values[0]);Message msg=new Message();msg.obj=roateDegree;msg.what=Config.DEGREE;handler.sendMessage(msg); // Log.d("degree","value[0]的值為"+Math.toDegrees(values[0])); // Log.d("degree","value[1]的值為"+Math.toDegrees(values[1])); // Log.d("degree","value[2]的值為"+Math.toDegrees(values[2]));}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_magnetic);mSensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);//得到傳感器服務(wù)Sensor sensorAcc=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//得到加速度傳感器Sensor sensorMagn=mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);//得到地磁傳感器mSensorManager.registerListener(listener,sensorAcc,SensorManager.SENSOR_DELAY_GAME);//注冊(cè)加速度傳感器監(jiān)聽(tīng)事件mSensorManager.registerListener(listener,sensorMagn,SensorManager.SENSOR_DELAY_GAME);//注冊(cè)地磁傳感器監(jiān)聽(tīng)事件mCompassView= (Compass) findViewById(R.id.myview_compass);}@Overrideprotected void onDestroy() {super.onDestroy();if (mSensorManager!=null){mSensorManager.unregisterListener(listener);//注銷listener}} }
SurfaceView
public class Compass extends SurfaceView implements SurfaceHolder.Callback{private int width;private int height;private SurfaceHolder surfaceHolder;private Thread thread;private Paint mPaintCircle;private Paint mPaintPoint;private Paint mPaintRed;private Paint mPaintBule;private Paint mPaintText;private Canvas mCanvas;private boolean isRun=true;private Path mPathRed;private Path mPathBlue;private String[] array={"E","S","W","N"};private float degree=0;/**** 該方法用來(lái)得到從傳感器得到的旋轉(zhuǎn)角度* @param degree 旋轉(zhuǎn)角度*/public void setDegree(float degree) {this.degree = degree;}public Compass(Context context) {super(context);}public Compass(Context context, AttributeSet attrs) {super(context, attrs);mPathRed=new Path();mPathBlue=new Path();mPaintText=new Paint();mPaintText.setColor(Color.BLACK);mPaintText.setTextAlign(Paint.Align.CENTER);mPaintText.setTextSize(50);mPaintRed=new Paint();mPaintRed.setColor(Color.RED);mPaintRed.setStyle(Paint.Style.FILL);mPaintRed.setStrokeWidth(10);mPaintBule=new Paint();mPaintBule.setColor(Color.BLUE);mPaintBule.setStyle(Paint.Style.FILL);mPaintBule.setStrokeWidth(10);surfaceHolder=getHolder();surfaceHolder.addCallback(this);mPaintPoint=new Paint();mPaintPoint.setColor(Color.BLACK);mPaintPoint.setStrokeWidth(10);mPaintCircle=new Paint();mPaintCircle.setColor(Color.BLACK);mPaintCircle.setAntiAlias(true);mPaintCircle.setStrokeWidth(5);mPaintCircle.setStyle(Paint.Style.STROKE);}//設(shè)置畫(huà)布的長(zhǎng)和高@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);width=getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);height=getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);setMeasuredDimension(width,height);}@Overridepublic void surfaceCreated(final SurfaceHolder holder) {thread=new Thread(new Runnable() {@Overridepublic void run() {while (isRun){mCanvas=holder.lockCanvas();//首先是鎖定畫(huà)布mCanvas.drawColor(Color.WHITE);//添加一個(gè)背景為白色的畫(huà)布mCanvas.drawCircle(width/2,height/2,200,mPaintCircle);mCanvas.drawPoint(width/2,height/2,mPaintPoint);mPathRed.reset();mPathRed.moveTo(width/2-20,height/2);mPathRed.lineTo(width/2+20,height/2);mPathRed.lineTo(width/2,height/2-40);mPathRed.close();mCanvas.drawPath(mPathRed,mPaintRed);mPathBlue.reset();mPathBlue.moveTo(width/2-20,height/2);mPathBlue.lineTo(width/2+20,height/2);mPathBlue.lineTo(width/2,height/2+40);mPathBlue.close();mCanvas.drawPath(mPathBlue,mPaintBule);for (int i=1;i<=12;i++){mCanvas.save();mCanvas.rotate(degree+360/12*i,width/2,height/2);//將從主線程傳遞過(guò)來(lái)的角度添加上去重新繪制mCanvas.drawLine(width/2,height/2-200,width/2,height/2-180,mPaintCircle);mCanvas.restore();}for (int i=1;i<=4;i++){mCanvas.save();mCanvas.rotate(degree+360/4*i,width/2,height/2);//將從主線程傳遞過(guò)來(lái)的角度添加上去重新繪制mCanvas.drawText(array[i-1],width/2,height/2-120,mPaintText);mCanvas.restore();}holder.unlockCanvasAndPost(mCanvas);//最后將所畫(huà)的內(nèi)容提交上去,與lockCanvas配合使用try {//因?yàn)锳ndroid手機(jī)的刷新頻率一般為每秒25幀到30幀,因此延時(shí)一個(gè)來(lái)減少刷新頻率以及減少無(wú)用功Thread.sleep(40);} catch (InterruptedException e) {e.printStackTrace();}}}});thread.start();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {if (isRun==true){//檔SurfaceView被銷毀時(shí),線程也被停止isRun=false;}} }總結(jié)
以上是生活随笔為你收集整理的传感器的应用/SurfaceView/制作简单的指南针的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: FreeSwitch呼入处理流程
- 下一篇: onenote标注pdf笔记_如何利用O