android上使用藍牙設備進行語音輸入


主要實現步驟如下:
1.確保已經和藍牙耳機配對連接上。
2.開啟藍牙信道
AudioManager mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setBluetoothScoOn(true);
mAudioManager.startBluetoothSco();
3.開啟語音識別
4.退出時關閉藍牙信道
mAudioManager.setBluetoothScoOn(false);
mAudioManager.stopBluetoothSco();
5.額外需要添加的權限:
<uses-permission android:name="android.permission.BROADCAST_STICKY" />  注:部分手機如無此權限會報錯
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

以上方法到android5.0以上可能無用

提供另外一種方法

  1. package com.example.dkdh.testrecord;
  2. import android.app.Activity;
  3. import android.bluetooth.BluetoothAdapter;
  4. import android.bluetooth.BluetoothDevice;
  5. import android.bluetooth.BluetoothHeadset;
  6. import android.bluetooth.BluetoothProfile;
  7. import android.content.BroadcastReceiver;
  8. import android.content.Context;
  9. import android.content.Intent;
  10. import android.content.IntentFilter;
  11. import android.media.AudioManager;
  12. import android.media.MediaPlayer;
  13. import android.media.MediaRecorder;
  14. import android.os.Bundle;
  15. import android.os.Environment;
  16. import android.util.Log;
  17. import android.view.View;
  18. import android.widget.Button;
  19. import android.widget.TextView;
  20. import android.widget.Toast;
  21. import com.example.dkdh.testrecord.util.FucUtil;
  22. import com.example.dkdh.testrecord.util.JsonParser;
  23. import com.iflytek.cloud.InitListener;
  24. import com.iflytek.cloud.RecognizerListener;
  25. import com.iflytek.cloud.RecognizerResult;
  26. import com.iflytek.cloud.SpeechConstant;
  27. import com.iflytek.cloud.SpeechError;
  28. import com.iflytek.cloud.SpeechRecognizer;
  29. import com.iflytek.cloud.SpeechUtility;
  30. import com.iflytek.cloud.ErrorCode;
  31. import java.io.IOException;
  32. import java.util.HashMap;
  33. import java.util.LinkedHashMap;
  34. import java.util.List;
  35. public class MainActivity extends Activity implements View.OnClickListener{
  36.     private final String TAG = MainActivity.class.getSimpleName();
  37.     private final String XF_APP_ID = "xxxxxx";
  38.     BluetoothHeadset headset;
  39.     private Button start,stop;
  40.     private TextView result;
  41.     private AudioManager mAudioManager = null;
  42.     private BluetoothHeadset mBluetoothHeadset;
  43.     private BluetoothAdapter mBluetoothAdapter;
  44.     private BluetoothDevice mBluetoothDevice;
  45.     private SpeechRecognizer mIat;
  46.     //    // 語音聽寫UI
  47. //    private RecognizerDialog mIatDialog;
  48. //    // 用HashMap存儲聽寫結果
  49.     private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();
  50.     @Override
  51.     protected void onCreate(Bundle savedInstanceState) {
  52.         super.onCreate(savedInstanceState);
  53.         setContentView(R.layout.activity_main);
  54.         SpeechUtility.createUtility(this, SpeechConstant.APPID + "=" + XF_APP_ID);
  55.         result = (TextView)findViewById(R.id.result);
  56.         start = (Button)findViewById(R.id.startRec);
  57.         stop = (Button)findViewById(R.id.stopRec);
  58.         start.setOnClickListener(this);
  59.         stop.setOnClickListener(this);
  60.        
  61.         
  62.         mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
  63.         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  64.         mBluetoothAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET);
  65.         //        // 初始化識別無UI識別對象
  66. //        // 使用SpeechRecognizer對象,可根據回調消息自定義界面;第二個參數:本地識別時傳mInitListener
  67.         mIat = SpeechRecognizer.createRecognizer(this, mInitListener);
  68.     }
  69.     private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener(){
  70.         @Override
  71.         public void onServiceConnected(int profile, BluetoothProfile proxy) {
  72.             if (profile == BluetoothProfile.HEADSET){
  73.                 mBluetoothHeadset = (BluetoothHeadset) proxy;
  74.                 List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
  75.                 if (devices.size()>0){
  76.                     mBluetoothDevice = devices.get(0);
  77.                     int state = mBluetoothHeadset.getConnectionState(mBluetoothDevice);
  78.                     Log.e("==============","headset state:"+state);
  79.                     if (state==BluetoothHeadset.STATE_CONNECTED){
  80.                         Log.e("=================","bluetooth headset connected");
  81.                     }
  82.                 }
  83.             }
  84.         }
  85.         @Override
  86.         public void onServiceDisconnected(int profile) {
  87.             if (profile == BluetoothProfile.HEADSET){
  88.                 mBluetoothHeadset = null;
  89.             }
  90.         }
  91.     };
  92.     @Override
  93.     public void onClick(View v) {
  94.         switch (v.getId()){
  95.             case R.id.startRec:
  96.           startRecordWav();
  97.           break;
  98.             case R.id.stopRec:
  99.       stopRecordWav();
  100.      break;
  101.             default:
  102.      break;
  103.         }
  104.     }
  105.     /**
  106.      * 識別實時語音
  107.      */
  108.     private void recog(){
  109.         mIatResults.clear();
  110.         // 設置參數
  111.         setParam();
  112.         int ret = 0;
  113.             // 不顯示聽寫對話框
  114.             ret = mIat.startListening(mRecognizerListener);
  115.             if (ret != ErrorCode.SUCCESS) {
  116.                 showTip("聽寫失敗,錯誤碼:" + ret);
  117.             } else {
  118. //                showTip("");
  119.             }
  120.     }
  121.    
  122.     /**
  123.      * 初始化監聽器。
  124.      */
  125.     private InitListener mInitListener = new InitListener() {
  126.         @Override
  127.         public void onInit(int code) {
  128.             Log.i(TAG, "SpeechRecognizer init() code = " + code);
  129.             if (code != ErrorCode.SUCCESS) {
  130.                 showTip("初始化失敗,錯誤碼:" + code);
  131.             }
  132.         }
  133.     };
  134.     /**
  135.      * 聽寫監聽器。
  136.      */
  137.     private RecognizerListener mRecognizerListener = new RecognizerListener() {
  138.         @Override
  139.         public void onBeginOfSpeech() {
  140.             // 此回調表示:sdk內部錄音機已經准備好了,用戶可以開始語音輸入
  141.             showTip("開始說話");
  142.         }
  143.         @Override
  144.         public void onError(SpeechError error) {
  145.             // Tips:
  146.             // 錯誤碼:10118(您沒有說話),可能是錄音機權限被禁,需要提示用戶打開應用的錄音權限。
  147.             showTip(error.getPlainDescription(true));
  148. //            showTip("錯誤碼:10118(您沒有說話),可能是錄音機權限被禁,請打開應用的錄音權限。");
  149.         }
  150.         @Override
  151.         public void onEndOfSpeech() {
  152.             // 此回調表示:檢測到了語音的尾端點,已經進入識別過程,不再接受語音輸入
  153.             showTip("結束說話");
  154.         }
  155.         @Override
  156.         public void onResult(RecognizerResult results, boolean isLast) {
  157.             String text = JsonParser.parseIatResult(results.getResultString());
  158.             Log.i(TAG, text);
  159.             showTip(text);
  160.             if(isLast) {
  161.                 //TODO 最后的結果
  162.                 result.append(text);
  163.             }
  164.         }
  165.         @Override
  166.         public void onVolumeChanged(int volume, byte[] data) {
  167. //            showTip("當前正在說話,音量大小:" + volume);
  168.             Log.i(TAG,"當前正在說話,音量大小:" + volume);
  169.             Log.i(TAG, "返回音頻數據:" + data.length);
  170.         }
  171.         @Override
  172.         public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
  173.             // 以下代碼用於獲取與雲端的會話id,當業務出錯時將會話id提供給技術支持人員,可用於查詢會話日志,定位出錯原因
  174.             // 若使用本地能力,會話id為null
  175.             //        if (SpeechEvent.EVENT_SESSION_ID == eventType) {
  176.             //                String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
  177.             //                Log.d(TAG, "session id =" + sid);
  178.             //        }
  179.         }
  180.     };
  181.     /**
  182.      * Toast顯示提示
  183.      */
  184.     private void showTip(String str){
  185.         Toast.makeText(this,str,Toast.LENGTH_SHORT).show();
  186.     }
  187.     /**
  188.      * 參數設置
  189.      * @return
  190.      */
  191.     public void setParam(){
  192.         // 清空參數
  193.         mIat.setParameter(SpeechConstant.PARAMS, null);
  194.         // 設置引擎
  195.         mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
  196.         // 設置返回結果格式
  197.         mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
  198.         // 設置語言
  199.         mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
  200.         // 設置語言區域
  201.         mIat.setParameter(SpeechConstant.ACCENT,"mandarin");
  202.         // 設置語音前端點:靜音超時時間,即用戶多長時間不說話則當做超時處理
  203.         mIat.setParameter(SpeechConstant.VAD_BOS, "8000");
  204.         // 設置語音后端點:后端點靜音檢測時間,即用戶停止說話多長時間內即認為不再輸入, 自動停止錄音
  205.         mIat.setParameter(SpeechConstant.VAD_EOS, "1000");
  206.         // 設置標點符號,設置為"0"返回結果無標點,設置為"1"返回結果有標點
  207.         mIat.setParameter(SpeechConstant.ASR_PTT, "0");
  208.         // 設置音頻保存路徑,保存音頻格式支持pcm、wav,設置路徑為sd卡請注意WRITE_EXTERNAL_STORAGE權限
  209.         // 注:AUDIO_FORMAT參數語記需要更新版本才能生效
  210.         mIat.setParameter(SpeechConstant.AUDIO_FORMAT,"wav");
  211.         mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/iat.wav");
  212. //       設置錄音時長,單位ms
  213.         mIat.setParameter(SpeechConstant.KEY_SPEECH_TIMEOUT,"60000");
  214.         //設置音頻源,MIC、VOICE_RECOGNITION、VOICE_COMMUNICATION可用,但與不同android系統有關
  215.         mIat.setParameter(SpeechConstant.AUDIO_SOURCE, MediaRecorder.AudioSource.VOICE_COMMUNICATION+"");
  216.     }
  217.    
  218.     /**
  219.      * 停止錄音
  220.      */
  221.     private void stopRecordWav(){
  222.         Log.e(TAG, "停止錄音");
  223.         mBluetoothHeadset.stopVoiceRecognition(mBluetoothDevice);
  224.     }
  225.     /**
  226.      * 錄音,自主控制錄音格式、速率等
  227.      */
  228.     private void startRecordWav(final int source){
  229.         if (!mAudioManager.isBluetoothScoAvailableOffCall()) {
  230.             Log.d(TAG, "系統不支持藍牙錄音");
  231.             return;
  232.         }
  233.         if (mBluetoothHeadset == null){
  234.             Toast.makeText(this, "藍牙耳機對象null",Toast.LENGTH_SHORT).show();
  235.             return;
  236.         }
  237.         if (mBluetoothDevice!=null){
  238.             mBluetoothHeadset.startVoiceRecognition(mBluetoothDevice);
  239.         }
  240.         IntentFilter audioStateFilter = new IntentFilter();
  241.         audioStateFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
  242.         audioStateFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
  243.         registerReceiver(new BroadcastReceiver() {
  244.             @Override
  245.             public void onReceive(Context context, Intent intent) {
  246.                 String action = intent.getAction();
  247.                 if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)){
  248.                     int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,-1);
  249.                     if (state==BluetoothHeadset.STATE_AUDIO_CONNECTED){
  250.                         Log.e("==============","開始藍牙語音識別");
  251.                         recog();
  252.                         unregisterReceiver(this); // 別遺漏
  253.                     }
  254.                 }
  255.             }
  256.         },audioStateFilter);
  257.     }
  258.     @Override
  259.     protected void onResume(){
  260.         super.onResume();
  261.     }
  262. }


免責聲明!

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



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