Android 傳感器開發詳解

Android 傳感器開發詳解

傳感器

傳感器的分類

方向傳感器

陀螺儀傳感器

磁場傳感器

重力傳感器

線性加速度傳感器

溫度傳感器

光傳感器

壓力傳感器

心率傳感器

實例獲取各傳感器數據并展示

傳感器的介紹

Android系統提供了對傳感器的支持,如果手機的硬件提供了這些傳感器的話,那么我們就可以通過代碼獲取手機外部的狀態。比如說手機的擺放狀態、外界的磁場、溫度和壓力等等。

傳感器開發

對于我們開發者來說,開發傳感器十分簡單。只需要注冊監聽器,接收回調的數據就行了,下面來詳細介紹下各傳感器的開發。

使用

第一步

// 獲取傳感器管理對象

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

第二步

// 獲取傳感器的類型(TYPE_ACCELEROMETER:加速度傳感器)

mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

這里我們除了可以獲取加速度傳感器之外,還可以獲取其他類型的傳感器,如:

  • Sensor.TYPE_ORIENTATION:方向傳感器。

  • Sensor.TYPE_GYROSCOPE:陀螺儀傳感器。

  • Sensor.TYPE_MAGNETIC_FIELD:磁場傳感器。

  • Sensor.TYPE_GRAVITY:重力傳感器。

  • Sensor.TYPE_LINEAR_ACCELERATION:線性加速度傳感器。

  • Sensor.TYPE_AMBIENT_TEMPERATURE:溫度傳感器。

  • Sensor.TYPE_LIGHT:光傳感器。

  • Sensor.TYPE_PRESSURE:壓力傳感器。

第三步

在onResume()方法中監聽傳感器傳回的數據:

@Override

protected void onResume() {

super.onResume();

// 為加速度傳感器注冊監聽器

mSensorManager.registerListener(new SensorEventListener() {

    // 當傳感器的值改變的時候回調該方法

    @Override

    public void onSensorChanged(SensorEvent event) {

    }

    // 當傳感器精度發生改變時回調該方法

    @Override

    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

}, mSensor, SensorManager.SENSOR_DELAY_GAME);

}

其中,registerListener(SensorEventListener listener, Sensor sensor,int samplingPeriodUs)的三個參數說明如下:

listener:監聽傳感器時間的監聽器,該監聽器需要實現SensorEventListener接口。

sensor:傳感器對象。

samplingPeriodUs:指定獲取傳感器頻率,一共有如下幾種:

  • SensorManager.SENSOR_DELAY_FASTEST:最快,延遲最小,同時也最消耗資源,一般只有特別依賴傳感器的應用使用該頻率,否則不推薦。

  • SensorManager.SENSOR_DELAY_GAME:適合游戲的頻率,一般有實時性要求的應用適合使用這種頻率。

  • SensorManager.SENSOR_DELAY_NORMAL:正常頻率,一般對實時性要求不高的應用適合使用這種頻率。

  • SensorManager.SENSOR_DELAY_UI:適合普通應用的頻率,這種模式比較省電,而且系統開銷小,但延遲大,因此只適合普通小程序使用。

并在onStop()方法中取消注冊:

@Override

protected void onStop() {

super.onStop();

// 取消監聽

mSensorManager.unregisterListener(this);

}

簡單3步,就完成了監聽加速度傳感器的開發,是不是so easy?

列子

下面一個列子,演示了完整的監聽加速度傳感器的開發,并將結果顯示到屏幕上:

public class MainActivity extends AppCompatActivity implements SensorEventListener{

private SensorManager mSensorManager;

private TextView mTxtValue;

private Sensor mSensor;

@Override

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    mTxtValue = (TextView) findViewById(R.id.txt_value);

    // 獲取傳感器管理對象

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

    // 獲取傳感器的類型(TYPE_ACCELEROMETER:加速度傳感器)

    mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

}

@Override

protected void onResume() {

    super.onResume();

    // 為加速度傳感器注冊監聽器

    mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);

}

@Override

protected void onStop() {

    super.onStop();

    // 取消監聽

    mSensorManager.unregisterListener(this);

}

// 當傳感器的值改變的時候回調該方法

@Override

public void onSensorChanged(SensorEvent event) {

    float[] values = event.values;

    StringBuilder sb = new StringBuilder();

    sb.append("X方向的加速度:");

    sb.append(values[0]);

    sb.append("\nY方向的加速度:");

    sb.append(values[1]);

    sb.append("\nZ方向的加速度:");

    sb.append(values[2]);

    mTxtValue.setText(sb.toString());

}

// 當傳感器精度發生改變時回調該方法

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

}

運行結果:

[圖片上傳失敗...(image-19445-1529942146391)]

方向傳感器(高版本后廢棄)

方向傳感器用于感應手機的擺放位置,它給我們返回了三個角度,這三個角度可以確定手機的擺放狀態。

  • 第一個角度:表示手機頂部朝向與正北方的夾角。當手機繞著Z軸旋轉時,該角度值發生改變。比如,當該角度為0度時,表明手機頂部朝向正北;該角度為90度時,表明手機頂部朝向正東;該角度為180度時,表明手機朝向正南;該角度為270度時,表明手機頂部朝向正西。

  • 第二個角度:表示手機頂部或尾部翹起的高度。當手機繞著X軸傾斜時,該角度值發生變化,該角度的取值范圍是-180~180度。假設手機屏幕朝上水平放在桌子上,如果桌子是完全水平的,該角度值應該是0度。假如從手機頂部開始抬起,直到將手機沿X軸旋轉180度(屏幕向下水平放在桌子上),在這個旋轉的過程中,該角度值會從0度變化到-180度。也就是說,從手機頂部抬起時,該角度的值會逐漸減少,直到等于-180度;如果從手機底部開始抬起,直到將手機沿X軸旋轉180度(屏幕向下水平放在桌子上),該角度的值會從0度變化到180度,也就是說,從手機底部抬起時,該角度的值會逐漸增大,直到等于180度。

  • 第三個角度:表示手機左側或右側翹起的角度。當手機繞著Y軸傾斜時,該角度值發生改變。該角度的取值范圍是:-90~90度。假設將手機屏幕朝上水平放在桌面上,如果桌面是完全水平的,該角度應該為0度。如果將手機從左側開始慢慢抬起,知道將手機沿著Y軸旋轉90度(手機與桌面垂直),在這個旋轉的過程中,該角度值會從0度變化到-90度。也就是說,從手機左側開始抬起時,該角度的值會逐漸的減少,知道等于-90度。如果從手機的右側抬起,則剛好相反,會從0度變化,直到90度。

通過在應用程序中使用方向傳感器,可以實現如:地圖導航、水平儀、指南針等應用。

陀螺儀傳感器

陀螺儀傳感器用于感應手機的旋轉速度。陀螺儀傳感器給我們返回了當前設備的X、Y、Z三個坐標軸(坐標系統與加速度傳感器一模一樣)的旋轉速度。旋轉速度的單位是弧度/秒,旋轉速度為:

正值代表逆時針旋轉,負值代表順時針旋轉。關于返回的三個角速度說明如下:

  • 第一個值:代表該設備繞X軸旋轉的角速度。

  • 第二個值:代表該設備繞Y軸旋轉的角速度。

  • 第三個值:代表該設備繞Z軸旋轉的角速度。

磁場傳感器

磁場感應器主要讀取設備周圍的磁場強度。即便是設備周圍沒有任何直接的磁場,設備也會始終處于地球的磁場中,除非你不在地球。。隨著手機設備擺放狀態的改變,周圍磁場在手機的X、Y、Z方向上的影響也會發生改變。磁場傳感器會返回三個數據,分別代表周圍磁場分解到X、Y、Z三個方向的磁場分量,磁場數據的單位是微特斯拉。

重力傳感器

重力傳感器會返回一個三維向量,這個三維向量可顯示重力的方向和強度。重力傳感器的坐標系統和加速度傳感器的坐標系統相同。

線性加速度傳感器

線性加速度傳感器返回一個三維向量顯示設備在各個方向的加速度(不包含重力加速度)。線性加速度傳感器的坐標系統和加速度傳感器的坐標系統相同。

線性加速度傳感器、重力傳感器、加速度傳感器,這三者輸出值的關系如下:

加速度傳感器 = 重力傳感器 + 線性加速度傳感器。

溫度傳感器

溫度傳感器用于獲取設備所處環境的溫度。溫度傳感器會返回一個數據,代表手機設備周圍的溫度,單位是攝氏度。

光傳感器

光傳感器用于獲取設備周圍光的強度。光傳感器會返回一個數據,代表手機周圍光的強度,單位是勒克斯。

壓力傳感器

壓力傳感器用于獲取設備周圍壓力的大小。壓力傳感器會返回一個數據,代表設備周圍壓力的大小。

心率傳感器

心率傳感器是在5.0之后新增的一個傳感器,用于返回佩戴設備的人每分鐘的心跳次數。該傳感器返回的數據準確性可以通過SensorEvent的accuracy進行判斷,如果該屬性值為:SENSOR_STATUS_UNRELIABLE或SENSOR_STATUS_NO_CONTACT,則表明傳感器返回的數據是不太可靠的,應該丟棄。

在使用心率傳感器時,需要增加如下權限:

<uses-permission android:name="android.permission.BODY_SENSORS"/>

實例(獲取各傳感器數據并展示)

public class MainActivity extends AppCompatActivity implements SensorEventListener{

private SensorManager mSensorManager;

private TextView mTxtValue1;

private TextView mTxtValue2;

private TextView mTxtValue3;

private TextView mTxtValue4;

private TextView mTxtValue5;

private TextView mTxtValue6;

private TextView mTxtValue7;

private TextView mTxtValue8;

private TextView mTxtValue9;

@Override

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    mTxtValue1 = (TextView) findViewById(R.id.txt_value1);

    mTxtValue2 = (TextView) findViewById(R.id.txt_value2);

    mTxtValue3 = (TextView) findViewById(R.id.txt_value3);

    mTxtValue4 = (TextView) findViewById(R.id.txt_value4);

    mTxtValue5 = (TextView) findViewById(R.id.txt_value5);

    mTxtValue6 = (TextView) findViewById(R.id.txt_value6);

    mTxtValue7 = (TextView) findViewById(R.id.txt_value7);

    mTxtValue8 = (TextView) findViewById(R.id.txt_value8);

    mTxtValue9 = (TextView) findViewById(R.id.txt_value9);

    // 獲取傳感器管理對象

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

}

@Override

protected void onResume() {

    super.onResume();

    // 為加速度傳感器注冊監聽器

    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);

    // 為方向傳感器注冊監聽器

    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME);

    // 為陀螺儀傳感器注冊監聽器

    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);

    // 為磁場傳感器注冊監聽器

    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_GAME);

    // 為重力傳感器注冊監聽器

    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY), SensorManager.SENSOR_DELAY_GAME);

    // 為線性加速度傳感器注冊監聽器

    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION), SensorManager.SENSOR_DELAY_GAME);

    // 為溫度傳感器注冊監聽器

    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE), SensorManager.SENSOR_DELAY_GAME);

    // 為光傳感器注冊監聽器

    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_GAME);

    // 為壓力傳感器注冊監聽器

    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE), SensorManager.SENSOR_DELAY_GAME);

}

@Override

protected void onStop() {

    super.onStop();

    // 取消監聽

    mSensorManager.unregisterListener(this);

}

// 當傳感器的值改變的時候回調該方法

@Override

public void onSensorChanged(SensorEvent event) {

    float[] values = event.values;

    // 獲取傳感器類型

    int type = event.sensor.getType();

    StringBuilder sb;

    switch (type){

        case Sensor.TYPE_ACCELEROMETER:

            sb = new StringBuilder();

            sb.append("加速度傳感器返回數據:");

            sb.append("\nX方向的加速度:");

            sb.append(values[0]);

            sb.append("\nY方向的加速度:");

            sb.append(values[1]);

            sb.append("\nZ方向的加速度:");

            sb.append(values[2]);

            mTxtValue1.setText(sb.toString());

            break;

        case Sensor.TYPE_ORIENTATION:

            sb = new StringBuilder();

            sb.append("\n方向傳感器返回數據:");

            sb.append("\n繞Z軸轉過的角度:");

            sb.append(values[0]);

            sb.append("\n繞X軸轉過的角度:");

            sb.append(values[1]);

            sb.append("\n繞Y軸轉過的角度:");

            sb.append(values[2]);

            mTxtValue2.setText(sb.toString());

            break;

        case Sensor.TYPE_GYROSCOPE:

            sb = new StringBuilder();

            sb.append("\n陀螺儀傳感器返回數據:");

            sb.append("\n繞X軸旋轉的角速度:");

            sb.append(values[0]);

            sb.append("\n繞Y軸旋轉的角速度:");

            sb.append(values[1]);

            sb.append("\n繞Z軸旋轉的角速度:");

            sb.append(values[2]);

            mTxtValue3.setText(sb.toString());

            break;

        case Sensor.TYPE_MAGNETIC_FIELD:

            sb = new StringBuilder();

            sb.append("\n磁場傳感器返回數據:");

            sb.append("\nX軸方向上的磁場強度:");

            sb.append(values[0]);

            sb.append("\nY軸方向上的磁場強度:");

            sb.append(values[1]);

            sb.append("\nZ軸方向上的磁場強度:");

            sb.append(values[2]);

            mTxtValue4.setText(sb.toString());

            break;

        case Sensor.TYPE_GRAVITY:

            sb = new StringBuilder();

            sb.append("\n重力傳感器返回數據:");

            sb.append("\nX軸方向上的重力:");

            sb.append(values[0]);

            sb.append("\nY軸方向上的重力:");

            sb.append(values[1]);

            sb.append("\nZ軸方向上的重力:");

            sb.append(values[2]);

            mTxtValue5.setText(sb.toString());

            break;

        case Sensor.TYPE_LINEAR_ACCELERATION:

            sb = new StringBuilder();

            sb.append("\n線性加速度傳感器返回數據:");

            sb.append("\nX軸方向上的線性加速度:");

            sb.append(values[0]);

            sb.append("\nY軸方向上的線性加速度:");

            sb.append(values[1]);

            sb.append("\nZ軸方向上的線性加速度:");

            sb.append(values[2]);

            mTxtValue6.setText(sb.toString());

            break;

        case Sensor.TYPE_AMBIENT_TEMPERATURE:

            sb = new StringBuilder();

            sb.append("\n溫度傳感器返回數據:");

            sb.append("\n當前溫度為:");

            sb.append(values[0]);

            mTxtValue7.setText(sb.toString());

            break;

        case Sensor.TYPE_LIGHT:

            sb = new StringBuilder();

            sb.append("\n光傳感器返回數據:");

            sb.append("\n當前光的強度為:");

            sb.append(values[0]);

            mTxtValue8.setText(sb.toString());

            break;

        case Sensor.TYPE_PRESSURE:

            sb = new StringBuilder();

            sb.append("\n壓力傳感器返回數據:");

            sb.append("\n當前壓力為:");

            sb.append(values[0]);

            mTxtValue9.setText(sb.toString());

            break;

    }

}

// 當傳感器精度發生改變時回調該方法

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

}

運行結果:

[圖片上傳失敗...(image-564491-1529942146390)]

https://blog.csdn.net/airsaid/article/details/52902299

+??YU???!

MySensorDemo

Day09_Sensor_Demo

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

推薦閱讀更多精彩內容