<p>This post is about how to implement speech to text feature in an android application using <span style="color: #0000ff;"><strong>SpeechRecognizer</strong></span>. <span style="color: #008000;"><strong>Speech to text</strong></span> means that anything that the user says is converted into text.</p> 
 
 
 
 
 
<div class="wp-block-buttons is-content-justification-center is-layout-flex wp-block-buttons-is-layout-flex"> 
<div class="wp-block-button"><a class="wp-block-button__link has-white-color has-text-color has-background" style="background-color: #040b6d;" href="https://github.com/arunk7839/SpeechToTextDemo"><strong>DOWNLOAD CODE</strong></a></div> 
</div> 
<p><amp-youtube layout="responsive" width="1200" height="675" data-videoid="qSVQW0S36Ek" title="Android Speech to Text Example using SpeechRecognizer"><a placeholder href="https://youtu.be/qSVQW0S36Ek"><img src="https://i.ytimg.com/vi/qSVQW0S36Ek/hqdefault.jpg" layout="fill" object-fit="cover" alt="Android Speech to Text Example using SpeechRecognizer"></a></amp-youtube></p> 
<h4><span style="color: #000080;"><strong>SpeechRecognizer</strong></span></h4> 
<p><strong><span style="color: #008000;">SpeechRecognizer</span></strong> class provides access to the speech recognition service. This service allows access to the speech recognizer. <br />This class&#8217;s methods must be invoked only from the main application thread.</p> 
<h4><span style="color: #000080;"><strong>Creating new Project</strong></span></h4> 
<p class="p1">1. Create a new project by going to <span style="color: #008000;"><b>File </b><span class="s1"><b>⇒</b></span></span><b><span style="color: #008000;"> New Android Project</span>,</b> fill the required details and then click on <span style="color: #0000ff;"><strong>finish</strong></span>.</p> 
<p>2. Open AndroidManifest.xml file and add <strong><span style="color: #0000ff;">RECORD_AUDIO</span></strong> permission as shown below:</p> 
<p><span style="color: #0000ff;"><strong>AndroidManifest.xml</strong></span></p> 
<pre><;?xml version="1.0" encoding="utf-8"?>;<br /><;manifest xmlns:android="http://schemas.android.com/apk/res/android"<br /> package="com.c1ctech.speechtotextdemo">;<br /><br /><strong><span style="color: #008000;"> <;uses-permission android:name="android.permission.RECORD_AUDIO" />;</span></strong><br /> <br /> <;application<br /> android:allowBackup="true"<br /> android:icon="@mipmap/ic_launcher"<br /> android:label="@string/app_name"<br /> android:roundIcon="@mipmap/ic_launcher_round"<br /> android:supportsRtl="true"<br /> android:theme="@style/Theme.SpeechToTextDemo">;<br /> <;activity<br /> android:name=".MainActivity"<br /> android:exported="true">;<br /> <;intent-filter>;<br /> <;action android:name="android.intent.action.MAIN" />;<br /><br /> <;category android:name="android.intent.category.LAUNCHER" />;<br /> <;/intent-filter>;<br /> <;/activity>;<br /> <;/application>;<br /><br /><;/manifest>;</pre> 
<h4><span style="color: #000080;"><strong>The Layout File</strong></span></h4> 
<p>3. The below layout file consist of an ImageButton for the mic icon and an EditText to show the text that is converted from the speech.</p> 
<p><span style="color: #0000ff;"><strong>activity_main.xml</strong></span></p> 
<pre><;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> xmlns:app="http://schemas.android.com/apk/res-auto"<br /> xmlns:tools="http://schemas.android.com/tools"<br /> android:layout_width="match_parent"<br /> android:layout_height="match_parent"<br /> tools:context=".MainActivity">;<br /><br /> <;TextView<br /> android:id="@+id/tv_speech_to_text"<br /> android:layout_width="match_parent"<br /> android:layout_height="wrap_content"<br /> android:layout_alignParentTop="true"<br /> android:layout_marginTop="160dp"<br /> android:gravity="center"<br /> android:text="Speech to Text"<br /> android:textColor="@color/purple_700"<br /> android:textSize="30sp"<br /> android:textStyle="bold" />;<br /><br /> <;RelativeLayout<br /> android:id="@+id/rl"<br /> android:layout_width="match_parent"<br /> android:layout_height="wrap_content"<br /> android:layout_below="@+id/tv_speech_to_text"<br /> android:layout_marginLeft="10dp"<br /> android:layout_marginTop="30dp"<br /> android:layout_marginRight="10dp">;<br /><br /> <;EditText<br /> android:id="@+id/edtSpeechText"<br /> android:layout_width="match_parent"<br /> android:layout_height="wrap_content"<br /> android:layout_centerInParent="true"<br /> android:layout_marginRight="15dp"<br /> android:layout_toLeftOf="@id/imgBtnMic"<br /> android:hint="Text output of recorded audio"<br /> android:padding="10dp" />;<br /><br /> <;ImageButton<br /> android:id="@+id/imgBtnMic"<br /> android:layout_width="40dp"<br /> android:layout_height="40dp"<br /> android:layout_alignParentRight="true"<br /> android:backgroundTint="#F9F8FA"<br /> android:paddingRight="10dp"<br /> android:src="@drawable/ic_mic_off" />;<br /><br /> <;/RelativeLayout>;<br /><br /><;/RelativeLayout>;</pre> 
<h4><span style="color: #000080;"><strong>Requesting Permission at Runtime</strong></span></h4> 
<p>4. From Android Marshmallow, we must have to take <strong><span style="color: #008000;">RECORD_AUDIO</span></strong> permission from the user at runtime.</p> 
<pre>if(isPermissionGranted())<br />{ <strong><span style="color: #008000;">//request permission if it is not granted by user.</span></strong><br /> requestPermission();<br />}<br /><br />private void requestPermission() {<br /> if (Build.VERSION.SDK_INT >;= Build.VERSION_CODES.M) {<br /> ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, PERMISSION_RECORD_AUDIO_REQUEST);<br /> }<br />}<br /><br />private boolean isPermissionGranted() {<br /> return ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED;<br />}<br /><br />@Override<br />public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {<br /> super.onRequestPermissionsResult(requestCode, permissions, grantResults);<br /> if (requestCode == PERMISSION_RECORD_AUDIO_REQUEST &;&; grantResults.length >; 0) {<br /><br /><strong><span style="color: #008000;"> //when user allows the permission.</span></strong><br /> if (grantResults[0] == PackageManager.PERMISSION_GRANTED)<br /> Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();<br /> }<br />}</pre> 
<h4><strong><span style="color: #000080;">Creating a SpeechRecognizer </span></strong></h4> 
<p>5. To implement speech to text functionality, we need to create a <strong><span style="color: #008000;">SpeechRecognizer</span></strong> instance. We also need an Intent to listen to the speech.</p> 
<pre>private SpeechRecognizer speechRecognizer;<br /><br /><strong><span style="color: #008000;">//creating SpeechRecognizer instance</span></strong><br />speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);<br /><br />final Intent speechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);<br />speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);<br />speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());</pre> 
<p> ;</p> 
<h4><strong><span style="color: #000080;">Setting RecognitionListener to SpeechRecognizer</span></strong></h4> 
<p>6<strong>. </strong>The <span style="color: #008000;"><strong>setRecognitionListener()</strong></span> will receive all the callbacks from the created <strong><span style="color: #008000;">SpeechRecognizer</span></strong>.</p>
<!-- WP QUADS Content Ad Plugin v. 2.0.98.1 -->
<div class="quads-location quads-ad2" id="quads-ad2" style="float:none;margin:0px;">

</div>
 
<pre>speechRecognizer.setRecognitionListener(new RecognitionListener() {<br /> @Override<br /> public void onReadyForSpeech(Bundle bundle) {<br /> }<br /><br /><strong><span style="color: #008000;"> //The user has started to speak.</span></strong><br /> @Override<br /> public void onBeginningOfSpeech() {<br /> editText.setText("");<br /> editText.setHint("Listening...");<br /> }<br /><br /> @Override<br /> public void onRmsChanged(float v) {<br /> }<br /><br /> @Override<br /> public void onBufferReceived(byte[] bytes) {<br /> }<br /><br /> @Override<br /> public void onEndOfSpeech() {<br /> }<br /><br /> @Override<br /> public void onError(int i) {<br /> }<br /><br /><span style="color: #008000;"><strong> //called when recognition results are ready.</strong></span><br /> @Override<br /> public void onResults(Bundle bundle) {<br /> micButton.setImageResource(R.drawable.ic_mic_off);<br /> ArrayList<;String>; data = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);<br /> editText.setText(data.get(0));<br /> }<br /><br /> @Override<br /> public void onPartialResults(Bundle bundle) {<br /> }<br /><br /> @Override<br /> public void onEvent(int i, Bundle bundle) {<br /> }<br />});</pre> 
<h4><strong><span style="color: #000080;">Adding Touch Listener to Button</span></strong></h4> 
<ul> 
<li><strong><span style="color: #0000ff;">ACTION_DOWN (Button pressed gesture has started):</span></strong> starts listening for speech.</li> 
<li><strong><span style="color: #0000ff;">ACTION_UP (Button pressed gesture has finished):</span></strong> stops listening for speech.</li> 
</ul> 
<pre>micButton.setOnTouchListener(new View.OnTouchListener() {<br /> @Override<br /> public boolean onTouch(View view, MotionEvent motionEvent) {<br /><br /> if (motionEvent.getAction() == MotionEvent.ACTION_UP) {<br /> speechRecognizer.stopListening();<br /> }<br /><br /> if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {<br /> micButton.setImageResource(R.drawable.ic_mic);<br /> speechRecognizer.startListening(speechRecognizerIntent);<br /> }<br /> return false;<br /> }<br />});</pre> 
<h4><span style="color: #000080;"><strong>Complete MainActivity Code</strong></span></h4> 
<p>7. Given below is the complete MainActivity code.</p> 
<pre>package com.c1ctech.speechtotextdemo;<br /><br />import androidx.appcompat.app.AppCompatActivity;<br />import android.os.Bundle;<br />import androidx.annotation.NonNull;<br />import androidx.core.app.ActivityCompat;<br />import androidx.core.content.ContextCompat;<br />import android.Manifest;<br />import android.content.Intent;<br />import android.content.pm.PackageManager;<br />import android.os.Build;<br />import android.speech.RecognitionListener;<br />import android.speech.RecognizerIntent;<br />import android.speech.SpeechRecognizer;<br />import android.view.MotionEvent;<br />import android.view.View;<br />import android.widget.*;<br />import android.widget.Toast;<br />import java.util.ArrayList;<br />import java.util.Locale;<br /><br />public class MainActivity extends AppCompatActivity {<br /><br /> public static final Integer PERMISSION_RECORD_AUDIO_REQUEST = 1;<br /> private SpeechRecognizer speechRecognizer;<br /> private EditText editText;<br /> private ImageButton micButton;<br /><br /> @Override<br /> protected void onCreate(Bundle savedInstanceState) {<br /> super.onCreate(savedInstanceState);<br /> setContentView(R.layout.activity_main);<br /><br /> if (isPermissionGranted()) {<br /> requestPermission();<br /> }<br /><br /> editText = findViewById(R.id.edtSpeechText);<br /> micButton = findViewById(R.id.imgBtnMic);<br /> speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);<br /><br /> final Intent speechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);<br /> speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);<br /> speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());<br /><br /> speechRecognizer.setRecognitionListener(new RecognitionListener() {<br /> @Override<br /> public void onReadyForSpeech(Bundle bundle) {<br /> }<br /><br /> @Override<br /> public void onBeginningOfSpeech() {<br /> editText.setText("");<br /> editText.setHint("Listening...");<br /> }<br /><br /> @Override<br /> public void onRmsChanged(float v) {<br /> }<br /><br /> @Override<br /> public void onBufferReceived(byte[] bytes) {<br /> }<br /><br /> @Override<br /> public void onEndOfSpeech() {<br /> }<br /><br /> @Override<br /> public void onError(int i) {<br /> }<br /><br /> @Override<br /> public void onResults(Bundle bundle) {<br /> micButton.setImageResource(R.drawable.ic_mic_off);<br /> ArrayList<;String>; data = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);<br /> editText.setText(data.get(0));<br /> }<br /><br /> @Override<br /> public void onPartialResults(Bundle bundle) {<br /> }<br /><br /> @Override<br /> public void onEvent(int i, Bundle bundle) {<br /><br /> }<br /> });<br /><br /> micButton.setOnTouchListener(new View.OnTouchListener() {<br /> @Override<br /> public boolean onTouch(View view, MotionEvent motionEvent) {<br /><br /><strong><span style="color: #008000;"> //ACTION_UP: A pressed gesture has finished.</span></strong><br /> if (motionEvent.getAction() == MotionEvent.ACTION_UP) {<br /> speechRecognizer.stopListening();<br /> }<br /><br /><span style="color: #008000;"><strong> //ACTION_DOWN: A pressed gesture has started.</strong></span><br /> if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {<br /> micButton.setImageResource(R.drawable.ic_mic);<br /> speechRecognizer.startListening(speechRecognizerIntent);<br /> }<br /> return false;<br /> }<br /> });<br /> }<br /><br /> @Override<br /> protected void onDestroy() {<br /> super.onDestroy();<br /> speechRecognizer.destroy();<br /> }<br /><br /> private void requestPermission() {<br /> if (Build.VERSION.SDK_INT >;= Build.VERSION_CODES.M) {<br /> ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, PERMISSION_RECORD_AUDIO_REQUEST);<br /> }<br /> }<br /><br /> private boolean isPermissionGranted() {<br /> return ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED;<br /> }<br /><br /> @Override<br /> public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {<br /> super.onRequestPermissionsResult(requestCode, permissions, grantResults);<br /> if (requestCode == PERMISSION_RECORD_AUDIO_REQUEST &;&; grantResults.length >; 0) {<br /><br /> if (grantResults[0] == PackageManager.PERMISSION_GRANTED)<br /> Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();<br /> }<br /> }<br />}</pre> 
<p>When you run the app it will look like this as shown below:</p> 
<p><img class="alignnone wp-image-2971" src="https://c1ctech.com/wp-content/uploads/2021/12/Screenshot_20211201-195838_Permission-controller-498x1024.jpg" alt="" width="312" height="642" /> <img class="alignnone wp-image-2972" src="https://c1ctech.com/wp-content/uploads/2021/12/Screenshot_20211202-114237_SpeechToTextDemo-498x1024.jpg" alt="" width="312" height="641" />

