Android传感器的使用开发、简易指南针
原文鏈接地址:http://blog.csdn.net/aiynmimi/article/details/48660505
簡介
現在每部Android手機里邊都會內置有許多傳感器,如光照傳感器、加速度傳感器、地磁傳感器、壓力傳感器、溫度傳感器等,它們能夠監測到各種發生在手機撒花姑娘的物理事件。當然Android系統只是負責將這些傳感器所輸出的信息傳遞給我們,然后我們可以利用這些信息去開發一些好玩的應用。
用法
每種傳感器的用法步驟幾乎都一樣,只是不同傳感器的數據參數會有略微不同,這里以光照傳感器為例,介紹一些Android傳感器的使用步驟:?
①獲取SensorManager的實例
②SensorManager是系統所有傳感器的管理器,有了它的實例后就可以調用getDefaultSensor()方法來得到任意的傳感器類型。
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Sensor sensor=sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_LIGHT);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>③然后我們需要對傳感器輸出的信號進行監聽,這就要借助SensorEventListener來實現,SensorEventListener是一個接口,其中定義了onSensorChanged()和onAccuracyChanged()兩個方法。當傳感器的精度發生變化時就會調用onAccuracyChanged()方法,當監測到的數值發生變化時就會調用onSensorChanged()方法,方法中傳入一個SensorEvent參數,這個參數里又包含一個values數組,所有傳感器輸出的信息都存放在這里。
SensorEventListener listener=new SensorEventListener() {@Overridepublic void onSensorChanged(SensorEvent event) { }@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};④下面我們需要調用SensorManager的registerListener()方法來注冊SensorEventListener才能使其生效,registerListener()方法接收3個參數,第一個參數就是SensorEventListener的實例,第一個參數是Sensor的實例,第三個參數是用于表示傳感器輸出信息的更新速率,共有SENSOR_DELAY_UI、SENSOR_DELAY_NORMAL、SENSOR_DELAY_GAME和SENSOR_DELAY_FASTEST這四種值可選,其更新速率依次遞增!
sensorManager.registerListener(listener,sensor,SensorManager.SENSOR_DELAY_GAME); ⑤當程序退出或傳感器使用完畢時,一定要調用方法unregisterListener()將其使用的資源釋放掉:
@Overrideprotected void onDestroy() {super.onDestroy();if (sensorManager!=null){sensorManager.unregisterListener(listener);}}
注意:?
1. 加速度傳感器輸出的信息存放的values數組中有3個值,分別代表手機在X軸,Y軸和Z軸方向上的加速度信息。由于地心引力的存在,手機都會有一個重力加速度9.8m/s2。當手機平放時,這個加速度作用在Z軸上,豎立時,這個加速度作用在Y軸上,當手機橫立時,這個加速度作用在X軸。?
2. 方向傳感器,Sensor.TYPE_ORIENTATION,它輸出的值在values數組中,values[0]記錄手機圍繞Z軸的旋轉角度,values[1]記錄手機圍繞X軸的旋轉角度,values[2]記錄手機圍繞Y軸的旋轉角度。但是Android早已廢棄了Sensor.TYPE_ORIENTATION這種傳感器類型,而是通過加速度傳感器和地磁傳感器共同計算得出。
簡易指南針的展示
上邊提到方向傳感器已經由加速度傳感器和地磁傳感器共同計算替代。下面是具體的用法:
用法
①首先分別獲得加速度傳感器和地磁傳感器的實例,并給它們注冊監聽器:
Sensor magneticSensor=sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); Sensor accelerometerSensor=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); sensorManager.registerListener(listener,magneticSensor,SensorManager.SENSOR_DELAY_GAME); sensorManager.registerListener(listener,accelerometerSensor,SensorManager.SENSOR_DELAY_GAME); ②接下來再onSensorChanged()方法中可以獲取到SensorEvent的values數組,分別記錄著加速度傳感器和地磁傳感器的值。然后將這兩個值傳入到SensorManager的getRotationMatrix()方法中就可以得到一個包含旋轉矩陣的R數組。SensorManager.getOrientation(R,values); values是一個長度為3的float數組,其中values[0]記錄手機圍繞Z軸的 旋轉弧度 ,values[1]記錄手機圍繞X軸的 旋轉弧度 ,values[2]記錄手機圍繞Y軸的 旋轉弧度 。?
注意這里計算出的數據是弧度,如果要轉換為角度,則調用下面方法: Math.toDegrees(values[0])
values[0]的取值范圍是-180°到180°,其中±180°表示正南方向,0°表示正北方向,-90°表示正西方向,90°表示正東方向。
源碼:
我們自己畫一個簡單的指南針MyCompassView,繼承SurfaceView
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView;/*** Created by Administrator on 2015/9/21.*/ public class MyCompassView extends SurfaceView {private int width;private int height;private Paint paint_circle;private Paint paint_line;private Paint paint_text;private String[] direction = {"E","S", "W","N"};private float degree;private boolean isRunning=true;public void setDegree(float degree) {this.degree = degree;}public MyCompassView(Context context) {super(context);}public MyCompassView(Context context, AttributeSet attrs) {super(context, attrs);SurfaceHolder holder = getHolder();holder.addCallback(callback);paint_circle = new Paint();paint_circle.setColor(Color.rgb(197, 194, 186));//畫筆顏色paint_circle.setStrokeWidth(20);//畫筆粗細paint_circle.setStyle(Paint.Style.STROKE);//空心paint_circle.setAntiAlias(true);//設置抗鋸齒paint_line = new Paint();paint_line.setColor(Color.RED);paint_line.setStrokeWidth(15);paint_line.setAntiAlias(true);paint_text = new Paint();paint_text.setColor(Color.YELLOW);paint_text.setTextSize(50);paint_text.setAntiAlias(true);paint_text.setTextAlign(Paint.Align.CENTER);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);setMeasuredDimension(width, height);}SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(final SurfaceHolder holder) {//此處開啟線程new Thread(new Runnable() {@Overridepublic void run() {while (isRunning) {Canvas canvas = holder.lockCanvas();canvas.drawColor(Color.rgb(65, 64, 61));canvas.drawCircle(width / 2, height / 2, 300, paint_circle);canvas.save();canvas.rotate(degree, width / 2, height / 2);for (int i = 1; i <= 4; i++) {canvas.save();canvas.rotate(360 / 4 * i, width / 2, height / 2);canvas.drawText(direction[i - 1], width / 2, height / 2 - 250, paint_text);canvas.restore();}canvas.drawCircle(width / 2, height / 2, 50, paint_line);Path path=new Path();path.moveTo(width/2-50,height/2);path.lineTo(width/2+50,height/2);path.lineTo(width/2,height/2-200);path.close();canvas.drawPath(path,paint_line);canvas.drawText(-(int)(degree)+"°",width/2,height/2,paint_text);canvas.restore();holder.unlockCanvasAndPost(canvas);}}}).start();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {holder.setFixedSize(width,height);}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {//關閉線程isRunning=false;}}; } 然后加入到我們的布局中: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><com.example.administrator.mycompass.MyCompassViewandroid:id="@+id/mycompassview"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_centerInParent="true"/></RelativeLayout> 最后是我們主活動中的代碼:import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle;public class MainActivity extends AppCompatActivity {private SensorManager sensorManager;private MyCompassView myCompassView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myCompassView= (MyCompassView) findViewById(R.id.mycompassview);sensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);Sensor magneticSensor=sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);Sensor accelerometerSensor=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);sensorManager.registerListener(listener,magneticSensor,SensorManager.SENSOR_DELAY_GAME);sensorManager.registerListener(listener,accelerometerSensor,SensorManager.SENSOR_DELAY_GAME);}@Overrideprotected void onDestroy() {super.onDestroy();if (sensorManager!=null){sensorManager.unregisterListener(listener);}}private SensorEventListener listener=new SensorEventListener() {float[] accelerometerValues=new float[3];float[] magneticValues=new float[3];@Overridepublic void onSensorChanged(SensorEvent event) {if (event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){accelerometerValues=event.values.clone();}else if (event.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD){magneticValues=event.values.clone();}float[] R=new float[9];float[] values=new float[3];SensorManager.getRotationMatrix(R,null,accelerometerValues,magneticValues);SensorManager.getOrientation(R,values);float degree= -(float) Math.toDegrees(values[0]);//旋轉角度myCompassView.setDegree(degree);}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}}; }
總結
以上是生活随笔為你收集整理的Android传感器的使用开发、简易指南针的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux部署Oracle11gR2 R
- 下一篇: 打电话显示短信呼服务器,已启用短信呼服务