Música local en Android: por qué MediaStore y Media3 resuelven problemas diferentes
Los usuarios que guardan colecciones MP3 o FLAC necesitan descubrir archivos y reproducirlos sin exigir una cuenta o una conexión de red. Esas tareas no deberían tratarse como si fueran la misma capa del sistema.
El problema y el alcance del ejemplo
La ficha de Amplify: Reproductor Hi-Res resume su función así: «Reproductor de música sin conexión con ecualizador de 10 bandas y FLAC.» Amplify anuncia reproducción offline, FLAC y ecualización de diez bandas. En este ejemplo aislamos la obtención de una URI de audio con MediaStore; después esa URI puede consumirse con Media3. No se afirma que Amplify use internamente esas bibliotecas.
Cómo reproducir la idea
En un proyecto Kotlin Android, declara el permiso de lectura de audio correspondiente a la versión del sistema (READ_MEDIA_AUDIO en Android 13+) y solicítalo en ejecución antes de hacer la consulta. La búsqueda debe ejecutarse fuera del hilo principal.
import android.content.ContentUris
import android.content.Context
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
fun audioUris(context: Context): List<Uri> {
val base = if (Build.VERSION.SDK_INT >= 29) {
MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
} else {
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
}
val projection = arrayOf(MediaStore.Audio.Media._ID)
val result = mutableListOf<Uri>()
context.contentResolver.query(base, projection, null, null, null)?.use { c ->
val idIndex = c.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)
while (c.moveToNext()) {
result += ContentUris.withAppendedId(base, c.getLong(idIndex))
}
}
return result
}
// Después, en una Activity con permiso y Media3 configurado:
// val player = ExoPlayer.Builder(this).build()
// player.setMediaItem(MediaItem.fromUri(audioUris(this).first()))
// player.prepare()
// player.play()
// player.release() cuando termine su ciclo de vida.
Qué demuestra el código
La lista almacena identificadores de contenido (content://), no rutas absolutas. En Android 10+ usamos la colección de volúmenes externos compartidos para cubrir más de una ubicación cuando el sistema las indexa. Esto facilita trabajar con el modelo de almacenamiento moderno. El reproductor debe manejar la eliminación de archivos y las URI que dejan de estar disponibles.
Pruebas recomendadas
Copia un MP3 y un FLAC de prueba al dispositivo, comprueba su indexación, concede permiso y compara las URI detectadas. Activa modo avión y valida que el acceso local no necesita Internet. Evita llamar first() sin comprobar que la lista contiene elementos.
Límites que conviene reconocer
No se implementa cola, reproducción en segundo plano, etiquetas, procesamiento DSP ni verificación bit-perfect. El hecho de poder decodificar FLAC tampoco demuestra una salida de audio Hi-Res de extremo a extremo.
Qué aprendemos
Separar descubrimiento multimedia, motor de reproducción y procesamiento de audio simplifica las pruebas y evita atribuir capacidades de hardware al formato del archivo.
Contexto y enlaces del autor
El tema se relaciona con las funciones declaradas públicamente de Amplify: Reproductor Hi-Res, una aplicación Android de AppInitDev. El código anterior es un ejemplo independiente: no se ha inspeccionado el repositorio privado ni se afirma que sea la implementación interna de la app. La referencia aparece al final para ofrecer contexto, no como requisito para completar el tutorial.
- Google Play: Amplify: Reproductor Hi-Res
- Página de la aplicación: https://musicpro.appinitdev.com/
- Sitio del desarrollador: AppInitDev

Top comments (0)