作者:辛集小怪兽_603 | 来源:互联网 | 2023-09-23 16:28
引言由于为期半年的项目结束了,进入了一段“疗养”的真空期,因此有时间可以去归纳整理项目的经验,学习新的姿势与技巧,对自己技术水平也是一种提升。另外,个人懒癌症严重,为强迫自己努力学习,立了
引言
由于为期半年的项目结束了,进入了一段“疗养”的真空期,因此有时间可以去归纳整理项目的经验,学习新的姿势与技巧,对自己技术水平也是一种提升。另外,个人懒癌症严重,为强迫自己努力学习,立了一些福来阁(比如没有写出博客女装什么的咳咳,我一定会拔旗成功的,哼),总体来说督促效果还是挺不错的。
项目中使用的Android和linux进行客户端的开发,结合项目的实战经验,七月份写的博客内容主要围绕Android开发进行,研究的内容预定为:Android中谷歌语音搜索功能探究(开篇),app应用意外关闭后MediaPlayer进行断点播放(预计两到三章左右)
为何选择Android谷歌语音搜索作为第一篇正式的博文?第一实现功能较为简单,代码量很小,可以为后续的文章热热身;第二语音搜索这个功能强大的,尤其是谷歌作为IT巨头,语音搜索体感非常棒,识别快而精准。谷歌的语音搜索可以广泛应用与基于LBS的Android应用程序中,调用谷歌api获取搜索结果,然后根据这个结果做自己想要的功能。
言归正传,下面开始正式介绍谷歌的语音搜索。
谷歌语音搜索基础
语音识别是Google在API Level3,也就是SDK1.5中引入的。根据官方的SDK的资料,语音检索的模式行为(action)有4种:
ACTION_GET_LANGUAGE_DETAILS ---> API Level8引入
ACTION_RECOGNIZE_SPEECH ---> API Level3引入
ACTION_VOICE_SEARCH_HANDS_FREE ---> API Level16引入
ACTION_WEB_SEARCH ---> API Level3引入
大致的功能为:
ACTION_GET_LANGUAGE_DETAILS:一个广播性质的intent,用于获取meta-data, 不常用。
ACTION_RECOGNIZE_SPEECH:起一个activity将用户所说的内容发送至语音识别器,结果将会从onActivityResult中返回。(注: 官方不再支持startActivity的方式起intent, 改为startActivityResult)。该部分是核心功能。
ACTION_VOICE_SEARCH_HANDS_FREE:API16中新引入的功能,不常用,目的是让用户在不使用客户端的情况下也能进行语音搜索,例如处于锁屏的安全模式中。如果要想使用该模式必须在manifest中加入如下:
1 <action android:name="android.speech.action.VOICE_SEARCH_HANDS_FREE" />
ACTION_WEB_SEARCH:通过Web网络检索来实现。
自定义设置项(Option)主要有以下3个:
EXTRA_LANGUAGE_MODEL:语音识别的语言设置
EXTRA_PROMPT: 语音输入时显示的提示文字
EXTRA_MAX_RESULTS: 语音搜索结果最大值设定
此外需要注意一点,在没有谷歌服务的地区是不能进行谷歌语音服务的,括弧笑。而且手机不支持语音搜索的话,本地需要预先安装一个语音包:Voice_Search_2.1.4.apk, 这个版本非常老,2011年出的一直没有更新,原生态的皮肤令人怀念。如果没有在google-market中下载到,可以到如下网址下载:
http://www.coolapk.com/apk/com.google.android.voicesearch
谷歌语音搜索的实现
实现的方法可以概括为以下四步:
1 起一个名为RecognizerIntent的Intent活动
2 putExtra中填入语音搜索的常量设定
3 startActivityResult
4 onActivityResult等待搜索结果。
核心代码示例:
添加一个RadiaGroup, 设置3种常用的语音搜索模式。
<RadioGroup
android:id="@+id/search_group"
android:orientation="vertical"
android:layout_marginLeft="90dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton
android:checked="true"
android:text="ACTION_RECOGNIZE_SPEECH"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<RadioButton
android:text="ACTION_WEB_SEARCH"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<RadioButton
android:text="ACTION_VOICE_SEARCH_HANDS_FREE"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
RadioGroup>
在MainActivity中获取RadioGroup所选的内容,代码如下
1 private String getRecognizerMode() {
2
3 for (int i=0; i) {
4
5 RadioButton btn = (RadioButton) radioBtn.getChildAt(i);
6
7 if (btn.isChecked()) {
8
9 if (btn.getText().equals(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)) {
10
11 return RecognizerIntent.ACTION_RECOGNIZE_SPEECH;
12
13 } else if (btn.getText().equals(RecognizerIntent.ACTION_WEB_SEARCH)) {
14
15 return RecognizerIntent.ACTION_WEB_SEARCH;
16
17 } else if (btn.getText().equals(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE)) {
18
19 return RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE;
20
21 }
22
23 else {
24
25 return null;
26
27 }
28
29 }
30
31 }
32
33 return null;
34
35 }
然后是点击语音按钮后,执行startVoiceRecognition这个方法起intent操作
1 private void startVoiceRecognition(String mode) {
2
3 try {
4
5 Intent intent = new Intent(mode);
6
7 intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
8
9 RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
10
11 intent.putExtra(RecognizerIntent.EXTRA_PROMPT, R.string.voice_begin);
12
13 intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "zh-HK");
14
15 startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
16
17 } catch (Exception e) {
18
19 e.printStackTrace();
20
21 Toast.makeText(this, "No Google Voice app, plz download.", Toast.LENGTH_SHORT).show();
22
23 }
24
25 }
在测试中发现,语音搜索所识别的内容依赖于机器的系统环境,如果是中文系统识别出的是中文的搜索内容,如果是日文系统的则是日文的搜索内容。RecognizerIntent.EXTRA_LANGUAGE这个属性似乎没有什么乱用。
最后是onActivityResult回调结果部分
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("lsy", "onActivityResult --> requestCode: " + requestCode + " resultCode: " + resultCode);
if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {
ArrayList results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
if (results.size() > 0) {
String result = results.get(0).toString().trim();
if (null != result && result.length() > 0) {
searchResult.setText(result);
// 获取所有检索结果
// for (String str : results) {
// searchResult.append(str + "/n");
// }
} else {
Toast.makeText(this, "Voice Content Fail", Toast.LENGTH_SHORT).show();
}
} else {
Log.d("lsy", "onActivityResult --> Voice Content Fail");
Toast.makeText(this, "Voice Content Fail", Toast.LENGTH_SHORT).show();
}
}
}
所有搜索的结果保存在一个ArrayList的列表中,第一个数据是匹配值最高,代码中因为需要拿最匹配的值去做地图搜索才会选择第一个数据。注释部分可以打印出所有满足搜索条件的值。
总结
谷歌的语音搜索可以帮助我们实现在LBS类应用中进行语音定位,其搜索精度高,速度快,只是不可描述的存在限制了这个好用的功能,很是可惜。后续基于谷歌语音开发的内容可以包括:历史语音搜索记录、语音联想功能、与自主开发导航软件的协同工作等,由于时间仓促没有来的及实现,有兴趣的朋友可以实验下。
本文对网上关于谷歌语音搜索的文章进行总结和部分拓展,做了点微小的贡献,甚是惭愧。
参考博文
http://blog.csdn.net/h7870181/article/details/11151773
http://blog.csdn.net/gumanren/article/details/6771265