quinta-feira, 13 de dezembro de 2012

Dica: estudem códigos

Hoje, serei sucinto!
Aprendam a ler códigos.
Estudem códigos de terceiros.
Estraiam o máximo estudando códigos.
Aprendam a visualizar aplicações de uma técnica usada um um código em outras situações.
E, finalmente, lembrem-se do ditado: Para um bom programador, um código vale mais que mil palavras!


terça-feira, 11 de dezembro de 2012

Content Provider, usando

 Para usar o Content Provider MyLocationProvider definido no último post, vamos tomar como base a mesma aplicação que testamos em diversos posts anteriores.

 O app tem as seguintes características:

 1. A activity inicia lendo os dados existentes no Content Provider e os mostra numa ListView. Para isso usamos um ManagedQuery, como o cursor resultante da leitura será gerenciado, o ListView será atualizado automaticamente quando o Content Provider for alterado.
 Usamos um ListAdapter extendido de um CursorAdapter para tratar os dados do cursor.
 A leitura dos dados é feita com um Limit de 20 linhas para ficar mais rápido e exemplificar o uso da clausula no db. A ordem é decrescente de data. O último location gravado é o primeiro do ListView.
 No método onStart é iniciado o service para coleta dos dados dos Locations Providers.
 Temos tres botões:
 .Start - inicia a coleta de dados no service
 .Stop - para a coleta de dados no service
 .Clear DB - Deleta todos os registros existentes no Content Provider

 2. No service:
 .Uso da tecnica produtor/consumidor para gravar os dados através de uma worker thread.
 .Uso de uma BlockingQueue para passar os Locations da thread principal para o thread consumidora
 .A worker thread é iniciada no onBind e fica aguardando os Locations para gravar no Content Provider
 .Uso da tecnica de controle do encerramento de uma thread através do envio de um objeto indicativo de fim

 Vamos aos códigos:

 AndroidManifest.xml

main.xml


linhalista.xml


ListAdapter.java

MyLocationActivity.java

MyLocationService.java

Algumas observações finais:
 .Normalmente não gravamos todos os Locations recebidos, fazemos uma seleção dos mais precisos, por tempo, etc.
 .Ou, definimos critérios para os providers nos enviar somente os locations em conformidade com os mesmos.
 .O metodo ManagedQuery está deprecated a partir do API 11, Android 3.0.x
 .Foi substituído pelo CursorLoader
 .O acesso aos dados para o ListView está na UI Thread, se ficar muito demorado usar uma AsyncTask.
 .Não testei o método update

Vejam o resultado, no Xperia mini:





 Abraços







Content Provider, criando um

 Content Provider é uma interface genérica para acesso a dados no ambiente Android. Somente através do Content Provider é possível compartilhar dados entre aplicações. O acesso a um Content Provider é padronizado, e como sempre, acessar um Content Provider nativo ou um definido por você segue o mesmo formato, sem distinção.
 Acessamos um Content Provider por intermédio da classe cliente ContentResolver.

 Nesse teste, vamos implementar um Content Provider usando o SQLite como repositório de dados. Vamos fazer um Content Provider de localizações geográficas.
 O exemplo é baseado no sample NotePad. Então, toda semelhança não é mera coincidência!

 Como pretendemos acessar o Content Provider em múltiplas threads, estamos testando também o uso de uma trava de leitura-escrita para tornar os métodos de acesso ao Content Provider seguros em relação às threads.
 Devido ao fato de que esse banco de dados pode ficar muito grande, também implementaremos uma forma de acessar os dados usando a clausula "limit" do SQL.

 Vamos seguir os seguintes passos para criar nosso Content Provider:

 1. Criar uma classe contrato. Essa é uma classe com as constantes do Content Provider, como URIs, MIME types, nome das colunas da tabela, etc. Esta classe estabelece o contrato entre o Content Provider e as aplicações clientes.
 MyLocation.class

 2. Definição da base de dados
  Vamos extender a classe SQLiteOpenHelper e implementar os métodos onCreate e onUpgrade.

 3. Criando o Content Provider
  Além de implementar os métodos onCreate, query, insert, delete, update e getType vamos definir também uma instância da classe utilitária UriMatcher. O UriMatcher nos ajudará a manipular as URIs para identificar qual formato estamos tratando.
 Também vamos instanciar um trava ReentrantReadWriteLock. 

 Vejamos o código:

 MyLocationProvider.class

 4. Registrar o Content Provider no Manifest file.



Com a opção android:exported="false" estamos informando que esse Content Provider é privado à aplicação.

 Pronto!
 Estamos com o Content Provider criado, no próximo post veremos como usá-lo.

 Abraços!