How To Make A Voice Recorder App With Kotlin? (With Code Samples)

Elitist The Constantine
4 min readJan 10, 2023

Here is an example of a simple voice recorder app written in Kotlin for Android:

1-) Start by creating a new Android project in Android Studio, and then add the following permissions to the AndroidManifest.xml file:

2-) Next, create a new activity_main.xml file in the res/layout directory. This file will define the layout for the main activity of the app.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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:orientation="vertical"
tools:context=".MainActivity">

<Button
android:id="@+id/start_recording_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Recording" />

<Button
android:id="@+id/stop_recording_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop Recording"
android:enabled="false" />

</LinearLayout>

To add pause and resume functionality to your voice recorder app, you can use the pause() and resume() methods of the MediaRecorder class. Here's an example of how you might add this functionality to the app:

You would need to add two more buttons in the activity_main.xml to handle the pause and resume actions:

<Button
android:id="@+id/pause_recording_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pause Recording"
android:enabled="false" />

<Button
android:id="@+id/resume_recording_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Resume Recording"
android:enabled="false" />

In MainActivity.kt, you need to set onClickListeners to those two buttons:

pause_recording_button.setOnClickListener {
mediaRecorder?.pause()
start_recording_button.isEnabled = true
stop_recording_button.isEnabled = true
pause_recording_button.isEnabled = false
resume_recording_button.isEnabled = true
Toast.makeText(this, "Recording Paused", Toast.LENGTH_SHORT).show()
}

resume_recording_button.setOnClickListener {
mediaRecorder?.resume()
start_recording_button.isEnabled = false
stop_recording_button.isEnabled = true
pause_recording_button.isEnabled = true
resume_recording_button.isEnabled = false
Toast.makeText(this, "Recording Resumed", Toast.LENGTH_SHORT).show()
}

To manage the buttons state on the UI, you could change the state of the button while starting recording, pause and stop the recording. For example, in the start button onClickListener:

start_recording_button.setOnClickListener {
outputFile = "${Environment.getExternalStorageDirectory().absolutePath}/recording.3gp"
try {
// MediaRecorder configuration
// ...
start_recording_button.isEnabled = false
stop_recording_button.isEnabled = true
pause_recording_button.isEnabled = true
resume_recording_button.isEnabled = false
} catch (e: IllegalStateException) {
// handle error
} catch (e: IOException) {
// handle error
}
}

This layout defines two buttons: one for starting a recording, and one for stopping a recording. The "stop recording" button is initially disabled.

4-) Next, create a new MainActivity.kt file in the src/main/java directory. This file will define the behavior of the main activity of the app.

import android.Manifest
import android.content.pm.PackageManager
import android.media.MediaRecorder
import android.os.Bundle
import android.os.Environment
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.activity_main.*
import java.io.IOException

class MainActivity : AppCompatActivity() {
private var mediaRecorder: MediaRecorder? = null
private var outputFile: String = ""

override fun onCreate(savedInstanceState: Bundle?) {
// ...
// Request write external storage permission
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
}

// Set up the start recording button
start_recording_button.setOnClickListener {
outputFile = "${Environment.getExternalStorageDirectory().absolutePath}/recording.3gp"

try {
mediaRecorder = MediaRecorder()
mediaRecorder?.setAudioSource(MediaRecorder.AudioSource.MIC)
mediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
mediaRecorder?.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
mediaRecorder?.setOutputFile(outputFile)

mediaRecorder?.prepare()
mediaRecorder?.start()

start_recording_button.isEnabled = false
stop_recording_button.isEnabled = true

Toast.makeText(this, "Recording started", Toast.LENGTH_SHORT).show()
} catch (e: IllegalStateException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
}
}

// Set up the stop recording button
stop_recording_button.setOnClickListener {
mediaRecorder?.stop()
mediaRecorder?.release()
mediaRecorder = null

start_recording_button.isEnabled = true
stop_recording_button.isEnabled = false

Toast.makeText(this, "Recording saved to $outputFile", Toast.LENGTH_SHORT).show()
}
}
}

When the "start recording" button is clicked, the app creates a new instance of the MediaRecorder class, configures it to record audio from the microphone, and starts the recording. The "stop recording" button stops the recording, releases the MediaRecorder instance, and saves the recorded audio to a file named "recording.3gp" in the external storage directory of the device.

Here are a few additional things you can consider adding to your voice recorder app:

Handling errors: In the code I provided earlier, errors are simply being printed to the console. In a real-world app, you would want to handle errors more gracefully by showing an error message to the user and allowing them to try again.

Playback functionality: Once a recording has been saved, it would be useful to allow the user to play back the recording to listen to it. You could add a "Play" button to the app's UI and use the MediaPlayer class to play the recorded audio file.

File naming: As is, the app will overwrite the same file in the external storage every time you record. Instead, you should consider using a unique filename for each recording or prompt the user to enter a name for the recording before starting recording.

Recording status: It would be helpful to show the user the recording status while they are recording. You could add a TextView to the app's UI and update it to show the current recording time or remaining time.

Timer function : If you want to record for a specific amount of time then you could add a timer function where you can set the time for which you want to record after that it will automatically stop the recording.

Audio visualization: You could also consider adding audio visualization (such as a visual equalizer) to the app, which would give the user a visual representation of the audio they are recording.

Format options: If you want to support different audio formats, you can add an option in the app to select the desired audio format.

This is just a simple example of how to create a voice recorder app in Kotlin, there are many things you can improve such as handling errors, adding functionality to play the recorded audio, saving the audio file with a proper file name, etc

--

--