Diferencia entre revisiones de «PDM Avanzado Obtendo información Multimedia»
Ir a la navegación
Ir a la búsqueda
Línea 213: | Línea 213: | ||
==Caso práctico== | ==Caso práctico== | ||
− | Neste código imos ver un exemplo de como conseguir información multimedia | + | Neste código imos ver un exemplo de como conseguir información multimedia dos arquivos de audio que se atopan na SD-EXTERNA. |
+ | |||
:<syntaxhighlight lang="java" line enclose="div" highlight="" > | :<syntaxhighlight lang="java" line enclose="div" highlight="" > |
Revisión del 18:49 23 nov 2015
Sumario
Introdución
- A partires da API 23 o acceso a SD considérase un permiso perigoso polo que temos que solicitar dentro da aplicación o permiso ao usuario.
- Isto está explicado no enlace seguinte: Permisos especiais Android 6.0 API 23.
- Teremos que solicitar o permiso Manifest.permission.READ_EXTERNAL_STORAGE se queremos acceder a tarxeta SD Externa e temos no AndroidManifiest un target=23 e estamos a probar cun dispositivo cunha API 23.
- Pode suceder que queiramos facer unha aplicación que teña acceso a os arquivos multimedia da nosa tarxeta SD e obter a información multimedia (autor, título, xénero,...) asociada a ela.
- Imos ver dúas formas de facer isto, tendo en conta que o acceso á SD Externa para buscar arquivos pode non funcionar en versións iguais ou superiores á API 23.
Obtendo a información dos arquivos multimedia: Método 1
- Nas versións anteriores de Android podíamos percorrer toda a tarxeta buscando os arquivos de tipo 'multimedia' e extraendo as súas propiedades (título, xénero,...).
- Un exemplo de código:
Clase onde gardaríamos as propiedades:
1 public class Cancion {
2
3 public int id;
4 public String titulo;
5 public String artista;
6 public String album;
7 public String genero;
8 public String year;// Tiene que ser un String porque en algunas canciones no esta en formato de numero
9 public String duracion;
10 public String numeroPista;
11 public byte[] imagen;
12 public String fechaAdd;
13 public String ruta;
14
15 public Cancion(){
16
17 }
18 public Cancion(int id,String titulo,String artista,String album,String genero,
19 String duracion,String year,byte[] imagen,String fechaAdd,String numeroPista,String ruta){
20
21 this.id=id;
22 this.titulo=titulo;
23 this.artista=artista;
24 this.album=album;
25 this.genero=genero;
26 this.year=year;
27 this.duracion=duracion;
28 this.numeroPista=numeroPista;
29 this.fechaAdd=fechaAdd;
30 this.ruta=ruta;
31 }
32
33 }
Método que devolve un obxecto da clase Cancion cos datos obtidos a partires dun File:
1 public static Cancion crearCanciones(File cancion){
2
3 MediaMetadataRetriever mmr = new MediaMetadataRetriever();
4
5 Cancion c= new Cancion();
6 c.titulo=mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
7 c.artista=mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
8 c.album=mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM);
9 c.genero=mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE);
10 c.numeroPista=mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER);
11 c.duracion=String.format("%1$TM:%1$TS",Long.parseLong(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)));
12 c.year=mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR);
13 c.ruta=cancion.getAbsolutePath();
14 return c;
15 }
Obtendo a información dos arquivos multimedia: Método 2
- Outra forma de acceder aos contidos multimedia tanto da tarxeta SD Interna como a SD Externa é a través da clase MediaStore.
- A forma de acceder é a seguinte:
- Determinamos o tipo de arquivo que queremos explorar:
1 Uri allsongsuri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
- Neste caso estamos a buscar os arquivos de audio da tarxeta SD Interna.
- Podemos utilizar:
- MediaStore.Audio: Arquivos de audio.
- MediaStore.Files: Arquivos multimedia e non multimedia.
- MediaStore.Images: Arquivos de imaxe
- MediaStore.Video: Arquivos de vídeo.
- E podemos indicar a tarxeta externa coa constante: EXTERNAL_CONTENT_URI.
- Debemos de facer unha query buscando os arquivos que pertenzan a ese tipo. O resultado da query será un curso coas referencias aos arquivos:
1 Cursor cursor; 2 Uri allsongsuri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI; 3 4 cursor = getContentResolver().query(allsongsuri, null, null, null, "_id");
- Percorremos o listado de arquivos e obtemos a información multimedia:
1 do { 2 String nomeCancion = cursor 3 .getString(cursor 4 .getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)); 5 int idCancion = cursor.getInt(cursor 6 .getColumnIndex(MediaStore.Audio.Media._ID)); 7 8 String fullPath = cursor.getString(cursor 9 .getColumnIndex(MediaStore.Audio.Media.DATA)); 10 11 String nomeAlbum = cursor.getString(cursor 12 .getColumnIndex(MediaStore.Audio.Media.ALBUM)); 13 14 15 } while (cursor.moveToNext());
- Podemos obter moita máis información multimedia nestes enlaces:
Obtendo a xénero
- Á hora de buscar o xénero xa se complica a cousa. A idea é de buscar por cada canción o/os xéneros aos que pertence.
- Polo tanto necesitamos facer unha nova consulta levando como parámetro o ID da canción obtida do paso anterior:
1 String[] genresProjection = { // Indicamos os campos que imos recuperar da consulta 2 MediaStore.Audio.Genres.NAME, 3 MediaStore.Audio.Genres._ID 4 }; 5 6 Uri uri = MediaStore.Audio.Genres.getContentUriForAudioId("external", idCancion); 7 8 Cursor genresCursor; 9 String info=""; 10 genresCursor = getContentResolver().query(uri, genresProjection, null, null, null); // Facemos a consulta 11 int genre_column_index = genresCursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME); 12 13 if (genresCursor.moveToFirst()) { 14 info += "Xéneros: "; 15 do { 16 info += genresCursor.getString(genre_column_index) + " "; 17 } while (genresCursor.moveToNext()); 18 }
- Info tería os xéneros da canción.
- Outra forma sería a de buscar todas as cancións que teñan un determinado xénero:
1 public void listarXeneros(){ 2 int index; 3 long genreId; 4 Uri uri; 5 Cursor genrecursor; 6 Cursor tempcursor; 7 String[] proj1 = {MediaStore.Audio.Genres.NAME, MediaStore.Audio.Genres._ID}; 8 String[] proj2 = {MediaStore.Audio.Media.DISPLAY_NAME}; 9 10 genrecursor = getContentResolver().query(MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI, proj1, null, null, null); 11 if (genrecursor.moveToFirst()) { 12 do { 13 index = genrecursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME); 14 Log.i("Nome do xénero:", genrecursor.getString(index)); 15 16 index = genrecursor.getColumnIndexOrThrow(MediaStore.Audio.Genres._ID); 17 genreId = Long.parseLong(genrecursor.getString(index)); 18 uri = MediaStore.Audio.Genres.Members.getContentUri("external", genreId); 19 20 tempcursor = getContentResolver().query(uri, proj2, null,null,null); 21 Log.i("Número de cancións dese xénero:", tempcursor.getCount() + ""); 22 if (tempcursor.moveToFirst()) { 23 do { 24 index = tempcursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME); 25 Log.i("Nome da canción:", tempcursor.getString(index)); 26 } while(tempcursor.moveToNext()); 27 } 28 } while(genrecursor.moveToNext()); 29 } 30 31 }
Caso práctico
Neste código imos ver un exemplo de como conseguir información multimedia dos arquivos de audio que se atopan na SD-EXTERNA.
1 import android.Manifest; 2 3 import android.app.Activity; 4 import android.content.pm.PackageManager; 5 import android.database.Cursor; 6 import android.net.Uri; 7 import android.os.Build; 8 import android.provider.MediaStore; 9 import android.os.Bundle; 10 import android.util.Log; 11 import android.view.Menu; 12 import android.view.MenuItem; 13 import android.widget.Toast; 14 15 import java.util.List; 16 17 public class MainActivity extends Activity { 18 19 private String[] STAR = { "*" }; 20 21 // Usado por si necesitamos diferentes permisos, para identificar cual de ellos es 22 private final int CODIGO_IDENTIFICADOR=1; 23 24 25 public void pedirPermiso(){ 26 27 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 28 requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, CODIGO_IDENTIFICADOR); 29 } 30 else 31 listarCancions(); 32 33 34 } 35 36 @Override 37 public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 38 39 switch (requestCode) { 40 case CODIGO_IDENTIFICADOR: { 41 // Se o usuario premeou o boton de cancelar o array volve cun null 42 if (grantResults.length > 0 43 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 44 // PERMISO CONCEDIDO 45 listarCancions(); 46 } else { 47 // PERMISO DENEGADO 48 Toast.makeText(this, "É NECESARIO O PERMISO PARA ACCEDER Á TARXETA EXTERNA", Toast.LENGTH_LONG).show(); 49 } 50 return; 51 } 52 53 // Comprobamos os outros permisos 54 55 } 56 } 57 58 } 59 public void listarCancions() 60 { 61 62 Cursor cursor; 63 Uri allsongsuri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 64 65 if (isSdPresent()) { 66 67 cursor = getContentResolver().query(allsongsuri, null, null, null, "_id"); 68 if (cursor != null) { 69 if (cursor.moveToFirst()) { 70 do { 71 String songname = cursor 72 .getString(cursor 73 .getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)); 74 int song_id = cursor.getInt(cursor 75 .getColumnIndex(MediaStore.Audio.Media._ID)); 76 77 String fullpath = cursor.getString(cursor 78 .getColumnIndex(MediaStore.Audio.Media.DATA)); 79 80 String albumname = cursor.getString(cursor 81 .getColumnIndex(MediaStore.Audio.Media.ALBUM)); 82 83 84 Uri uri = MediaStore.Audio.Genres.getContentUriForAudioId("external", song_id); 85 86 String[] genresProjection = { 87 MediaStore.Audio.Genres.NAME, 88 MediaStore.Audio.Genres._ID 89 }; 90 Cursor genresCursor; 91 String info=""; 92 genresCursor = getContentResolver().query(uri, 93 genresProjection, null, null, null); 94 int genre_column_index = genresCursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME); 95 96 if (genresCursor.moveToFirst()) { 97 info += "Xéneros: "; 98 do { 99 info += genresCursor.getString(genre_column_index) + " "; 100 } while (genresCursor.moveToNext()); 101 } 102 Log.i("INFO", songname); 103 Log.i("INFO", albumname); 104 Log.i("INFO", info); 105 106 } while (cursor.moveToNext()); 107 } 108 cursor.close(); 109 } 110 } 111 } 112 113 114 public static boolean isSdPresent() 115 { 116 return android.os.Environment.getExternalStorageState().equals( 117 android.os.Environment.MEDIA_MOUNTED); 118 } 119 120 @Override 121 protected void onCreate(Bundle savedInstanceState) { 122 super.onCreate(savedInstanceState); 123 setContentView(R.layout.activity_main); 124 125 126 pedirPermiso(); 127 128 } 129 130 @Override 131 public boolean onCreateOptionsMenu(Menu menu) { 132 // Inflate the menu; this adds items to the action bar if it is present. 133 getMenuInflater().inflate(R.menu.menu_main, menu); 134 return true; 135 } 136 137 @Override 138 public boolean onOptionsItemSelected(MenuItem item) { 139 // Handle action bar item clicks here. The action bar will 140 // automatically handle clicks on the Home/Up button, so long 141 // as you specify a parent activity in AndroidManifest.xml. 142 int id = item.getItemId(); 143 144 //noinspection SimplifiableIfStatement 145 if (id == R.id.action_settings) { 146 return true; 147 } 148 149 return super.onOptionsItemSelected(item); 150 } 151 }
-- Ángel D. Fernández González -- (2015).