【轉】Android 加速度傳感器 (G-Sensor)

 

http://blog.csdn.net/stevenliyong/archive/2009/09/13/4547568.aspx

 

Android 加速度傳感器 (G-Sensor) 收藏
 

Android 加速度傳感器的類型是  Sensor.TYPE_ACCELEROMETER

 

通過 android.hardware.SensorEvent 返回加速度傳感器值。

 

加速度傳感器返回值的單位是加速度的單位 m/s^2(米每二次方秒),有三個方向的值分別是

 

values[0]: x-axis 方向加速度 

values[1]: y-axis 方向加速度 

values[2]: z-axis 方向加速度 

 

 

其中x,y,z方向的定義是以水平放置在的手機的右下腳爲參照系座標原點(如下圖)

x 方向就是手機的水平方向,右爲正

y 方向就是手機的水平垂直方向,前爲正

y 方向就是手機的空間垂直方向,天空的方向爲正,地球的方向爲負

 

 

 

x<0         x>0
                ^
                |
    +-----------+-->  y>0
    |           |
    |           |
    |           |
    |           |   / z<0
    |           |  /
    |           | /
    O-----------+/
    |[]  [ ]  []/
    +----------/+     y<0
              /
             /
           |/ z>0 (toward the sky)

    O: Origin (x=0,y=0,z=0)

 

 

需要注意的是,由於地球固有的重力加速度g (值爲9.8 m/s^2),

因此現實中實際加速度值應該是 z方向返回值 - 9.8 m/s^2.

比如你以 2 m/s^2 的加速度將手機拋起,這時z方向的返回值應該是 11.8 m/s^2.

反之若以手機以2 m/s^2 的加速度墜落,則z方向的返回值應該是 7.8 m/s^2.

x,y方向則沒有上述限制。

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/stevenliyong/archive/2009/09/13/4547568.aspx

 

 

 

http://blog.csdn.net/stevenliyong/archive/2009/09/14/4550121.aspx

 

深入探討 Android 傳感器 收藏
轉自:http://www.ibm.com/developerworks/cn/opensource/os-android-sensor/index.html

Android 是一個面向應用程序開發的富平臺,它擁有許多具有吸引力的用戶界面元素和數據管理功能。Android 還提供了一組豐富的接口選項。在本文中,學習如何配合使用 Android 的各種傳感器選項監控您的環境。樣例代碼展示瞭如何在 Android 電話中錄製音頻。想構建自己的嬰兒監視器嗎?想用聲音來接聽電話或者打開房門嗎?請學習如何利用配備有 Android 的設備的硬件功能。
簡介

對於 Java™ 開發人員來說,Android 平臺是通過使用硬件傳感器創建創新應用程序的理想平臺。我們將學習一些可用於 Android 應用程序的接口連接選項,包括使用傳感器子系統和錄製音頻片段。

利用配備 Android 的設備的硬件功能可以構建哪些應用程序呢?任何需要電子監視和監聽的應用程序都可以構建。嬰兒監視器、安全系統,甚至地震儀都可以。理論上講,您不能同時出現在兩個地方,但 Android 可以利用一些可行的方法實現這一點。縱觀本文始末,您必須記住,使用的 Android 設備不僅僅侷限於 “手機”,還可以是部署在固定位置、具有無線網絡連接的設備,比如 EDGE 或 WiFi。下載 本文示例的源文件。

 

 


 回頁首
 

 

Android 傳感器功能

使用 Android 平臺有一個很新穎的地方,那就是您可以在設備內部訪問一些 “好工具”。過去,訪問設備底層硬件的能力一度讓移動開發人員感到非常棘手。儘管 Android Java 環境的角色仍然是您和設備的橋樑,但 Android 開發團隊讓許多硬件功能浮出了水面。該平臺是一個開源平臺,因此您可以自由地編寫代碼實現您的任務。

如果尚未安裝 Android,您可以 下載 Android SDK。您還可以 瀏覽 android.hardware 包的內容並參考本文的示例。android.media 包 包含了一些提供有用和新穎功能的類。

Android SDK 中包含的一些面向硬件的功能描述如下。


表 1. Android SDK 中提供的面向硬件的特性
特性 描述
android.hardware.Camera 允許應用程序與相機交互的類,可以截取照片、獲取預覽屏幕的圖像,修改用來治理相機操作的參數。
android.hardware.SensorManager 允許訪問 Android 平臺傳感器的類。並非所有配備 Android 的設備都支持 SensorManager 中的所有傳感器,雖然這種可能性讓人非常興奮。(可用傳感器的簡介見下文)
android.hardware.SensorListener 在傳感器值實時更改時,希望接收更新的類要實現的接口。應用程序實現該接口來監視硬件中一個或多個可用傳感器。例如,本文中的 代碼 包含實現該接口的類,實現後可以監視設備的方向和內置的加速表。
android.media.MediaRecorder 用於錄製媒體樣例的類,對於錄製特定位置(比如嬰兒保育)的音頻活動非常有用。還可以分析音頻片段以便在訪問控件或安全應用程序時進行身份鑑定。例如,它可以幫助您通過聲音打開門,以節省時間,不需要從房產經紀人處獲取鑰匙。
android.FaceDetector 允許對人臉(以位圖形式包含)進行基本識別的類。不可能有兩張完全一樣的臉。可以使用該類作爲設備鎖定方法,無需記密碼 — 這是手機的生物特徵識別功能。
android.os.* 包含幾個有用類的包,可以與操作環境交互,包括電源管理、文件查看器、處理器和消息類。和許多可移動設備一樣,支持 Android 的電話可能會消耗大量電能。讓設備在正確的時間 “醒來” 以監視感興趣的事件是在設計時需要首先關注的方面。
java.util.Date
java.util.Timer
java.util.TimerTask 當測量實際的事件時,數據和時間往往很重要。例如,java.util.Date 類允許您在遇到特定的事件或狀況時獲取時間戳。您可以使用 java.util.Timer 和 java.util.TimerTask 分別執行週期性任務或時間點任務。


android.hardware.SensorManager 包含幾個常量,這表示 Android 傳感器系統的不同方面,包括:

傳感器類型
方向、加速表、光線、磁場、臨近性、溫度等。
採樣率
最快、遊戲、普通、用戶界面。當應用程序請求特定的採樣率時,其實只是對傳感器子系統的一個提示,或者一個建議。不保證特定的採樣率可用。
準確性
高、低、中、不可靠。
SensorListener 接口是傳感器應用程序的中心。它包括兩個必需方法:

onSensorChanged(int sensor,float values[]) 方法在傳感器值更改時調用。該方法只對受此應用程序監視的傳感器調用(更多內容見下文)。該方法的參數包括:一個整數,指示更改的傳感器;一個浮點值數組,表示傳感器數據本身。有些傳感器只提供一個數據值,另一些則提供三個浮點值。方向和加速表傳感器都提供三個數據值。
當傳感器的準確性更改時,將調用 onAccuracyChanged(int sensor,int accuracy) 方法。參數包括兩個整數:一個表示傳感器,另一個表示該傳感器新的準確值。
要與傳感器交互,應用程序必須註冊以偵聽與一個或多個傳感器相關的活動。註冊使用 SensorManager 類的 registerListener 方法完成。本文中的 代碼示例 演示瞭如何註冊和註銷 SensorListener。

記住,並非所有支持 Android 的設備都支持 SDK 中定義的所有傳感器。如果某個傳感器無法在特定的設備上使用,您的應用程序就會適當地降級。

 

 


 回頁首
 

 

傳感器示例

樣例應用程序僅監控對方向和加速表傳感器的更改(源代碼見 下載)。當收到更改時,傳感器值在 TextView 小部件的屏幕上顯示。圖 1 展示了該應用程序的運行情況。


圖 1. 監視加速和方向
 


使用 Eclipse 環境和 Android Developer Tools 插件創建的應用程序。(關於使用 Eclipse 開發 Android 應用程序的信息,請參見 參考資料。)清單 1 展示了該應用程序的代碼。


清單 1. IBMEyes.java
    
package com.msi.ibm.eyes;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.hardware.SensorManager;
import android.hardware.SensorListener;
public class IBMEyes extends Activity implements SensorListener {
    final String tag = "IBMEyes";
    SensorManager sm = null;
    TextView xViewA = null;
    TextView yViewA = null;
    TextView zViewA = null;
    TextView xViewO = null;
    TextView yViewO = null;
    TextView zViewO = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // get reference to SensorManager
        sm = (SensorManager) getSystemService(SENSOR_SERVICE);
        setContentView(R.layout.main);
        xViewA = (TextView) findViewById(R.id.xbox);
        yViewA = (TextView) findViewById(R.id.ybox);
        zViewA = (TextView) findViewById(R.id.zbox);
        xViewO = (TextView) findViewById(R.id.xboxo);
        yViewO = (TextView) findViewById(R.id.yboxo);
        zViewO = (TextView) findViewById(R.id.zboxo);
    }
    public void onSensorChanged(int sensor, float[] values) {
        synchronized (this) {
            Log.d(tag, "onSensorChanged: " + sensor + ", x: " +
values[0] + ", y: " + values[1] + ", z: " + values[2]);
            if (sensor == SensorManager.SENSOR_ORIENTATION) {
                xViewO.setText("Orientation X: " + values[0]);
                yViewO.setText("Orientation Y: " + values[1]);
                zViewO.setText("Orientation Z: " + values[2]);
            }
            if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
                xViewA.setText("Accel X: " + values[0]);
                yViewA.setText("Accel Y: " + values[1]);
                zViewA.setText("Accel Z: " + values[2]);
            }           
        }
    }
   
    public void onAccuracyChanged(int sensor, int accuracy) {
     Log.d(tag,"onAccuracyChanged: " + sensor + ", accuracy: " + accuracy);
    }
    @Override
    protected void onResume() {
        super.onResume();
      // register this class as a listener for the orientation and accelerometer sensors
        sm.registerListener(this,
                SensorManager.SENSOR_ORIENTATION |SensorManager.SENSOR_ACCELEROMETER,
                SensorManager.SENSOR_DELAY_NORMAL);
    }
   
    @Override
    protected void onStop() {
        // unregister listener
        sm.unregisterListener(this);
        super.onStop();
    }   
}
 


編寫應用程序必須基於常見的活動,因爲它只是利用從傳感器獲取的數據更新屏幕。在設備可能在前臺執行其他活動的應用程序中,將應用程序構建爲服務可能更加合適。

該活動的 onCreate 方法可以引用 SensorManager,其中包含所有與傳感器有關的函數。onCreate 方法還建立了對 6 個 TextView 小部件的引用,您需要使用傳感器數據值更新這些小部件。

onResume() 方法使用對 SensorManager 的引用通過 registerListener 方法註冊傳感器更新:

第一個參數是實現 SensorListener 接口的類的實例。
第二個參數是所需傳感器的位掩碼。在本例中,應用程序從 SENSOR_ORIENTATION 和 SENSOR_ACCELEROMETER 請求數據。
第三個參數是一個系統提示,指出應用程序更新傳感器值所需的速度。
應用程序(活動)暫停後,需要註銷偵聽器,這樣以後就不會再收到傳感器更新。這通過 SensorManager 的 unregisterListener 方法實現。惟一的參數是 SensorListener 的實例。

在 registerListener 和 unregisterListener 方法調用中,應用程序使用關鍵字 this。注意類定義中的 implements 關鍵字,其中聲明瞭該類實現 SensorListener 接口。這就是要將它傳遞到 registerListener 和 unregisterListener 的原因。

SensorListener 必須實現兩個方法 onSensorChange 和 onAccuracyChanged。示例應用程序不關心傳感器的準確度,但關注傳感器當前的 X、Y 和 Z 值。onAccuracyChanged 方法實質上不執行任何操作;它只在每次調用時添加一個日誌項。

似乎經常需要調用 onSensorChanged 方法,因爲加速表和方向傳感器正在快速發送數據。查看第一個參數確定哪個傳感器在發送數據。確認了發送數據的傳感器之後,將使用方法第二個參數傳遞的浮點值數組中所包含的數據更新相應的 UI 元素。該示例只是顯示這些值,但在更加高級的應用程序中,還可以分析這些值,比較原來的值,或者設置某種模式識別算法來確定用戶(或外部環境)的行爲。

現在您已經瞭解了傳感器子系統,接下來的部分將回顧一個在 Android 手機上錄製音頻的代碼樣例。該樣例運行在 DEV1 開發設備上。

 

 


 回頁首
 

 

使用 MediaRecorder

android.media 包包含與媒體子系統交互的類。使用 android.media.MediaRecorder 類進行媒體採樣,包括音頻和視頻。MediaRecorder 作爲狀態機運行。您需要設置不同的參數,比如源設備和格式。設置後,可執行任何時間長度的錄製,直到用戶停止。

清單 2 包含的代碼在 Android 設備上錄製音頻。顯示的代碼不包括應用程序的 UI 元素(完整源代碼見 下載)。


清單 2. 錄製音頻片段
    
MediaRecorder mrec ;
File audiofile = null;
private static final String TAG="SoundRecordingDemo";
protected void startRecording() throws IOException
{
   mrec.setAudioSource(MediaRecorder.AudioSource.MIC);
   mrec.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
   mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
   if (mSampleFile == null)
   {
       File sampleDir = Environment.getExternalStorageDirectory();
       try
       {
          audiofile = File.createTempFile("ibm", ".3gp", sampleDir);
       }
       catch (IOException e)
       {
           Log.e(TAG,"sdcard access error");
           return;
       }
   }
   mrec.setOutputFile(audiofile.getAbsolutePath());
   mrec.prepare();
   mrec.start();
}
protected void stopRecording()
{
   mrec.stop();
   mrec.release();
   processaudiofile(audiofile.getAbsolutePath());
}
protected void processaudiofile()
{
   ContentValues values = new ContentValues(3);
   long current = System.currentTimeMillis();
   values.put(MediaStore.Audio.Media.TITLE, "audio" + audiofile.getName());
   values.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
   values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/3gpp");
   values.put(MediaStore.Audio.Media.DATA, audiofile.getAbsolutePath());
   ContentResolver contentResolver = getContentResolver();
  
   Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
   Uri newUri = contentResolver.insert(base, values);
  
   sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, newUri));
}
 


在 startRecording 方法中,實例化並初始化 MediaRecorder 的實例:

輸入源被設置爲麥克風(MIC)。
輸出格式被設置爲 3GPP(*.3gp 文件),這是移動設備專用的媒體格式。
編碼器被設置爲 AMR_NB,這是音頻格式,採樣率爲 8 KHz。NB 表示窄頻。SDK 文檔 解釋了不同的數據格式和可用的編碼器。
音頻文件存儲在存儲卡而不是內存中。External.getExternalStorageDirectory() 返回存儲卡位置的名稱,在該目錄中將創建一個臨時文件名。然後,通過調用 setOutputFile 方法將文件關聯到 MediaRecorder 實例。音頻數據將存儲到該文件中。

調用 prepare 方法完成 MediaRecorder 的初始化。準備開始錄製流程時,將調用 start 方法。在調用 stop 方法之前,將對存儲卡上的文件進行錄製。release 方法將釋放分配給 MediaRecorder 實例的資源。

音頻採樣完成之後,需要採取以下步驟:

向設備的媒體庫添加該音頻。
執行一些模式識別步驟確定聲音:
這是嬰兒的啼哭聲嗎?
這是所有人的聲音嗎?是否要解鎖手機?
這是 “芝麻開門” 嗎?是否要打開通往 “祕密通道” 的大門?
自動將音頻文件上傳到網絡位置以便處理。
在該代碼樣例中,processaudiofile 方法將音頻添加到媒體庫。使用 Intent 通知設備上的媒體應用程序有新內容可用。

關於該代碼片段最後要注意的是:如果您試用,它一開始不會錄製音頻。您將看到創建的文件,但是沒有任何音頻。您需要向 AndroidManifest.xml 文件添加權限:

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


現在,您已經學了一點關於與 Android 傳感器和錄製音頻相關的內容。下一節將更全面的介紹與數據採集和報告系統有關的應用程序架構。

 

 


 回頁首
 

 

Android 作爲傳感器平臺

Android 平臺包含各種用於監視環境的傳感器選項。有了輸入或模擬選項數組,以及高級計算和互聯功能,Android 成爲構建實際系統的最佳平臺。圖 2 顯示了輸入、應用程序邏輯、通知方法或輸出之間的簡單視圖。


圖 2. 以 Android 爲中心的傳感器系統的方塊圖
 


該架構很靈活;應用程序邏輯可以劃分爲本地 Android 設備和服務器端資源(可以實現更大的數據庫和計算功能)。例如,本地 Android 設備上錄製的音軌可以 POST 到 Web 服務器,其中將根據音頻模式數據庫比較數據。很明顯,這僅僅是冰山一角。希望您能更深入地研究,讓 Android 平臺超越移動電話的範疇。

 

 


 回頁首
 

 

結束語

在本文中,我們介紹了 Android 傳感器。樣例應用程序度量了方向和加速,以及使用 MediaRecorder 類與錄製功能進行交互。對於構建實際系統,Android 是一個靈活、有吸引力的平臺。Android 領域發展迅速,並且不斷壯大。請務必關注該平臺。

下載

描述 名字 大小 下載方法
Eyes 源代碼 os-android-sensorEyes.zip 28KB HTTP
IBMAudio 源代碼 os-android-sensorIBMAudio.zip 33KB HTTP

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/stevenliyong/archive/2009/09/14/4550121.aspx

 

 

 

 

http://blog.csdn.net/stevenliyong/archive/2009/09/15/4555331.aspx

 

Android 方向傳感器 (Orientation Sensor) 收藏
Android 方向傳感器的類型是  Sensor.TYPE_ORIENTATION

通過 android.hardware.SensorEvent 返回方向傳感器值。

方向傳感器返回值的單位是角度,有三個值分別是

values[0]: 方位角 

values[1]: 傾斜角 

values[2]: 旋轉角

如同加速度傳感器一樣,首先Android中 x,y,z 定義是以水平放置在的手機的右下腳爲參照系座標原點(如下圖)

x 方向就是手機的水平方向,右爲正

y 方向就是手機的水平垂直方向,前爲正

z 方向就是手機的空間垂直方向,天空的方向爲正,地球的方向爲負

座標原點是手機屏幕的左下腳。 

x<0         x>0
                ^
                |
    +-----------+-->  y>0
    |           |
    |           |
    |           |
    |           |   / z<0
    |           |  /
    |           | /
    O-----------+/ 
    |[]  [ ]  []/
    +----------/+     y<0
              /
             /
           |/ z>0 (toward the sky)

    O: Origin (x=0,y=0,z=0)

方向角的定義是手機y軸 水平面上的投影 與 正北方向的夾角。 (值得範圍是 0 ~ 359 其中0=North, 90=East, 180=South, 270=West)

傾斜角的定義是手機y軸 與水平面的夾角 (手機z軸向y軸方向移動爲正 ,值得範圍是 -180 ~ 180)

旋轉角的定義是手機x軸 與水平面的夾角 (手機x軸離開z軸方向爲正, 值得範圍是 -90 ~ 90)

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/stevenliyong/archive/2009/09/15/4555331.aspx

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章