android上使用藍牙設備進行語音輸入
阿新 • • 發佈:2018-01-15
view return 對話 nvi pat 顯示 you esc 註意
主要實現步驟如下:
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以上可能無用
提供另外一種方法
- package com.example.dkdh.testrecord;
- import android.app.Activity;
- import android.bluetooth.BluetoothAdapter;
- import android.bluetooth.BluetoothDevice;
- import android.bluetooth.BluetoothHeadset;
- import android.bluetooth.BluetoothProfile;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.media.AudioManager;
- import android.media.MediaPlayer;
- import android.media.MediaRecorder;
- import android.os.Bundle;
- import android.os.Environment;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
- import android.widget.TextView;
- import android.widget.Toast;
- import com.example.dkdh.testrecord.util.FucUtil;
- import com.example.dkdh.testrecord.util.JsonParser;
- import com.iflytek.cloud.InitListener;
- import com.iflytek.cloud.RecognizerListener;
- import com.iflytek.cloud.RecognizerResult;
- import com.iflytek.cloud.SpeechConstant;
- import com.iflytek.cloud.SpeechError;
- import com.iflytek.cloud.SpeechRecognizer;
- import com.iflytek.cloud.SpeechUtility;
- import com.iflytek.cloud.ErrorCode;
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.LinkedHashMap;
- import java.util.List;
- public class MainActivity extends Activity implements View.OnClickListener{
- private final String TAG = MainActivity.class.getSimpleName();
- private final String XF_APP_ID = "xxxxxx";
- BluetoothHeadset headset;
- private Button start,stop;
- private TextView result;
- private AudioManager mAudioManager = null;
- private BluetoothHeadset mBluetoothHeadset;
- private BluetoothAdapter mBluetoothAdapter;
- private BluetoothDevice mBluetoothDevice;
- private SpeechRecognizer mIat;
- // // 語音聽寫UI
- // private RecognizerDialog mIatDialog;
- // // 用HashMap存儲聽寫結果
- private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- SpeechUtility.createUtility(this, SpeechConstant.APPID + "=" + XF_APP_ID);
- result = (TextView)findViewById(R.id.result);
- start = (Button)findViewById(R.id.startRec);
- stop = (Button)findViewById(R.id.stopRec);
- start.setOnClickListener(this);
- stop.setOnClickListener(this);
- mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
- mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- mBluetoothAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET);
- // // 初始化識別無UI識別對象
- // // 使用SpeechRecognizer對象,可根據回調消息自定義界面;第二個參數:本地識別時傳mInitListener
- mIat = SpeechRecognizer.createRecognizer(this, mInitListener);
- }
- private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener(){
- @Override
- public void onServiceConnected(int profile, BluetoothProfile proxy) {
- if (profile == BluetoothProfile.HEADSET){
- mBluetoothHeadset = (BluetoothHeadset) proxy;
- List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
- if (devices.size()>0){
- mBluetoothDevice = devices.get(0);
- int state = mBluetoothHeadset.getConnectionState(mBluetoothDevice);
- Log.e("==============","headset state:"+state);
- if (state==BluetoothHeadset.STATE_CONNECTED){
- Log.e("=================","bluetooth headset connected");
- }
- }
- }
- }
- @Override
- public void onServiceDisconnected(int profile) {
- if (profile == BluetoothProfile.HEADSET){
- mBluetoothHeadset = null;
- }
- }
- };
- @Override
- public void onClick(View v) {
- switch (v.getId()){
- case R.id.startRec:
- startRecordWav();
- break;
- case R.id.stopRec:
- stopRecordWav();
- break;
- default:
- break;
- }
- }
- /**
- * 識別實時語音
- */
- private void recog(){
- mIatResults.clear();
- // 設置參數
- setParam();
- int ret = 0;
- // 不顯示聽寫對話框
- ret = mIat.startListening(mRecognizerListener);
- if (ret != ErrorCode.SUCCESS) {
- showTip("聽寫失敗,錯誤碼:" + ret);
- } else {
- // showTip("");
- }
- }
- /**
- * 初始化監聽器。
- */
- private InitListener mInitListener = new InitListener() {
- @Override
- public void onInit(int code) {
- Log.i(TAG, "SpeechRecognizer init() code = " + code);
- if (code != ErrorCode.SUCCESS) {
- showTip("初始化失敗,錯誤碼:" + code);
- }
- }
- };
- /**
- * 聽寫監聽器。
- */
- private RecognizerListener mRecognizerListener = new RecognizerListener() {
- @Override
- public void onBeginOfSpeech() {
- // 此回調表示:sdk內部錄音機已經準備好了,用戶可以開始語音輸入
- showTip("開始說話");
- }
- @Override
- public void onError(SpeechError error) {
- // Tips:
- // 錯誤碼:10118(您沒有說話),可能是錄音機權限被禁,需要提示用戶打開應用的錄音權限。
- showTip(error.getPlainDescription(true));
- // showTip("錯誤碼:10118(您沒有說話),可能是錄音機權限被禁,請打開應用的錄音權限。");
- }
- @Override
- public void onEndOfSpeech() {
- // 此回調表示:檢測到了語音的尾端點,已經進入識別過程,不再接受語音輸入
- showTip("結束說話");
- }
- @Override
- public void onResult(RecognizerResult results, boolean isLast) {
- String text = JsonParser.parseIatResult(results.getResultString());
- Log.i(TAG, text);
- showTip(text);
- if(isLast) {
- //TODO 最後的結果
- result.append(text);
- }
- }
- @Override
- public void onVolumeChanged(int volume, byte[] data) {
- // showTip("當前正在說話,音量大小:" + volume);
- Log.i(TAG,"當前正在說話,音量大小:" + volume);
- Log.i(TAG, "返回音頻數據:" + data.length);
- }
- @Override
- public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
- // 以下代碼用於獲取與雲端的會話id,當業務出錯時將會話id提供給技術支持人員,可用於查詢會話日誌,定位出錯原因
- // 若使用本地能力,會話id為null
- // if (SpeechEvent.EVENT_SESSION_ID == eventType) {
- // String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
- // Log.d(TAG, "session id =" + sid);
- // }
- }
- };
- /**
- * Toast顯示提示
- */
- private void showTip(String str){
- Toast.makeText(this,str,Toast.LENGTH_SHORT).show();
- }
- /**
- * 參數設置
- * @return
- */
- public void setParam(){
- // 清空參數
- mIat.setParameter(SpeechConstant.PARAMS, null);
- // 設置引擎
- mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
- // 設置返回結果格式
- mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
- // 設置語言
- mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
- // 設置語言區域
- mIat.setParameter(SpeechConstant.ACCENT,"mandarin");
- // 設置語音前端點:靜音超時時間,即用戶多長時間不說話則當做超時處理
- mIat.setParameter(SpeechConstant.VAD_BOS, "8000");
- // 設置語音後端點:後端點靜音檢測時間,即用戶停止說話多長時間內即認為不再輸入, 自動停止錄音
- mIat.setParameter(SpeechConstant.VAD_EOS, "1000");
- // 設置標點符號,設置為"0"返回結果無標點,設置為"1"返回結果有標點
- mIat.setParameter(SpeechConstant.ASR_PTT, "0");
- // 設置音頻保存路徑,保存音頻格式支持pcm、wav,設置路徑為sd卡請註意WRITE_EXTERNAL_STORAGE權限
- // 註:AUDIO_FORMAT參數語記需要更新版本才能生效
- mIat.setParameter(SpeechConstant.AUDIO_FORMAT,"wav");
- mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/iat.wav");
- // 設置錄音時長,單位ms
- mIat.setParameter(SpeechConstant.KEY_SPEECH_TIMEOUT,"60000");
- //設置音頻源,MIC、VOICE_RECOGNITION、VOICE_COMMUNICATION可用,但與不同android系統有關
- mIat.setParameter(SpeechConstant.AUDIO_SOURCE, MediaRecorder.AudioSource.VOICE_COMMUNICATION+"");
- }
- /**
- * 停止錄音
- */
- private void stopRecordWav(){
- Log.e(TAG, "停止錄音");
- mBluetoothHeadset.stopVoiceRecognition(mBluetoothDevice);
- }
- /**
- * 錄音,自主控制錄音格式、速率等
- */
- private void startRecordWav(final int source){
- if (!mAudioManager.isBluetoothScoAvailableOffCall()) {
- Log.d(TAG, "系統不支持藍牙錄音");
- return;
- }
- if (mBluetoothHeadset == null){
- Toast.makeText(this, "藍牙耳機對象null",Toast.LENGTH_SHORT).show();
- return;
- }
- if (mBluetoothDevice!=null){
- mBluetoothHeadset.startVoiceRecognition(mBluetoothDevice);
- }
- IntentFilter audioStateFilter = new IntentFilter();
- audioStateFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
- audioStateFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
- registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)){
- int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,-1);
- if (state==BluetoothHeadset.STATE_AUDIO_CONNECTED){
- Log.e("==============","開始藍牙語音識別");
- recog();
- unregisterReceiver(this); // 別遺漏
- }
- }
- }
- },audioStateFilter);
- }
- @Override
- protected void onResume(){
- super.onResume();
- }
- }
android上使用藍牙設備進行語音輸入