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