zoukankan      html  css  js  c++  java
  • 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. }
  • 相关阅读:
    rocketmq 修改broker和namesrv默认设置的堆内存大小
    linux 向文件中添加内容 sed
    页面 请求错误总结
    将pgsql中的所有表的序列当前值设置为所需的值
    pg 强制断开连接 删库
    测试的基本概念
    Linking(3)
    Linking(1)
    Linking(2)
    Nginx Learning (5)
  • 原文地址:https://www.cnblogs.com/dongweiq/p/8288336.html
Copyright © 2011-2022 走看看