开篇先吐槽下,在Android 平台开发原生的SpeechRecognizer真是难受的,不像ios,无比轻松,平台统一。 由于Android 平台的碎片化问题比较严重,各个厂商都有自己的实现,尤其是语音助手出来以后,每家的语音服务肯定是不一样的。
目前Android原生的SpeechRecognizer做法应该有两种
- 默认调用原生SpeechRecognizer,并稍作修改
- 调用第三方,科大讯飞,百度等
这两种做法中
- 1. 在Google原生系统是可以的,但是在国内的环境是需要修改,修改后能保证各个机型基本可以用,至于识别效果就要看各个机型自己实现的怎么样了
- 2. 最简单省心省力,如果你的项目可以这么做,那么兄弟恭喜你,你是最幸福的
这里我们不讲第三方的,大家可以自己去集成第三方sdk,主要讨论原生的开发
首先权限不要忘记(记得6.0以后动态请求权限)
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
复制代码
在SpeechRecognizer.class有这样SpeechRecognizer .isRecognitionAvailable一个方法
/**
* Checks whether a speech recognition service is available on the system. If this method
* returns {
@code false}, {
@link SpeechRecognizer#createSpeechRecognizer(Context)} will
* fail.
*
* @param context with which {
@code SpeechRecognizer} will be created
* @return {
@code true} if recognition is available, {
@code false} otherwise
*/
public static boolean isRecognitionAvailable(final Context context) {
final List<ResolveInfo> list = context.getPackageManager().queryIntentServices(
new Intent(RecognitionService.SERVICE_INTERFACE), 0);
return list != null && list.size() != 0;
}
复制代码
该方法在使用语音识别前建议要调用下,该方法是检查当前系统有没有语音识别服务,我相信绝大多数厂商都有这个服务,但是都有自己特别的实现,但是它至少有,有就可以用。但是,你像oppo的7.0以后机器,这个方法调用后就是false,这时候就是毫无办法了。oppo 7.0以后就是这样调用完后返回false,对于 oppo 这种情况,可以在手机上装一个**讯飞语音+**的app,语音识别就可以了,但是这种方法我估计没人会用,用户体验太差。
如果该方法返回false在我们调用*SpeechRecognizer.startListening();*方法的时候会日志中发现这行log
no selected voice recognition service
复制代码
该日志在SpeechRecognizer.startListening(final Intent recognizerIntent)方法中,大家可以进源码查看这里就不贴了。
检查完如果语音识别可用,接下来有两种做法我们一个个来
- 直接创建实例启动服务
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(context);
mSpeechRecognizer.setRecognitionListener(this);
复制代码
创建识别实例,并添加监听,这里没有什么问题,在监听中我们可以拿到我们的想要的回调
/**
* Used for receiving notifications from the SpeechRecognizer when the
* recognition related events occur. All the callbacks are executed on the
* Application main thread.
* 值的注意的是,所有的回调都在主线程
*/
public interface RecognitionListener {
// 实例准备就绪
void onReadyForSpeech(Bundle params);