Criando seu próprio gravador de voz Android usando o Kotlin

Criando seu próprio gravador de voz Android usando o Kotlin


A estrutura multimídia Android suporta gravação e reprodução de áudio. Neste artigo, mostrarei como desenvolver um aplicativo de gravação simples que grave e armazene o áudio no armazenamento local de um dispositivo Android usando o MediaRecorder do Android SDK.


Você também aprenderá como solicitar permissões de um usuário em tempo real e como trabalhar com o armazenamento local de um dispositivo Android.


Criação da interface do usuário


Primeiro, precisamos criar uma interface para gravação de som. Esse é um layout simples de três botões que será usado para iniciar, pausar / retomar e parar a gravação.


 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 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_sound_recorder_heading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Sound Recorder" android:layout_centerHorizontal="true" android:textSize="32dp" android:textStyle="bold" android:textColor="#000" android:layout_marginTop="32dp"/> <Button android:id="@+id/button_start_recording" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start" android:layout_alignParentBottom="true" android:layout_marginLeft="32dp" android:layout_marginBottom="32dp" android:layout_centerVertical="true"/> <Button android:id="@+id/button_pause_recording" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Pause" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="32dp"/> <Button android:id="@+id/button_stop_recording" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Stop" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginBottom="32dp" android:layout_marginRight="32dp"/> </RelativeLayout> 

Permissões de solicitação necessárias


Após criar a interface do usuário, podemos começar a usar o MediaRecorder para implementar a funcionalidade básica do nosso aplicativo. Mas primeiro, precisamos solicitar as permissões necessárias para gravar áudio e acessar o armazenamento local. Faremos isso com algumas linhas simples de código em nosso arquivo AndroidManifest.xml :


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

Você também precisa verificar se o usuário aprovou as permissões antes de podermos usar nosso MediaRecorder . Vamos fazê-lo na Atividade 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) } 

Nota: posteriormente, essas linhas de código serão movidas para o OnClickListener botão Iniciar da gravação de áudio, para garantir que o MediaRecorder não seja MediaRecorder sem as permissões necessárias.


Grave e salve o áudio


Adicionando OnClickListeners


Adicione ouvintes aos botões para que eles respondam aos eventos do usuário. Como mencionei anteriormente, uma verificação das permissões necessárias será adicionada ao OnClickListener do botão Iniciar da gravação de áudio:


 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() } 

Configurar o MediaRecorder


Em seguida, precisamos especificar o caminho para salvar o áudio e configurar o 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) } 

Pegamos o caminho para a raiz do nosso armazenamento externo e adicionamos o nome do nosso registro e tipo de arquivo. Depois disso, criamos um objeto MediaRecorder e definimos a fonte de som, MediaRecorder áudio, formato e arquivo para gravação.


Grave e salve o áudio


O código usado para iniciar o MediaRecorder é definido no OnClickListener botão Iniciar da gravação de áudio:


 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() } } 

Como você pode ver, precisamos chamar a função de prepare antes de começarmos a gravar. Também incorporamos a chamada no bloco try-catch para que o aplicativo não seja interrompido quando a função de prepare falhar.


OnClickListeners botão de parar a gravação são muito semelhantes ao código acima.


 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() } } 

Aqui, verificamos se o MediaRecorder está em MediaRecorder momento antes de parar a gravação, porque nosso aplicativo será interrompido se o método stop for chamado enquanto o MediaRecorder não for MediaRecorder . Depois disso, alteramos a variável de estado para false para que o usuário não possa pressionar o botão Parar novamente.


Resta definir o OnClickListener para o botão de pausa / retomar.


 @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 } 

Nestes dois métodos, verificamos se o MediaRecorder está MediaRecorder . Se funcionar, faremos uma pausa na gravação e alteraremos o texto do botão para continuar. Pressionar novamente retomará a gravação.


Finalmente, podemos gravar o áudio e ouvi-lo abrindo o arquivo recording.mp3 , que será salvo no nosso armazenamento local. Basta abrir o explorador de arquivos e fazer uma pesquisa no nome do arquivo recording.mp3 .


Código fonte


Aqui está o código fonte completo do nosso aplicativo:


 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() } } } 

Conclusão


Agora você sabe como o MediaRecorder funciona, como solicitar permissões em tempo real e por que é importante fazer isso. Você também aprendeu sobre o armazenamento local do seu dispositivo Android e como armazenar dados nele.


Uma versão mais complexa deste aplicativo, que possui alguns recursos adicionais, como reproduzir suas gravações usando o MediaPlayer , está disponível no Github .

Source: https://habr.com/ru/post/pt444616/


All Articles