65.9K
CodeProject 正在变化。 阅读更多。
Home

开发具有语音识别功能的Android*应用程序

2013年12月2日

CPOL

4分钟阅读

viewsIcon

26970

开发具有语音识别功能的Android*应用程序

访问 Intel® Android 开发者专区

Android 无法识别语音,因此典型的 Android 设备也无法识别语音。或者,有没有办法可以识别?

最简单的方法是让另一个应用程序为我们进行识别。在 Android 中让另一个应用程序执行某项操作称为使用 Intent

我们的目标设备必须至少有一个应用程序能够处理语音识别的 Intent,该 Intent 由 RecognizerIntent.ACTION_RECOGNIZE_SPEECH 操作调用。

其中一个应用程序是Google 语音搜索。它是 Android 上最好的识别器之一,支持多种语言。此服务需要互联网连接,因为语音识别在 Google 服务器上进行。此应用程序有一个非常简单的Activity,用于告知用户他们可以说话。用户停止说话的那一刻,对话框关闭,我们的应用程序(Intent 调用者)会收到一个包含已识别语音的字符串数组。

语音识别示例

让我们编写一个小示例应用程序,演示如何在应用程序中使用语音搜索。

我们的应用程序需要执行以下操作

  • 接收语音识别请求
  • 检查用于语音识别的应用程序的可用性
  • 如果语音识别可用,则调用其 Intent 并接收结果
  • 如果语音识别不可用,则显示安装 Google 语音搜索的对话框,并在用户愿意时将其重定向到 Google Play

首先,我们创建一个实现语音识别逻辑的类。将此类命名为 SpeechRecognitionHelper,我们在其中声明一个静态的公共函数 run(),该函数将接收启动识别的请求

/**
 * A helper class for speech recognition
 */
public class SpeechRecognitionHelper {

/**
     * Running the recognition process. Checks availability of recognition Activity,
     * If Activity is absent, send user to Google Play to install Google Voice Search.
    * If Activity is available, send Intent for running.
     *
     * @param callingActivity = Activity, that initializing recognition process
     */
    public static void run(Activity callingActivity) {
        // check if there is recognition Activity
        if (isSpeechRecognitionActivityPresented(callingActivity) == true) {
            // if yes – running recognition
            startRecognition(callingActivity);
        } else {
            // if no, then showing notification to install Voice Search
            Toast.makeText(callingActivity, "In order to activate speech recognition you must install \"Google Voice Search\"", Toast.LENGTH_LONG).show();
            // start installing process
            installGoogleVoiceSearch(callingActivity);
        }
    }
}

如您所见,除了 run() 函数之外,我们还需要实现另外三个函数

  • isSpeechRecognitionActivityPresented – 检查系统中是否存在语音识别应用程序
  • installGoogleVoiceSearch – 初始化 Google 语音搜索安装过程
  • startRecognition – 准备适当的 Intent 并运行识别

要检查设备是否具有语音识别应用程序,我们可以使用 PackageManager 类中的 queryIntentActivities 方法。此方法返回可以处理指定 Intent 的 Activity 列表。要获取 PackageManager 的实例,我们可以使用 getPackageManager

我们的代码如下所示

isSpeechRecognitionActivityPresented

/**
     * Checks availability of speech recognizing Activity
     *
     * @param callerActivity – Activity that called the checking
     * @return true – if Activity there available, false – if Activity is absent
     */
    private static boolean isSpeechRecognitionActivityPresented(Activity callerActivity) {
        try {
            // getting an instance of package manager
            PackageManager pm = callerActivity.getPackageManager();
            // a list of activities, which can process speech recognition Intent
            List activities = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);

            if (activities.size() != 0) {    // if list not empty
                return true;                // then we can recognize the speech
            }
        } catch (Exception e) {

        }

        return false; // we have no activities to recognize the speech
    }

现在实现 startRecognition 函数。此函数将形成启动语音识别 Activity 的适当 Intent。您可以在文档页面上找到有关如何执行此操作的详细信息。

源代码

   /**
     * Send an Intent with request on speech 
     * @param callerActivity  - Activity, that initiated a request
     */
    private static void startRecognitionActivity(Activity callerActivity) {

        // creating an Intent with “RecognizerIntent.ACTION_RECOGNIZE_SPEECH” action
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

        // giving additional parameters:
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Select an application");    // user hint
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);    // setting recognition model, optimized for short phrases – search queries
        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);    // quantity of results we want to receive
//choosing only 1st -  the most relevant 

        // start Activity ant waiting the result
        ownerActivity.startActivityForResult(intent, SystemData.VOICE_RECOGNITION_REQUEST_CODE);
    }

最后,我们将实现 installGoogleVoiceSearch。此函数将显示一个对话框,询问用户是否要安装 Google 语音搜索,并在用户同意的情况下将其发送到 Google Play。

/**
     * Asking the permission for installing Google Voice Search. 
     * If permission granted – sent user to Google Play
     * @param callerActivity – Activity, that initialized installing
     */
    private static void installGoogleVoiceSearch(final Activity ownerActivity) {

        // creating a dialog asking user if he want
        // to install the Voice Search
        Dialog dialog = new AlertDialog.Builder(ownerActivity)
            .setMessage("For recognition it’s necessary to install \"Google Voice Search\"")    // dialog message
            .setTitle("Install Voice Search from Google Play?")    // dialog header
            .setPositiveButton("Install", new DialogInterface.OnClickListener() {    // confirm button

                // Install Button click handler
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    try {
                        // creating an Intent for opening applications page in Google Play
                        // Voice Search package name: com.google.android.voicesearch
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.voicesearch"));
                        // setting flags to avoid going in application history (Activity call stack)
                        intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                        // sending an Intent
                        ownerActivity.startActivity(intent);
                     } catch (Exception ex) {
                         // if something going wrong
                         // doing nothing
                     }
                }})

            .setNegativeButton("Cancel", null)    // cancel button
            .create();

        dialog.show();    // showing dialog
    }

差不多就是这样。我们运行语音识别 Activity。然后请求用户安装语音搜索的权限,并在用户同意时将其发送到 Google Play。我们还有一件事要做,那就是收集语音识别结果。

我们使用 startActivityForResult 函数发送请求以收集已启动 Activity 的结果。我们还需要在 Intent 调用 Activity 中重新定义 OnActivityResult 方法。可以这样做

// Activity Results handler
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        // if it’s speech recognition results
        // and process finished ok
        if (requestCode == SystemData.VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {

            // receiving a result in string array
            // there can be some strings because sometimes speech recognizing inaccurate
            // more relevant results in the beginning of the list
            ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            // in “matches” array we holding a results... let’s show the most relevant
            if (matches.size() > 0) Toast.makeText(this, matches.get(0), Toast.LENGTH_LONG).show();
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

现在我们准备好了

创建的 SpeechRecognitionHelper 类允许我们仅通过调用一个函数 run() 来执行语音识别请求。

只需将此类添加到我们的项目中并在需要的地方调用 run 函数即可添加识别功能。然后,通过重新定义发起识别调用的 Activity 的 onActivityResult 方法来处理文本结果。

有关更多信息,您可以查看 Android 开发者网站。在这里,您会找到有关如何执行语音识别的优秀示例,以及更重要的是,如何获取可用语言列表。如果您想识别非用户默认区域设置的语言,则需要此列表。

要快速将语音输入集成到您的应用程序中,您可以下载并使用此 SpeechRecognitionHelper 类的代码。

关于作者

Stanislav 在英特尔公司软件与服务集团工作。他拥有 10 多年的软件开发经验。他的主要兴趣是优化性能、功耗和并行编程。在他目前作为应用程序工程师为基于英特尔的设备提供技术支持的职位上,Stanislav 与软件开发人员和 SoC 架构师密切合作,帮助他们在英特尔平台上获得最佳性能。Stanislav 拥有国家研究型大学高等经济学院数学经济学硕士学位。

Mikhail 是此博客的合著者,也是一名英特尔暑期实习生,他在洛巴切夫斯基大学学习计算机科学。他喜欢深入研究数学和进行 Android 编程技巧。

Intel 和 Intel 标志是 Intel Corporation 在美国和/或其他国家/地区的商标。
版权所有 © 2013 英特尔公司。保留所有权利。
*其他名称和品牌可能被声明为他人的财产。

其他相关文章

要详细了解 Intel 的 Android 开发工具,请访问 Intel® Android 开发者专区

© . All rights reserved.