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);
}
android蓝牙耳机下的语音(输入/识别)及按键监听的更多相关文章
- Android TV开发中所有的遥控器按键监听及注意事项,新增home键监听
原文:Android TV开发中所有的遥控器按键监听及注意事项,新增home键监听 简单记录下android 盒子开发遥控器的监听 ,希望能帮到新入门的朋友们 不多说,直接贴代码 public cla ...
- Android OkHttp文件上传与下载的进度监听扩展
http://www.loongwind.com/archives/290.html 上一篇文章介绍了用Retrofit实现文件的上传与下载,但是我们发现没办法监听上传下载的进度,毕竟我们在做开发的时 ...
- 关于android软键盘enter键的替换与事件监听
android软键盘事件监听enter键 软件盘的界面替换只有一个属性android:imeOptions,这个属性的可以取的值有 normal,actionUnspecified,actionNo ...
- Android开发笔记(11)——DialogFragment & 点击监听
转载请注明:http://www.cnblogs.com/igoslly/p/6931519.html DialogFragment使用 & 点击监听 /* DialogFragment是用于 ...
- Android蓝牙线控切歌、连接状态监听(无线耳机也适用)
1. 监听蓝牙设备(音频)连接状态 所有代码已测试在Android11也能正常使用 (Android SDK 30) 首先新建一个广播类 BluetoothStateReceiver /** * @a ...
- linux下如何开启oracle服务和开启监听
su - oracle 切换到oracle用户模式下 sqlplus /nolog //登录sqlplus SQL> connect /as sysdba //连接oracle SQL&g ...
- linux下oracle11g R2的启动与关闭监听、数据库
su - oracle 切换到oracle账户 lsnrctl start 启动监听 sqlplus /nolog 登陆sqlplus conn /as ...
- Android ListView 之 SimpleAdapter 二 (包含 item 中按钮监听)
1 MainActivity.java package com.myadapter; import java.util.ArrayList; import java.util.HashMap; ...
- android脚步---UI界面修改,增加按钮和监听
我的UU界面,其布局如下: 需要修改的部分: 意见反馈居中,还有增加backbutton 首先在mainactivity中找到我的UU的定义:dialogue public void showAbou ...
随机推荐
- 深入解读Quartz的原理
Quartz是一个大名鼎鼎的Java版开源定时调度器,功能强悍,使用方便. 一.核心概念 Quartz的原理不是很复杂,只要搞明白几个概念,然后知道如何去启动和关闭一个调度程序即可. 1 ...
- ubuntu修改用户名并修改home对应的目录名
1.新建一个新的用户user2 sudo adduser temporary sudo adduser temporary sudo 2.从user1 logout.进入新建用户user2,修改use ...
- 洛谷SP16549 QTREE6 - Query on a tree VI(LCT)
洛谷题目传送门 思路分析 题意就是要维护同色连通块大小.要用LCT维护子树大小就不说了,可以看看蒟蒻的LCT总结. 至于连通块如何维护,首先肯定可以想到一个很naive的做法:直接维护同色连通块,每次 ...
- 【题解】 bzoj1923: [Sdoi2010]外星千足虫 (线性基/高斯消元)
bzoj1923,戳我戳我 Solution: 这个高斯消元/线性基很好看出来,主要是判断在第K 次统计结束后就可以确定唯一解的地方和\(bitset\)的骚操作 (我用的线性基)判断位置,我们可以每 ...
- 51nod1134——(最长上升子序列)
给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递增的) 例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10. Input 第1行:1个 ...
- 未处理的异常 stack overflow
今天在编译程序时遇到“0x00e304f7 处有未经处理的异常: 0xC00000FD: Stack overflow”的错误,也就是栈溢出了,google了一下,原来是我申请的一个变量太大了,con ...
- 在Linux中以普通用户开机自动运行脚本程序
测试环境:CentOS6.5 管理员:root 普通用户:test1 实现目标:在Linux启动时,以普通用户test1自动运行位于根目录下的脚本程序test.py,该程序会在每次执行时自动向本地日志 ...
- vmware:Could not open /dev/vmmon: No such file or directory.
Q: Could not open /dev/vmmon: No such file or directory. Please make sure that the kernel module `vm ...
- VMware Workstation 12序列号:
VMware Workstation 12序列号: 5A02H-AU243-TZJ49-GTC7K-3C61N
- 异步消息处理机制Handler
Android 中的异步消息处理主要由四个部分组成,Message.Handler.MessageQueue 和Looper. 1. Message Message 是在线程之间传递的消息,它可以在内 ...