Creación de su propia grabadora de voz de Android con Kotlin

Creación de su propia grabadora de voz de Android con Kotlin


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

Configurar MediaRecorder


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 .

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


All Articles