Android筆記----Android感應器開發

來源:互聯網
上載者:User

Android筆記----Android感應器開發

Android的感應器開發

Android的常用感應器

感應器應用案例

 

 

 

 

Android的感應器開發

1.1 開發感應器應用

開發感應器的步驟如下:

調用Context的getSystemService(Context.SENSOR_SERVICE)方法擷取SensorManager對象。

調用SensorManager的getDefaultSensor(int type)方法來擷取指定類型的感應器。

一般在Activity的onResume()方法中調用SensorManager的registerListener()為指定感應器註冊監聽器即可。程式可以通過實現監聽器即可擷取感應器傳回來的資料。

SersorManager提供的註冊感應器的方法為registerListener(SensorListener listener, Sensor sensor, int rate)該方法中三個參數說明如下:

listener:監聽感應器事件的監聽器

sensor:感應器對象

rate:指定擷取感應器資料的頻率

rate可以擷取感應器資料的頻率,支援如下幾個頻率值:

SENSOR_DELAY_FASTEST:最快,延遲最小。

SENSOR_DELAY_GAME:適合遊戲的頻率。

SENSOR_DELAY_NORMAL:正常頻率

SENSOR_DELAY_UI:適合普通使用者介面的頻率。

例:加速度感應器:

AccelerometerTest.java

public class AccelerometerTest extends Activityimplements SensorEventListener{// 定義系統的Sensor管理器SensorManager sensorManager;EditText etTxt1;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 擷取程式介面上的文字框組件etTxt1 = (EditText) findViewById(R.id.txt1);// 擷取系統的感應器管理服務sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);}@Overrideprotected void onResume(){super.onResume();// 為系統的加速度感應器註冊監聽器sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_GAME);}@Overrideprotected void onStop(){// 取消註冊sensorManager.unregisterListener(this);super.onStop();}// 以下是實現SensorEventListener介面必須實現的方法// 當感應器的值發生改變時回調該方法@Overridepublic void onSensorChanged(SensorEvent event){float[] values = event.values;StringBuilder sb = new StringBuilder();sb.append(X方向上的加速度:);sb.append(values[0]);sb.append(Y方向上的加速度:);sb.append(values[1]);sb.append(Z方向上的加速度:);sb.append(values[2]);etTxt1.setText(sb.toString());}// 當感應器精度改變時回調該方法。@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy){}}

 

需要指出的是,感應器的座標系統與螢幕座標系統不同,感應器座標系統的X軸沿螢幕向右;Y軸則沿螢幕向上,Z軸在垂直螢幕向上。

當拿著手機橫向左右移動時,可能產生X軸上的加速度;拿著手機前後移動時,可能產生Y軸上的加速度;當拿著手機豎向上下移動時,可能產生Z軸上的加速度。

 

1.2 下載和安裝SensorSimulator

SensorSimulator是感應器的類比工具,安裝這個類比工具之後,開發人員就可以在Android模擬器上開發、調試感應器應用。

SensorSimulator,由PC端程式和手機端程式組成,當兩端的程式運行並建立串連之後,使用者可以通過PC端的程式來改變手機的感測資料。

下載和安裝SensorSimulator步驟如下:

登入到http://code.google.com/p/openintents/wiki/SensorSimulator網站或FTP上,下載SensorSimulator的最新版本。

下載SensorSimulator工具後,下載完成後得到一個sensorsimulator-2.0-rc1.zip壓縮包。解壓該檔案,得到如下檔案結構。

安裝SensorSimulator的手機端程式。通過命令視窗進入到上面檔案的bin目錄下,輸入如下命令來安裝SensorSimulatorSettings-2.0-rc1.apk檔案。adb install SensorSimulatorSettings-2.0-rc1.apk

運行SensorSimulator的PC端程式,通過命令視窗進入到上面檔案的bin目錄下,並在視窗內執行如下命令:java –jar sensorsimulator-2.0-rc1.jar。運行該程式出現如下介面。

運行SensorSimulator的手機端程式。

在SensorSimulator的手機端程式中填寫SensorSimulator的PC端程式的監聽IP地址、監聽連接埠。

切換到SensorSimulator的Testting Tab頁,單擊該Tab裡的Connect按鈕,SensorSimulator手機端和PC端串連。

 

1.3 利用SensorSimulator開發感應器應用

通過使用SensorSimulator,接下來就可以在Android模擬器中開發、調試感應器應用了。不過使用SensorSimulator開發感應器應用與開發真實的感應器應用略有區別。

Android應用必須通過引用外部JAR包的形式來引用SensorSimulator的lib目錄下的sensorsimulator-2.0-rc1.jar包。

在應用項目上按右鍵選擇“Build Path” à “Add External Archives…”,找到sensorsimulator-2.0-rc1.jar所在位置,將其添加到項目中。

應用程式編程使用SensorManagerSimulator代替了原有的SensorManager。

應用程式擷取SensorManagerSimulator之後,需要調用connectSimulator()方法串連模擬器。

應用程式編程時所用的Sensor、SensorEvent、 SensorEventListener等不再是Android提供的類,而是由SensorSimulator提供的類。

應用程式需要訪問網路的許可權。

例:利用感測類比工具開發加速度感應器:

 

AccelSimulatorTest.java

import org.openintents.sensorsimulator.hardware.SensorManagerSimulator;import org.openintents.sensorsimulator.hardware.Sensor;import org.openintents.sensorsimulator.hardware.SensorEvent;import org.openintents.sensorsimulator.hardware.SensorEventListener;import android.app.Activity;import android.hardware.SensorManager;import android.os.Bundle;import android.widget.EditText;public class AccelSimulatorTest extends Activityimplements SensorEventListener{// 定義模擬器的Sensor管理器private SensorManagerSimulator mSensorManager;// 定義介面上的文字框組件EditText etTxt1;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 擷取程式介面的文字框組件etTxt1 = (EditText) findViewById(R.id.txt1);// 擷取感應器模擬器的感應器管理服務mSensorManager = SensorManagerSimulator.getSystemService(this, SENSOR_SERVICE);// 串連感應器模擬器mSensorManager.connectSimulator();}@Overrideprotected void onResume(){super.onResume();// 為系統的加速度感應器註冊監聽器mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_GAME);}@Overrideprotected void onStop(){// 取消註冊mSensorManager.unregisterListener(this);super.onStop();}// 以下是實現SensorEventListener介面必須實現的方法// 當感應器的值發生改變時回調該方法@Overridepublic void onSensorChanged(SensorEvent event){float[] values = event.values;StringBuilder sb = new StringBuilder();sb.append(X方向上的加速度:);sb.append(values[0]);sb.append(Y方向上的加速度:);sb.append(values[1]);sb.append(Z方向上的加速度:);sb.append(values[2]);etTxt1.setText(sb.toString());}@Override// 當感應器精度改變時回調該方法。public void onAccuracyChanged(Sensor sensor, int accuracy){}}

 

 

 

Android的常用感應器

2.1加速度感應器Accelerometer

加速度感應器主要感應手機的運動,在註冊了感應器監聽器後加速度感應器主要捕獲3個參數values[0]、values[1]、values[2]。

values[0]:空間座標系中x軸方向上的加速度減去重力加速度減去中立加速度在x軸上的分量。

values[1]:空間座標系中x軸方向上的加速度減去重力加速度減去中立加速度在y軸上的分量。

values[2]:空間座標系中x軸方向上的加速度減去重力加速度減去中立加速度在z軸上的分量。

上述3個資料的單位均為米每二次方秒。

距離說明:

當手機平放到案頭靜止時,加速度為重力加速度g,通過0減去-g(重力加速度g方向為z軸反方向,故為負值)得到values[2]為g。

如果把手機水平方向右推,此時手機x方向上的加速度為正,即values[0]為正。

當把手機以a米每二次方秒的加速度豎值向上舉時,values[2]的傳回值為(a+g)米每二次方秒,通過a減去-g得到。

 

2.2 方向感應器Orientation

方向感應器主要感應手機方位的變化,其每次讀取的都是靜態狀態值,在註冊了感應器監聽器後方向感應器主要捕獲3個參數values[0]、values[1]、values[2],關於三個角度的說明如下:

第一個角度:表示手機頂部朝向與正北方向的夾角。當手機繞著Z軸旋轉時,該角度值發生改變。

第二個角度:表示手機頂部或尾部翹起的角度,當手機繞著X軸傾斜時,該角度值發生變化。

第三個角度:表示手機左側或右側翹起的角度。當手機繞著Y軸傾斜時,該角度值發生變化。

 

2.3磁場感應器Magnetic Field

磁場感應器主要用於感應周圍的磁感應強度。即使周圍沒有任何直接的磁場,手機裝置也始終會處於地球磁場中。隨著手機狀態裝置擺放狀態的改變,周圍磁場在手機的X、Y、Z方向上的會發生改變。

磁場感應器感應器會返回三個資料,三個資料分別代表周圍磁場分解到X、Y、Z三個方向上的磁場分量。磁場資料的單位是微特斯拉(uT)。

 

2.4光感應器Light

光感應器用於感應周圍的光強,註冊監聽器後只捕獲一個參數:values[0]。該參數代表周圍的光照強度,單位為勒克斯(lux)。

 

2.5溫度感應器Temperature

溫度感應器用於擷取手機裝置所處環境的溫度。溫度感應器會返回一個資料,該資料代表手機裝置周圍的溫度,單位是攝氏度。

 

2.6壓力感應器 Pressure

壓力感應器用於擷取手機裝置所處環境的壓力的大小。壓力感應器會返回一個資料,代表手機裝置周圍的壓力大小。

 

例:感應器應用:

 

SensorSimulatorTest.java

public class SensorSimulatorTest extends Activityimplements SensorEventListener{// // 定義真機的Sensor管理器// private SensorManager mSensorManager;// 定義模擬器的Sensor管理器private SensorManagerSimulator mSensorManager;EditText etOrientation;EditText etMagnetic;EditText etTemerature;EditText etLight;EditText etPressure;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 擷取介面上的EditText組件etOrientation = (EditText) findViewById(R.id.etOrientation);etMagnetic = (EditText) findViewById(R.id.etMagnetic);etTemerature = (EditText) findViewById(R.id.etTemerature);etLight = (EditText) findViewById(R.id.etLight);etPressure = (EditText) findViewById(R.id.etPressure);// 擷取真機的感應器管理服務// mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);// 擷取感應器模擬器的感應器管理服務mSensorManager = SensorManagerSimulator.getSystemService(this,SENSOR_SERVICE);// 串連感應器模擬器mSensorManager.connectSimulator();}@Overrideprotected void onResume(){super.onResume();// 為系統的方向感應器註冊監聽器mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),SensorManager.SENSOR_DELAY_GAME);// 為系統的磁場感應器註冊監聽器mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),SensorManager.SENSOR_DELAY_GAME);// 為系統的溫度感應器註冊監聽器mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_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);}@Overrideprotected void onStop(){// 程式退出時取消註冊感應器監聽器mSensorManager.unregisterListener(this);super.onStop();}@Overrideprotected void onPause(){// 程式暫停時取消註冊感應器監聽器mSensorManager.unregisterListener(this);super.onPause();}// 以下是實現SensorEventListener介面必須實現的方法@Override// 當感應器精度改變時回調該方法。public void onAccuracyChanged(Sensor sensor, int accuracy){}@Overridepublic void onSensorChanged(SensorEvent event){float[] values = event.values;// // 真機上擷取觸發event的感應器類型// int sensorType = event.sensor.getType();// 模擬器上擷取觸發event的感應器類型int sensorType = event.type;StringBuilder sb = null;// 判斷是哪個感應器發生改變switch (sensorType){// 方向感應器case Sensor.TYPE_ORIENTATION:sb = new StringBuilder();sb.append(繞Z軸轉過的角度:);sb.append(values[0]);sb.append(繞X軸轉過的角度:);sb.append(values[1]);sb.append(繞Y軸轉過的角度:);sb.append(values[2]);etOrientation.setText(sb.toString());break;// 磁場感應器case Sensor.TYPE_MAGNETIC_FIELD:sb = new StringBuilder();sb.append(X方向上的角度:);sb.append(values[0]);sb.append(Y方向上的角度:);sb.append(values[1]);sb.append(Z方向上的角度:);sb.append(values[2]);etMagnetic.setText(sb.toString());break;// 溫度感應器case Sensor.TYPE_TEMPERATURE:sb = new StringBuilder();sb.append(當前溫度為:);sb.append(values[0]);etTemerature.setText(sb.toString());break;// 光感應器case Sensor.TYPE_LIGHT:sb = new StringBuilder();sb.append(當前光的強度為:);sb.append(values[0]);etLight.setText(sb.toString());break;// 壓力感應器case Sensor.TYPE_PRESSURE:sb = new StringBuilder();sb.append(當前壓力為:);sb.append(values[0]);etPressure.setText(sb.toString());break;}}}

 

感應器應用案例

對感應器的支援是Android系統的特性之一,通過使用感應器可以開發出各種有趣的應用,我們通過方向感應器來開發指南針。

開發指南針的思路比較簡單:程式先準備一張指南針圖片,該圖片上方向指標指向北方。接下來開發一個檢測方向的感應器,程式檢測到手機頂部繞Z軸轉過多少度,讓指南針圖片反向轉過多少度即可。

該應用中只要在介面中添加一張圖片,並讓圖片總是反向轉過方向感應器反回的第一個角度即可。

 

例:指南針:

Compass.java

public class Compass extends Activityimplements SensorEventListener{// 定義顯示指南針的圖片ImageView znzImage;// 記錄指南針圖片轉過的角度float currentDegree = 0f;// 定義模擬器的Sensor管理器//private SensorManagerSimulator mSensorManager; // 定義真機的Sensor管理器SensorManager mSensorManager;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 擷取介面中顯示指南針的圖片znzImage = (ImageView) findViewById(R.id.znzImage); // 擷取真機的感應器管理服務 mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);//// 擷取感應器模擬器的感應器管理服務//mSensorManager = SensorManagerSimulator.getSystemService(this,//SENSOR_SERVICE);//// 串連感應器模擬器//mSensorManager.connectSimulator();}@Overrideprotected void onResume(){super.onResume();// 為系統的方向感應器註冊監聽器mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),SensorManager.SENSOR_DELAY_GAME);}@Overrideprotected void onPause(){// 取消註冊mSensorManager.unregisterListener(this);super.onPause();}@Overrideprotected void onStop(){// 取消註冊mSensorManager.unregisterListener(this);super.onStop();}@Overridepublic void onSensorChanged(SensorEvent event){// 真機上擷取觸發event的感應器類型int sensorType = event.sensor.getType();//// 模擬器上擷取觸發event的感應器類型//int sensorType = event.type;switch (sensorType){case Sensor.TYPE_ORIENTATION:// 擷取繞Z軸轉過的角度。float degree = event.values[0];// 建立旋轉動畫(反向轉過degree度)RotateAnimation ra = new RotateAnimation(currentDegree,-degree, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f);// 設定動畫的期間ra.setDuration(200);// 運行動畫znzImage.startAnimation(ra);currentDegree = -degree;break;}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy){}}

 

main.xml


 

例:水平儀:

Gradienter.java

public class Gradienter extends Activity implements SensorEventListener{// 定義水平儀的儀錶盤MyView show;// 定義水平儀能處理的最大傾斜角,超過該角度,氣泡將直接在位於邊界。int MAX_ANGLE = 30;// // 定義真機的Sensor管理器// SensorManager mSensorManager;// 定義模擬器的Sensor管理器SensorManagerSimulator mSensorManager;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 擷取水平儀的主組件show = (MyView) findViewById(R.id.show);// 擷取真機的感應器管理服務// mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);// 擷取感應器模擬器的感應器管理服務mSensorManager = SensorManagerSimulator.getSystemService(this,SENSOR_SERVICE);// 串連感應器模擬器mSensorManager.connectSimulator();}@Overridepublic void onResume(){super.onResume();// 為系統的方向感應器註冊監聽器mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),SensorManager.SENSOR_DELAY_GAME);}@Overrideprotected void onPause(){// 取消註冊mSensorManager.unregisterListener(this);super.onPause();}@Overrideprotected void onStop(){// 取消註冊mSensorManager.unregisterListener(this);super.onStop();}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy){}@Overridepublic void onSensorChanged(SensorEvent event){float[] values = event.values;// // 真機上擷取觸發event的感應器類型// int sensorType = event.sensor.getType();// 模擬器上擷取觸發event的感應器類型int sensorType = event.type;switch (sensorType){case Sensor.TYPE_ORIENTATION:// 擷取與Y軸的夾角float yAngle = values[1];// 擷取與Z軸的夾角float zAngle = values[2];// 氣泡位於中間時(水平儀完全水平),氣泡的X、Y座標int x = (show.back.getWidth() - show.bubble.getWidth()) / 2;int y = (show.back.getHeight() - show.bubble.getHeight()) / 2;// 如果與Z軸的傾斜角還在最大角度之內if (Math.abs(zAngle) <= MAX_ANGLE){// 根據與Z軸的傾斜角度計算X座標的變化值(傾斜角度越大,X座標變化越大)int deltaX = (int) ((show.back.getWidth() - show.bubble.getWidth()) / 2 * zAngle / MAX_ANGLE);x += deltaX;}// 如果與Z軸的傾斜角已經大於MAX_ANGLE,氣泡應到最左邊else if (zAngle > MAX_ANGLE){x = 0;}// 如果與Z軸的傾斜角已經小於負的MAX_ANGLE,氣泡應到最右邊else{x = show.back.getWidth() - show.bubble.getWidth();}// 如果與Y軸的傾斜角還在最大角度之內if (Math.abs(yAngle) <= MAX_ANGLE){// 根據與Y軸的傾斜角度計算Y座標的變化值(傾斜角度越大,Y座標變化越大)int deltaY = (int) ((show.back.getHeight() - show.bubble.getHeight()) / 2 * yAngle / MAX_ANGLE);y += deltaY;}// 如果與Y軸的傾斜角已經大於MAX_ANGLE,氣泡應到最下邊else if (yAngle > MAX_ANGLE){y = show.back.getHeight() - show.bubble.getHeight();}// 如果與Y軸的傾斜角已經小於負的MAX_ANGLE,氣泡應到最右邊else{y = 0;}// 如果計算出來的X、Y座標還位於水平儀的儀錶盤內,更新水平儀的氣泡座標if (isContain(x, y)){show.bubbleX = x;show.bubbleY = y;}// 通知系統重回MyView組件show.postInvalidate();break;}}// 計算x、y點的氣泡是否處於水平儀的儀錶盤內private boolean isContain(int x, int y){// 計算氣泡的圓心座標X、Yint bubbleCx = x + show.bubble.getWidth() / 2;int bubbleCy = y + show.bubble.getWidth() / 2;// 計算水平儀儀錶盤的圓心座標X、Yint backCx = show.back.getWidth() / 2;int backCy = show.back.getWidth() / 2;// 計算氣泡的圓心與水平儀儀錶盤的圓心之間的距離。double distance = Math.sqrt((bubbleCx - backCx) * (bubbleCx - backCx)+ (bubbleCy - backCy) * (bubbleCy - backCy));// 若兩個圓心的距離小於它們的半徑差,即可認為處於該點的氣泡依然位於儀錶盤內if (distance < (show.back.getWidth() - show.bubble.getWidth()) / 2){return true;}else{return false;}}}

 

MyView.java

public class MyView extends View{// 定義水平儀儀錶盤圖片Bitmap back;// 定義水平儀中的泡泡圖標Bitmap bubble;// 定義水平儀中氣泡 的X、Y座標int bubbleX, bubbleY;public MyView(Context context, AttributeSet attrs){super(context, attrs);// 載入水平儀圖片和泡泡圖片back = BitmapFactory.decodeResource(getResources(), R.drawable.back);bubble = BitmapFactory.decodeResource(getResources(), R.drawable.bubble);}@Overrideprotected void onDraw(Canvas canvas){super.onDraw(canvas);// 繪製水平儀錶盤圖片canvas.drawBitmap(back, 0, 0, null);// 根據氣泡座標繪製氣泡canvas.drawBitmap(bubble, bubbleX, bubbleY, null);}}

 

 

<framelayout android:background="#fff" android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"></framelayout>

 

 

 

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.