日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

传感器的应用/SurfaceView/制作简单的指南针

發布時間:2023/12/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 传感器的应用/SurfaceView/制作简单的指南针 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傳感器的簡單應用之光照傳感器

1.手機上傳感器的使用首先需要得到系統服務

private SensorManager mSensorManager; mSensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);

2.然后得到在得到服務的類型,即選用哪種傳感器

Sensor sensor=mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);

3.需要注冊監聽傳感器的使用

//注冊監聽事件,第一個參數是SensorEventListener,第二個參數是傳感器的類型,第三個參數是刷新頻率,mSensorManager.registerListener(listener,sensor,SensorManager.SENSOR_DELAY_NORMAL);

4.注冊監聽事件是:

//當傳感器精度發生變化時,會調用onAccuracyChanged方法,當傳感器檢測到的數值發生變化時,就會調用onSensorChanged方法//在光照強度監聽住event數組中目前只有一個值,即光照強度private SensorEventListener listener=new SensorEventListener() {@Overridepublic void onSensorChanged(SensorEvent event) {float values=event.values[0];mTextView.setText("當前關照強度為"+values+"lx");}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};

5.最后在onDestory中注銷該監聽事件,釋放資源

if (mSensorManager!=null){mSensorManager.unregisterListener(listener);//注銷監聽事件,釋放資源}

傳感器的簡單應用之加速度傳感器

1.加速度傳感器的使用基本和光照傳感器類似,只不過是將得到的傳感器的類型改變為TYPE_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.在注冊監聽事件中SensorEvent的values數組存放了3個值

//加速度傳感器的監聽事件,在values數組中會存放3個值,分別代表手機在X軸Y軸Z軸方向上的加速度信息//由于地心引力的存在,初始的加速度的值大約為9.8m/s*s,當手機平放的時候這個加速度是在Z軸方向上的//當手機豎起來的時候這個加速度是在Y軸上的,當手機橫立起來的時候這個加速度方向是在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){//如果某一個方向上的加速度值大于15.0就彈出一個ToastToast.makeText(AccelerometerActivity.this, "恭喜獲獎", Toast.LENGTH_SHORT).show();}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};

3.最后在onDestroy()方法中注銷監聽事件,釋放資源

@Overrideprotected void onDestroy() {super.onDestroy();if (mSensorManager!=null){mSensorManager.unregisterListener(listener);}}

傳感器的綜合引用,加速度傳感器和地磁傳感器的結合,以及SurfaceView繪畫來制作一個簡單的指南針

1.首先是得到這兩個傳感器,然后進行注冊監聽。

private SensorManager mSensorManager;mSensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);//得到傳感器服務Sensor sensorAcc=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//得到加速度傳感器Sensor sensorMagn=mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);//得到地磁傳感器mSensorManager.registerListener(listener,sensorAcc,SensorManager.SENSOR_DELAY_GAME);//注冊加速度傳感器監聽事件mSensorManager.registerListener(listener,sensorMagn,SensorManager.SENSOR_DELAY_GAME);//注冊地磁傳感器監聽事件

2.然后在監聽事件中得到加速度傳感器和地磁傳感器的值,并將值進行計算得到旋轉的弧度,然后轉換成旋轉的角度,最后將得到的角度傳遞給SurfaceView上

private SensorEventListener listener=new SensorEventListener() {float[] accValues=new float[3];float[] magnValues=new float[3];@Overridepublic void onSensorChanged(SensorEvent event) {//加速度傳感器上有3個值分別代表X軸Y軸和Z軸上的值,因此需要將其賦值到一個float數組中if (event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){accValues=event.values.clone();}//地磁傳感器上的event上也有3個值,分別代表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];//調用getRotationMatrix()方法會得到一個包含旋轉矩陣的R數組//第一個參數是一個長度為9的float數組,getRotationMatrix()方法計算出來的旋轉數據就會賦值到這個數組中去,//第二個參數是一個用于將地磁向量轉換成重力坐標的旋轉矩陣,通常指定為null即可//第三個和第四個參數分別傳入加速度傳感器和地磁傳感器的輸出值SensorManager.getRotationMatrix(R,null,accValues,magnValues);//getOrientation()該方法就可以計算手機的旋轉數據了//R是getRotationMatrix方法得到的旋轉矩陣,values是一個長度為3的float數組,手機在各個方向上的旋轉數據都會被存放到這個數組中//values[0]表示手機圍Z軸的旋轉角度,values[1]表示手機圍繞X軸的旋轉角度,values[2]表示手機圍繞Y軸的旋轉角度SensorManager.getOrientation(R,values);//將得到的數據轉換(弧度)成角度//將得到的角度傳入到Message中然后通過Handler發送到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中繪制指南針
因為SurfaceView不像View一樣UI主線程會調用View的OnDraw方法,而SurfaceView中和 主線程沒有任何關系,因此在SurfaceView中進行要實現CallBack方法,然后實現在surfaceCreated方法中創建一個線程,然后利用Handler進行通訊
(1)首先得到SurfaceHolder,得到這個View的持有者
(2)然后繼承SurfaceHolder.Callback接口,復寫里面的方法surfaceCreated、surfaceChanged、surfaceDestroyed這三個方法,

private SurfaceHolder surfaceHolder;surfaceHolder=getHolder();surfaceHolder.addCallback(this);

(3)在surfaceCreated方法中創建一個線程進行繪制操作

@Overridepublic void surfaceCreated(final SurfaceHolder holder) {thread=new Thread(new Runnable() {@Overridepublic void run() {while (isRun){mCanvas=holder.lockCanvas();//首先是鎖定畫布mCanvas.drawColor(Color.WHITE);//添加一個背景為白色的畫布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);//將從主線程傳遞過來的角度添加上去重新繪制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);//將從主線程傳遞過來的角度添加上去重新繪制mCanvas.drawText(array[i-1],width/2,height/2-120,mPaintText);mCanvas.restore();}holder.unlockCanvasAndPost(mCanvas);//最后將所畫的內容提交上去,與lockCanvas配合使用try {//因為Android手機的刷新頻率一般為每秒25幀到30幀,因此延時一個來減少刷新頻率以及減少無用功Thread.sleep(40);} catch (InterruptedException e) {e.printStackTrace();}}}});thread.start();}

指南針的程序為:

MainActivity

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個值分別代表X軸Y軸和Z軸上的值,因此需要將其賦值到一個float數組中if (event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){accValues=event.values.clone();}//地磁傳感器上的event上也有3個值,分別代表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];//調用getRotationMatrix()方法會得到一個包含旋轉矩陣的R數組//第一個參數是一個長度為9的float數組,getRotationMatrix()方法計算出來的旋轉數據就會賦值到這個數組中去,//第二個參數是一個用于將地磁向量轉換成重力坐標的旋轉矩陣,通常指定為null即可//第三個和第四個參數分別傳入加速度傳感器和地磁傳感器的輸出值SensorManager.getRotationMatrix(R,null,accValues,magnValues);//getOrientation()該方法就可以計算手機的旋轉數據了//R是getRotationMatrix方法得到的旋轉矩陣,values是一個長度為3的float數組,手機在各個方向上的旋轉數據都會被存放到這個數組中//values[0]表示手機圍Z軸的旋轉角度,values[1]表示手機圍繞X軸的旋轉角度,values[2]表示手機圍繞Y軸的旋轉角度SensorManager.getOrientation(R,values);//將得到的數據轉換(弧度)成角度//將得到的角度傳入到Message中然后通過Handler發送到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);//得到傳感器服務Sensor sensorAcc=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//得到加速度傳感器Sensor sensorMagn=mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);//得到地磁傳感器mSensorManager.registerListener(listener,sensorAcc,SensorManager.SENSOR_DELAY_GAME);//注冊加速度傳感器監聽事件mSensorManager.registerListener(listener,sensorMagn,SensorManager.SENSOR_DELAY_GAME);//注冊地磁傳感器監聽事件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;/**** 該方法用來得到從傳感器得到的旋轉角度* @param degree 旋轉角度*/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);}//設置畫布的長和高@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();//首先是鎖定畫布mCanvas.drawColor(Color.WHITE);//添加一個背景為白色的畫布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);//將從主線程傳遞過來的角度添加上去重新繪制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);//將從主線程傳遞過來的角度添加上去重新繪制mCanvas.drawText(array[i-1],width/2,height/2-120,mPaintText);mCanvas.restore();}holder.unlockCanvasAndPost(mCanvas);//最后將所畫的內容提交上去,與lockCanvas配合使用try {//因為Android手機的刷新頻率一般為每秒25幀到30幀,因此延時一個來減少刷新頻率以及減少無用功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被銷毀時,線程也被停止isRun=false;}} }

總結

以上是生活随笔為你收集整理的传感器的应用/SurfaceView/制作简单的指南针的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。