基于Android TTS服务开发智能助手

简介:

简介

本文中将向你展示一个基本的Android应用程序,此程序能够聆听用户的声音并把它转换为文本数据。而且,此程序还能够进行文本分析,然后执行相应的命令来实现数据存储及用户应答功能。

注意,本文源码工程下载地址是:https://github.com/sitepoint-editors/SpeechApplication。

程序快照如下:

创建应用程序

打开Android Studio创建一个新的项目,选择最小版本的Android API 18并添加一个空的Activity。这也是本项目中唯一的一个Activity。

为了实现视图的全屏显示,打开配置文件AndroidManifest.xml,并设置如下:


  
  
  1. android:theme="@style/Theme.AppCompat.NoActionBar" 

这个配置将使我们当前的活动(Activity)中隐藏ActionBar的显示。

到此,你已经拥有一个全屏式的白色背景色布局的视图,其中仅有一个TextView控件。为了作一些改进,你可以把一个渐变形状添加到RelativeLayout上。

接下来,右击drawable文件夹并选择New->Drawable resource file。命名这个资源文件为background,并使用如下代码替换原来的内容:


  
  
  1. <?xml version="1.0" encoding="UTF-8"?> 
  2.  
  3. <shape xmlns:android="http://schemas.android.com/apk/res/android" 
  4.  
  5. android:shape="rectangle" > 
  6.  
  7. <gradient 
  8.  
  9. android:type="linear" 
  10.  
  11. android:startColor="#FF85FBFF" 
  12.  
  13. android:endColor="#FF008080" 
  14.  
  15. android:angle="45"/> 
  16.  
  17. </shape> 

实际上,你可以根据自己的喜欢任意地修改颜色与角度。

注意:布局中的ImageButton控件使用了一个来自于https://design.google.com/icons/#ic_mic_none网站提供的图像。你可以下载并把它以资源方式添加使用。

接下来,更新文件activity_main.xml中的代码:


  
  
  1. <?xml version="1.0" encoding="utf-8"?> 
  2.  
  3. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android" 
  4.  
  5. xmlns:tools="http://schemas.android.com/tools" 
  6.  
  7. android:layout_width="match_parent" 
  8.  
  9. android:layout_height="match_parent" 
  10.  
  11. android:background="@drawable/background" 
  12.  
  13. android:id="@+id/rel" 
  14.  
  15. tools:context="com.example.theodhor.speechapplication.MainActivity"
  16.  
  17. <ImageButton 
  18.  
  19. android:layout_width="wrap_content" 
  20.  
  21. android:layout_height="wrap_content" 
  22.  
  23. android:id="@+id/microphoneButton" 
  24.  
  25. android:layout_centerVertical="true" 
  26.  
  27. android:layout_centerHorizontal="true" 
  28.  
  29. android:src="@drawable/ic_mic_none_white_48dp" 
  30.  
  31. android:background="@null"/> 
  32.  
  33. </RelativeLayout> 

增加说话功能

现在,用户接口部分已经完成,接下来要编写位于MainActivity内部的Java代码了。

首先,在onCreate方法上面声明一个变量TextToSpeech:


  
  
  1. private TextToSpeechtts; 

然后,在onCreate方法中添加如下代码:


  
  
  1. tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() { 
  2.  
  3. @Override 
  4.  
  5. public void onInit(int status) { 
  6.  
  7. if (status == TextToSpeech.SUCCESS) { 
  8.  
  9. int result = tts.setLanguage(Locale.US); 
  10.  
  11. if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { 
  12.  
  13. Log.e("TTS""This Language is not supported"); 
  14.  
  15.  
  16. speak("Hello"); 
  17.  
  18. else { 
  19.  
  20. Log.e("TTS""Initilization Failed!"); 
  21.  
  22.  
  23.  
  24. }); 

上述代码将启动系统中的TextToSpeech服务。其中的speak()方法使用了一个String类型的参数,它是你要求你的Android设备需要念出的文字。

下面要创建这个方法,并添加如下代码:


  
  
  1. private void speak(String text){ 
  2.  
  3. if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.LOLLIPOP) { 
  4.  
  5. tts.speak(text, TextToSpeech.QUEUE_FLUSH, nullnull); 
  6.  
  7. }else
  8.  
  9. tts.speak(text, TextToSpeech.QUEUE_FLUSH, null); 
  10.  
  11.  

上面代码中使用了Build.VERSION检查,因为tts.speak(param,param,param)格式的调用对于Android API 5.1来说已经废弃了。

在speak()方法后面再创建另一个方法,用于当用户关闭程序时负责停止TextToSpeech服务:


  
  
  1. @Override 
  2.  
  3. public void onDestroy() { 
  4.  
  5. if (tts != null) { 
  6.  
  7. tts.stop(); 
  8.  
  9. tts.shutdown(); 
  10.  
  11.  
  12. super.onDestroy(); 
  13.  

到此,一旦你启动程序,这个程序便能说出“Hello”这样的语句了。接下来要实现的是使程序具备听的功能。

增加聆听功能

为了使程序能够具备听的功能,你需要使用麦克风按钮。为此,需要在onCreate方法中添加如下代码:


  
  
  1. findViewById(R.id.microphoneButton).setOnClickListener(new View.OnClickListener() { 
  2.  
  3. @Override 
  4.  
  5. public void onClick(View v) { 
  6.  
  7. listen(); 
  8.  
  9.  
  10. }); 

点击ImageButton控件时,将触发调用下面这个函数:


  
  
  1. private void listen(){ 
  2.  
  3. Intent i = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); 
  4.  
  5. i.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); 
  6.  
  7. i.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault()); 
  8.  
  9. i.putExtra(RecognizerIntent.EXTRA_PROMPT, "Say something"); 
  10.  
  11. try { 
  12.  
  13. startActivityForResult(i, 100); 
  14.  
  15. } catch (ActivityNotFoundException a) { 
  16.  
  17. Toast.makeText(MainActivity.this, "Your device doesn't support Speech Recognition", Toast.LENGTH_SHORT).show(); 
  18.  
  19.  

此方法将启动listening Activity,这个活动会显示一个带有一段文本提示的对话框。讲话所使用的语言是设备提供的,通过Locale.getDefault()方法实现。

StartActivityForResult (i,100)方法等待当前活动返回一个结果。100只是一个附加到已启动活动的随机代码,其实也可以是一个任何适合你需要的数字。当结果从已启动的活动返回时,它包含这个代码并使用此代码来区分来自于彼此的多个结果。

要从已启动的活动中捕获结果,需要添加下面的重写方法:


  
  
  1. @Override 
  2.  
  3. protected void onActivityResult(intrequestCode, intresultCode, Intent data) { 
  4.  
  5. super.onActivityResult(requestCode, resultCode, data); 
  6.  
  7. if(requestCode == 100){ 
  8.  
  9. if (resultCode == RESULT_OK &&null != data) { 
  10.  
  11. ArrayList<String> res = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); 
  12.  
  13. String inSpeech = res.get(0); 
  14.  
  15. recognition(inSpeech); 
  16.  
  17.  
  18.  

这个方法捕获来自于活动的每一个结果并使用requestCode来处理语言识别器结果数据。如果requestCode等于100,requestCode等于OK并且来自于这个结果的数据不是null。你会从res.get(0)中取得result字符串。

接下来,创建一个新方法recognition,此方法将使用一个String类型的参数:


  
  
  1. private void recognition(String text){ 
  2.  
  3. Log.e("Speech",""+text); 
  4.  

到现在为止,当用户点击麦克风按钮时,程序能够听声音了,并且能够把用户的语言转换为文本数据,最终结果将通过Error日志打印输出。

增加学习功能

为了使程序更有趣一些,在这一小节中你要使应用程序能够学习一些简单的事情,例如你的名字。为了实现这一功能,需要使用本地存储功能。

首先,在onCreate方法中添加如下代码:


  
  
  1. private SharedPreferences preferences; 
  2.  
  3. private SharedPreferences.Editor editor; 
  4.  
  5. private static final String PREFS = "prefs"
  6.  
  7. private static final String NAME = "name"
  8.  
  9. private static final String AGE = "age"
  10.  
  11. private static final String AS_NAME = "as_name"

然后,在onCreate方法中添加如下代码:


  
  
  1. preferences = getSharedPreferences(PREFS,0); 
  2.  
  3. editor = preferences.edit(); 

首先,你需要使应用程序提问问题,所以需要把speak("Hello")修改为speak(“What is your name?)。

在这里,您可以使用一个简单的逻辑;所以,当有人问"你的名字是什么?",答案是"我的名字是Dori",于是从答案中提出名字。一个简单的方法是把答案拆分由空格分隔的字符串并获取最后一个索引的值。

于是,我们要更新recognition方法中的代码,如下所示:


  
  
  1. private void recognition(String text){ 
  2.  
  3. Log.e("Speech",""+text); 
  4.  
  5. //creating an array which contains the words of the answer 
  6.  
  7. String[] speech = text.split(" "); 
  8.  
  9. //the last word is our name 
  10.  
  11. String name = speech[speech.length-1]; 
  12.  
  13. //we got the name, we can put it in local storage and save changes 
  14.  
  15. editor.putString(NAME,name).apply(); 
  16.  
  17. //make the app tell our name 
  18.  
  19. speak("Your name is "+preferences.getString(NAME,null)); 
  20.  

recognition方法使用来自用户语音的所有结果。既然讲话可能是不同的,你可以使用它们可能包含的某些单词来区别它们。

例如,这个方法中的代码可以是:


  
  
  1. private void recognition(String text){ 
  2.  
  3. Log.e("Speech",""+text); 
  4.  
  5. String[] speech = text.split(" "); 
  6.  
  7. //if the speech contains these words, the user is saying their name 
  8.  
  9. if(text.contains("my name is")){ 
  10.  
  11. String name = speech[speech.length-1]; 
  12.  
  13. Log.e("Your name""" + name); 
  14.  
  15. editor.putString(NAME,name).apply(); 
  16.  
  17. speak("Your name is "+preferences.getString(NAME,null)); 
  18.  
  19.  

但这仍然是一个与应用程序的简单交互。你可以让它学习你的年龄,或者给它起一个名字。

在同一个方法中,你可以尝试下面这些简单的条件:


  
  
  1. //This must be the age 
  2.  
  3. //Just speak: I am x years old. 
  4.  
  5. if(text.contains("years") &&text.contains("old")){ 
  6.  
  7. String age = speech[speech.length-3]; 
  8.  
  9. Log.e("THIS""" + age); 
  10.  
  11. editor.putString(AGE, age).apply(); 
  12.  
  13.  
  14. //Then ask it for your age 
  15.  
  16. if(text.contains("how old am I")){ 
  17.  
  18. speak("You are "+preferences.getString(AGE,null)+" years old."); 
  19.  

应用程序能够告诉你时间信息:


  
  
  1. //Ask: What time is it? 
  2.  
  3. if(text.contains("what time is it")){ 
  4.  
  5. SimpleDateFormatsdfDate = new SimpleDateFormat("HH:mm");//dd/MM/yyyy 
  6.  
  7. Date now = new Date(); 
  8.  
  9. String[] strDate = sdfDate.format(now).split(":"); 
  10.  
  11. if(strDate[1].contains("00"))strDate[1] = "o'clock"
  12.  
  13. speak("The time is " + sdfDate.format(now)); 
  14.  

小结

在我创建的GitHub工程(https://github.com/sitepoint-editors/SpeechApplication)中包含了更多的例子,你可以充分地进行实验并开发出你自己真正的Android助手程序。

最后,希望你喜欢这个教程,并希望你能够与自己的手机产生一次真正有用的对话。





作者:朱先忠
来源:51CTO
目录
相关文章
|
1月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
1月前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
27 1
|
1月前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
20天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
41 19
|
1月前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
20天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
45 14
|
23天前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
21天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
31 5
|
20天前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
|
21天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。