Thursday, May 2, 2019

Tutorial Membuat Aplikasi Text to Speech dan Speech to Text Kotlin menggunakan Android Studio

TTS-STT KOTLIN
TTS-STT KOTLIN
Halo sobat 48😁 kali ini saya akan membagikan sebuah artikel yang membahas Tutorial Membuat Aplikasi Text to Speech dan Speech to Text Kotlin menggunakan Android Studio. Mungkin jika kalian cari di Youtube dan Google sudah banyak artikel yang membuat tutorial ini. Namun tutorial yang saya buat ini menggunakan bahasa Kotlin, bukan Java seperti yang lain. Karena menurut saya masih jarang yang migrasi ke bahasa Kotlin ini.

Nah, disini saya akan membuatkan tutorial cara membuat Text to Speech dan Speech to Text bahasa Kotlin tersebut. Jika kalian ingin SOURCE CODE Text to Speech dan Speech to Text Kotlin ini, silahkan download di Github saya DISINI. Tetapi jika kalian ingin tahu cara mengaplikasikannya, silahkan lanjut baca artikel ini sampai selesai😄

Jika kalian ingin mencoba membuat aplikasi ini dengan tutorial versi video, berikut saya berikan Videonya:

Jangan lupa subscribe Channel Youtube saya juga ya Azhar Rivaldi, karena disana ada banyak tutorial-tutorial untuk membuat aplikasi lainnya. Oke langsung saja tanpa basa-basi lagi kita langsung ke langkah pertama :

1. Buat project baru di Android Studio dengan cara klik File ⇒ Project Baru. Ketika diminta untuk memilih Default Activity, pilih Empty Activity dan klik next. Untuk minSDK, disini saya set API 17 ya.

2. Karena kita menggunakan Kotlin, maka ubah build.gradle menjadi seperti ini :


dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

3. Tambahkan Permission di Android Manifest.xml seperti ini :


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.azhar.texttospeech">

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme.NoActionBar">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

4. Ubah isi MainActivity.kt dan activity_main.xml menjadi seperti ini :


package com.azhar.texttospeech

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.support.design.widget.Snackbar
import com.azhar.texttospeech.translation_engine.ConversionCallback
import com.azhar.texttospeech.translation_engine.TranslatorFactory
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : BasePermissionActivity() {

    override fun getActivityLayout(): Int {

        return R.layout.activity_main
    }

    @SuppressLint("SetTextI18n")
    override fun setUpView() {

        setSupportActionBar(toolBar)

        //SPEECH TO TEXT
        speechToText.setOnClickListener({ view ->

            Snackbar.make(view, "Bicara Sekarang", Snackbar.LENGTH_LONG)
                .setAction("Action", null).show()

            TranslatorFactory
                .instance
                .with(TranslatorFactory.TRANSLATORS.SPEECH_TO_TEXT,
                    object : ConversionCallback {
                        override fun onSuccess(result: String) {
                            sttOutput.text = result
                        }

                        override fun onCompletion() {
                        }

                        override fun onErrorOccurred(errorMessage: String) {
                            erroConsole.text = "Speech2Text Error: $errorMessage"
                        }

                    }).initialize("Bicara Sekarang !!", this@MainActivity)

        })

        //TEXT TO SPEECH
        textToSpeech.setOnClickListener { view ->

            val stringToSpeak: String = ttsInput.text.toString()

            if (stringToSpeak.isNotEmpty()) {

                TranslatorFactory
                    .instance
                    .with(TranslatorFactory.TRANSLATORS.TEXT_TO_SPEECH,
                        object : ConversionCallback {
                            override fun onSuccess(result: String) {
                            }

                            override fun onCompletion() {
                            }

                            @SuppressLint("SetTextI18n")
                            override fun onErrorOccurred(errorMessage: String) {
                                erroConsole.text = "Text2Speech Error: $errorMessage"
                            }

                        })
                    .initialize(stringToSpeak, this)

            } else {
                ttsInput.setText("Invalid input")
                Snackbar.make(view, "Please enter some text to speak", Snackbar.LENGTH_LONG).show()
            }

        }

    }

    fun findString(listOfPossibleMatches: ArrayList?, stringToMatch: String): Boolean {

        if (null != listOfPossibleMatches) {

            for (transaltion in listOfPossibleMatches) {

                if (transaltion.contains(stringToMatch)) {

                    return true
                }
            }
        }
        return false
    }

    fun share(messageToShare: String, activity: Activity) {

        val shareIntent = Intent(Intent.ACTION_SEND)
        shareIntent.type = "text/plain"
        shareIntent.putExtra(Intent.EXTRA_TEXT, messageToShare)
        activity.startActivity(Intent.createChooser(shareIntent, "Share using"))
    }
}



<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context=".MainActivity">

    <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">

        <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#03a9f4"
                android:orientation="vertical"
                tools:showIn="@layout/activity_main">

            <android.support.v7.widget.Toolbar
                    android:id="@+id/toolBar"
                    card_view:title="TTS-SST"
                    card_view:titleTextColor="@color/white"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:background="#29b6fc"
                    android:elevation="4dp"
                    android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

            <android.support.v7.widget.CardView
                    android:id="@+id/card_view"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    android:backgroundTint="#29b6fc"
                    card_view:cardCornerRadius="4dp">

                <RelativeLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:padding="10dp">

                    <TextView
                            android:id="@+id/sttHeading"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_alignParentLeft="true"
                            android:layout_alignParentTop="true"
                            android:text="@string/speech_to_text"
                            android:textColor="@color/white"
                            android:textSize="21sp"
                            android:textStyle="bold"/>

                    <android.support.design.widget.FloatingActionButton
                            android:id="@+id/speechToText"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_alignParentRight="true"
                            android:layout_centerVertical="true"
                            android:layout_margin="@dimen/fab_margin"
                            android:backgroundTint="@color/colorPrimary"
                            android:src="@drawable/vector_hear"/>

                    <TextView
                            android:id="@+id/sttLabel"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_alignParentLeft="true"
                            android:layout_below="@+id/sttHeading"
                            android:layout_marginTop="10dp"
                            android:layout_toLeftOf="@+id/speechToText"
                            android:text="@string/speech_to_text_output"
                            android:textColor="@color/white"
                            android:textSize="13sp"/>

                    <ScrollView
                            android:id="@+id/wrap"
                            android:layout_width="wrap_content"
                            android:layout_height="80dp"
                            android:layout_alignParentLeft="true"
                            android:layout_below="@+id/sttLabel"
                            android:layout_marginTop="10dp"
                            android:layout_toLeftOf="@+id/speechToText"
                            android:background="#29b6fc">

                        <TextView
                                android:id="@+id/sttOutput"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:text="Speech to Text output will be shown here"
                                android:textColor="@color/colorPrimaryDark"
                                android:textSize="18sp"/>

                    </ScrollView>

                </RelativeLayout>

            </android.support.v7.widget.CardView>

            <android.support.v7.widget.CardView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    android:backgroundTint="#29b6fc"
                    card_view:cardCornerRadius="4dp">

                <RelativeLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:padding="10dp"
                >

                    <TextView
                            android:layout_toLeftOf="@+id/textToSpeech"
                            android:id="@+id/ttsHeading"
                            android:layout_alignParentLeft="true"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_centerVertical="true"
                            android:gravity="left"
                            android:textStyle="bold"
                            android:layout_alignParentTop="true"
                            android:text="Text to Speech"
                            android:textColor="@color/white"
                            android:textSize="21sp"
                    />

                    <android.support.design.widget.FloatingActionButton
                            android:id="@+id/textToSpeech"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:backgroundTint="@color/colorPrimary"
                            android:layout_alignParentRight="true"
                            android:layout_margin="@dimen/fab_margin"
                            android:src="@drawable/vector_speak"/>

                    <TextView
                            android:id="@+id/ttsLabel"
                            android:layout_below="@+id/ttsHeading"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginTop="10dp"
                            android:layout_alignParentLeft="true"
                            android:layout_toLeftOf="@+id/textToSpeech"
                            android:focusableInTouchMode="true"
                            android:backgroundTint="@color/colorAccent"
                            android:text="Text to speech input:"
                            android:textColor="@color/white"
                            android:textSize="13sp"
                    />

                    <android.support.v7.widget.AppCompatEditText
                            android:id="@+id/ttsInput"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_below="@+id/ttsLabel"
                            android:layout_marginBottom="10dp"
                            android:layout_marginTop="20dp"
                            android:gravity="left"
                            android:focusable="true"
                            app:backgroundTint="@color/colorPrimary"
                            android:hint="Enter Text and click on speak button"
                            android:textColorHint="@color/colorPrimaryDark"
                            android:textColor="@color/white"
                            android:textSize="18sp"
                    />

                </RelativeLayout>

            </android.support.v7.widget.CardView>

            <android.support.v7.widget.CardView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    android:backgroundTint="#29b6fc"
                    card_view:cardCornerRadius="4dp">

                <LinearLayout
                        android:padding="10dp"
                        android:layout_width="match_parent"
                        android:orientation="vertical"
                        android:layout_height="wrap_content">

                    <TextView
                            android:id="@+id/error_heading"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_below="@+id/tts_border"
                            android:layout_marginTop="10dp"
                            android:gravity="left"
                            android:text="ERROR HANDLING "
                            android:textAllCaps="true"
                            android:textColor="@color/white"
                            android:textSize="21sp"
                            android:textStyle="bold"/>

                    <TextView
                            android:textColor="@color/white"
                            android:id="@+id/error_label"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_below="@+id/error_heading"
                            android:layout_marginTop="10dp"
                            android:gravity="left"
                            android:text="Error message:"
                            android:textSize="13sp"
                    />

                    <TextView
                            android:id="@+id/erroConsole"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_below="@+id/error_label"
                            android:layout_marginBottom="10dp"
                            android:layout_marginTop="10dp"
                            android:gravity="left"
                            android:text="Error will be shown here"
                            android:textColor="#F00"
                            android:textSize="20sp"
                            android:textStyle="bold"/>

                </LinearLayout>

            </android.support.v7.widget.CardView>

        </LinearLayout>

    </ScrollView>

</android.support.design.widget.CoordinatorLayout>

5. Untuk Permission Android M, buat BasePermissionActivity.kt :


package com.azhar.texttospeech

import android.Manifest
import android.annotation.TargetApi
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import java.util.*

abstract class BasePermissionActivity : AppCompatActivity() {

    private val REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getActivityLayout())

        if (Build.VERSION.SDK_INT >= 23) {

            fuckMarshmallow()
        } else {

            setUpView()
        }
    }

    //SetUp views after permission granted
    abstract fun setUpView()

    // activity view
    abstract fun getActivityLayout(): Int

    @TargetApi(Build.VERSION_CODES.M)
    private fun fuckMarshmallow() {

        val permissionsList = ArrayList()

        if (!isPermissionGranted(permissionsList, Manifest.permission.RECORD_AUDIO))

            if (permissionsList.size > 0) {

                requestPermissions(
                    permissionsList.toTypedArray(),
                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS
                )
                return
            }
        //add listeners on view
        setUpView()
    }

    @TargetApi(Build.VERSION_CODES.M)
    private fun isPermissionGranted(permissionsList: MutableList, permission: String): Boolean {

        if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
            permissionsList.add(permission)

            // Check for Rationale Option
            if (!shouldShowRequestPermissionRationale(permission))
                return false
        }
        return true
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
        when (requestCode) {
            REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS -> {
                val perms = HashMap()
                perms[Manifest.permission.RECORD_AUDIO] = PackageManager.PERMISSION_GRANTED

                for (i in permissions.indices)
                    perms[permissions[i]] = grantResults[i]

                if (perms[Manifest.permission.RECORD_AUDIO] == PackageManager.PERMISSION_GRANTED) {

                    // All Permissions Granted
                    setUpView()

                } else {
                    // Permission Denied
                    Toast.makeText(applicationContext, "Some Permissions are Denied Exiting App", Toast.LENGTH_SHORT)
                        .show()

                    finish()
                }
            }
            else -> super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        }
    }
}


6. Buat TranslatorFactory.kt untuk penerjemah ucapan kata :


package com.azhar.texttospeech.translation_engine

import android.app.Activity
import com.azhar.texttospeech.translation_engine.translators.SpeechToTextConverter
import com.azhar.texttospeech.translation_engine.translators.TextToSpeckConverter

class TranslatorFactory private constructor() {

    enum class TRANSLATORS {
        TEXT_TO_SPEECH,
        SPEECH_TO_TEXT
    }

    interface IConverter {
        fun initialize(message: String, appContext: Activity): IConverter

        fun getErrorText(errorCode: Int): String
    }

    fun with(TRANSLATORS: TRANSLATORS, conversionCallback: ConversionCallback): IConverter {
        return when (TRANSLATORS) {
            TranslatorFactory.TRANSLATORS.TEXT_TO_SPEECH ->
                //Get Text to speech translator
                TextToSpeckConverter(conversionCallback)

            TranslatorFactory.TRANSLATORS.SPEECH_TO_TEXT ->

                //Get speech to text translator
                SpeechToTextConverter(conversionCallback)
        }
    }

    companion object {
        val instance = TranslatorFactory()
    }
}

7. Buat ConversionCallback.kt :


package com.azhar.texttospeech.translation_engine

interface ConversionCallback {

    fun onSuccess(result: String)

    fun onCompletion()

    fun onErrorOccurred(errorMessage: String)

} 

8. Untuk penerjemah teks menjadi ucapan, buat TextToSpeckConverter.kt :


package com.azhar.texttospeech.translation_engine.translators

import android.annotation.TargetApi
import android.app.Activity
import android.os.Build
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.util.Log
import com.azhar.texttospeech.translation_engine.ConversionCallback
import com.azhar.texttospeech.translation_engine.TranslatorFactory
import java.util.*

class TextToSpeckConverter (private val conversionCallaBack: ConversionCallback) : TranslatorFactory.IConverter {
    private val TAG = SpeechToTextConverter::class.java.name
    private var textToSpeech: TextToSpeech? = null

    override fun initialize(message: String, appContext: Activity): TranslatorFactory.IConverter {
        textToSpeech = TextToSpeech(appContext, TextToSpeech.OnInitListener { status ->
            if (status != TextToSpeech.ERROR) {
                textToSpeech!!.language = Locale.getDefault()
                textToSpeech!!.setPitch(1.3f)
                textToSpeech!!.setSpeechRate(1f)
                textToSpeech!!.language = Locale.US

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    ttsGreater21(message)
                } else {
                    ttsUnder20(message)
                }
            } else {
                conversionCallaBack.onErrorOccurred("Failed to initialize TTS engine")
            }
        })
        return this
    }

    private fun finish() {
        if (textToSpeech != null) {
            textToSpeech!!.stop()
            textToSpeech!!.shutdown()
        }
    }

    private fun ttsUnder20(text: String) {
        val map = HashMap()
        map[TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID] = "MessageId"

        textToSpeech!!.setOnUtteranceProgressListener(object : UtteranceProgressListener() {

            override fun onStart(utteranceId: String) {
                Log.d(TAG, "started listening")
            }

            override fun onError(utteranceId: String?, errorCode: Int) {
                super.onError(utteranceId, errorCode)
                conversionCallaBack.onErrorOccurred("Some Error Occurred " + getErrorText(errorCode))

            }

            override fun onError(utteranceId: String) {
                conversionCallaBack.onErrorOccurred("Some Error Occurred $utteranceId")
            }

            override fun onDone(utteranceId: String) {
                //do some work here
                conversionCallaBack.onCompletion()
                finish()
            }
        })

        textToSpeech!!.speak(text, TextToSpeech.QUEUE_FLUSH, map)

    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private fun ttsGreater21(text: String) {
        val utteranceId = this.hashCode().toString() + ""
        textToSpeech!!.speak(text, TextToSpeech.QUEUE_FLUSH, null, utteranceId)
    }

    override fun getErrorText(errorCode: Int): String {
        val message: String
        when (errorCode) {
            TextToSpeech.ERROR -> message = "Generic error"
            TextToSpeech.ERROR_INVALID_REQUEST -> message = "Client side error, invalid request"
            TextToSpeech.ERROR_NOT_INSTALLED_YET -> message = "Insufficient download of the voice data"
            TextToSpeech.ERROR_NETWORK -> message = "Network error"
            TextToSpeech.ERROR_NETWORK_TIMEOUT -> message = "Network timeout"
            TextToSpeech.ERROR_OUTPUT -> message = "Failure in to the output (audio device or a file)"
            TextToSpeech.ERROR_SYNTHESIS -> message = "Failure of a TTS engine to synthesize the given input."
            TextToSpeech.ERROR_SERVICE -> message = "error from server"
            else -> message = "Didn't understand, please try again."
        }
        return message
    }
}

9. Yang terakhir buat SpeechToTextConverter.kt untuk meng-convert ucapan menjadi teks :


package com.azhar.texttospeech.translation_engine.translators

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.speech.RecognitionListener
import android.speech.RecognizerIntent
import android.speech.SpeechRecognizer
import android.util.Log
import com.azhar.texttospeech.translation_engine.ConversionCallback
import com.azhar.texttospeech.translation_engine.TranslatorFactory
import java.util.*

class SpeechToTextConverter (private val conversionCallback: ConversionCallback) : TranslatorFactory.IConverter {

    private val TAG = SpeechToTextConverter::class.java.name

    override fun initialize(message: String, appContext: Activity): SpeechToTextConverter {

        val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
        intent.putExtra(
            RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
        )
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
        intent.putExtra(
            RecognizerIntent.EXTRA_PROMPT,
            message
        )
        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5)
        intent.putExtra(
            RecognizerIntent.EXTRA_CALLING_PACKAGE,
            appContext.getPackageName()
        )

        //Add listeners
        val listener = CustomRecognitionListener()
        val sr = SpeechRecognizer.createSpeechRecognizer(appContext)
        sr.setRecognitionListener(listener)
        sr.startListening(intent)
        return this
    }

    internal inner class CustomRecognitionListener : RecognitionListener {

        override fun onReadyForSpeech(params: Bundle) {
            Log.d(TAG, "onReadyForSpeech")
        }

        override fun onBeginningOfSpeech() {
            Log.d(TAG, "onBeginningOfSpeech")
        }

        override fun onRmsChanged(rmsdB: Float) {
            Log.d(TAG, "onRmsChanged")
        }

        override fun onBufferReceived(buffer: ByteArray) {
            Log.d(TAG, "onBufferReceived")
        }

        override fun onEndOfSpeech() {
            Log.d(TAG, "onEndofSpeech")
        }

        override fun onError(error: Int) {
            Log.e(TAG, "error $error")
            conversionCallback.onErrorOccurred(getErrorText(error))
        }

        override fun onResults(results: Bundle) {
            var translateResults = String()
            val data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
            for (result in data) {
                translateResults += result + "\n"
            }
            conversionCallback.onSuccess(translateResults)
        }

        override fun onPartialResults(partialResults: Bundle) {
            Log.d(TAG, "onPartialResults")
        }

        override fun onEvent(eventType: Int, params: Bundle) {
            Log.d(TAG, "onEvent $eventType")
        }
    }

    override fun getErrorText(errorCode: Int): String {
        val message: String
        when (errorCode) {
            SpeechRecognizer.ERROR_AUDIO -> message = "Audio recording error"
            SpeechRecognizer.ERROR_CLIENT -> message = "Client side error"
            SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS -> message = "Insufficient permissions"
            SpeechRecognizer.ERROR_NETWORK -> message = "Network error"
            SpeechRecognizer.ERROR_NETWORK_TIMEOUT -> message = "Network timeout"
            SpeechRecognizer.ERROR_NO_MATCH -> message = "No match"
            SpeechRecognizer.ERROR_RECOGNIZER_BUSY -> message = "RecognitionService busy"
            SpeechRecognizer.ERROR_SERVER -> message = "error from server"
            SpeechRecognizer.ERROR_SPEECH_TIMEOUT -> message = "No speech input"
            else -> message = "Didn't understand, please try again."
        }
        return message
    }
}

10. Selesai dan kalian Run. Jika kalian mengikuti langkah-langkah diatas dengan baik, pasti aplikasi yang kalian buat akan berjalan sebagaimana mestinya. Namun jika mengalami Error, silahkan berikan komentar dan kita diskusikan bersama.

Demikian informasi yang saya bagikan untuk kalian. Jangan lupa bagikan artikel ini ke teman-teman kalian agar ikut membaca Tutorial Membuat Aplikasi Text to Speech dan Speech to Text Kotlin menggunakan Android Studio ini. Subscribe juga blog Rivaldi 48 ini agar kalian mendapatkan notifikasi saat Admin update artikel terbaru. Semoga kalian lebih nyaman dan mudah dalam mengakses Blog Rivaldi 48 dimanapun kalian berada. Terima Kasih. Follow Instagram Admin @azhardvls_

3 comments

Silahkan tinggalkan komentar jika Anda punya saran, kritik, atau pertanyaan seputar topik pembahasan. Gunakan bahasa yang bijak dan santun. Terima Kasih.
EmoticonEmoticon