看起来谷歌已经使第三方应用程序可以使用Google Now的离线语音识别功能。 名称为Utter的应用程序正在使用它。
是否有人看到如何使用这个离线语音识别做简单语音命令的实现?您是否只是使用常规SpeechRecognizer API,然后它会自动工作?
看起来谷歌已经使第三方应用程序可以使用Google Now的离线语音识别功能。 名称为Utter的应用程序正在使用它。
是否有人看到如何使用这个离线语音识别做简单语音命令的实现?您是否只是使用常规SpeechRecognizer API,然后它会自动工作?
谷歌在那次搜索更新中悄悄启用了离线识别,但是(目前)SpeechRecognizer类中没有可用的API或额外的参数。请参见本帖子底部的编辑然而,该功能可以不需要额外的编码即可使用,但是用户的设备需要正确配置才能开始工作,这就是问题所在,我想这也是很多开发人员认为他们“缺少某些东西”的原因。
此外,由于硬件限制,谷歌已经限制了某些果冻豆设备使用离线识别。具体适用于哪些设备并未记录在案,实际上,没有任何文件记录,因此为用户配置功能已被证明是一种试错(对他们来说)。对于一些人来说,它可以立刻起作用-对于那些不能的人,这就是我提供给他们的“指南”。
编辑:暂时将设备区域设置为英国英语似乎也会启动此功能。
一些用户报告说,他们仍然需要重启多次才能开始工作,但他们最终都会成功,通常不清楚触发器是什么,关键在于Google Search APK中,因此不公开或不属于AOSP的一部分。通过在离线时使用onPartialResults,在在线时使用onResults,我成功地实现了具有离线功能的语音服务。
显然,可以通过直接下载文件并在正确的位置手动安装离线语音识别来绕过Google硬件要求。然而,个人经验是,我不需要重新启动或执行其他操作,只需将语言设置更改为英式英语,然后再改回即可。
MyService.class
public class MyService extends Service implements SpeechDelegate, Speech.stopDueToDelay {
public static SpeechDelegate delegate;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
try {
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
((AudioManager) Objects.requireNonNull(
getSystemService(Context.AUDIO_SERVICE))).setStreamMute(AudioManager.STREAM_SYSTEM, true);
}
} catch (Exception e) {
e.printStackTrace();
}
Speech.init(this);
delegate = this;
Speech.getInstance().setListener(this);
if (Speech.getInstance().isListening()) {
Speech.getInstance().stopListening();
} else {
System.setProperty("rx.unsafe-disable", "True");
RxPermissions.getInstance(this).request(permission.RECORD_AUDIO).subscribe(granted -> {
if (granted) { // Always true pre-M
try {
Speech.getInstance().stopTextToSpeech();
Speech.getInstance().startListening(null, this);
} catch (SpeechRecognitionNotAvailable exc) {
//showSpeechNotSupportedDialog();
} catch (GoogleVoiceTypingDisabledException exc) {
//showEnableGoogleVoiceTyping();
}
} else {
Toast.makeText(this, R.string.permission_required, Toast.LENGTH_LONG).show();
}
});
}
return Service.START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
@Override
public void onStartOfSpeech() {
}
@Override
public void onSpeechRmsChanged(float value) {
}
@Override
public void onSpeechPartialResults(List<String> results) {
for (String partial : results) {
Log.d("Result", partial+"");
}
}
@Override
public void onSpeechResult(String result) {
Log.d("Result", result+"");
if (!TextUtils.isEmpty(result)) {
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onSpecifiedCommandPronounced(String event) {
try {
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
((AudioManager) Objects.requireNonNull(
getSystemService(Context.AUDIO_SERVICE))).setStreamMute(AudioManager.STREAM_SYSTEM, true);
}
} catch (Exception e) {
e.printStackTrace();
}
if (Speech.getInstance().isListening()) {
Speech.getInstance().stopListening();
} else {
RxPermissions.getInstance(this).request(permission.RECORD_AUDIO).subscribe(granted -> {
if (granted) { // Always true pre-M
try {
Speech.getInstance().stopTextToSpeech();
Speech.getInstance().startListening(null, this);
} catch (SpeechRecognitionNotAvailable exc) {
//showSpeechNotSupportedDialog();
} catch (GoogleVoiceTypingDisabledException exc) {
//showEnableGoogleVoiceTyping();
}
} else {
Toast.makeText(this, R.string.permission_required, Toast.LENGTH_LONG).show();
}
});
}
}
@Override
public void onTaskRemoved(Intent rootIntent) {
//Restarting the service if it is removed.
PendingIntent service =
PendingIntent.getService(getApplicationContext(), new Random().nextInt(),
new Intent(getApplicationContext(), MyService.class), PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
assert alarmManager != null;
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
super.onTaskRemoved(rootIntent);
}
}
更多细节,请参阅。
希望这能对未来的某个人有所帮助。