編輯:開發入門
簡介
對於 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
)。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 領域發展迅速,並且不斷壯大。請務必關注該平台。
和android UI layout一樣,我們也可以在XML中定義應用程序的菜單。通過在菜單的onCreateOptionsMenu方法中膨脹菜單layout
就是上面的樣子做這個過程中我碰到兩個問題:1:如何做帶尾巴的氣泡VIEw2:如何把這個View添加到MapVIEw中.1:如何做帶尾巴的氣泡VIEw我是采用背景圖的方式
android開發平台是開放的平台,而位於四層框架頂端的應用開發,必然涉及到android組件。本文將為大家詳細介紹android組件。 組件(Component)
用Intent實現一個簡單的短信程序和電話撥號程序一樣,短信也是任何一款手機不可或缺的基本應用,是使用頻率最高的程序之一。現 在,我們再實現一個自己的短信程
XMLvsJSON 應用程序真實的實時更新需要注意的是,樣例應用程序沒