Android 傳感器 指北

什么是傳感器

維基百科是這樣定義的:傳感器是一種物理裝置或生物器官,能夠探測、感受外界的信號、物理條件(如光、熱、濕度)或化學組成(如煙霧),并將探知的信息傳遞給其他裝置或器官。


常用傳感器介紹與用法

Android平臺支持三個大類的傳感器

  • Motion sensors(運動傳感器)

這些傳感器測量加速力,并沿三個軸的旋轉力。此類別包括加速度計,重力感應器, 陀螺儀和旋轉矢量傳感器。

  • Environmental sensors (環境傳感器)

這些傳感器測量各種環境參數,例如環境空氣溫度和壓力,照明和濕度。此類別包括氣壓計,光度計,和溫度計。

  • Position sensors (位置傳感器)

這些傳感器測量設備的物理位置。這個類別包括方向傳感器和磁力計。


傳感器實現流程

第一步:得到SensorManager

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

第二步:注冊傳感器

Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);     
if (null != sensor) mSensorManager.registerListener(this, sensor,SensorManager.SENSOR_DELAY_NORMAL);

registerListener這個方法有三個參數。

  • 第一個參數是傳感器數據變化的監聽器

我們需要去實現SensorEventListener接口,他里面有兩個回調方法,

@Override  public void onSensorChanged(SensorEvent event) {   //當傳感器的數值發生變化時調用  }   
@Override  public void onAccuracyChanged(Sensor sensor, int accuracy) {   //傳感器的精度發生變化時調用  }

onSensorChanged方法只有一個SensorEvent類型的參數event,其中SensorEvent類有一個values變量非常重要,該變量的類型是float[]。但該變量最多只有3個元素,而且根據傳感器的不同,values變量中元素所代表的含義也不同。

  • 第二個參數是我們需要監聽的傳感器
Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

Sensor.TYPE_ACCELEROMETER則是Android設定傳感器類型,這里是指加速度傳感器,

  • 第三個參數是傳感器數據更新數據的速度

有以下四個值可選,他們的速度是遞增的
SENSOR_DELAY_UI
SENSOR_DELAY_NORMAL
SENSOR_DELAY_GAME
SENSOR_DELAY_FASTEST

傳感器的注銷

//注銷所有傳感器對象
public void unregisterListener(SensorEventListener listener)
//注銷指定的傳感器對象
public void unregisterListener(SensorEventListener listener, Sensor sensor)

sensor的獲取依舊是通過SensorManager.getDefaultSensor()方法。

獲得手機支持的所有傳感器

Listsensors = sensorManager.getSensorList(Sensor.TYPE_ALL);

Android傳感器類型表

  • 加速度傳感器:TYPE_ACCELEROMETER

  • 周圍溫度傳感器:TYPE_AMBIENT_TEMPERATURE

  • 重力傳感器:TYPE_GRAVITY

  • 陀螺儀傳感器:TYPE_GYROSCOPE

  • 光照傳感器:TYPE_LIGHT

  • 線性加速度傳感器:TYPE_LINEAR_ACCELERATION

  • 磁力傳感器:TYPE_MAGNETIC_FIELD

  • 方向傳感器: TYPE_ORIENTATION

  • 壓力傳感器:TYPE_PRESSURE

  • 接近傳感器:TYPE_PROXIMITY

  • 相對濕度傳感器:TYPE_RELATIVE_HUMIDITY

  • 旋轉矢量傳感器:TYPE_ROTATION_VECTOR

  • 溫度傳感器: TYPE_TEMPERATURE


傳感器使用實踐

這里以方向傳感器為例

方向傳感器的獲取方式

Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);

上面這個,對,已經被google棄用了,了解就好。

Android中的坐標系


這里寫圖片描述

小喬畫圖的有點丑,將就著看吧,Z軸默認垂直于地面,所謂獲取的三個Values數組即對應手機與Z,Y,X形成的夾角,后面會說明,

前面說了,TYPE_ORIENTATION已被棄用,那么最新的方向傳感器是如何做的呢?

事實上,Android 獲取手機旋轉的方向和角度是通過加速度傳感器和地磁傳感器共同計算得出的

OK,我們這時候是需要同時使用兩個傳感器的,看代碼

Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sensorManager.registerListener(listener, accelerometerSensor,SensorManager.SENSOR_DELAY_GAME);
sensorManager.registerListener(listener, magneticSensor,SensorManager.SENSOR_DELAY_GAME);

同時使用了加速度傳感器和地磁傳感器

獲取旋轉矩陣數組R

SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticValues);

獲取手機旋轉數據

SensorManager.getOrientation(R, values);

values 是一個長度為 3 的 float 數組,手機在各個方向上的旋轉數據都會被存放到這個數組當中。

對應關系:
values[0]->Z軸、values[1]->X軸、values[2]->Y軸

values[0]的取值范圍是-180到180 度,其中±180 度表示正南方向,0 度表示正北方向,-90 度表示正西方向,90 度表示正東方向,如圖


這里寫圖片描述

所謂,實踐是檢驗真理的唯一標準,這是我檢測后自行畫的,大家看一下就明白該怎么根據獲取到的角度來做對應的處理了

一個完整的方向傳感器封裝類

public class DirectionSensorUtils implements SensorEventListener {

    private static DirectionSensorUtils sInstance;
    private SensorManager sensorManager;
    float[] accelerometerValues = new float[3];
    float[] magneticValues = new float[3];

    public static DirectionSensorUtils getInstance() {
        if (sInstance == null) {
            synchronized (DirectionSensorUtils.class) {
                if (sInstance == null) {
                    sInstance = new DirectionSensorUtils();
                }
            }
        }
        return sInstance;
    }

    private CompassChange compassChange;

    public  interface CompassChange {
        void onCompassChange( float rotateDegree);
    }


    //注冊傳感器
    public void registerSensor(Context context, CompassChange compassChange) {
        this.compassChange = compassChange;
        sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.
                TYPE_ACCELEROMETER);
        Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.
                TYPE_MAGNETIC_FIELD);
        sensorManager.registerListener(this, accelerometerSensor,
                SensorManager.SENSOR_DELAY_GAME);
        sensorManager.registerListener(this, magneticSensor,
                SensorManager.SENSOR_DELAY_GAME);
    }

    //解除傳感器注冊
    public void unregisterSensor() {
        if (sensorManager != null) {
            sensorManager.unregisterListener(this);
        }
    }


    @Override
    public void onSensorChanged(SensorEvent event) {

        // 判斷當前是加速度傳感器還是地磁傳感器
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            // 通過clone()獲取不同的values引用
            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);

        //values[0]->Z軸、values[1]->X軸、values[2]->Y軸
        //使用前請進行轉換,因為獲取到的值是弧度,示例如下
        //        Math.toDegrees(values[0]);
        //        Math.toDegrees(values[1]);
        //        Math.toDegrees(values[2]);

        float rotateDegree = -(float) Math.toDegrees(values[0]);

        if (compassChange!=null){
            compassChange.onCompassChange(rotateDegree);
        }
    }


    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • refs: https://developer.android.google.cn/guide/topics/se...
    richy_閱讀 41,981評論 5 31
  • 最近項目需要各種手機傳感器,于是就此來寫個總結,以此留痕。在Android開發中,會用到各種傳感器,但不一定每個真...
    樹新蜜蜂閱讀 1,364評論 1 2
  • Android傳感器定義 Android 傳感器相關術語微機電傳感器(MEMS)MEMS 通常制作在規格很小的硅芯...
    Jannonx閱讀 4,418評論 0 1
  • 傳感器 傳感器Sensor是一種檢測裝置,能感受到被測量的信息,并能將感受到的信息,按一定規律變換成為電信號或其他...
    Reathin閱讀 6,418評論 0 5
  • Android系統提供了對傳感器的支持,如果手機設備的硬件提供了這些傳感器,Android應用可以通過傳感器來獲取...
    trampcr閱讀 4,398評論 3 12