terça-feira, 2 de agosto de 2011

Recuperando e Lendo Arquivos de um Cartão de Memória - PARTE 1

    Embora o objetivo do artigo seja este, serão englobados outros conceitos importantes:
  • Reproduzir músicas, videos, imagens e texto;
  • Construir um layout básico utilizando Java;
  • Exibir uma animação de progresso;
  • Arquivos e Fluxos;
  • Elaboração de Menus;
  • Janela de alerta;
  • Intents;
  • ListViews.
    
    Por simplicidade, a aplicação reconhecerá apenas arquivos de vídeo (3gp), sonoros (mid, mp3), texto (txt) e imagens (png, gif, jpg). Para poder acompanhar esta série de artigos, é importante que você saiba instalar arquivos no emulador. Primeiro, abra o emulador em que
irá trabalhar. Após sua inicialização, será criado o seu sistema de arquivos, o qual você acessará com a ferramenta File Explorer. Para encontrá-la no eclipse, vá até a barra de ferramentas e siga o caminho: Windows > Show View > Other > File Explorer. A imagem a seguir mostra onde fica o cartão de memória, bem como os arquivos que foram instalados:
      No canto direito superior da janela acima, você deve usar o seguinte ícone para inserir arquivos na pasta que estiver selecionada:


     Sendo este projeto composto de duas telas, começaremos pela classe que representa a primeira delas.

ListaArquivos.java

1. private static int formatoSelecionado;
2. private static String nomeArqSelecionado;
3. private static ListView lista;
4. private static java.io.File sdcard;

    Começaremos pelas variáveis globais usadas nesta classe. campo formatoSelecionado guardará o tipo do arquivo correntemente selecionado na lista. nomeArqSelecionado, por sua vez, armazenará o nome do arquivo em si. A referência lista aponta para uma ListView, componente Android usado para listar tipos primitivos e objetos. A variável sdcard, por ser do tipo File, embora se refira tanto a diretórios quanto arquivos, neste caso armazenará o caminho para um cartão de memória.


CRIACAO DA TELA PRINCIPAL

01. @Override
02. public void onCreate(Bundle savedInstanceState)
03. {
04.     super.onCreate(savedInstanceState);
05.
06.     lista = new ListView(this);
07.     setContentView(lista);
08.
09.     lista.setOnItemSelectedListener(this);
10.
11.     sdcard = Environment.getExternalStorageDirectory();
12.
13.     alimentarLista();
14. }

    Agora destacaremos alguns pontos do método onCreate, cuja principal tarefa é criar a Activity em que vamos trabalhar. Esta tela contém um único view, portanto iremos declará-la em Java, dispensando um arquivo XML de layout, que é voltado a construção de telas mais complexas.
    Depois, precisaremos fazer com que nossa lista responda a seleções do usuário. Para isso, vamos associá-la ao método onItemSelected conforme linha 09:
    A linha 11 irá recuperar o diretório onde se encontra o cartão de memória do dispositivo, isto é, um valor do tipo File, que será referenciado por sdcard.
    A última instrução deste método irá invocar outro método, alimentarLista(). Falaremos dele no tópico seguinte.


ALIMENTANDO A LISTA

01. private final void alimentarLista()
02. {
03.     String[] listaArqExistentes = sdcard.list();
04.     String[] formatosArquivos = getResources().getStringArray(R.array.formatos_arquivos);
05.     List<String> listaArqProcurados = new ArrayList<String>();
06.
07.     final int MAX_FORMATOS = formatosArquivos.length;
08.     final int MAX_ARQUIVOS = listaArqExistentes.length;
09.
10.     for(int i = 0; i < MAX_ARQUIVOS; i++)
11.     {
12.         for(int j = 0; j < MAX_FORMATOS; j++)
13.         {
14.             if((listaArqExistentes[i].endsWith(formatosArquivos[j])))
15.             {
16.                 listaArqProcurados.add(listaArqExistentes[i]);
17.             }
18.         }
19.     }
20.
21.     if(listaArqProcurados.size() > 0)
22.     {
23.         ArrayAdapter<String> adaptadorArquivos = new ArrayAdapter<String>(this,
24.         android.R.layout.simple_list_item_1, listaArqProcurados);
25.
26.         lista.setAdapter(adaptadorArquivos);
27.     }
28.     else
29.     {
30.         AlertDialog.Builder msgErro = new AlertDialog.Builder(this);
31.         msgErro.setMessage("Nenhum arquivo encontrado!");
32.         msgErro.show();
33.     }
34. }

Vejamos agora o método encarregado de alimentar a lista. Se pelo menos um arquivo for
encontrado, a tela do dispositivo se apresentará da seguinte maneira:
Arquivo(s) localizado(s)
  Na linha 03, o método list() retorna um array com os nomes de todos os arquivos encontrados no cartão. Porém, nossa lista esta interessada em exibir apenas arquivos de texto (txt), imagens (jpg, png e gif), músicas (mp3 e mid) e vídeos (3gp). Para nos ajudar a filtrar esses formatos, foi criado o array formatosArquivos, que guardará os nomes das extensões desejadas.  Poderíamos ter declarado esse array no próprio código Java. Ao invés disso, optei por armazená-lo em um arquivo XML para depois recuperá-lo no código Java em si. O arquivo XML é criado dentro da pasta res/values/formatos_arquivos.xml do projeto e pode ser visto a seguir:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="formatos_arquivos">
<item>.mid</item>
<item>.mp3</item>
<item>.png</item>
<item>.jpg</item>
<item>.gif</item>
<item>.txt</item>
<item>.3gp</item>
<item>.mp4</item>
</string-array>
</resources>
   O mais gratificante é poder recuperar esse array no código Java com apenas uma linha:
getResources().getStringArray(R.array.formatos_arquivos);
Um vetor em Java pode ocupar muitas linhas, prejudicando a estética e legibilidade do código. Portanto, torna-se uma boa prática embuti-lo em um arquivo XML para depois recuperá-lo com uma simples linha.
    A seguir, iremos usar a variável listaArqProcurados para guardar apenas os nomes dos arquivos suportados pela aplicação. Mas por que usar uma List ao invés de um simples array? Mesmo sabendo que existem arquivos no cartão e em certo número, não temos certeza de seus formatos. Considerando que muitos não conhecem uma List e a abrangência do assunto, darei uma explicação suficiente para prosseguir com o artigo. Um array comum tem tamanho fixo, obtido no momento de sua criação. Já uma List não tem tamanho fixo, podendo este ser aumentado dinamicamente, conforme as necessidades da aplicação. Neste caso, o tamanho da List irá sempre depender do teste nas linhas 10-18, que buscará na lista de arquivos disponíveis no cartão apenas os formatos requeridos pelo aplicativo:
    Na linha 21, há um segundo teste, que verifica se pelo menos um arquivo das extensões exigidas foi encontrado, para então vincular listaArqProcurados à referência lista. Isso é conseguido com a classe ArrayAdapter, uma classe nativa do Android projetada para associar listas de objetos a uma ListView e a outros componentes. Tenha em mente que ListView e ArrayAdapter trabalham em equipe.
    No construtor desse ArrayAdapter, temos três parâmetros: o contexto no qual ele está inserido (nesse caso a Activity atual), um estilo pré-definido de ListView do Android e finalmente a lista de arquivos encontrados. A marcação <String> após o nome da classe indica que os elementos da lista são do tipo String. Por último, precisaremos vincular os elementos de List a ListView, conforme linha 26.
    Se nenhum arquivo dos requisitados for encontrado, uma mensagem de erro é lançada com ajuda da classe AlertDialog.Builder:

Arquivo(s) não localizado(s)


NOTA: A classe List é um tipo de Coleção. Consultando a documentação oficial do Java, você saberá mais a respeito.

2 comentários:

Fabio disse...

Como eu faço para capturar o caminho de um destes arquivos clicando sobre?

Unknown disse...

tenho a mesma duvida do Fabio... Preciso pegar um arquivo de audio e executá-lo. Com esse artigo agora conseguimos listar os arquivos, mas agora preciso do caminho para executá-lo no media player

Postar um comentário