眺めて覚える C# Xamarin　(5) 音声認識

# Androidの音声認識をプログラムしちゃおう!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/0909b41e-7cd7-7d53-1153-6ef4aa860a53.png)
###新しいプロジェクトを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/c921ca52-b0b8-48f0-be01-89c855ec7933.png)
#　モバイルアプリ(Xamarin forms)を選択 次へ
### Android アプリでもできるけど例題がほとんどないモバイルアプリで作るね!
####モバイルアプリのほうが何となくシンプルだから!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/028f9dd9-bb9a-ed4b-c6de-5833997f29b5.png)

# プロジェクト名は、シンプルにSpeech to TextをSp2Textにした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/4f164972-739a-b9d0-7795-5d2244d8cdd5.png)

##今回は、MainPageとMainActivityにプログラムを追加して作っていきます。
MainPage.Xamlには、User Interfaceをコーディングします。
MainActivityには、Amdroidの本来持っている音声認識を呼び出すルーチンをコーディングします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/ea052ff7-4c5c-6284-2ca0-b731bb15e104.png)

###MainActivity.csを見てみましょう。
Xamarin.Forms.MessagingCenter.Subscribe<Object, string>(this, "StartVoice", StartVoice);は、MainPagからメッセージが送信されるとprivate void StartVoice(object o, string arg)を(音声認識)起動します。

```MainActivity.cs
using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Content;
using Android.Speech;

namespace Sp2Text.Droid
{
    [Activity(Label = "Sp2Text", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        // 音声認識用定数定義
        private const int VOICE = 10;
        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);

            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
            //MainPageの開始ボタンか押された場合
            Xamarin.Forms.MessagingCenter.Subscribe<Object, string>(this, "StartVoice", StartVoice);
        }
        /// <summary>
        /// 音声認識の起動
        /// </summary>
        /// <param name="o"></param>
        /// <param name="arg"></param>
        private void StartVoice(object o, string arg)
        {
            var voiceIntent = new Intent(RecognizerIntent.ActionRecognizeSpeech);
            voiceIntent.PutExtra(RecognizerIntent.ExtraLanguageModel, RecognizerIntent.LanguageModelFreeForm);
            voiceIntent.PutExtra(RecognizerIntent.ExtraPrompt, "Speak Now :)");
            voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputCompleteSilenceLengthMillis, 1500);
            voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputPossiblyCompleteSilenceLengthMillis, 1500);
            voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputMinimumLengthMillis, 15000);
            voiceIntent.PutExtra(RecognizerIntent.ExtraMaxResults, 1);
            voiceIntent.PutExtra(RecognizerIntent.ExtraLanguage, Java.Util.Locale.Default);
            StartActivityForResult(voiceIntent, VOICE);
        }
        /// <summary>
        /// 音声認識終了処理
        /// </summary>
        /// <param name="requestCode"></param>
        /// <param name="resultVal"></param>
        /// <param name="data"></param>
        protected override void OnActivityResult(int requestCode, Result resultVal, Intent data)
        {
            if (requestCode == VOICE)
            {
                if (resultVal == Result.Ok)
                {
                    var matches = data.GetStringArrayListExtra(RecognizerIntent.ExtraResults);
                    var txt = matches[0].ToString();
                    //音声認識テキストをMainPageに送る
                    Xamarin.Forms.MessagingCenter.Send<Object, string>(this, "EndOfVoice", txt);
                }
            }
            base.OnActivityResult(requestCode, resultVal, data);
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}
```
UIのレイアウトは、次のように定義しまた。

```MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="Sp2Text.MainPage">

    <StackLayout>
        <StackLayout>
            <Button x:Name="btn" Text="音声認識開始"
                    FontSize="24"
                    Clicked="BtnClick"/>
            <Label x:Name="Lb" Text="音声認識結果" 
             FontSize="32"
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand" />
        </StackLayout>
    </StackLayout>
</ContentPage>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/04d369a7-dd1a-df70-dbbd-61e39cb4c27e.png)

```MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Sp2Text
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            //音声認識の終了したメッセージを受け取る
            MessagingCenter.Subscribe<Object, string>(this, "EndOfVoice", EndOfVoice);
        }
        /// <summary>
        /// ボタンがクリックされたとき
        /// </summary>
        /// <param name="s"></param>
        /// <param name="e"></param>
        void BtnClick(object s, EventArgs e)
        {
            // 音声開始コマンドをMainActivityに送信
            MessagingCenter.Send<Object, string>(this, "StartVoice", "StartVoice");
        }
        /// <summary>
        /// 音声認識の終了
        /// </summary>
        /// <param name="o"></param>
        /// <param name="arg"></param>
        void EndOfVoice(object o, string arg)
        {
            Lb.Text = arg;
        }
    }
}

```
実行すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/6873995f-ac1a-4a26-b762-6b30cb78a9f1.png)

##[Source](https://github.com/yutakahirata/speech2text)は、ここ
https://github.com/yutakahirata/speech2text