Saltar la navegación

5.2.3. Captura

Si nuestra app no tiene como objetivo la reproducción sino la captación de imagen o sonido, su arquitectura no tendrá por qué guardar relación directa con las arquitecturas vistas hasta ahora.

Deberemos tener en cuenta, sin embargo, otros factores, por ejemplo, si nuestra app utilizará otras aplicaciones como interfaz hacia el hardware o si, por el contrario, accederá directamente a la cámara o al micro.

Si nuestra app no pretende ser lo último en grabación, quizá sea conveniente llamar directamente a la grabadora instalada por defecto en nuestro móvil, con lo que ahorraremos esfuerzo y tiempo de desarrollo. Este podría ser el caso de una app que gestione tareas y permita además grabar notas de voz o vídeo. Quizá resultaría innecesario para una tarea tan sencilla meternos a programar el hardware de la cámara y el sonido.

No obstante, si realmente nuestra app se basa en la captación de media, querremos tener total control sobre el proceso y tendremos que estar al tanto de las interfaces y arquitectura de la cámara o el micro.

Vamos a comenzar utilizando una app preinstalada en el sistema que se anuncie como grabadora de vídeo y le solicitaremos que grabe uno para nosotros. Lo primero que necesitaremos es un FileProvider.

Por motivos de seguridad, Android no nos permite pasar rutas de una app a otra de forma directa; de ser así, la otra app podría escribir o borrar lo que quisiera dentro de nuestro directorio de aplicación. Mediante un FileProvider podremos compartir archivos de forma segura entre diferentes apps. En el manifest, dentro de la etiqueta application, definiremos nuestro provider de la siguiente manera:

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>

El FileProvider hace referencia a un documento XML que definirá nuestras rutas. Crearemos una carpeta "xml" dentro de la carpeta "res" y añadiremos el archivo provider_paths.xml con el siguiente código:

<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="v" path="videos" />
</paths>

Ahora podremos llamar a una aplicación que permita la grabación de vídeo, es decir, a una aplicación preinstalada que responda a una acción MediaStore.ACTION_VIDEO_CAPTURE. Nuestro código sería:

import android.content.Intent
import android.net.Uri
import android.provider.MediaStore
import androidx.core.content.FileProvider
import java.io.File
class Actividad: Activity() {
private val AUTHORITY = BuildConfig.APPLICATION_ID + ".provider"
private val VIDEOS = "videos"
private val FILENAME = "grabacion.mp4"
private val REQUEST_ID = 6969
private var outputUri: Uri? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
grabar()
}
private fun grabar() {
val output = File(File(filesDir, VIDEOS), FILENAME)
if(output.exists())
output.delete()
else
output.parentFile?.mkdirs()
outputUri = FileProvider.getUriForFile(this, AUTHORITY, output)
val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri)
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1)
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
or Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivityForResult(intent, REQUEST_ID)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_ID && resultCode == RESULT_OK) {
val view = Intent(Intent.ACTION_VIEW)
.setDataAndType(outputUri, "video/mp4")
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(view)
finish()
}
}
}

Creado con eXeLearning (Ventana nueva)