【Androidアプリ】音声テキスト変換アプリが完成♪

苦節三週間。。。
遂にスマホアプリが出来た🎵

###やったこと
・ボタン名整理
・ボタン処理時のバグ取り
・ファイル名取得
###・ボタン名整理
ボタン名等を以下のとおりとした。

```text
①保存File名を入力してください
音声テキスト変換したテキストをこのファイルに保存します。
②削除するFile名を入力してください
このファイルを削除します。
③音声入力してください
この文言の下のテキストエリアにカーソルを合わせて、Google音声入力としたあと、音声入力します。
④保存ボタン
このボタンを押すと上で定義したファイルにテキストが保存される。
⑤表示ボタン
このボタンを押すと上記の保存Fileに格納されているテキストが表示される。
⑥削除Fileボタン
このボタンを押すと、上記の削除するFile名に記載されたファイルが削除される。
また、何もファイル名がないあるいは、存在しないファイル名の場合は、存在するファイル名一覧を表示する。
⑦クリア
音声入力エリアと表示エリアをクリアします。
ただし、保存File名と削除File名はクリアしません。
※ここもクリアできますが残した方が使いやすいと思います
```

```strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Speech to Text</string>
    <string name="file_name">保存File名を入力してください</string>
    <string name="del_file_name">削除するFile名を入力してください</string>
    <string name="tv_name">音声入力してください</string>
    <string name="bt_click">保存</string>
    <string name="bt_click1">表示</string>
    <string name="bt_click2">File削除</string>
    <string name="bt_clear">クリア</string>
</resources>
```
###・ボタン処理時のバグ取り
削除Fileが存在しないのに削除しようとするとバグってアプリが落ちてしまいます。
そこで、それを検知して以下のように回避しました。
【参考】
[Null Safety](https://kotlinlang.org/docs/reference/null-safety.html)

```kotlin
                    val file1 = File(pathUtf8+"/"+ inputStr_delfile)
                    if (file1 != null && file1.length() > 0) {
                        file1.delete()
                    } else {
                        //file.delete()
                    }
```
###・ファイル名取得
削除Fileボタンを押したときの振舞いが以下のとおりです。
削除部分のコードは上記のとおりですが、それ以外の部分でファイル一覧を表示しています。
ここでは以下の３つを参考としています。
【参考】
①[【Android/Java】アプリ内のファイルの操作](https://chocolattips.hatenablog.com/entry/2017/01/22/000000)
②[Using Replace function in Kotlin](https://stackoverflow.com/questions/47355630/using-replace-function-in-kotlin)
③[Kotlinの文字列を連結する](https://www.codeflow.site/ja/article/kotlin-concatenate-strings)
すなわち
####①ファイルが存在するPathを取得し、ファイル名の一覧を取得する

```kotlin
                    var pathUtf8 =  getFilesDir().getAbsolutePath();

                    //ファイル名の一覧を取得する
                    val file = File(pathUtf8)
                    val files = file.listFiles()
```
####②③ファイルのPathを””に置き換えてファイル名のみにし、取得したファイル一覧を表示する
※コードは短いけど適度にハマりました

```kotlin
                    //取得した一覧を表示する
                    var f =""
                    for (i in files.indices) {
                        val fi= files[i]
                        val files_: String = fi.toString().replace( pathUtf8+ "/" ,"")
                        f = "ファイル" + (i + 1) +" "+ files_ +"\n"+ f
                    }
                    output.text = f
```
####この部分のコード
```kotlin
R.id.btClick2 -> {
                    var pathUtf8 =  getFilesDir().getAbsolutePath();

                    //ファイル名の一覧を取得する
                    val file = File(pathUtf8)
                    val files = file.listFiles()
                    //取得した一覧を表示する
                    var f =""
                    for (i in files.indices) {
                        val fi= files[i]
                        val files_: String = fi.toString().replace( pathUtf8+ "/" ,"")
                        f = "ファイル" + (i + 1) +" "+ files_ +"\n"+ f
                    }
                    output.text = f
                    val file1 = File(pathUtf8+"/"+ inputStr_delfile)
                    if (file1 != null && file1.length() > 0) {
                        file1.delete()
                    } else {
                        //file.delete()
                    }
                }
```
###完成イメージ

| 長いファイル名 | 多様な言語 |
|:-:|:-:|
|![nagame.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/1ed913dc-73d8-9690-4674-1ab5f66672c3.jpeg)| ![nandemo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/ac70347d-d06b-663d-75cd-c2b20dd958f1.jpeg)|
###まとめ
・音声テキスト変換アプリが完成した
・ファイル名は何語でも長くても使えた

・GooglePlayに登録しようと思う
###おまけ
```MainActivity.kt
package com.example.hellosample

import android.content.Context
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.io.File
import java.text.SimpleDateFormat
import java.util.*


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //表示ボタンであるButtonオブジェクトを取得。
        val btClick = findViewById<Button>(R.id.btClick)
        //表示ボタンであるButtonオブジェクトを取得。
        val btClick1 = findViewById<Button>(R.id.btClick1)
        //表示ボタンであるButtonオブジェクトを取得。
        val btClick2 = findViewById<Button>(R.id.btClick2)
        //リスナクラスのインスタンスを生成。
        val listener = HelloListener()
        //表示ボタンにリスナを設定。
        btClick.setOnClickListener(listener)
        //表示ボタンにリスナを設定。
        btClick1.setOnClickListener(listener)
        //表示ボタンにリスナを設定。
        btClick2.setOnClickListener(listener)
        //クリアボタンであるButtonオブジェクトを取得。
        val btClear = findViewById<Button>(R.id.btClear)
        //クリアボタンにリスナを設定。
        btClear.setOnClickListener(listener)
    }
    /**
     * ボタンをクリックしたときのリスナクラス。
     */
    private inner class HelloListener : View.OnClickListener {
        override fun onClick(view: View) {
            //名前入力欄であるEditTextオブジェクトを取得。
            val input = findViewById<EditText>(R.id.etName)

            //名前入力欄であるEditTextオブジェクトを取得。
            val input_file = findViewById<EditText>(R.id.fileName)

            //名前入力欄であるEditTextオブジェクトを取得。
            val input_delfile = findViewById<EditText>(R.id.delfileName)

            //メッセージを表示するTextViewオブジェクトを取得。
            val output = findViewById<TextView>(R.id.tvOutput)
            //入力された名前文字列を取得。
            val inputStr = input.text.toString()
            //入力された名前文字列を取得。
            val inputStr_file = input_file.text.toString()
            //入力された名前文字列を取得。
            val inputStr_delfile = input_delfile.text.toString()
            val df = SimpleDateFormat("HH:mm:ss")  //"yyyy/MM/dd HH:mm:ss"
            val date = Date()
            //input_count.setText("0")
            //idのR値に応じて処理を分岐。
            when(view.id) {
                //表示ボタンの場合…
                R.id.btClick -> {
                    //入力された名前文字列を取得。
                    val inputStr = input.text.toString()
                    //入力された名前文字列を取得。
                    val inputStr_file = input_file.text.toString()
                    //メッセージを表示。
                    val inputStr1 =  df.format(date) + "\n"+inputStr
                    output.text = inputStr1  //df.format(date) + "\n"+inputStr
                    //val fOut = openFileOutput("testfile.txt", Context.MODE_PRIVATE)
                    val fOut = openFileOutput(inputStr_file, Context.MODE_PRIVATE)
                    fOut.write(inputStr1.toByteArray())
                    fOut.close()
                }
                R.id.btClick1 -> {
                    var temp=""
                    var pathUtf8 =  getFilesDir().getAbsolutePath(); //"com.example.hellosample/files/testfile.txt"
                    //temp = File(pathUtf8+"/testfile.txt").readText(Charsets.UTF_8)
                    temp = File(pathUtf8+"/"+ inputStr_file).readText(Charsets.UTF_8)

                    output.text = temp  //df.format(date) + "\n"  + temp
                    input.setText("")
                }
                R.id.btClick2 -> {
                    var pathUtf8 =  getFilesDir().getAbsolutePath();

                    //ファイル名の一覧を取得する
                    val file = File(pathUtf8)
                    val files = file.listFiles()
                    //取得した一覧を表示する
                    var f =""
                    for (i in files.indices) {
                        val fi= files[i]
                        val files_: String = fi.toString().replace( pathUtf8+ "/" ,"")
                        f = "ファイル" + (i + 1) +" "+ files_ +"\n"+ f
                    }
                    output.text = f

                    val file1 = File(pathUtf8+"/"+ inputStr_delfile)
                    if (file1 != null && file1.length() > 0) {
                        file1.delete()
                    } else {
                        //file.delete()
                    }
                }

                //クリアボタンの場合…
                R.id.btClear -> {
                    //名前入力欄を空文字に設定。
                    input.setText("")
                    //メッセージ表示欄を空文字に設定。
                    output.text = ""

                }
            }
        }
    }
}
```

```activitymain.xml
<?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">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/tv_name"/>

    <EditText
            android:id="@+id/etName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="text" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="保存File名を入力してください"/>

    <EditText
            android:id="@+id/fileName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="text" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="削除するFile名を入力してください"/>

    <EditText
        android:id="@+id/delfileName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="text" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btClick"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/bt_click"/>

        <Button
            android:id="@+id/btClick1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/bt_click1" />

        <Button
            android:id="@+id/btClick2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/bt_click2" />

        <Button
            android:id="@+id/btClear"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/bt_clear"/>
    </LinearLayout>

    <ScrollView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/tvOutput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="25dp"
            android:text=""
            android:textSize="25sp" />
    </ScrollView>

</LinearLayout>
```

```strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Speech to Text</string>
    <string name="file_name">保存File名を入力してください</string>
    <string name="del_file_name">削除するFile名を入力してください</string>
    <string name="tv_name">音声入力してください</string>
    <string name="bt_click">保存</string>
    <string name="bt_click1">表示</string>
    <string name="bt_click2">File削除</string>
    <string name="bt_clear">クリア</string>
</resources>
```