Open In App

How to Build a Simple Voice Typer App in Android using Java?

Improve
Improve
Like Article
Like
Save
Share
Report

Pre-requisites:

In this article, we are going to build a simple Voice Typer app in Android using Java. This is a glimpse of the application we are going to build. The application contains a single Activity with two TextViews, one Spinner to choose language, an EditText to display the message, and two clickable ImageViews one to give voice input and the other to copy the message to the clipboard. We are going to use RecognizerIntent class to get voice input from users. A sample video is given below to get an idea about what we are going to do in this article.

Preview:

Step by Step Implementation

Step 1: Create a New Project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.

Step 2: Adding Vector Assets

Let’s add the necessary vector assets and drawable resource files. Go to app > res > drawable and add the following XML files. 

ic_mic.xml (Mic Icon)

XML




    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
  <path
      android:fillColor="@android:color/white"
      android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,
                        -3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,
                        5.1S6.7,14 6.7,11L5,11c0,3.41 2.72,6.23 6,6.72L11,21h2v-3.28c3.28,
                        -0.48 6,-3.3 6,-6.72h-1.7z"/>
</vector>


Preview:

ic_mic.xml

ic_copy.xml (Clipboard Icon)

XML




    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
  <path
      android:fillColor="@android:color/white"
      android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,
                        5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,
                        -0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z"/>
</vector>


Preview:

ic_copy.xml

et_bg.xml (Custom Background for EditText)

XML




<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true">
        <shape android:shape="rectangle">
            <stroke android:color="@color/purple_200" android:width="2dp"/>
            <corners android:radius="5dp"/>
        </shape>
    </item>
    <item android:state_focused="false">
        <shape android:shape="rectangle">
            <stroke android:color="#808080" android:width="2dp"/>
            <corners android:radius="5dp"/>
        </shape>
    </item>
</selector>


Preview:

et_bg.xml

Here is a screenshot for reference.

Step 3: Working with the activity_main.xml file

We have added the necessary resource files for the application we are building. Now, Let’s design the UI for our application. Add this layout resource file to app > res > layout. Below is the code for the activity_main.xml file. 

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
  
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="GeeksforGeeks"
        android:textColor="@android:color/holo_green_dark"
        android:textSize="48sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
  
    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="40dp"
        android:layout_marginTop="60dp"
        android:text="Choose your Language"
        android:textColor="@color/black"
        android:textSize="20sp"
        android:textStyle="normal"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />
  
    <Spinner
        android:id="@+id/spLang"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="55dp"
        android:layout_marginTop="18dp"
        android:layout_marginEnd="56dp"
        android:minHeight="48dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2"
        tools:ignore="SpeakableTextPresentCheck" />
  
    <EditText
        android:id="@+id/etSpeech"
        android:layout_width="350dp"
        android:layout_height="350dp"
        android:layout_marginStart="30dp"
        android:layout_marginTop="29dp"
        android:layout_marginEnd="31dp"
        android:background="@drawable/et_bg"
        android:ems="10"
        android:gravity="start|top"
        android:inputType="textMultiLine"
        android:maxLines="20"
        android:padding="10dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/spLang"
        tools:ignore="SpeakableTextPresentCheck" />
  
    <ImageView
        android:id="@+id/ivSpeak"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginStart="96dp"
        android:layout_marginTop="25dp"
        android:clickable="true"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/etSpeech"
        app:srcCompat="@drawable/ic_mic"
        tools:ignore="SpeakableTextPresentCheck" />
  
    <ImageView
        android:id="@+id/ivCopy"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginTop="25dp"
        android:layout_marginEnd="96dp"
        android:clickable="true"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/etSpeech"
        app:srcCompat="@drawable/ic_copy"
        tools:ignore="SpeakableTextPresentCheck" />
  
</androidx.constraintlayout.widget.ConstraintLayout>


Preview:

activity_main.xml

Step 4: Working with the MainActivity.java file

Now it’s time to initialize everything in MainActivity and implement Spinner and RecognizerIntent. Here is the complete code for MainActivity. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.

Java




package com.cs.voicetyper;
  
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
  
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;
  
import java.util.ArrayList;
  
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener{
  
    EditText etText;
    ImageView ivMic,ivCopy;
    Spinner spLangs;
    String lcode = "en-US";
  
    // Languages included
    String[] languages = {"English","Tamil","Hindi","Spanish","French",
                          "Arabic","Chinese","Japanese","German"};
  
    // Language codes
    String[] lCodes = {"en-US","ta-IN","hi-IN","es-CL","fr-FR",
                       "ar-SA","zh-TW","jp-JP","de-DE"};
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
  
        // initialize views
        etText = findViewById(R.id.etSpeech);
        ivMic = findViewById(R.id.ivSpeak);
        ivCopy = findViewById(R.id.ivCopy);
        spLangs = findViewById(R.id.spLang);
  
        // set onSelectedItemListener for the spinner
        spLangs.setOnItemSelectedListener(this);
  
        // setting array adapter for spinner
        ArrayAdapter adapter = new ArrayAdapter(this, R.layout.support_simple_spinner_dropdown_item,languages);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spLangs.setAdapter(adapter);
  
        // on click listener for mic icon
        ivMic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // creating intent using RecognizerIntent to convert speech to text
                Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,lcode);
                intent.putExtra(RecognizerIntent.EXTRA_PROMPT,"Speak now!");
                // starting intent for result
                activityResultLauncher.launch(intent);
            }
        });
  
        // on click listener to copy the speech
        ivCopy.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // code to copy to clipboard
                ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
                clipboardManager.setPrimaryClip(ClipData.newPlainText("label",etText.getText().toString().trim()));
                Toast.makeText(MainActivity.this, "Copied!", Toast.LENGTH_SHORT).show();
            }
        });
    }
  
    // activity result launcher to start intent
    ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    // if result is not empty
                    if (result.getResultCode() == Activity.RESULT_OK && result.getData()!=null) {
                        // get data and append it to editText
                        ArrayList<String> d=result.getData().getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
                        etText.setText(etText.getText()+" "+d.get(0));
                    }
                }
            });
  
    @Override
    public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
        // setting lcode corresponding
          // to the language selected
        lcode = lCodes[i];
    }
  
    @Override
    public void onNothingSelected(AdapterView<?> adapterView) {
        // automatically generated method 
          // for implementing onItemSelectedListener
    }
}


That’s it. Now we can run the application. Make sure that your project contains all the following files.

Here is the preview of the final application.

Output:



Last Updated : 19 Nov, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads