Creating Your Own Android Voice Recorder Using Kotlin

Original author: Gabriel Tanner
  • Transfer
  • Tutorial

Creating Your Own Android Voice Recorder Using Kotlin


The Android multimedia framework supports audio recording and playback. In this article, I will show how to develop a simple recording application that will record audio and save it to the local storage of an Android device using MediaRecorderthe Android SDK.


You will also learn how to request permissions from a user in real time and how to work with the local storage of an Android device.


User Interface Creation


First we need to create an interface for sound recording. This is a simple three-button layout that will be used to start, pause / resume, and stop recording.



Request Permissions Required


After creating the user interface, we can start using it MediaRecorderto implement the basic functionality of our application. But first, we need to request the necessary permissions to record audio and access local storage. We will do this with a few simple lines of code in our file AndroidManifest.xml:



You also need to check if the user has approved the permissions before we can use ours MediaRecorder. Let's do it in Activity MainActivity.kt:


if (ContextCompat.checkSelfPermission(this,
      Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this,
      Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
  val permissions = arrayOf(android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE)
  ActivityCompat.requestPermissions(this, permissions,0)
}

Note: later these lines of code will be moved to the OnClickListenerstart button of the audio recording so that we can make sure that MediaRecorderit will not be launched without the necessary permissions.


Record and save audio


Adding OnClickListeners


Add listeners to the buttons so that they respond to user events. As I mentioned earlier, a check for the necessary permissions will be added to the OnClickListener of the audio recording start button:


button_start_recording.setOnClickListener {
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        val permissions = arrayOf(android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE)
        ActivityCompat.requestPermissions(this, permissions,0)
    } else {
        startRecording()
    }
}
button_stop_recording.setOnClickListener{
    stopRecording()
}
button_pause_recording.setOnClickListener {
    pauseRecording()
}

Configure MediaRecorder


Next, we need to specify the path to save the audio and configure MediaRecorder.


private var output: String? = null
private var mediaRecorder: MediaRecorder? = null
private var state: Boolean = false
private var recordingStopped: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    output = Environment.getExternalStorageDirectory().absolutePath + "/recording.mp3"
    mediaRecorder = MediaRecorder()
    mediaRecorder?.setAudioSource(MediaRecorder.AudioSource.MIC)
    mediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
    mediaRecorder?.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
    mediaRecorder?.setOutputFile(output)
}

We take the path to the root of our external storage and add the name of our record and file type to it. After that, we create an object MediaRecorderand determine the sound source, audio encoder, format and file for recording.


Record and save audio


The code used to start MediaRecorderis defined in the OnClickListeneraudio recording start button:


private fun startRecording() {
    try {
        mediaRecorder?.prepare()
        mediaRecorder?.start()
        state = true
        Toast.makeText(this, "Recording started!", Toast.LENGTH_SHORT).show()
    } catch (e: IllegalStateException) {
        e.printStackTrace()
    } catch (e: IOException) {
        e.printStackTrace()
    }
}

As you can see, you need to call the function preparebefore we can start recording. We also embed the call into the try-catch block so that the application does not break when the function fails prepare.


OnClickListeners The record stop button is very similar to the code above.


private fun stopRecording() {
    if (state) {
        mediaRecorder?.stop()
        mediaRecorder?.release()
        state = false
    } else {
        Toast.makeText(this, "You are not recording right now!", Toast.LENGTH_SHORT).show()
    }
}

Here we check whether it is working at the moment MediaRecorderbefore we stop recording because our application will break if the method stopis called while it MediaRecorderwill not start. After that, we change the state variable to falseso that the user cannot press the stop button again.


It remains OnClickListenerfor us to define for the pause / resume button.


@SuppressLint("RestrictedApi", "SetTextI18n")
@TargetApi(Build.VERSION_CODES.N)
private fun pauseRecording() {
    if (state) {
        if (!recordingStopped) {
            Toast.makeText(this,"Stopped!", Toast.LENGTH_SHORT).show()
            mediaRecorder?.pause()
            recordingStopped = true
            button_pause_recording.text = "Resume"
        } else {
            resumeRecording()
        }
    }
}
@SuppressLint("RestrictedApi", "SetTextI18n")
@TargetApi(Build.VERSION_CODES.N)
private fun resumeRecording() {
    Toast.makeText(this,"Resume!", Toast.LENGTH_SHORT).show()
    mediaRecorder?.resume()
    button_pause_recording.text = "Pause"
    recordingStopped = false
}

In these two methods, we check to see if it works MediaRecorder. If it works, we will pause recording and change the button text to resume. Pressing it again will resume recording.


Finally, we can record audio and listen to it by opening a file recording.mp3that will be saved in our local storage. Just open the file explorer and search by file name recording.mp3.


Source


Here is the full source code of our application:


package com.example.android.soundrecorder
import android.Manifest
import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.content.pm.PackageManager
import android.media.MediaRecorder
import android.os.Build
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
import java.io.IOException
class MainActivity : AppCompatActivity() {
    private var output: String? = null
    private var mediaRecorder: MediaRecorder? = null
    private var state: Boolean = false
    private var recordingStopped: Boolean = false
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mediaRecorder = MediaRecorder()
        output = Environment.getExternalStorageDirectory().absolutePath + "/recording.mp3"
        mediaRecorder?.setAudioSource(MediaRecorder.AudioSource.MIC)
        mediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        mediaRecorder?.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
        mediaRecorder?.setOutputFile(output)
        button_start_recording.setOnClickListener {
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                val permissions = arrayOf(android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE)
                ActivityCompat.requestPermissions(this, permissions,0)
            } else {
                startRecording()
            }
        }
        button_stop_recording.setOnClickListener{
            stopRecording()
        }
        button_pause_recording.setOnClickListener {
            pauseRecording()
        }
    }
    private fun startRecording() {
        try {
            mediaRecorder?.prepare()
            mediaRecorder?.start()
            state = true
            Toast.makeText(this, "Recording started!", Toast.LENGTH_SHORT).show()
        } catch (e: IllegalStateException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
    @SuppressLint("RestrictedApi", "SetTextI18n")
    @TargetApi(Build.VERSION_CODES.N)
    private fun pauseRecording() {
        if (state) {
            if (!recordingStopped) {
                Toast.makeText(this,"Stopped!", Toast.LENGTH_SHORT).show()
                mediaRecorder?.pause()
                recordingStopped = true
                button_pause_recording.text = "Resume"
            } else {
                resumeRecording()
            }
        }
    }
    @SuppressLint("RestrictedApi", "SetTextI18n")
    @TargetApi(Build.VERSION_CODES.N)
    private fun resumeRecording() {
        Toast.makeText(this,"Resume!", Toast.LENGTH_SHORT).show()
        mediaRecorder?.resume()
        button_pause_recording.text = "Pause"
        recordingStopped = false
    }
    private fun stopRecording(){
        if (state) {
            mediaRecorder?.stop()
            mediaRecorder?.release()
            state = false
        } else {
            Toast.makeText(this, "You are not recording right now!", Toast.LENGTH_SHORT).show()
        }
    }
}

Conclusion


Now you know how it works MediaRecorder, how to request real-time permissions, and why it is important to do so. You also learned about the local storage of your Android device and how to store data in it.


A more complex version of this application, which has some additional features, such as playing your recordings with MediaPlayer, is available on Github .


Also popular now: