当前位置:首页 > 安卓源码 > 技术博客 >

Android开发实现文本到语音和语音到文本转化的示例

时间:2018-12-15 11:50 来源:互联网 作者:源码搜藏 浏览: 收藏 挑错 推荐 打印

Android开发实现文本到语音和语音到文本转化的示例 介绍 Android SDK文本到语音引擎是一个非常有用的工具,可以在您的Android应用中集成语音。在本文中,我们将介绍如何使用TTS引擎将文本转换为语音以及将语音转换为文本。在这个过程中,我们还将看到如何在

Android开发实现文本到语音和语音到文本转化的示例

Android开发实现文本到语音和语音到文本转化的示例Android开发实现文本到语音和语音到文本转化的示例

介绍

Android SDK文本到语音引擎是一个非常有用的工具,可以在您的Android应用中集成语音。在本文中,我们将介绍如何使用TTS引擎将文本转换为语音以及将语音转换为文本。在这个过程中,我们还将看到如何在具有语音功能的记事本应用程序中实际使用TTS。我已将该应用命名为TalkingNotePad。此应用程序具有标准的记事本功能,如打开和保存文本文件以及其他功能,如录音,说出文件内容和使用语音命令执行操作。此外,我们将简要介绍使用存储访问框架(SAF)执行文本文件输入和输出操作。在此应用程序中,可以使用按钮或使用语音执行命令。

通过直接使用按钮或使用语音命令可以使用以下选项:

  • 打开 - 打开文件
  • 保存 - 保存文件
  • 说话 - 说文字
  • 录制 - 录制语音
  • 语音命令 - 使用语音执行命令
  • 清除文本 - 清除文本
  • 帮助 - 显示帮助屏幕
  • 关于 - 显示关于屏幕

背景

要在任何应用程序中将文本转换为语音,都需要TextToSpeech类和TextToSpeech.OnInitListener接口的实例。该TextToSpeech.OnInitListener包含onInit()的时被调用方法TextToSpeech的发动机初始化完成。该onInit()方法有一个整数参数,表示TextToSpeech引擎初始化的状态。一旦TextToSpeech引擎初始化完成,我们就可以调用类的speak()方法TextToSpeech来播放文本作为语音。该speak()方法的第一个参数是要说出的文本,第二个参数是队列模式。队列模式参数可以是QUEUE_ADD在回放队列的末尾添加新条目,或者QUEUE_FLUSH用新条目覆盖回放队列中的条目。

要将语音转换为文本,我们可以使用RecognizerIntent带有ACTION_RECOGNIZE_SPEECH操作和startActivityForResult()方法的类,并在方法中处理结果onActivityResult()。

该ACTION_RECOGNIZE_SPEECH操作启动一个活动,提示用户发送语音并通过语音识别器发送,如下所示:

Android开发实现文本到语音和语音到文本转化的示例

识别结果存储在被ArrayList调用的中EXTRA_RESULTS。

要打开或创建文件,我们可以使用存储访问框架。存储访问框架包含以下元素:

  • 文档提供程序,允许从存储设备访问文件。
  • 客户端应用程序,它调用ACTION_OPEN_DOCUMENT或ACTION_CREATE_DOCUMENT意图处理文档提供程序返回的文件。
  • Picker,提供UI以从文档提供程序访问满足客户端应用程序搜索条件的文件。

在SAF中,我们可以分别使用ACTION_OPEN_DOCUMENT和ACTION_CREATE_DOCUMENT意图打开和创建文件。打开和创建文件的实际任务可以在onActivityResult()方法中实现。

打开和保存屏幕如下:

Android开发实现文本到语音和语音到文本转化的示例    Android开发实现文本到语音和语音到文本转化的示例

使用代码

以下布局为记事本应用程序创建界面:

隐藏   收缩 Android开发实现文本到语音和语音到文本转化的示例   复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    android:gravity="center">
    <ScrollView

        android:layout_width="600px"

        android:layout_height="600px"

        android:scrollbars="vertical"

        android:background="@drawable/shape">
        <EditText

            android:id="@+id/txtFileContents"

            android:layout_width="match_parent"

            android:layout_height="match_parent" />
    </ScrollView>
    <TableLayout

        android:layout_width="wrap_content"

        android:layout_height="wrap_content">
        <TableRow>
            <Button

                android:id="@+id/btnOpen"

                android:text="Open"

                android:drawableLeft="@drawable/open"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content" />
            <Button

                android:id="@+id/btnSave"

                android:text="Save"

                android:drawableLeft="@drawable/save"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content" />
        </TableRow>
        <TableRow>
            <Button

                android:id="@+id/btnSpeak"

                android:text="Speak"

                android:drawableLeft="@drawable/speak"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content" />
            <Button

                android:id="@+id/btnRecord"

                android:text="Record"

                android:drawableLeft="@drawable/record"

                android:layout_width="fill_parent"

                android:layout_height="wrap_content" />
        </TableRow>
        <TableRow>
            <Button

                android:id="@+id/btnVoiceCommand"

                android:text="Voice Command"

                android:drawableLeft="@drawable/command"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content" />
            <Button

                android:id="@+id/btnClear"

                android:text="Clear Text"

                android:drawableLeft="@drawable/clear"

                android:layout_width="fill_parent"

                android:layout_height="wrap_content" />
        </TableRow>
        <TableRow>
            <Button

                android:id="@+id/btnHelp"

                android:text="Help"

                android:drawableLeft="@drawable/help"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content" />
            <Button

                android:id="@+id/btnAbout"

                android:text="About"

                android:drawableLeft="@drawable/about"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content" />
        </TableRow>
    </TableLayout>
</LinearLayout>

它的背景EditText由drawable文件夹中的以下标记创建:

隐藏   复制代码
<?xml version="1.0" encoding="utf-8"?>
<shape

	xmlns:android="http://schemas.android.com/apk/res/android"

	android:shape="rectangle"

	android:width="300px"

	android:height="600px">
	<corners android:radius="50px" />
	<solid android:color="#FFFF00" />
	<stroke android:width="2px"

			android:color="#FFFF00" />
</shape>

以下函数触发ACTION_OPEN_DOCUMENTintent:

隐藏   复制代码
public void open()
{
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("*/*");
    startActivityForResult(intent,OPEN_FILE);
}

上面的代码触发在方法中执行以下代码,该onActivityResult()方法使用流类打开所选文件并在EditText控件上显示其内容:

隐藏   收缩 Android开发实现文本到语音和语音到文本转化的示例   复制代码
if (resultCode == RESULT_OK)
{
   try
   {
      Uri uri = data.getData();
      String filename=uri.toString().substring
      (uri.toString().indexOf("%")).replace
      ("%2F","/").replace("%3A","/storage/emulated/0/");
      //Here I have retrieved the filename by replacing characters in the uri.
      //It works on my device. Not sure about other devices.
      FileInputStream stream=new FileInputStream(new File(filename));
      InputStreamReader reader=new InputStreamReader(stream);
      BufferedReader br=new BufferedReader(reader);
      StringBuffer buffer=new StringBuffer();
      String s=br.readLine();
      while(s!=null)
      {
          buffer.append(s+"\n");
          s=br.readLine();
      }
      txtFileContents.setText(buffer.toString().trim());
      br.close();
      reader.close();
      stream.close();
   }
   catch(Exception ex)
   {
      AlertDialog.Builder builder=new AlertDialog.Builder(this);
      builder.setCancelable(true);
      builder.setTitle("Error");
      builder.setMessage(ex.getMessage());
      builder.setIcon(R.drawable.error);
      AlertDialog dialog=builder.create();
      dialog.show();
   }
}

同样,以下函数触发ACTION_CREATE_DOCUMENTintent:

隐藏   复制代码
public void save()
{
    Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_TITLE,"newfile.txt");
    startActivityForResult(intent,SAVE_FILE);
}

这导致执行以下代码以将EditText控件的内容保存到文件中:

隐藏   复制代码
if(resultCode==RESULT_OK)
{
    try
    {
        Uri uri = data.getData();
        String filename=uri.toString().substring
        (uri.toString().indexOf("%")).replace
        ("%2F","/").replace("%3A","/storage/emulated/0/");
        FileOutputStream stream=new FileOutputStream(new File(filename));
        OutputStreamWriter writer=new OutputStreamWriter(stream);
        BufferedWriter bw=new BufferedWriter(writer);
        bw.write(txtFileContents.getText().toString(),0,
                 txtFileContents.getText().toString().length());
        bw.close();
        writer.close();
        stream.close();
    }
    catch(Exception ex)
    {
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setCancelable(true);
        builder.setTitle("Error");
        builder.setMessage(ex.getMessage());
        builder.setIcon(R.drawable.error);
        AlertDialog dialog=builder.create();
        dialog.show();
    }
}

为了说出EditText控件的内容,使用以下用户定义的函数:

隐藏   复制代码
public void speak()
{
    if(txtFileContents.getText().toString().trim().length()==0)
    {
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setCancelable(true);
        builder.setTitle("Error");
        builder.setMessage("Nothing to speak. Please type or record some text.");
        builder.setIcon(R.drawable.error);
        AlertDialog dialog=builder.create();
        dialog.show();
    }
    else
    {
        tts=new TextToSpeech(getApplicationContext(),new TextToSpeech.OnInitListener()
        {
            public void onInit(int status)
            {
                if(status!=TextToSpeech.ERROR)
                {
                    tts.setLanguage(Locale.US);
                    String str=txtFileContents.getText().toString();
                    tts.speak(str,TextToSpeech.QUEUE_ADD,null);
                }
            }
        });
    }
}

上面的代码初始化TextToSpeech引擎并将语言设置为Locale.US。然后它将EditText控件的内容检索到string变量中,最后调用speak()函数将文本转换为语音。

以下代码用于使用ACTION_RECOGNIZE_SPEECHintent 记录语音:

隐藏   复制代码
public void record()
{
    Intent intent=new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,Locale.getDefault());
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    if(voiceCommandMode && !recording)
    {
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT,"Speak a command to be executed...");
    }
    else
    {
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT,"Say something to record...");
    }
    startActivityForResult(intent,RECORD_VOICE);
}

上面的代码检查我们是在执行语音命令还是录制正常语音,并根据具体情况显示不同的提示。然后它会触发onActivityResult()函数中以下代码的执行:

隐藏   收缩 Android开发实现文本到语音和语音到文本转化的示例   复制代码
    if(resultCode==RESULT_OK)
    {
        ArrayList result=data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
        if(voiceCommandMode)
        {
            String command=result.get(0).toUpperCase();
            if(command.equals("OPEN")||command.startsWith("OP")||command.startsWith("OB"))
            {
                Toast.makeText(getBaseContext(),"Executing Open Command",Toast.LENGTH_SHORT).show();
                open();
            }
            else if(command.equals("SAVE")||command.startsWith("SA")||command.startsWith("SE"))
            {
                Toast.makeText(getBaseContext(),"Executing Save Command",Toast.LENGTH_SHORT).show();
                save();
            }
            else if(command.equals("SPEAK")||command.startsWith("SPA")||
                    command.startsWith("SPE")||command.startsWith("SPI"))
            {
                Toast.makeText(getBaseContext(),"Executing Speak Command",Toast.LENGTH_SHORT).show();
                speak();
            }
            else if(command.equals("RECORD")||command.startsWith("REC")||command.startsWith("RAC")||
                    command.startsWith("RAK")||command.startsWith("REK"))
            {
                Toast.makeText(getBaseContext(),"Executing Record Command",Toast.LENGTH_SHORT).show();
                recording=true;
                record();
            }
            else if(command.equals("CLEAR")||command.equals("KLEAR")||
                command.startsWith("CLA")||command.startsWith("CLE")||
                command.startsWith("CLI")||command.startsWith("KLA")||
                command.startsWith("KLE")||command.startsWith("KLI"))
            {
                Toast.makeText(getBaseContext(),"Executing Clear Command",Toast.LENGTH_SHORT).show();
                clear();
            }
            else if(command.equals("HELP")||command.startsWith("HAL")||
                command.startsWith("HEL")||command.startsWith("HIL")||command.startsWith("HUL"))
            {
                Toast.makeText(getBaseContext(),"Executing Help Command",Toast.LENGTH_SHORT).show();
                help();
            }
            else if(command.equals("ABOUT")||command.startsWith("ABA")||command.startsWith("ABO"))
            {
                Toast.makeText(getBaseContext(),"Executing About Command",Toast.LENGTH_SHORT).show();
                about();
            }
            else
            {
                Toast.makeText(getBaseContext(),"Unrecognized command",Toast.LENGTH_SHORT).show();
            }
            voiceCommandMode=false;
        }
        else
        {
            txtFileContents.setText(result.get(0));
        }
     }
  }

如果单击“ 语音命令 ”按钮,上面的代码将执行一个语音命令。否则,它只是在EditText控件上显示语音文本。代码使用getStringArrayListExtra()带EXTRA_RESULTS参数的方法来获取结果ArrayList。然后,它使用该get()方法提取语音文本作为第一个元素。

注意:为了避免语音命令无法识别的问题,我将语音与类似的发声词进行了比较。我不确定它是否是最好的出路,但它似乎是一个快速的解决方案。

也可以通过单击按钮来执行命令。方法中的以下代码onClick()根据单击的按钮启动操作:

隐藏   收缩 Android开发实现文本到语音和语音到文本转化的示例   复制代码
voiceCommandMode=false;
recording=false;
Button b=(Button)v;
if(b.getId()==R.id.btnOpen)
{
    open();
}
if(b.getId()==R.id.btnSave)
{
    save();
}
if(b.getId()==R.id.btnSpeak)
{
    speak();
}
if(b.getId()==R.id.btnRecord)
{
    record();
}
if(b.getId()==R.id.btnVoiceCommand)
{
    voiceCommandMode=true;
    record();
}
if(b.getId()==R.id.btnClear)
{
    clear();
}
if(b.getId()==R.id.btnHelp)
{
    help();
}
if(b.getId()==R.id.btnAbout)
{
    about();
}

需要将以下权限添加到androidmanifest.xml文件,以便读取和写入外部存储:

隐藏   复制代码
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

兴趣点

这是使用TextToSpeechAPI的基于语音的Android应用程序的一个示例。可以使用TextToSpeechAPI 创建更多这样令人兴奋的应用程序。
实例源码下载

链接: https://pan.baidu.com/s/1-pfR0nzA7t_DgFU38YPbnQ 提取码: sfqk 复制这段内容后打开百度网盘手机App,操作更方便哦

Android开发实现文本到语音和语音到文本转化的示例 转载https://www.codesocang.com/appboke/39139.html

技术博客阅读排行

最新文章