需求:
最近需要在项目中需要集成各家的语音识别功能。包括讯飞,Alexa以及google的语音。前面两家的都有对应的api,集成到对应的项目中比较简单,这里只介绍如果集成Google的语音在项目上,像Google Assistant一样。因为google并没有公开的语音识别的api,网上许多文章上也有对google语音接口api的分析,但是现在都不好用了,不是限制了使用次数,就是要收费。这里先简单介绍下网上的方法和Google现在公开提供的收费语音识别。
1.网上方法
参考这篇文章:http://blog.laobubu.net/archivers/google-speech-api-pt2
2.Goole提供的收费接口:
参考官方文档:https://cloud.google.com/speech/(自备梯子)
需要Google账号,前60分钟免费,之后要收钱,而且必须要绑定信用卡。。
项目介绍:
Google有一个项目叫Voice Search,这个是官方的,不收费的项目,但是这个项目不是开源的,我们利用这个项目的源代码jar包来集成Google的语音。废话不多说,直接集成。
首先新建AS项目,。我们将voice_searc.jar包导入到lib下,将所需的资源文件全部拷到res对应目录下,将manifest文件对应的全部复制(jar包和资源文件最后在我的github上自行下载),这时候注意,这个jar包就是项目Voice Search所有的源代码,用过Voice search的人应该都知道,当时唤醒Voice Search说话的时候,会有一个弹框:
我们都知道jar包中不能存放资源文件,但是我们集成语音又必须用到里面的类,这个时候,如果是在eclipse上开发的话,比较简单,eclipse里面有个叫工程依赖的概念,可以将资源文件放在外部,利用固定id,直接引用。但是Android Studio上不行,因为即使固定了id,AS会在编译期间为每个资源重新生成资源id,导致报错,资源找不到)。
解决:在app同级目录下建一个public-xml.gradle配置文件,内容如下:
- afterEvaluate {
- for (variant in android.applicationVariants) {
- def scope = variant.getVariantData().getScope()
- String mergeTaskName = scope.getMergeResourcesTask().name
- def mergeTask = tasks.getByName(mergeTaskName)
- mergeTask.doLast {
- copy {
- int i=0
- from(android.sourceSets.main.res.srcDirs) {
- include 'values/public.xml'
- rename 'public.xml', (i++ == 0? "public.xml": "public_${i}.xml")
- }
- into(mergeTask.outputDir)
- }
- }
- }
- }
然后再app的gradle的开头添加:
- apply from: 'public-xml.gradle'
rebuild即可。
使用:
jar包和资源文件准备好之后,就是使用:
public class MainActivity extends AppCompatActivity {
private RecognitionController mController;
private RecognitionListener mCallback;
private VoiceSearchLogger mLogger;
private Button start, stop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.start_btn);
stop = (Button) findViewById(R.id.stop_btn);
VoiceSearchContainer localVoiceSearchContainer = VoiceSearchApplication.getContainer(this);
this.mController = localVoiceSearchContainer.createRecognitionController();
GservicesHelper mGservicesHelper = localVoiceSearchContainer.getGservicesHelper();
this.mCallback = new VoiceSearchRecognitionListener();
this.mLogger = localVoiceSearchContainer.getVoiceSearchLogger();
final Intent mIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mIntent.putExtra("fullRecognitionResultsRequest", true);
mIntent.putExtra("calling_package", "android");
mIntent.putExtra("contact_auth", true);
mIntent.putExtra("useLocation", true);
mIntent.putExtra("ptt", 0);
mIntent.putExtra("android.speech.extras.SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS", mGservicesHelper.getEndpointerCompleteSilenceMillis());
mIntent.putExtra("android.speech.extras.SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS", mGservicesHelper.getEndpointerPossiblyCompleteSilenceMillis());
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mController.onStartListening(mIntent, mCallback);
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mController.onStopListening(mCallback);
}
});
}
private class VoiceSearchRecognitionListener implements RecognitionListener {
private VoiceSearchRecognitionListener() {
}
public void onBeginningOfSpeech() {
Log.i("xyz", "---------->onBeginningOfSpeech");
}
public void onBufferReceived(byte[] paramArrayOfByte) {
}
public void onEndOfSpeech() {
Log.i("xyz", "---------->onEndOfSpeech");
}
public void onError(int paramInt) {
Log.i("xyz", "---------->onError:" + paramInt);
}
public void onEvent(int paramInt, Bundle paramBundle) {
}
public void onPartialResults(Bundle paramBundle) {
Log.i("xyz", "---------->onPartialResults");
Log.i("xyz", "onPartialResults:" + paramBundle.toString());
}
public void onReadyForSpeech(Bundle paramBundle) {
Log.i("xyz", "---------->onReadyForSpeech");
}
public void onResults(Bundle paramBundle) {
Log.i("xyz", "---------->onResults");
Log.i("xyz", "onResults:" + paramBundle.toString());
ArrayList<VoiceAction> localArrayList = paramBundle.getParcelableArrayList("fullRecognitionResults");
if (localArrayList != null && localArrayList.size() > 0) {
String str = localArrayList.get(0).toString();
Log.i("xyz", "-------------->result:" + str);
}else {
Log.i("xyz", "-------------->result:null");
}
}
public void onRmsChanged(float paramFloat) {
Log.i("xyz", "---------->onRmsChanged:" + paramFloat);
}
}
}
要注意的细节就是:参考我github的项目的资源文件夹以及lib包下的jar包和.so文件(如果出现为找到对应的.so文件,自己添加对应cpu架构的包,然后将libvoicesearch.so复制进去即可)一一复制,不能少不能改;manifest里面的内容也是。最后别忘了要在app的同级目录下新建gradle配置文件。
demo源码:https://github.com/CCCCoder/GoogleSpeech