PDM Avanzado Obtendo información Multimedia

De MediaWiki
Revisión del 18:46 23 nov 2015 de Wiki (discusión | contribuciones) (Página creada con «==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...»)
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Ir a la navegación Ir a la búsqueda

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 superiores á API 21.

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

  • 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:

  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).