需求:
最近需要在项目中需要集成各家的语音识别功能。包括讯飞,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项目,怎么建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); } } }