开发具备语音识别功能的 Android* 应用

作者:杜伟 (Intel)

下载文章

开发具备语音识别功能的 Android* 应用 [PDF 398KB]

Android 不能识别语音,因此一款 Android 设备通常也不能识别语音。 通过什么方式帮助它识别呢?

最简便的方法就是让另一种应用为我们识别语音。 让另一种应用处理 Android 中的任务被称为 使用意图

我们的目标设备必须至少有一个可以为语音识别处理意图的应用,并且可以被 RecognizerIntent.ACTION_RECOGNIZE_SPEECH 调用。

其中的一款应用就是 Google 语音搜索。 该应用是当前 Android 可用的最好识别器之一,可以支持多种语言。 由于语音识别是通过 Google 服务器处理的,因此该服务要求必须有互联网连接。 该应用具备一个非常简单的活动,通过它告知用户是否可以讲话。 当用户停止讲话时,会话就会关闭,然后我们的应用(意图调用程序)将收到一列带有已识别语音的字符串。

开发具备语音识别功能的 Android* 应用_第1张图片

语音识别示例

我们现在通过一个小的示例程序展示如何在应用中使用语音搜索。

我们的应用需要完成以下任务:

  • 收到语音识别请求
  • 检查语音识别应用的可用性
  • 如果语音识别可用,然后调用意图并接收结果
  • 如果语音识别不可用,然后会显示一个安装 Google 语音搜索的会话,并将用户重定向至 Google Play。

首先,我们需要创建一个类,为语音识别实现逻辑。 调用类 SpeechRecognitionHelper,此时我们需要声明一个静态的公共函数 run(),该函数将收到一个启动识别的请求:

 
  
01 /**
02  * A helper class for speech recognition
03  */
04 public class SpeechRecognitionHelper {
05  
06 /**
07      * Running the recognition process. Checks availability of recognition Activity,
08      * If Activity is absent, send user to Google Play to install Google Voice Search.
09     * If Activity is available, send Intent for running.
10      *
11      * @param callingActivity = Activity, that initializing recognition process
12      */
13     public static void run(Activity callingActivity) {
14         // check if there is recognition Activity
15         if (isSpeechRecognitionActivityPresented(callingActivity) == true) {
16             // if yes – running recognition
17             startRecognition(callingActivity);
18         } else {
19             // if no, then showing notification to install Voice Search
20             Toast.makeText(callingActivity, "In order to activate speech recognition you must install \"Google Voice Search\"", Toast.LENGTH_LONG).show();
21             // start installing process
22             installGoogleVoiceSearch(callingActivity);
23         }
24     }
25 }
如您所见,除 run() 函数之外,我们还需要执行三个函数:
  • isSpeechRecognitionActivityPresented — 检查语音识别应用是否存在于系统中
  • installGoogleVoiceSearch — 初始化 Google 语音搜索安装进程
  • startRecognition — 准备适合的意图并运行识别

为了检查设备是否有语音识别应用,我们可以使用类 PackageManager 中的 queryIntentActivities 方法。 该方法列出了可以处理指定意图的各种活动。 为了接收 PackageManager 的一个实例,我们可以使用 getPackageManager。

我们的代码如下所示:

isSpeechRecognitionActivityPresented

 
  
01 /**
02      * Checks availability of speech recognizing Activity
03      *
04      * @param callerActivity – Activity that called the checking
05      * @return true – if Activity there available, false – if Activity is absent
06      */
07     private static boolean isSpeechRecognitionActivityPresented(Activity callerActivity) {
08         try {
09             // getting an instance of package manager
10             PackageManager pm = callerActivity.getPackageManager();
11             // a list of activities, which can process speech recognition Intent
12             List activities = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
13  
14             if (activities.size() != 0) {    // if list not empty
15                 return true;                // then we can recognize the speech
16             }
17         } catch (Exception e) {
18  
19         }
20  
21         return false; // we have no activities to recognize the speech
22     }

现在执行 startRecognition 函数。 该函数为启动语音识别活动提供适合的意图。 如欲了解有关该过程的详细信息,请查看 文档页。

源代码:

 
  
01    /**
02      * Send an Intent with request on speech
03      * @param callerActivity  - Activity, that initiated a request
04      */
05     private static void startRecognitionActivity(Activity callerActivity) {
06  
07         // creating an Intent with “RecognizerIntent.ACTION_RECOGNIZE_SPEECH” action
08         Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
09  
10         // giving additional parameters:
11         intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Select an application");    // user hint
12         intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);    // setting recognition model, optimized for short phrases – search queries
13         intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);    // quantity of results we want to receive
14 //choosing only 1st -  the most relevant
15  
16         // start Activity ant waiting the result
17         ownerActivity.startActivityForResult(intent, SystemData.VOICE_RECOGNITION_REQUEST_CODE);
18     }

最后,我们需要执行 installGoogleVoiceSearch。 该函数将会显示出一个会话,询问用户是否需要安装 Google 语音搜索,如果用户同意,则将其转至 Google Play。

 
  
01 /**
02      * Asking the permission for installing Google Voice Search.
03      * If permission granted – sent user to Google Play
04      * @param callerActivity – Activity, that initialized installing
05      */
06     private static void installGoogleVoiceSearch(final Activity ownerActivity) {
07  
08         // creating a dialog asking user if he want
09         // to install the Voice Search
10         Dialog dialog = new AlertDialog.Builder(ownerActivity)
11             .setMessage("For recognition it’s necessary to install \"Google Voice Search\"")    // dialog message
12             .setTitle("Install Voice Search from Google Play?")    // dialog header
13             .setPositiveButton("Install", new DialogInterface.OnClickListener() {    // confirm button
14  
15                 // Install Button click handler
16                 @Override
17                 public void onClick(DialogInterface dialog, int which) {
18                     try {
19                         // creating an Intent for opening applications page in Google Play
20                         // Voice Search package name: com.google.android.voicesearch
21                         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.voicesearch"));
22                         // setting flags to avoid going in application history (Activity call stack)
23                         intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
24                         // sending an Intent
25                         ownerActivity.startActivity(intent);
26                      } catch (Exception ex) {
27                          // if something going wrong
28                          // doing nothing
29                      }
30                 }})
31  
32             .setNegativeButton("Cancel", null)    // cancel button
33             .create();
34  
35         dialog.show();    // showing dialog
36     }

大致就是这样。 我们运行语音识别活动。 然后请求用户的许可,安装语音搜索并在取得用户同意之后将其转至 Google Play。 我们还需要做的一件事就是收集语音识别的结果。

我们使用 startActivityForResult 函数发送一个请求,收集已启动活动的结果。 我们还需要在我们的意图调用程序活动中重新定义一个 OnActivityResult 方法。 按照以下方式进行定义:

 
  
01 // Activity Results handler
02     @Override
03     public void onActivityResult(int requestCode, int resultCode, Intent data) {
04  
05         // if it’s speech recognition results
06         // and process finished ok
07         if (requestCode == SystemData.VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {
08  
09             // receiving a result in string array
10             // there can be some strings because sometimes speech recognizing inaccurate
11             // more relevant results in the beginning of the list
12             ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
13  
14             // in “matches” array we holding a results... let’s show the most relevant
15             if (matches.size() > 0) Toast.makeText(this, matches.get(0), Toast.LENGTH_LONG).show();
16         }
17  
18         super.onActivityResult(requestCode, resultCode, data);
19     }

现在我们已经准备就绪

借助已创建的类 SpeechRecognitionHelper,我们只需调用一个函数 run() 就能执行一个语音识别请求。

此时只需在我们的项目中添加该类并在需要的位置中调用运行函数就能添加一个识别功能。 然后为发起识别请求的活动重新定义 onActivityResult 方法并执行处理文本结果。

如欲了解更多信息,请查看 Android 开发人员 网站。 这里的一些正确 示例 展示了如何实现语音识别,更重要的是,如何获取可用的语言列表。 如果您想要识别除用户默认位置之外的一种语言,您就需要使用该列表。

如果您想快速地将语音输入集成到您的应用中,您可以下载该代码并将其用于 SpeechRecognitionHelper 类。

作者介绍

Stanislav 任职于英特尔公司的软件和服务事业部。 他在软件开发领域拥有十几年的丰富经验。 他关注的主要领域包括性能优化、功耗和并行程序设计。 作为英特尔的一名应用工程师,Stanislav 与软件开发人员和 SoC 架构师紧密协作,帮助他们在英特尔平台上实现尽可能出色的性能。 Stanislav 毕业于国立研究大学高等经济学院,拥有数理经济学硕士学位。

Mikhail 协助完成了本文的编写。Mikhail 是英特尔的一名暑期实习生,目前正在罗巴切夫斯基大学学习计算机科学。 他喜欢研究数学和 Android 编程技巧。

英特尔和 Intel 标识是英特尔公司在美国和/或其他国家的商标。
版权所有 © 2013 年英特尔公司。 保留所有权利。
*其他的名称和品牌可能是其他所有者的资产。


你可能感兴趣的:(IntelAndroid)