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