
El marco multimedia de Android admite la grabación y reproducción de audio. En este artículo, mostraré cómo desarrollar una aplicación de grabación simple que grabará audio y lo almacenará en el almacenamiento local de un dispositivo Android usando MediaRecorder
desde el SDK de Android.
También aprenderá cómo solicitar permisos de un usuario en tiempo real y cómo trabajar con el almacenamiento local de un dispositivo Android.
Creación de interfaz de usuario
Primero necesitamos crear una interfaz para la grabación de sonido. Este es un diseño simple de tres botones que se usará para iniciar, pausar / reanudar y detener la grabación.
<?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>
Solicitar permisos requeridos
Después de crear la interfaz de usuario, podemos comenzar a usar MediaRecorder
para implementar la funcionalidad básica de nuestra aplicación. Pero primero, necesitamos solicitar los permisos necesarios para grabar audio y acceder al almacenamiento local. Haremos esto con algunas líneas simples de código en nuestro archivo AndroidManifest.xml
:
<uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
También debe verificar si el usuario ha aprobado los permisos antes de que podamos usar nuestro MediaRecorder
. Hagámoslo en 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) }
Nota: más adelante, estas líneas de código se OnClickListener
al OnClickListener
botón de inicio para grabar audio, de modo que podamos asegurarnos de que MediaRecorder
no se MediaRecorder
sin los permisos necesarios.
Graba y guarda audio
Agregar OnClickListeners
Agregue oyentes a los botones para que respondan a los eventos del usuario. Como mencioné anteriormente, se agregará una verificación de los permisos necesarios al OnClickListener del botón de inicio de grabación de audio:
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() }
A continuación, debemos especificar la ruta para guardar el audio y configurar 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) }
Tomamos la ruta a la raíz de nuestro almacenamiento externo y le agregamos el nombre de nuestro registro y tipo de archivo. Después de eso, creamos un objeto MediaRecorder
y definimos la fuente de sonido, el MediaRecorder
audio, el formato y el archivo para la grabación.
Graba y guarda audio
El código utilizado para iniciar MediaRecorder
se define en OnClickListener
botón de inicio de grabación de audio:
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 puede ver, necesitamos llamar a la función de prepare
antes de que podamos comenzar a grabar. También incorporamos la llamada en el bloque try-catch para que la aplicación no se rompa cuando falla la función de prepare
.
OnClickListeners
botón detener grabación son muy similares al código anterior.
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() } }
Aquí verificamos si MediaRecorder
se está MediaRecorder
actualmente antes de detener la grabación porque nuestra aplicación se interrumpirá si se llama al método de stop
mientras MediaRecorder
no se MediaRecorder
. Después de eso, cambiamos la variable de estado a false
para que el usuario no pueda presionar el botón de detención nuevamente.
Nos queda definir el OnClickListener
para el botón de pausa / reanudar.
@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 }
En estos dos métodos, verificamos si MediaRecorder
está MediaRecorder
. Si funciona, haremos una pausa en la grabación y cambiaremos el texto del botón para reanudar. Al presionarlo nuevamente se reanudará la grabación.
Finalmente, podemos grabar audio y escucharlo abriendo el archivo recording.mp3
, que se guardará en nuestro almacenamiento local. Simplemente abra el explorador de archivos y realice una búsqueda en el nombre del archivo recording.mp3
.
Código fuente
Aquí está el código fuente completo de nuestra aplicación:
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() } } }
Conclusión
Ahora ya sabe cómo funciona MediaRecorder
, cómo solicitar permisos en tiempo real y por qué es importante hacerlo. También aprendió sobre el almacenamiento local de su dispositivo Android y cómo almacenar datos en él.
Una versión más compleja de esta aplicación, que tiene algunas características adicionales, como reproducir sus grabaciones usando MediaPlayer
, está disponible en Github .