發布日期:2022-10-09 點擊率:148
重力傳感器與方向傳感器的開發步驟類似,只要理清了期中的x,y,z的值之后就可以根據他們的變化來進行編程了,首先來看一副圖
假設當地的重力加速度值為g
當手機正面朝上的時候,z的值為q,反面朝上的時候,z的值為-g
當手機右側面朝上的時候,x的值為g,右側面朝上的時候,x的值為-g
當手機上側面朝上的時候,y的值為g,右側面朝上的時候,y的值為-g
了解了重力傳感器中X,Y,Z的含義之后下面我們就開始學習如何使用
首先我們創建一個傳感器管理器和一個傳感器監聽器,管理器用來管理傳感器以及創建各種各樣的傳感器,監聽器用來監視傳感器的變化并且進行相應的操作
private SensorManager sensorManager;
private MySensorEventListener mySensorEventListener;
mySensorEventListener=new MySensorEventListener();//這個監聽器當然是我們自己定義的,在重力感 應器感應到手機位置有變化的時候,我們可以采取相應的操作,這里緊緊是將x,y,z的值打印出來
private final class MySensorEventListener implements SensorEventListener{
@Override
//可以得到傳感器實時測量出來的變化值
public void onSensorChanged(SensorEvent event) {
//重力傳感器
if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
float x=event.values[SensorManager.DATA_X];
float y=event.values[SensorManager.DATA_Y];
float z=event.values[SensorManager.DATA_Z];
//tv_accelerometer是界面上的一個TextView標簽,不再贅述
tv_orientation.setText("Orientation:"+x+","+y+","+z);
}
}
我們在onResume方法中創建重力傳感器,并向系統注冊監聽器
protected void onResume() {
Sensor sensor_accelerometer=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(mySensorEventListener,sensor_accelerometer, SensorManager.SENSOR_DELAY_UI);
super.onResume();
}
最后我們在onPause()中注銷所有傳感器的監聽,釋放重力感應器資源!
protected void onPause() {
/注銷所有傳感器的監聽
sensorManager.unregisterListener(mySensorEventListener);
super.onPause();
}
到此,有關重力傳感器的介紹完畢!
本節教程主要講解Android傳感器編程的基礎知識,包括加速度傳感器(accelerometer)、陀螺儀(gyroscope)、環境光照傳感器(light)、磁力傳感器(magnetic field)、方向傳感器(orientation)、壓力傳感器(pressure)、距離傳感器(proximity)和溫度傳感器(temperature)。
一、前言
我很喜歡電腦,可是筆記本還是太大,筆記本電腦再小還是要弄個小包背起來的,智能手機則不同,它完全就是一個手機,可以隨意裝在一個口袋里隨身攜帶。因此我在2002年左右時最喜歡玩裝備是Dell的PDA,2007年的時候最喜歡玩的是N73,而在2010年最喜歡玩的則是Milestone。眼見著手機的功能越來越強,時至今日智能手機甚至在某些方面已經強過了臺式機和筆記本。本節課講的就是智能手機強過臺式機和筆記本的地方:傳感器。
2008年的時候我很喜歡我的小白筆記本Macbook,喜歡玩它的一個小軟件,一拍桌子,筆記本感受到了震動,它就轉換了一個桌面出來,這讓我像個小孩子一樣沒事就拍拍桌子。這一功能這得益于蘋果筆記本內置有傳感器。
我不知道iPhone手機是不是第一個把各種各樣的傳感器運用在手機上的,不過我知道iPhone是把傳感器運用在手機上最成功的第一個。隨后的Android系統也內置了大量的傳感器,這讓Android系統手機和普通的諾基亞智能機和Windows CE智能機相比牛氣了許多,在擁有了Milestone之后,我的N73就被仍在抽屜的角落里了。
從Android1.5開始,系統內置了對多達八種傳感器的支持,他們分別是:加速度傳感器(accelerometer)、陀螺儀(gyroscope)、環境光照傳感器(light)、磁力傳感器(magnetic field)、方向傳感器(orientation)、壓力傳感器(pressure)、距離傳感器(proximity)和溫度傳感器(temperature)。
利用這些傳感器我們可以制作出各種有趣的應用程序和游戲。譬如在口袋里晃一晃手機,手機就開始神不知鬼不覺的錄音,不要著急這個很容易做,我們在本文的結尾就一起制作這個小應用。
本講的學習方式還是在實戰中學習,需要提醒的是模擬器中無法模擬傳感器,因此你需要準備一款Android真機才能運行本講的例子。
二、實例:手機傳感器清單
我們還是先看程序后解釋。
1、創建一個項目 Lesson37_HelloSensor ,主Activity名字叫 mainActivity.java。
2、UI布局文件main.xml的內容如下:
XML/HTML代碼 3、mainActivity.java的內容如下:
Java代碼 package basic.android.lesson37; import java.util.List; import android.app.Activity; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorManager; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //準備顯示信息的UI組建 final TextView tx1 = (TextView) findViewById(R.id.TextView01); //從系統服務中獲得傳感器管理器 SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE); //從傳感器管理器中獲得全部的傳感器列表 List
4、連接真機Milestone,編譯并運行程序,顯示結果如下:
5、結合上面的程序我們做一些解釋。
1)Android所有的傳感器都歸傳感器管理器 SensorManager 管理,獲取傳感器管理器的方法很簡單:
String service_name=Context.SENSOR_SERVICE;
SensorManager sensorManager=(SensorManager)getSystemService(service_name);
2)現階段Android支持的傳感器有8種,它們分別是:
傳感器類型常量 內部整數值 中文名稱 Sensor.TYPE_ACCELEROMETER 1 加速度傳感器 Sensor.TYPE_MAGNETIC_FIELD 2 磁力傳感器 Sensor.TYPE_ORIENTATION 3 方向傳感器 Sensor.TYPE_GYROSCOPE 4 陀螺儀傳感器 Sensor.TYPE_LIGHT 5 環境光照傳感器 Sensor.TYPE_PRESSURE 6 壓力傳感器 Sensor.TYPE_TEMPERATURE 7 溫度傳感器 Sensor.TYPE_PROXIMITY 8 距離傳感器
3)從傳感器管理器中獲取其中某個或者某些傳感器的方法有如下三種:
第一種:獲取某種傳感器的默認傳感器
Sensor defaultGyroscope=sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
第二種:獲取某種傳感器的列表
List
本文發布:Android開發網
本文地址:
2012年11月1日
發布:雞啄米
分類:Android開發教程
瀏覽:
評論:1
加速度傳感器
加速度傳感器又叫G-sensor,返回x、y、z三軸的加速度數值。 該數值包含地心引力的影響,單位是m/s^2。 將手機平放在桌面上,x軸默認為0,y軸默認0,z軸默認9.81。 將手機朝下放在桌面上,z軸為-9.81。 將手機向左傾斜,x軸為正值。 將手機向右傾斜,x軸為負值。 將手機向上傾斜,y軸為負值。 將手機向下傾斜,y軸為正值。
磁力傳感器
磁力傳感器簡稱為M-sensor,返回x、y、z三軸的環境磁場數據。 該數值的單位是微特斯拉(micro-Tesla),用uT表示。 單位也可以是高斯(Gauss),1Tesla=Gauss。 硬件上一般沒有獨立的磁力傳感器,磁力數據由電子羅盤傳感器提供(E-compass)。 電子羅盤傳感器同時提供下文的方向傳感器數據。
方向傳感器
方向傳感器簡稱為O-sensor,返回三軸的角度數據,方向數據的單位是角度。 為了得到精確的角度數據,E-compass需要獲取G-sensor的數據, 經過計算生產O-sensor數據,否則只能獲取水平方向的角度。 方向傳感器提供三個數據,分別為azimuth、pitch和roll。 azimuth:方位,返回水平時磁北極和Y軸的夾角,范圍為0°至360°。 0°=北,90°=東,180°=南,270°=西。 pitch:x軸和水平面的夾角,范圍為-180°至180°。 當z軸向y軸轉動時,角度為正值。 roll:y軸和水平面的夾角,由于歷史原因,范圍為-90°至90°。 當x軸向z軸移動時,角度為正值。 電子羅盤在獲取正確的數據前需要進行校準,通常可用8字校準法。 8字校準法要求用戶使用需要校準的設備在空中做8字晃動, 原則上盡量多的讓設備法線方向指向空間的所有8個象限。
陀螺儀傳感器
陀螺儀傳感器叫做Gyro-sensor,返回x、y、z三軸的角速度數據。 角速度的單位是radians/second。 根據Nexus S手機實測: 水平逆時針旋轉,Z軸為正。 水平逆時針旋轉,z軸為負。 向左旋轉,y軸為負。 向右旋轉,y軸為正。 向上旋轉,x軸為負。 向下旋轉,x軸為正。
光線感應傳感器
光線感應傳感器檢測實時的光線強度,光強單位是lux,其物理意義是照射到單位面積上的光通量。 光線感應傳感器主要用于Android系統的LCD自動亮度功能。 可以根據采樣到的光強數值實時調整LCD的亮度。
壓力傳感器
壓力傳感器返回當前的壓強,單位是百帕斯卡hectopascal(hPa)。
溫度傳感器
溫度傳感器返回當前的溫度。
距離傳感器
又稱接近傳感器,檢測物體與手機的距離,單位是厘米。 一些接近傳感器只能返回遠和近兩個狀態, 因此,接近傳感器將最大距離返回遠狀態,小于最大距離返回近狀態。 接近傳感器可用于接聽電話時自動關閉LCD屏幕以節省電量。 一些芯片集成了接近傳感器和光線傳感器兩者功能。
重力傳感器
重力傳感器簡稱GV-sensor,輸出重力數據。 在地球上,重力數值為9.8,單位是m/s^2。 坐標系統與加速度傳感器相同。 當設備復位時,重力傳感器的輸出與加速度傳感器相同。
線性加速度傳感器
線性加速度傳感器簡稱LA-sensor。 線性加速度傳感器是加速度傳感器減去重力影響獲取的數據。 單位是m/s^2,坐標系統與加速度傳感器相同。 加速度傳感器、重力傳感器和線性加速度傳感器的計算公式如下: 加速度=重力 + 線性加速度
旋轉矢量傳感器
旋轉矢量傳感器簡稱RV-sensor。 旋轉矢量代表設備的方向,是一個將坐標軸和角度混合計算得到的數據。 RV-sensor輸出三個數據: x*sin(theta/2) y*sin(theta/2) z*sin(theta/2) sin(theta/2)是RV的數量級。 RV的方向與軸旋轉的方向相同。 RV的三個數值,與cos(theta/2)組成一個四元組。 RV的數據沒有單位,使用的坐標系與加速度相同。 舉例: sensors_event_t.data[0]=x*sin(theta/2) sensors_event_t.data[1]=y*sin(theta/2) sensors_event_t.data[2]=z*sin(theta/2) sensors_event_t.data[3]= cos(theta/2)
大家好,由于最近會有對智能硬件相關的開發需求,所以最近這些天分享的博文也就大致掛鉤智能硬件了,像上一篇的藍牙分享,相信很多讀者已經看過了,那么今天我為大家帶來Android傳感器方面知識的介紹與使用方法,對于傳感器的使用,不同版本的Android手機也許存在較大的硬件差異,但是萬變不離其宗,本篇將通過幾個最常見的傳感器,滲透式的教會大家如何使用這些傳感器,帶領大家完成這部分的進階提高。讓每一位Android開發者都對傳感器的使用變得游刃有余。
1.Android的三大類傳感器
Android傳感器按大方向劃分大致有這么三類傳感器:動作(Motion)傳感器、環境(Environmental)傳感器、位置(Position)傳感器。
(1)動作傳感器
這類傳感器在三個軸(x、y、z)上測量加速度和旋轉角度。包括如下幾個傳感器:
加速(accelerometer)傳感器、重力(gravity)傳感器、陀螺儀(gyroscope)傳感器、旋轉向量(rotational vector )傳感器
下面來看一下傳感器世界的坐標系:
傳感器世界的坐標系
是不是已經有點感覺了。
(2)環境傳感器
這類傳感器可以測量不同環境的參數,例如,周圍環境的空氣溫度和壓強、光照強度和濕度。包括如下幾個傳感器:
濕度(barometer)傳感器、光線(photometer)傳感器、溫度(thermometer)傳感器
(3)位置傳感器
這類傳感器可以測量設備的物理位置。包括如下幾個傳感器:
方向(orientation)傳感器、磁力(magnetometer)傳感器
了解后我們就開始進入傳感器的編程工作了,接下來我們看一下Android為我們提供的傳感器框架(Android sensor framework,簡稱ASF)。
2.Android傳感器框架
Android SDK為我們提供了ASF,可以用來訪問當前Android設備內置的傳感器。ASF提供了很多類和接口,幫助我們完成各種與傳感器有關的任務。例如:
1)確定當前Android設備內置了哪些傳感器。
2)確定某一個傳感器的技術指標。
3)獲取傳感器傳回來的數據,以及定義傳感器回傳數據的精度。
4)注冊和注銷傳感器事件監聽器,這些監聽器用于監聽傳感器的變化,通常從傳感器回傳的數據需要利用這些監聽器完成。
ASF允許我們訪問很多傳感器類型,這些傳感器有一些是基于硬件的傳感器,還有一些是基于軟件的傳感器。基于硬件的傳感器就是直接以芯片形式嵌入到Android設備中,這些傳感器直接從外部環境獲取數據。基于軟件的傳感器并不是實際的硬件芯片,基于軟件的傳感器傳回的數據本質上也來自于基于硬件的傳感器,只是這些數據通常會經過二次加工。所以基于軟件的傳感器也可以稱為虛擬(virtual)傳感器或合成(synthetic)傳感器。
Android對每個設備的傳感器都進行了抽象,其中SensorManger類用來控制傳感器,Sensor用來描述具體的傳感器,SensorEventListener用來監聽傳感器值的改變。
(1)SensorManager類
用于創建sensor service的實例。該類提供了很多用于訪問和枚舉傳感器,注冊和注銷傳感器監聽器的方法。而且還提供了與傳感器精度、掃描頻率、校正有關的常量。
(2)Sensor類
Sensor類為我們提供了一些用于獲取傳感器技術參數的方法。如版本、類型、生產商等。例如所有傳感器的TYPE類型如下:
注意:1-8是硬件傳感器,9是軟件傳感器,其中方向傳感器的數據來自重力和磁場傳感器,10-12是硬件或軟件傳感器。
序號
傳感器
Sensor類中定義的TYPE常量
1
加速度傳感器
TYPE_ACCELEROMETER
2
溫度傳感器
TYPE_AMBIENT_TEMPERATURE
3
陀螺儀傳感器
TYPE_GYROSCOPE
4
光線傳感器
TYPE_LIGHT
5
磁場傳感器
TYPE_MAGNETIC_FIELD
6
壓力傳感器
TYPE_PRESSURE
7
臨近傳感器
TYPE_PROXIMITY
8
濕度傳感器
TYPE_RELATIVE_HUMIDITY
9
方向傳感器
TYPE_ORIENTATION
10
重力傳感器
TYPE_GRAVITY
11
線性加速傳感器
TYPE_LINEAR_ACCELERATION
12
旋轉向量傳感器
TYPE_ROTATION_VECTOR
(3)SensorEvent類
系統使用該類創建傳感器事件對象。該對象可以提供與傳感器事件有關的信息。傳感器事件對象包括的信息有原始的傳感器回傳數據、傳感器類型、數據的精度以及觸發事件的時間。
(4)SensorEventListener接口
該接口包含兩個回調方法,當傳感器的回傳值或精度發生變化時,系統會調用這兩個回調方法。
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
}
到了這里,我們就可以進行傳感器開發工作了。
3.獲取傳感器技術參數
下來我們編寫代碼來獲取一下自己手機的傳感器技術參數。
TextView tvSensors=(TextView) findViewById(R.id.tv_sensors);
//獲取傳感器SensorManager對象
SensorManager sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
List
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
//判斷傳感器類別
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER: //加速度傳感器
final float alpha=(float) 0.8;
gravity[0]=alpha * gravity[0] + (1 - alpha) * event.values[0];
gravity[1]=alpha * gravity[1] + (1 - alpha) * event.values[1];
gravity[2]=alpha * gravity[2] + (1 - alpha) * event.values[2];
String accelerometer="加速度傳感器
" + "x:"
+ (event.values[0] - gravity[0]) + "
" + "y:"
+ (event.values[1] - gravity[1]) + "
" + "z:"
+ (event.values[2] - gravity[2]);
tvAccelerometer.setText(accelerometer);
//重力加速度9.81m/s^2,只受到重力作用的情況下,自由下落的加速度
break;
case Sensor.TYPE_GRAVITY://重力傳感器
gravity[0]=event.values[0];//單位m/s^2
gravity[1]=event.values[1];
gravity[2]=event.values[2];
break;
default:
break;
}
}
protected void onResume() {
super.onResume();
//注冊加速度傳感器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),//傳感器TYPE類型
SensorManager.SENSOR_DELAY_UI);//采集頻率
//注冊重力傳感器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY),
SensorManager.SENSOR_DELAY_FASTEST);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
}
我們將手機水平正面朝上放置于桌子上,看一下效果圖:
我們可以看到正值和負值,那什么情況是正值?什么情況是負值呢?
設備沿x軸正方向推動,x軸加速度為正值。
設備沿y軸正方向推動,y軸加速度為正值。
如果沿z軸正方向推動,此時手機相對于桌子水平正面朝上放置,z軸加速度為正值。由底部朝著頂部以a m/s^2的加速度推動,那么z軸的加速度為a + 9.81,所以如果計算實際的加速度(抵消重力加速度),需要減9.81。
5.位置傳感器的組成及使用方法
Android提供了磁場傳感器和方向傳感器用于確定設備的位置,還提供了測量設備正面到某一個鄰近物體距離的傳感器(鄰近傳感器)。
鄰近傳感器在手機中很常見。像接聽電話時手機屏幕滅屏就是使用的鄰近傳感器。方向傳感器是基于軟件的,該傳感器的回傳數據來自加速度傳感器和磁場傳感器。
位置傳感器對于確定設備在真實世界中的物理位置非常有用。例如,可以組合磁場傳感器和加速度傳感器測量設備相對于地磁北極的位置,還可以利用方向傳感器確定當前設備相對于自身參照系的位置。
磁場傳感器和方向傳感器都返回值3個值(SensorEvent.values),而鄰近傳感器只返回1個值。
下面我們具體看一下他們的返回值:
方向傳感器:
SensorEvent.values[0]:繞著Z軸旋轉的角度。如果Y軸(正常拿手機的方向)正對著北方,該值是0,如果Y軸指向南方,改值是180,Y軸指向東方,該值是90,如果Y軸指向西方,該值是270。
SensorEvent.values[1]:繞著X軸旋轉的度數。當從Z軸正方向朝向Y軸正方向,改值為正值。反之,為負值。該值在180至-180之間變動。
SensorEvent.values[2]:繞著Y軸旋轉的度數。當從Z軸正方向朝向X軸正方向,改值為正值。反之,為負值。該值在180至-180之間變動。
磁場傳感器:
SensorEvent.values[0]:沿著X軸的磁力(μT,millitesla)
SensorEvent.values[1]:沿著Y軸的磁力(μT,millitesla)
SensorEvent.values[2]:沿著Y軸的磁力(μT,millitesla)
鄰近傳感器:
SensorEvent.values[0]:手機正面距離鄰近物理的距離(CM)
(1)臨近傳感器
這里以臨近傳感器作為示例工程實現一下,其他傳感器實現大同小異。
public class SensorActivity extends AppCompatActivity implements SensorEventListener {
private TextView tvProximity;
private SensorManager mSensorManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_motion_sensor);
tvProximity=(TextView) findViewById(R.id.tv_proximity);
//獲取傳感器SensorManager對象
mSensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
//判斷傳感器類別
switch (event.sensor.getType()) {
case Sensor.TYPE_PROXIMITY://臨近傳感器
tvProximity.setText(String.valueOf(event.values[0]));
break;
default:
break;
}
}
protected void onResume() {
super.onResume();
//注冊臨近傳感器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),
SensorManager.SENSOR_DELAY_UI);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
}
運行程序,我間斷的擋住臨近傳感器,看一下效果圖:
0.0是我擋住臨近傳感器時候的值,8.0是我將手移開時的值。
下面我們再來看一個比較叼的傳感器,與自然息息相關。
6.環境傳感器的組成及使用方法
Android提供了用于檢測不同的外部環境的傳感器。例如,可以檢測周圍空氣的濕度、光線、空氣的壓強和溫度,這些傳感器都是基于硬件的傳感器。除了光線傳感器外,其他傳感器在普通的Android設備中很少見。所以如果使用環境傳感器,最好運行時對當前Android設備所支持的傳感器進行檢測。
(1)環境傳感器的返回值
大多數動作傳感器和位置傳感器都返回多個值,而所有的環境傳感器都只返回一個值:
傳感器
TYPE值
返回值
單位
溫度傳感器
TYPE_AMBIENT_TEMPERATURE
event.values[0]
°C
壓力傳感器
TYPE_PRESSURE
event.values[0]
hPa
光線傳感器
TYPE_LIGHT
event.values[0]
lx
濕度傳感器
TYPE_RELATIVE_HUMIDITY
event.values[0]
RH(%)
注意:環境傳感器返回的值很少受到雜音的干擾,而動作和位置傳感器經常需要消除雜音的影響。例如,加速度傳感器要消除重力對其回傳值的影響。
(2)光線傳感器回傳數據
//最強的光線強度(估計只有沙漠地帶才能達到這個值)
public static final float LIGHT_SUNLIGHT_MAX=.0f;
//萬里無云時陽光直射的強度
public static final float LIGHT_SUNLIGHT=.0f;
//有陽光,但被云彩抵消了部分光線時的強度
public static final float LIGHT_SHADE=.0f;
//多云時的光線強度
public static final float LIGHT_OVERCAST=.0f;
//太陽剛剛升起時(日出)的光線強度
public static final float LIGHT_SUNRISE=400.0f;
//在陰雨天,沒有太陽時的光線強度
public static final float LIGHT_CLOUDY=100.0f;
//夜晚有月亮時的光線強度
public static final float LIGHT_FULLMOON=0.25f;
//夜晚沒有月亮時的光線強度(當然,也不能有路燈,就是漆黑一片)
public static final float LIGHT_NO_MOON=0.001f;
環境傳感器的使用方法與動作、位置傳感器大同小異,在次不再贅述。
相信通過本篇的學習,大家的開發水準都會有一定的提高,而大家的提高是我最欣慰的事情了。也希望大家多多支持腳本之家。
下一篇: PLC、DCS、FCS三大控
上一篇: 電氣控制線路圖控制原