android藍牙耳機下的語音(輸入/識別)及按鍵監聽


背景:本人負責公司android平台的app開發,最近要開發一個語音助手類的app,類似於靈犀語音助手、蟲洞語音助手等。其中有兩個藍牙耳機下的語音識別問題,比較折騰人,問題描述:1.藍牙耳機連接下捕獲藍牙按鍵事件,啟動語音識別;2.正常啟動識別時也必須通過藍牙耳機錄入音頻進行語音識別。這兩個問題,測試發現靈犀語音助手都解決了,所以本人負責的這個app也必須解決。網上搜了相關的資料,基本上是鳳毛麟角,因此本人在此貢獻一點小發現供大家參考,如有不對的地方歡迎指正。

       針對第一個問題,藍牙耳機的按鍵監聽,牆內牆外的資料搜遍,沒有發現完美的解決方案(這里看到有人提出的解決辦法:http://blog.csdn.net/kangear/article/details/40430673,感覺有點另類,而且也不適合我的app的應用場景,所以沒嘗試),雖然接聽鍵(該鍵還有很多功能,不細說,以下都稱接聽鍵)的單按、雙按沒法監聽,但是長按卻是可以捕獲到,默認情況下,已經連接到android手機的藍牙耳機,長按接聽鍵幾秒后會系統會發出一個action=android.intent.action.VOICE_COMMAND的Intent,靈犀語音助手就是使用這個來監聽長按的,既然如此,我就仿照靈犀來做吧:

       1.首先,在AndroidManifest.xml中指定的一個activity (用於捕獲藍牙耳機長按事件的activity,以下以A代替之)中添加:

         <intent-filter android:priority="2147483647">
            <action android:name="android.intent.action.VOICE_COMMAND" />
            <category android:name="android.intent.category.DEFAULT" />
           </intent-filter>

當在連接了藍牙耳機的情況下,長按接聽鍵幾秒,出現提示音后(請戴着藍牙耳機按,要不聽不見,一不小心就成關機了),馬上松開,就會彈出一個選擇啟動某個app的對話框,凡是添加了以上intent-filter的activity的app都會出現對話框中,這需要引導用戶選擇你的app並選擇始終啟動你的app(注意A的launchMode,我這里建議設成singleTask),選中確定之后你的app就會被啟動,如果A還沒有創建,那A自然會被創建啦,如果A已經被創建了,則調用A的onNewIntent(Intent intent)方法,因此你只要在A中檢查接收到的intent的action就能監聽藍牙耳機的長按事件了。

       2.關於藍牙耳機下的識別問題,本app用的語音識別sdk是訊飛的,針對這個問題訊飛有給出解決方法:

在調用語音識別引擎識別前,打開sco,關鍵代碼:

       AudioManager mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
       mAudioManager.setBluetoothScoOn(true);
       mAudioManager.startBluetoothSco();

識別啟動並識別完成后,關閉sco:

       mAudioManager.setBluetoothScoOn(false);
       mAudioManager.stopBluetoothSco();

按照這個方法,便可以實現音頻錄入。

        當然你會問why,這里簡單的介紹一下藍牙耳機的兩種鏈路,A2DP及SCO。android的api表明:A2DP是一種單向的高品質音頻數據傳輸鏈路,通常用於播放立體聲音樂;而SCO則是一種雙向的音頻數據的傳輸鏈路,該鏈路只支持8K及16K單聲道的音頻數據,只能用於普通語音的傳輸,若用於播放音樂那就只能呵呵了。兩者的主要區別是:A2DP只能播放,默認是打開的,而SCO既能錄音也能播放,默認是關閉的。既然要錄音肯定要打開sco啦,因此識別前調用上面的代碼就可以通過藍牙耳機錄音了,錄完記得要關閉。

        雖然上面的方法能夠實現錄音,但測試中發現一個問題:startBluetoothSco()和stopBluetoothSco()時,藍牙耳機都會有一個提示音,如果識別本身就有提示音,那么加上藍牙的提示音就會讓人莫名其妙了,在體驗上很不友好。而本人在測試靈犀的藍牙功能時竟發現沒有提示音?為了完整的復制,必須把提示音去掉,然后我又上網搜了一遍,資料真的是鳳毛麟角,沒什么收獲。無奈中翻翻android關於藍牙部分的api,發現打開及關閉sco還有另外一種辦法,那就是android.bluetooth.BluetoothHeadset類的startVoiceRecognition(BluetoothDevice device)及stopVoiceRecognition(BluetoothDevice device),經過測試發現,通過這兩個方法打開sco及關閉sco藍牙耳機是不會有提示音,題外說一句:訊飛真會坑!!!下面列出關鍵代碼:

                //以下代碼用於在已經連接藍牙耳機的狀態下獲取BluetoothHeadset,監聽藍牙耳機的連接只需接收action=BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED的廣播即可,此處不再贅述。

private BluetoothHeadset bluetoothHeadset;

BluetoothProfile.ServiceListener blueHeadsetListener=new BluetoothProfile.ServiceListener() {

@Override
public void onServiceDisconnected(int profile) {
Log.i("blueHeadsetListener", "onServiceDisconnected:"+profile);
if(profile==BluetoothProfile.HEADSET){
bluetoothHeadset=null;
}
}

@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
Log.i("blueHeadsetListener", "onServiceConnected:"+profile);
if(profile==BluetoothProfile.HEADSET){
bluetoothHeadset=(BluetoothHeadset) proxy;
}
}
};

 

private void initBlueToothHeadset(){
         BluetoothAdapter adapter;
         if(android.os.Build.VERSION.SDK_INT<android.os.Build.VERSION_CODES.JELLY_BEAN_MR2){//android4.3之前直接用BluetoothAdapter.getDefaultAdapter()就能得到BluetoothAdapter
          adapter=BluetoothAdapter.getDefaultAdapter();
         }
         else{
          BluetoothManager bm=(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
          adapter=bm.getAdapter();
         }
         adapter.getProfileProxy(context, blueHeadsetListener, BluetoothProfile.HEADSET);
 }

 

        
       如果要通過藍牙耳機的sco鏈路輸出音頻,必須要在sco打開的狀態下,把streamType設置為AudioManager.STREAM_VOICE_CALL。
 
       最后有兩點要注意的:
     1.測試發現,當sco打開時,第1點中提到的藍牙耳機接聽鍵長按將不會發送android.intent.action.VOICE_COMMAND,必須在sco關閉時長按才會有這一事件。
     2.sco打開及關閉都是比較消耗時間的,特別是打開,大概是幾百毫秒-幾秒的時間,請注意要在sco徹底打開時再啟動語音識別,sco的狀態可以通過接收action=AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED的廣播監聽,或者使用BluetoothHeadset的isAudioConnected(BluetoothDevice device)判斷。測試發現BluetoothHeadset的相關方法打開sco比較快(個人感覺,不明真相,求大神科普)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM