Android特色開發(fā)之傳感器和語音識別分析
2011/02/11
隨著科技的快速演進,現(xiàn)代人對移動通信、無線上網(wǎng)與多媒體娛樂的需求更甚以往,所謂的智能手機(Smart Phone)便成了炙手可熱的個人消費電子產(chǎn)品之一,從Apple不斷推出iPhone企圖顛覆消費者對手機的想象、RIM推出主打商務功能的黑莓機、Google的Android系統(tǒng)讓眾家手機廠商爭食大餅,到微軟屢敗屢戰(zhàn)的從WinMo一路開發(fā)到WP7,智能手機的這塊戰(zhàn)場可說是打的如火如荼。然而在這些眾家競爭者中,Android可說是目前行情看俏的一套操作系統(tǒng),以國際市調研究機構Gartner最新出爐2010年第三季的調查為例,采用Android操作系統(tǒng)的智能手機在過去一年以來成長幅度最高,光是市占率便是前一年同期的七倍之多,銷售量更是達到14倍的成長,同時也一舉從市占率排名的第六名竄升到第二名。而在今年一月份甫落幕的國際消費性電子展(CES),也處處可見各式各樣采用Android操作系統(tǒng)的產(chǎn)品。 下面我們通過一個例子來分析Android中傳感器的使用,這里分析的是方向傳感器(TYPE_ORIENTATION)。
4.Android 中傳感器的功能
要在Android中使用傳感器,首先需要了解SensorManager和SensorEventListener。顧名思義,SensorManager就是所有傳感器的一個綜合管理類,包括了傳感器的種類、采樣率、精準度等。我們可以通過getSystemService方法來取得一個SensorManager對象。代碼如下:
SensorManager mSensorManager = SensorManager)getSystemService(SENSOR_SERVICE);
取得SensorManager對象之后,可以通過getSensorList方法來獲得我們需要的傳感器類型,保存到一個傳感器列表中。通過如下代碼可以得到一個方向傳感器:
List sensors = mSensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
要與傳感器交互,應用程序必須注冊以偵聽與一個或多個傳感器相關的活動。Android中提供了registerListener來注冊一個傳感器,并提供了unregisterListener來卸載一個傳感器。registerListener方法包括3個參數(shù):第1個參數(shù),接收信號的Listener實例;第2個參數(shù),想接收的傳感器類型的列表(即上一步創(chuàng)建的List對象);第3個參數(shù),接收頻度。調用之后返回一個布爾值,true表示成功,false表示失敗。當然,之后不再使用時,我們還需要卸載。代碼如下:
//注冊傳感器
Boolean mRegisteredSensor = mSensorManager.registerListener(this, sensor,
SensorManager.SENSOR_DELAY_FASTEST);
//卸載傳感器
mSensorManager.unregisterListener(this);
其中,SensorEventListener是使用傳感器的核心部分,包括以下兩個方法必須實現(xiàn):
onSensorChanged (SensorEvent event) 方法在傳感器值更改時調用。該方法只由受此應用程序監(jiān)視的傳感器調用。該方法的參數(shù)包括一個SensorEvent對象,該對象主要包括一組浮點數(shù),表示傳感器獲得的方向、加速度等信息。例如,以下代碼可以取得其值:
float x = event.values[SensorManager.DATA_X];
float y = event.values[SensorManager.DATA_Y];
float z = event.values[SensorManager.DATA_Z];
onAccuracyChanged (Sensor sensor,int accuracy) 方法在傳感器的精準度發(fā)生改變時調用。其參數(shù)包括兩個整數(shù):一個表示傳感器,另一個表示該傳感器新的準確值。
具體實現(xiàn)如代碼清單1所示。
代碼清單1 \Examples_09_01\src\com\yarin\android\Examples_09_01\Activity01.java
public class Activity01 extends Activity implements SensorEventListener
{
private boolean mRegisteredSensor;
//定義SensorManager
private SensorManager mSensorManager;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mRegisteredSensor = false;
//取得SensorManager實例
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
}
protected void onResume()
{
super.onResume();
//接收SensorManager的一個列表(Listener)
//這里我們指定類型為TYPE_ORIENTATION(方向傳感器)
List sensors = mSensorManager.getSensorList
(Sensor.TYPE_ORIENTATION);
if (sensors.size() > 0)
{
Sensor sensor = sensors.get(0);
//注冊SensorManager
//this->接收sensor的實例
//接收傳感器類型的列表
//接收的頻率
mRegisteredSensor = mSensorManager.registerListener(this,
sensor, SensorManager.SENSOR_DELAY_FASTEST);
}
}
protected void onPause()
{
if (mRegisteredSensor)
{
//如果調用了registerListener
//這里我們需要unregisterListener來卸載/取消注冊
mSensorManager.unregisterListener(this);
mRegisteredSensor = false;
}
super.onPause();
}
//當精準度發(fā)生改變時
//sensor->傳感器
//accuracy->精準度
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
//處理精準度改變
}
// 當傳感器在被改變時觸發(fā)
public void onSensorChanged(SensorEvent event)
{
// 接收方向傳感器的類型
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION)
{
//這里我們可以得到數(shù)據(jù),然后根據(jù)需要來處理
//由于模擬器上面無法測試效果,因此我們暫時不處理數(shù)據(jù)
float x = event.values[SensorManager.DATA_X];
float y = event.values[SensorManager.DATA_Y];
float z = event.values[SensorManager.DATA_Z];
}
}
}
上面的例子中演示了如何獲得方向傳感器的方向、加速度等信息,我們可以根據(jù)得到的數(shù)值與上一次得到的數(shù)值之間的關系來進行需要的操作。SensorManager中還有很多常量和一些常用的方法,如下:
getDefaultSensor:得到默認的傳感器對象。
getInclination:得到地磁傳感器傾斜角的弧度值。
getOrientation:得到設備旋轉的方向。
getSensorList:得到指定傳感器的列表。
二、語音識別
語音識別技術在手機上應用得相當廣泛,我們?nèi)粘W铑l繁的溝通方式是語音,在手機應用中,大部分是通過硬件手動輸入,目前這依然是主要與手機互動的方式,然而對于像手機這種小巧的移動設備來說,使用鍵盤甚至是虛擬鍵盤打字是一件非常不爽的事情。于是,
Google推出了強大的語音搜索業(yè)務。2008年11月,Google的語音搜索已經(jīng)在iPhone平臺上線,而Android在1.5 SDK版本中也加強了語音識別功能,并應用到了搜索功能上,這的確是一個非常讓人驚喜的更新。我們只需要點擊搜索框旁邊的那個小話筒形狀的按鈕,如圖1所示,Android就可以通過語音識別你要搜索的內(nèi)容。如果你的語音不夠清晰,Android也可以通過大體的意思來提供一些選擇,其宗旨是最大限度地改善人機交互的便捷性。相信很快會有更多人性化的功能出現(xiàn)在Android平臺上,比如我們在玩游戲時,可以通過語音來控制操作,讓我們期待每一次革新帶給我們的便捷吧!
圖1:Android語音識別按鈕
Android中主要通過RecognizerIntent來實現(xiàn)語音識別,它主要包括一些常量來表示語音的模式等,如表1所示。
表1 RecognizerIntent包括的常量
這里我們只需要通過Intent來傳遞一個動作以及一些屬性,然后通過startActivityForResult來開始語音,代碼如下:
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_
MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_PROMPT,"開始語音");
startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
當然,如果找不到設置,就會拋出異常ActivityNotFoundException,所以我們需要捕捉這個異常。當然,另外需要實現(xiàn)onActivityResult方法,當語音結束時,會觸發(fā)來獲得語音的字符序列。下面我們通過一個例子來學習語音識別,當我們點擊“開始使用語音識別”按鈕時,開始語音,然后在onActivityResult方法中取得結果并顯示出來,運行效果如圖2所示。由于在模擬器上沒有設備,所以顯示了ActivityNotFoundException異常,當我們在真機上測試、開始語音時,如圖3所示,語音結束后取出的字符序列如圖所示。
圖:ActivityNotFoundException異常圖2開始語音圖3獲取的字符序列
該例子很簡單,具體實現(xiàn)如代碼清單所示。
代碼清單
\Examples_09_02\src\com\yarin\android\Examples_09_02\Activity01.java
public class Activity01 extends Activity
{
private static final int VOICE_RECOGNITION_REQUEST_CODE = 4321;
private ListView mList;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mList = (ListView) findViewById(R.id.ListView01);
Button button = (Button) findViewById(R.id.Button01);
button.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
try
{
//通過Intent傳遞語音識別的模式,開啟語音
Intent intent = new Intent
(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
//語言模式和自由形式的語音識別
intent.putExtra(RecognizerIntent.EXTRA_
LANGUAGE_MODEL,RecognizerIntent.
LANGUAGE_MODEL_FREE_FORM);
//提示語音開始
intent.putExtra(RecognizerIntent.EXTRA_
PROMPT,"開始語音");
//開始執(zhí)行我們的Intent、語音識別
startActivityForResult(intent,
VOICE_RECOGNITION_REQUEST_CODE);
}
catch (ActivityNotFoundException e)
{
//找不到語音設備裝置
Toast.makeText(Activity01.this,
"ActivityNotFoundException",
Toast.LENGTH_LONG).show();
}
}
});
}
//當語音結束時的回調函數(shù)onActivityResult
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent
data)
{
// 判斷是否是我們執(zhí)行的語音識別
if(requestCode==VOICE_RECOGNITION_REQUEST_CODE&&resultCode==RESULT_OK)
{
// 取得語音的字符
ArrayList<String> results = data.getStringArrayListExtra
RecognizerIntent.EXTRA_RESULTS);
//設置視圖更新
//mList.setAdapter(new ArrayAdapter<String>(this,android.
R.layout.simple_list_item_1,results));
String resultsString = "";
for (int i = 0; i < results.size(); i++)
{
resultsString += results.get(i);
}
Toast.makeText(this,resultsString,Toast.LENGTH_LONG).show();
super.onActivityResult(requestCode, resultCode, data);
}
}
}
OFweek電子工程網(wǎng)
[英文]測試你的IVR-關鍵步驟 2011-01-26 |
云計算占互聯(lián)網(wǎng)“高地” 多媒體應用借機全面開花 2011-01-24 |
[英文]如何確保最大化關鍵任務IVR系統(tǒng)正常運行時間 2010-12-10 |
黑客攻擊新招:利用語音釣魚欺詐 2010-12-06 |
我國號碼攜帶業(yè)務訪問數(shù)據(jù)庫技術方案的研究分析 2010-11-30 |