36
Parte 1   Conceitos Básicos Começando a desenvolver aplicativos para Android 23 de março de 2010  105 comentários Este post é o primeiro de uma série em que vou ensinar, passo a passo, como criar um aplicativo para a plataforma android. Android é a plataforma do google para dispositivos móveis que equipa um grande número de telefones no mercado. (g1, motorola dext, milestone, nexus one…) O qu e preciso para começ ar a des envolver par a andr oi d?  Uma idéia e força de vontade :). E claro, saber programar em Java. Você NÃO precisa de um hardware (telefone) para isso. A grande maioria dos testes pode ser feito no emulador! Além disso, Android é uma plataforma de código aberto e o desenvolvimento de programas é amplamente incentivado pelo Google (e pela Motorola, como vamos ver no final do post). Por on de começ ar ?  O primeiro passo é montar seu ambiente de desenvolvimento. 1) Montar o ambiente padrão fornecido pelo Google. Para isso, você precisará seguir os seguintes passos: - Instalar o Eclipse (www.eclipse.org ) - Instalar o Android SDK (developer.android.com/sdk ) - Instalar o ADT Plugin (developer.android.com/sdk/eclipse-adt.html ) Todos os links contém as instruções para instalação dos component es. Caso haja dúvidas, coloque nos comentários!  DICA: Você pode “economizar” os passos acima usando o ambiente do  Motodev    que é basicamente a  junção de todos os passos acima e mais algumas ferramentas. Para instalar o Motodev Studio até a  página http://develo per.motorola.c om/docstools/mo todevstudio/  

Artigos de Programacao ANDROID - Felipe Silveira

Embed Size (px)

DESCRIPTION

Programacao Android

Citation preview

Parte 1 Conceitos Bsicos

Comeando a desenvolver aplicativos para Android23 de maro de 2010105 comentriosEste post o primeiro de uma srie em que vou ensinar, passo a passo,como criar um aplicativo para a plataforma android.

Android a plataforma do google para dispositivos mveis que equipa um grande nmero de telefones no mercado. (g1, motorola dext, milestone, nexus one)O que preciso para comear a desenvolver para android?Uma idia e fora de vontade :). E claro, saber programar em Java. Voc NO precisa de um hardware (telefone) para isso. A grande maioria dos testes pode ser feito no emulador!Alm disso, Android uma plataforma de cdigo aberto e o desenvolvimento de programas amplamente incentivado pelo Google (e pela Motorola, como vamos ver no final do post).Por onde comear?O primeiro passo montar seu ambiente de desenvolvimento.1) Montar o ambiente padro fornecido pelo Google. Para isso, voc precisar seguir os seguintes passos:- Instalar o Eclipse (www.eclipse.org)- Instalar o Android SDK (developer.android.com/sdk)- Instalar o ADT Plugin (developer.android.com/sdk/eclipse-adt.html)Todos os links contm as instrues para instalao dos componentes. Caso haja dvidas, coloque nos comentrios!DICA: Voc pode economizar os passos acima usando o ambiente doMotodev que basicamente a juno de todos os passos acima e mais algumas ferramentas. Para instalar o Motodev Studio v at a pginahttp://developer.motorola.com/docstools/motodevstudio/ importante dizer que os aplicativos gerados pelo Motodev Studio funcionaro em todos os telefones, e no s em telefones Motorola.Com isso terminamos o nosso primeiro passo. No prximo passo, vou mostrar como criar um projeto android no eclipse. At l!Criando um projeto Android (Helloworld!)2 de abril de 201096 comentriosNo artigo da semana passada vimos comomontar o ambiente de desenvolvimento android. Caso seu ambiente ainda no esteja funcionando, volte l e veja o que faltou.Hoje iremos criar nosso primeiro projeto android o nosso Helloworld.Passo 1 Criando o projeto no EclipseAbra o Eclipse, v at File>New>ProjectNa tela que aparecer, escolha Android Project e clique em Next.

Criando um "Android Project"Aps isso, ir aparecer a tela com as configuraes de seu projeto android.Nesta tela, voc precisa inserir os seguintes dados: Project name- o nome do projeto no eclipse. Build Target a verso do Android para a qual o seu projeto ser direcionado. Application name o nome da sua aplicao o nome que aparecer no telefone. Package name- opackageno qual sero criadas as suas classes java. Create Activity Marque este checkbox e coloque um nome na caixa de texto. frente explicarei o que umaActivity.Depois disso, basta clicar em Finish.

Configurando o projeto android

Passo 2 Imprimindo um textoAps isso, ser criado um novo projeto e dentro dele, na pasta src// voc encontrar um arquivo .java com o nome daActivityque voc colocou no passo anterior.Para fazer a sua aplicao imprimir um texto na tela, modifique este arquivo dessa forma:view plaincopy to clipboardprint?1. packagebr.com.felipesilveira.hello_world;2. 3. importandroid.app.Activity;4. importandroid.os.Bundle;5. importandroid.widget.TextView;6. 7. publicclassHelloWorldextendsActivity{8. /**Calledwhentheactivityisfirstcreated.*/9. @Override10. publicvoidonCreate(BundlesavedInstanceState){11. super.onCreate(savedInstanceState);12. TextViewview=newTextView(this);13. view.setText("Hello,Android");14. setContentView(view);15. 16. }17. }Parte 3 Rodando a aplicao no emuladorPara rodar nosso recm criado programa no emulador do google, v at Run>Run as Android Application. Uma instncia do emulador ser criada, com o nosso HelloWorld rodando.

Hello World rodando no emuladorO que uma Activity?Neste HelloWorld tivemos contato com o primeiro elemento de um cdigo android: AActivity.Uma Activity basicamente uma classe gerenciadora de UI (Interface com o usurio). Todo aplicativo android comea por uma Activity. Para saber mais, veja a documentao da classeActivity. Nos prximos artigos falaremos bastante sobre ela, suas caractersticas, seu ciclo de vida e como manipul-la corretamente.DICA: Alm de rodar a aplicao, voc pode explorar um pouco o emulador, para conhecer o sistema operacional Android, caso ainda no conhea. Durante o desenvolvimento, o emulador ser seu melhor amigo, ento essa a oportunidade para conhec-lo bem.

Trabalhando com layouts XML em Android17 de abril de 201020 comentriosOl pessoal, hoje vou falar sobre a definio dolayout de sua aplicao Android usando XML.Definir os layouts atravs dessa tcnica a forma mais comum de se comear o desenvolvimento de uma aplicao.Para exemplificar os estudos que faremos a partir de agora, usaremos uma aplicao de exemplo, que construiremos juntos, a partir dos prximos posts.A idia fazer uma aplicao onde o usurio poder entrar com algumas anotaes, e visualizar as ltimas entradas.O layout ser mais ou menos assim:

esboo do layoutCriando o main.xmlPara novos projetos android, o arquivo main.xml j automaticamente criado. Ele fica no diretrio res/layout, com o contedo:view plaincopy to clipboardprint?1. 2. 7. 12. Neste arquivo temos contato com os primeiros elementos de um arquivo de layout XML: LinearLayout, que apenas um container. TextView, que um elemento de texto. Nesse caso est imprimindo a string cujo id @string/hello. (No se preocupe, falaremos sobre strings e seus ids frente nesse curso)Para criar um layout parecido com o rascunho do incio do post, iremos inserir outros dois elementos: EditText uma caixa de texto onde o usurio ir entrar com as anotaes; ListView uma lista de anotaes previamente submetidas.Assim, o nosso novo XML:view plaincopy to clipboardprint?1. 2. 7. 13. 14. 19. 20. Carregando o arquivo XML na aplicaoPara que a nossa aplicao tenha o layout definido pelo arquivo XML, preciso carreg-lo.Isso feito atravs da funo setContentView(), como no cdigo abaixo:view plaincopy to clipboardprint?1. publicvoidonCreate(BundlesavedInstanceState){2. super.onCreate(savedInstanceState);3. setContentView(R.layout.main);4. }O parmetro R.layout.main indica que o arquivo de layout a ser carregado o main.xml. (Se o se arquivo se chamar abobrinha.xml, o parmetro dever ser R.layout.abobrinha) possvel utilizar mais de um arquivo XML para uma mesma tela, para formar layouts mais sofisticados. Trataremos disso frente nesse curso.Compilando o nosso projeto e rodando no emulador, temos o seguinte resultado:

QuickNotes rodando no emuladorNo prximo post iremos acrescentar um boto a este layout, e iremos aprender um pouco mais sobre os parmetros de um documento XML.DICA: Existe uma ferramenta online, gratuita, para edio de arquivos de layout XML. oDroidDraw.LEITURA RECOMENDADA: Para aprender mais sobre a definio de layout de aplicaes android, visite a pgina User Interface da documentao oficial. (em ingls)Trabalhando com layouts XML em Android (II)22 de abril de 201023 comentriosOl a todos!No post passado aprendemoscomo criar um documento XML que define o layout de uma aplicao Android.Hoje iremos adicionar um boto a este layout, que permita ao usurio inserir novas anotaes.Adicionando um boto a um layout androidPara adicionar um boto clicvel ao nosso layout, usaremos o widgetButton.Queremos que ele fique ao lado esquerdo da caixa de texto. Como fazer isso?1. Diminuir o tamanho da caixa de texto. Para fazer isso, s alterar a propriedadeandroid:layout_width.Originalmente o valor dela era fill_parent isso quer dizer: ocupe todo o espao disponvel. Ao invs disso, vamos usar 240 pixels.2. Inserir o boto logo aps a caixa de texto.3. Inserir um novoLinearLayoutque ir conter a caixa de texto e o boto. Isso necessrio porque oLinearLayoutque definimos anteriormente (e que ocupa toda a tela) tem a propriedadeandroid:orientation=vertical.Essa propriedade faz com que seus elementos sejam dispostos verticalmente (um debaixo do outro) e no isso que queremos para estes dois elementos (a caixa de texto e o boto queremos que fiquem lado a lado).Assim, temos o nosso novo main.xml:view plaincopy to clipboardprint?1. 2. 7. 11. 17. 18. 24. 25. 26. 31. 32. Compilando as alteraes, temos a seguinte tela:

Novo layout da aplicao android - agora com o boto "Inserir"No prximo post veremos como controlar o boto de inserir.

Activity o que isso?2 de maio de 201030 comentriosHoje iremos conhecer uma das mais importantes classes de uma aplicao Android: A classeActivity.No post Criando um projeto Android (Helloworld!) comecei a falar sobre ela:Uma Activity basicamente uma classe gerenciadora de UI (Interface com o usurio). Todo aplicativo android comea por uma Activity.Ou seja, quando uma aplicao android executada, na verdade a sua Activity principal que lanada.Ciclo de vida de uma ActivityUma das coisas que importante conhecer sobre a Activity o seu ciclo de vida. E para explic-lo, nada melhor do que o seguinte diagrama*:

Ciclo de vida de uma Activity

Este diagrama de fundamental importncia para o correto entendimento do funcionamento de uma aplicao android. Ele introduz, implicitamente, os estados que uma Activity pode estar, os quais explico no desenho abaixo:

Estados de uma ActivityVoltando ao diagrama do ciclo de vida, temos as seguintes funes: onCreate() a primeira funo a ser executada quando uma Activity lanada. Geralmente a responsvel por carregar os layouts XML e outras operaes de inicializao. executada somente uma vez durante a vida til da Activity.

onStart() chamada imediatamente aps a onCreate() e tambm quando uma Activity que estava em background volta a ter foco. onResume()Assim como a onStart(), chamada na inicializao da Activity (logo aps a prpria onStart()) e tambm quando uma Activity volta a ter foco. Qual a diferena entre as duas? A onStart() s chamada quando a Activity no estava mais visvel na tela e volta a ter o foco, enquanto a onResume()sempre chamada nas retomadas de foco.

onPause() a primeira funo a ser invocada quando a Activity perde o foco (ou seja, uma outra Activity vem frente).

onStop() Anloga onPause(), s chamada quando a Activity fica completamente encoberta por outra Activity (no mais visvel).

onDestroy()A ltima funo a ser executada. Depois dela, a Activity considerada morta ou seja, nao pode mais ser relanada. Se o usurio voltar a requisitar essa Activity, outro objeto ser contrudo. onRestart()Chamada imediatamente antes da onStart(), quando uma Activity volta a ter o foco depois de estar em background.Executando uma ActivityJ sabemos que quando a sua aplicao executada, a Activity definida como padro (nacriao do projeto) lanada. Mas eu posso criar outras Activities? claro que sim.E para executar outras Activities, basta usar as funes startActivity() e startActivityForResult(). No exemplo abaixo, lanamos uma segunda Activity a partir da principal, e esperamos umresultadodela como se fosse um retorno de funo.view plaincopy to clipboardprint?1. staticfinalintPICK_CONTACT_REQUEST=0;2. 3. @Override4. publicvoidonCreate(BundlesavedInstanceState){5. super.onCreate(savedInstanceState);6. setContentView(R.layout.main);7. startActivityForResult(8. newIntent(Intent.ACTION_CONTACT_REQUEST,9. newUri("content://contacts")),10. CONTACT_REQUEST);11. }12. 13. protectedvoidonActivityResult(intrequestCode,intresultCode,14. Intentdata){15. if(requestCode==CONTACT_REQUEST){16. if(resultCode==RESULT_OK){17. //fazeralgumacoisa...18. }19. }Quando a segunda Activity terminar a sua execuo, a funo onActivityResult() ser invocada, com o resultado como parmetro.

Mas como uma Activity define o seu resultado, a ser lido por aquela que a chamou?Isso feito invocando-se a funosetResult (int resultCode),como por exemplo:1. setResult(Intent.RESULT_OK);Algum percebeu que eu no disse nada sobre os parmetros da startActivityForResult()? Isso porque este o assunto do meu prximo post o mecanismo de Uris em Android. At l!

*diagrama traduzido de http://developer.android.com/reference/android/app/Activity.html

Criando uma Activity secundria6 de maio de 201044 comentriosNo post passado vimos como lanar uma Activity a partir de outra, usando as funesstartActivity()estartActivityForResult().Hoje usaremos esta tcnica para mostrar ao usurio uma tela de Boas Vindas na nossa aplicao de exemplo, o QuickNotes.Para criar essa nova Activity, usaremos alguma funes doMotodev. Se voc no est usando a IDE da Motorola, no tem problema s criar os arquivos manualmente. Porm recomendo o uso da IDE, por facilitar bastante a nossa vida.Vamos comear criando a Activity que dar Boas Vindas ao usurio.V at o menu MOTODEV >New > New Android Activity. Na tela de configurao, entre com o nome da Activity a ser criada:

Configurando a Activity a ser criadaAps clicar em Finish, j haver a classe WelcomeActivity no diretriosrcdo nosso projeto.Com a Activity criada, o prximo passo criar o arquivo XMLque definir o seu layout. Crie o arquivo welcome.xml no diretoriores/layoutcom o seguinte contedo:view plaincopy to clipboardprint?1. 2. 6. 13. 14. 20. 21. Este arquivo XML define uma Activity com um texto e um boto logo abaixo, com a palavra Continuar.Aps criado o arquivo, vamos carreg-lo no mtodo onCreate() da WelcomeActivity():1. setContentView(R.layout.welcome);Lanando a WelcomeActivityPara lanar a WelcomeActivity a partir da MainActivity, usaremos a funo startActivity(). Esta funo recebe como parmetro umIntent. Posteriormente iremos aprofundar nosso conhecimento sobre essa importante classe, mas por enquanto o que voc precisa saber que ela usada para fazer a comunicao entre Activities.No cdigo abaixo instanciamos umIntentcuja nica funo lanar a WelcomeActivity, e ento o usamos como parmetro para a startActivity.Dessa forma, o cdigo da MainActivity fica assim:view plaincopy to clipboardprint?1. packagebr.com.felipesilveira.quicknotes;2. 3. importandroid.app.Activity;4. importandroid.os.Bundle;5. importandroid.content.Intent;6. 7. publicclassMainActivityextendsActivity{8. /**Calledwhentheactivityisfirstcreated.*/9. @Override10. publicvoidonCreate(BundlesavedInstanceState){11. super.onCreate(savedInstanceState);12. setContentView(R.layout.main);13. 14. Intenti=newIntent(this,WelcomeActivity.class);15. startActivity(i);16. }17. }Tratando os eventos de um botoAt agora, j temos a Activity secundria sendo lanada, mas o que deve acontecer quando o usurio clicar no boto Continuar?A WelcomeActivity deve morrer- Dessa forma, a ltima Activity instanciada ser mostrada novamente que por sinal a nossa MainAcitivity!Para fazer isso, devemos adicionar um listener ao boto para que o mtodo finish() seja invocado ao clique do usurio. O mtodo finish() da classe Activity fora a morte desta.O cdigo da WelcomeActivity fica assim:view plaincopy to clipboardprint?1. packagebr.com.felipesilveira.quicknotes;2. 3. importandroid.app.Activity;4. importandroid.os.Bundle;5. importandroid.view.View;6. importandroid.widget.Button;7. 8. publicclassWelcomeActivityextendsActivity{9. /**10. *@seeandroid.app.Activity#onCreate(Bundle)11. */12. @Override13. protectedvoidonCreate(BundlesavedInstanceState){14. super.onCreate(savedInstanceState);15. setContentView(R.layout.welcome);16. 17. finalButtonbutton=(Button)findViewById(R.id.welcome_ok_button);18. 19. button.setOnClickListener(newView.OnClickListener(){20. publicvoidonClick(Viewv){21. finish();22. }23. });24. }25. }Executando nosso projeto, temos a seguinte tela:

WelcomeActivity sendo executadaAssim, finalizamos nossa Activity de Boas Vindas. At o prximo artigo!

Trabalhando com logs em android13 de maio de 20103 comentriosHoje irei falar sobre um mecanismo simples porm muito til para uma aplicao android: os logs.Os logs permitem ao desenvolvedor debugar erros durante o desenvolvimento e tambm investigar problemas com o software em produo, ou seja, com o usurio final.Para este fim, android tem um classe especfica: A classeLog(android.util.Log).Para criar os log, temos disposio as funesLog.v(), Log.d(), Log.i(), Log.w(), r Log.e().Mas por que tantas funes?Porque os log em java tem alguns tipos ou nveis so eles: DEBUG logs impressos pela funo Log.d() ERROR logs impressos pela funo Log.e() INFO logs impressos pela funo Log.i() VERBOSE logs impressos pela funo Log.v() WARN logs impressos pela funo Log.w()Todas estas funes recebem como parmetros duas strings a primeira, chamada deTAG, e a segunda que a mensagem em si. ATAG uma string que ir identificar a sua aplicao, tornando mais fcil identificar quais logs foram impressos por ela. (Todas as aplicaes imprimem o log no mesmo stream. Assim, a nica forma de separar osseuslogs filtrando pelasuaTag) uma boa prtica definir a TAG como uma string constante:view plaincopy to clipboardprint?1. privatestaticfinalStringTAG="QuickNotesMainActivity";Dessa forma, para imprimir um log de DEBUG basta usar a linha abaixo:view plaincopy to clipboardprint?1. Log.d(TAG,"mensagemdedebug");Visualizando logs pelo DDMSPara visualizar os logs de nossa aplicao, usaremos o DDMS. Abrindo a aba Logcat, temos a seguinte tela:

Lendo logs pelo logcatNoponto 1marcado na imagem, temos os botes de filtragem de nveis. Estes botes permitem que voc escolha quais logs quer ver DEBUG, por exemplo. J noponto 3, voc pode escrever um texto, que ser um filtro para os logs. Por exemplo, se digitar QuickNotesMainActivity, ir ver s os logs que ns colocamos no cdigo acima.Finalmente, noponto 2temos a mensagem de log em si.DICA: Seja cuidadoso com os logs. Eles podem interferir na performance de sua aplicao se, por exemplo, forem colocados dentro de um loop.

Parte 2 Content Providers e Bancos de Dados

Content Providers25 de maio de 201018 comentriosOsContent Providersso parte importantssima da arquitetura de um sistema android. responsabilidade deles prover s aplicaes o contedo que elas precisam para funcionar, ou seja, os dados.Mas por que so realmente necessrios?As aplicaes poderiam muito bem acessar diretamente um banco de dados, por exemplo. Porm, uma boa prtica tornar o modo como os dados so gravados transparente aplicao. Dessa forma, a aplicao pode manter o foco nas interaes com o usurio.Alm disso, essa tcnica permite a criao deShared Content Providers, que so providers pblicos que podem ser acessados por vrias aplicaes. Por exemplo, existe o content provider de SMS/MMS que permite a qualquer aplicao ler as mensagens recebidas por um telefone celular.E como feita a comunicao entre Content Providers e Aplicaes?Uri. Guarde bem este nome, pois voc ir precisar muito dele durante a sua carreira como desenvolvedor android.Toda a comunicao entre aplicaes e providers feita atravs dos mtodos da interface ContentProvider,que sempre recebem um objeto Uri como parmetro. O formato da Uri definido pelo content provider. Por exemplo, a Uricontent://sms/inboxacessa as mensagens de inbox no Content Provider de SMS. Falaremos um pouco mais sobre as Uris a seguir, mas primeiro, vamos conhecer os mtodos que usaremos para envi-las para o provider: query(Uri, String[], String, String[], String)- usado para recuperar dados. insert(Uri, ContentValues) usado para inserir dados. update(Uri, ContentValues, String, String[]) usado para atualizar dados. delete(Uri, String, String[]) usado para deletar dados. getType(Uri) usado para obter o MIME type de certo dado.O QuickNotes Content ProviderDepois dessa rpida introduo, vamos colocar a mo na massa.Iremos criar um content provider para o QuickNotes, que servir para gravar e recuperar as anotaes do usurio, da seguinte forma:

Intencionalmente coloquei a caixa que definecomoo provider ir gravar os dados para mostrar que isso irrelevante para a aplicao.A estrutura das URIsUmaUriusada para acessar Content Provider segue o formato:content://////Onde authority o nome do provider, e os parmetros so aqueles definidos pelo provider. Por exemplo, a seguinte Uri:content://sms/conversations/10Acessa o Content Provider deSMS, e seleciona aconversationde Id nmero10.Criando um Content ProviderPara criar seu prprio content provider, preciso fazer 2 coisas:1. Criar uma sub-classe da ContentProvider, implementando os mtodos pblicos que eu citei no comeo do artigo;2. Registrar o provider no AndroidManifest.xmlVamos comear criando a classe QuickNotesProvider:view plaincopy to clipboardprint?1. packagebr.com.felipesilveira.quicknotes;2. 3. importandroid.content.ContentProvider;4. importandroid.net.Uri;5. importandroid.content.ContentValues;6. importandroid.database.Cursor;7. 8. publicclassQuickNotesProviderextendsContentProvider{9. //AquidefinimososformatospossveisdeUrique10. //onossoprovideriraceitar.11. publicstaticfinalUriCONTENT_URI=Uri12. .parse("content://br.com.felipesilveira.quicknotes.quicknotesprovider");13. 14. @Override15. publicintdelete(Uriuri,Stringselection,String[]selectionArgs){16. return0;17. }18. 19. @Override20. publicStringgetType(Uriuri){21. returnnull;22. }23. 24. @Override25. publicUriinsert(Uriuri,ContentValuesvalues){26. returnnull;27. }28. 29. @Override30. publicbooleanonCreate(){31. returnfalse;32. }33. 34. @Override35. publicCursorquery(Uriuri,String[]projection,Stringselection,36. String[]selectionArgs,StringsortOrder){37. returnnull;38. }39. 40. @Override41. publicintupdate(Uriuri,ContentValuesvalues,Stringselection,42. String[]selectionArgs){43. return0;44. }45. }Agora, vamos registrar o nosso provider no AndroidManifest, adicionando a seguinte linha entre as tags e

E assim o nosso Content Provider est pronto para receber requisies da aplicao. Ainda no retorna nenhum resultado significativo mas isso faremos no prximo artigo, onde ensinarei como acessar um banco de dados SQLite, para fazer esse provider realmente efetivo.

DICA:Usando o MOTODEV Studio, a tarefa de criar um content provider fica muito mais fcil. Basta acessar New > Android Content Provider, que um template ser criado, com todos os mtodos! da s implementar a lgica deles.

Como usar banco de dados em uma aplicao android29 de maio de 201076 comentriosUm dos grandes diferenciais da plataforma android a grande quantidade de mdulos e APIsque as aplicaes tem disposio para usar. Eles do muito poder ao desenvolvedores, permitindo que estes faam coisas que eram impossveis em outras plataformas mveis.Um dos mais importantes mdulos o SQLite. Sim, amigos, j temos um SGDB (Sistema gerenciador de bancos de dados) instalado e pronto para usar! E exatamente o que faremos no artigo de hoje.No artigo anterior vimoscomo criar um Content Provider. Usaremos este provider para acessar o banco de dados.Para fazer isso, precisamos implementar os mtodos da classeContentProviderque vimos no artigo passado (query(), delete(), update(), etc) para prover ao usurio os mtodos para criar, atualizar, deletar e recuperar os dados. Alm disso, usaremos a classeSQLiteOpenHelperpara gerenciar a conexo com o banco de dados.A classe SQLiteOpenHelperA classe SQLiteOpenHelper, como dito anteriormente, ser usada para gerenciar o banco de dados. Para us-la, preciso criar uma subclasse implementando os mtodos abaixo: onCreate() Este mtodo chamado quando a conexo com o banco de dados for aberta pela primeira vez. aqui que criaremos o banco de dados, com o comando sql CREATE. onUpdate() Este mtodo chamado quando a verso do banco de dados muda. Por exemplo, digamos que voc criou uma nova verso de seu aplicativo que usa uma tabela a mais no banco de dados. Quando esta nova verso for instalada (em um telefone que j possuir a primeira verso) este mtodo ser chamado, ento voc poder criar apenas a nova tabela, mantendo os dados do usurio.O cdigoO cdigo do QuickNotesProvider fica assim, acessando o banco de dados. A seguir, eu explico algumas coisas que podem gerar dvidas.view plaincopy to clipboardprint?1. packagebr.com.felipesilveira.quicknotes;2. 3. importjava.util.HashMap;4. 5. importandroid.content.ContentProvider;6. importandroid.content.ContentUris;7. importandroid.content.Context;8. importandroid.content.UriMatcher;9. importandroid.net.Uri;10. importandroid.provider.BaseColumns;11. importandroid.content.ContentValues;12. importandroid.database.Cursor;13. importandroid.database.sqlite.SQLiteDatabase;14. importandroid.database.sqlite.SQLiteOpenHelper;15. importandroid.database.sqlite.SQLiteQueryBuilder;16. 17. publicclassQuickNotesProviderextendsContentProvider{18. 19. //Authoritydonossoprovider,aserusadonasUris.20. publicstaticfinalStringAUTHORITY=21. "br.com.felipesilveira.quicknotes.quicknotesprovider";22. 23. //Nomedoarquivoqueirconterobancodedados.24. privatestaticfinalStringDATABASE_NAME="quicknotes.db";25. 26. //Versaodobancodedados.27. //EstevalorimportantepoisusadoemfuturosupdatesdoDB.28. privatestaticfinalintDATABASE_VERSION=1;29. 30. //Nomedatabelaqueirconterasanotaes.31. privatestaticfinalStringNOTES_TABLE="notes";32. 33. //'Id'daUrireferentesnotasdousurio.34. privatestaticfinalintNOTES=1;35. 36. //Tagusadaparaimprimiroslogs.37. publicstaticfinalStringTAG="QuickNotesProvider";38. 39. //Instnciadaclasseutilitria40. privateDBHelpermHelper;41. 42. //Urimatcher-usadoparaextrairinformaesdasUris43. privatestaticfinalUriMatchermMatcher;44. 45. privatestaticHashMapmProjection;46. 47. static{48. mProjection=newHashMap();49. mProjection.put(Notes.NOTE_ID,Notes.NOTE_ID);50. mProjection.put(Notes.TEXT,Notes.TEXT);51. }52. 53. static{54. mMatcher=newUriMatcher(UriMatcher.NO_MATCH);55. mMatcher.addURI(AUTHORITY,NOTES_TABLE,NOTES);56. }57. 58. 59. /////////////////////////////////////////////////////////////////60. //MtodosoverrideddeContentProvider//61. /////////////////////////////////////////////////////////////////62. @Override63. publicintdelete(Uriuri,Stringselection,String[]selectionArgs){64. SQLiteDatabasedb=mHelper.getWritableDatabase();65. intcount;66. switch(mMatcher.match(uri)){67. caseNOTES:68. count=db.delete(NOTES_TABLE,selection,selectionArgs);69. break;70. default:71. thrownewIllegalArgumentException(72. "URIdesconhecida"+uri);73. }74. 75. getContext().getContentResolver().notifyChange(uri,null);76. returncount;77. }78. 79. @Override80. publicStringgetType(Uriuri){81. switch(mMatcher.match(uri)){82. caseNOTES:83. returnNotes.CONTENT_TYPE;84. default:85. thrownewIllegalArgumentException(86. "URIdesconhecida"+uri);87. }88. }89. 90. @Override91. publicUriinsert(Uriuri,ContentValuesvalues){92. switch(mMatcher.match(uri)){93. caseNOTES:94. SQLiteDatabasedb=mHelper.getWritableDatabase();95. longrowId=db.insert(NOTES_TABLE,Notes.TEXT,values);96. if(rowId>0){97. UrinoteUri=ContentUris.withAppendedId(98. Notes.CONTENT_URI,rowId);99. getContext().getContentResolver().notifyChange(100. noteUri,null);101. returnnoteUri;102. }103. default:104. thrownewIllegalArgumentException(105. "URIdesconhecida"+uri);106. }107. }108. 109. @Override110. publicbooleanonCreate(){111. mHelper=newDBHelper(getContext());;112. returntrue;113. }114. 115. @Override116. publicCursorquery(Uriuri,String[]projection,Stringselection,117. String[]selectionArgs,StringsortOrder){118. //AquiusaremosoSQLiteQueryBuilderparaconstruir119. //aqueryqueserfeitoaoDB,retornandoumcursor120. //queenviaremosaplicao.121. SQLiteQueryBuilderbuilder=newSQLiteQueryBuilder();122. SQLiteDatabasedatabase=mHelper.getReadableDatabase();123. Cursorcursor;124. switch(mMatcher.match(uri)){125. caseNOTES:126. //OBuilerreceberdoisparametros:atabela127. //ondeserfeitaabusca,eumaprojection-128. //quenadamaisqueumaHashMapcomoscampos129. //quequeremosrecuperardobancodedados.130. builder.setTables(NOTES_TABLE);131. builder.setProjectionMap(mProjection);132. break;133. 134. default:135. thrownewIllegalArgumentException(136. "URIdesconhecida"+uri);137. }138. 139. cursor=builder.query(database,projection,selection,140. selectionArgs,null,null,sortOrder);141. 142. cursor.setNotificationUri(getContext().getContentResolver(),uri);143. returncursor;144. }145. 146. @Override147. publicintupdate(Uriuri,ContentValuesvalues,Stringselection,148. String[]selectionArgs){149. SQLiteDatabasedb=mHelper.getWritableDatabase();150. intcount;151. switch(mMatcher.match(uri)){152. caseNOTES:153. count=db.update(NOTES_TABLE,values,154. selection,selectionArgs);155. break;156. default:157. thrownewIllegalArgumentException(158. "URIdesconhecida"+uri);159. }160. 161. getContext().getContentResolver().notifyChange(uri,null);162. returncount;163. }164. 165. /////////////////////////////////////////////////////////////////166. //InnerClassesutilitrias//167. /////////////////////////////////////////////////////////////////168. publicstaticfinalclassNotesimplementsBaseColumns{169. publicstaticfinalUriCONTENT_URI=Uri.parse("content://"170. +QuickNotesProvider.AUTHORITY+"/notes");171. 172. publicstaticfinalStringCONTENT_TYPE=173. "vnd.android.cursor.dir/"+QuickNotesProvider.AUTHORITY;174. 175. publicstaticfinalStringNOTE_ID="_id";176. 177. publicstaticfinalStringTEXT="text";178. }179. 180. privatestaticclassDBHelperextendsSQLiteOpenHelper{181. 182. DBHelper(Contextcontext){183. super(context,DATABASE_NAME,null,DATABASE_VERSION);184. }185. 186. /*OmtodoonCreatechamadoquandooproviderexecutadopela187. *primeiravez,eusadoparacriarastabelasnodatabase188. */189. @Override190. publicvoidonCreate(SQLiteDatabasedb){191. db.execSQL("CREATETABLE"+NOTES_TABLE+"("+192. Notes.NOTE_ID+"INTEGERPRIMARYKEYAUTOINCREMENT,"+193. Notes.TEXT+"LONGTEXT"+");");194. }195. 196. /*OmtodoonUpdateinvocadoquandoaversodobancodedados197. *muda.Assim,usadoparafazeradequaesparaaaplicao198. *funcionarcorretamente.199. */200. @Override201. publicvoidonUpgrade(SQLiteDatabasedb,202. intoldVersion,intnewVersion){203. //ComoaindaestamosnaprimeiraversodoDB,204. //noprecisamosnospreocuparcomoupdateagora.205. }206. }207. }208. 209. CursoresO primeiro conceito importante a se falar o conceito dosCursores. Como voc deve percebido, este o tipo de retorno do mtodoquery(), e no por acaso: Os cursores so apontadores de dados do banco de dados ou seja, uma interface que permite o acesso aos dados retornados pela query enviada pelo usurio.notifyChanges()Em todos os mtodos em que alteramos o banco de dados (inserimos, deletamos ou modificamos dados) importante chamar o mtodomodifyChanges(). Isso far com que as aplicaes que estejam utilizando este conjunto de dados sejam notificadas, permitindo a estas atualizar tambm os dados mostrados ao usurio.No prximo post iremos usar o QuickNotesProvider na nossa aplicao.

Acessando um Content Provider2 de junho de 201021 comentriosNo artigo de hoje comearemos a integrar a nossa aplicaoQuickNotescom oQuickNotesProvider,que criamos no artigo anterior.Vamos comear inserindo uma anotao do usurio no banco de dados. Para fazer isso, o primeiro passo adicionar umListenerao boto Inserir, da seguinte forma:1. ButtoninsertButton=(Button)findViewById(R.id.insert_button);2. insertButton.setOnClickListener(mInsertListener);E agora, criando o objeto mInsertListener. Ele precisa ser um objeto que implementa a interfaceOnClickListener,.Assim, precisamos implementar o mtodo onClick(), que ser chamado assim que o usurio pressionar o boto.view plaincopy to clipboardprint?1. //DefinindoumOnClickListenerparaoboto"Inserir"2. privateOnClickListenermInsertListener=newOnClickListener(){3. publicvoidonClick(Viewv){4. EditTexteditBox=(EditText)findViewById(R.id.edit_box);5. addNote(editBox.getText().toString());6. editBox.setText("");7. }8. };No cdigo acima eu fiz uma chamada a um mtodo que ainda no est implementado o mtodoaddNote(), que recebe um String que ser inserida no banco de dados. Ele ser o mtodo responsvel por efetivamente conversar com o content provider. Vamos implement-lo:view plaincopy to clipboardprint?1. /*2. *Mtodoresponsvelporinserirumregistronocontentprovider3. */4. protectedvoidaddNote(Stringtext){5. ContentValuesvalues=newContentValues();6. values.put(QuickNotesProvider.Notes.TEXT,text);7. 8. getContentResolver().insert(9. QuickNotesProvider.Notes.CONTENT_URI,values);10. }Assim, a MainActivity fica dessa forma:view plaincopy to clipboardprint?1. packagebr.com.felipesilveira.quicknotes;2. 3. importandroid.app.Activity;4. importandroid.os.Bundle;5. importandroid.view.View;6. importandroid.view.View.OnClickListener;7. importandroid.widget.Button;8. importandroid.widget.EditText;9. importandroid.content.ContentValues;10. importandroid.content.Intent;11. 12. publicclassMainActivityextendsActivity{13. 14. privatestaticfinalStringTAG="QuickNotesMainActivity";15. 16. /**Calledwhentheactivityisfirstcreated.*/17. @Override18. publicvoidonCreate(BundlesavedInstanceState){19. super.onCreate(savedInstanceState);20. setContentView(R.layout.main);21. 22. Intenti=newIntent(this,WelcomeActivity.class);23. startActivity(i);24. 25. ButtoninsertButton=(Button)findViewById(R.id.insert_button);26. insertButton.setOnClickListener(mInsertListener);27. 28. //adicionandoum'Hint'aoEditbox.29. EditTexteditBox=(EditText)findViewById(R.id.edit_box);30. editBox.setHint("Novanota...");31. }32. 33. //DefinindoumOnClickListenerparaoboto"Inserir"34. privateOnClickListenermInsertListener=newOnClickListener(){35. publicvoidonClick(Viewv){36. EditTexteditBox=(EditText)findViewById(R.id.edit_box);37. addNote(editBox.getText().toString());38. editBox.setText("");39. }40. };41. 42. /*43. *Mtodoresponsvelporinserirumregistronocontentprovider44. */45. protectedvoidaddNote(Stringtext){46. ContentValuesvalues=newContentValues();47. values.put(QuickNotesProvider.Notes.TEXT,text);48. 49. getContentResolver().insert(50. QuickNotesProvider.Notes.CONTENT_URI,values);51. }52. } importante salientar que estamos apenas inserindo o dado no banco de dados no estamos lendo-o em nenhum lugar na nossa aplicao, ainda.Mas como saber se o dado realmente foi inserido no banco de dados?Vou aproveitar esta pergunta para mostrar como acessar o banco de dados pelo shell do android. Isso muito til para auxiliar no desenvolvimento de aplicaes que lidam com banco de dados.Acessando banco de dados atravs do shellPara acessar o banco de dados pelo shell, iremos iniciar uma sesso com o comandoadb shelle ento usar o comandosqlite3 . A partir da, basta usar comandos SQL normais. Para ver a estrutura do banco de dados, o comando.schemadeve ser usado. Veja no exemplo abaixo:$ adb shell# sqlite3 /data/data/br.com.felipesilveira.quicknotes/databases/quicknotes.dbSQLite version 3.5.9Enter .help for instructionssqlite> .schema.schemaCREATE TABLE android_metadata (locale TEXT);CREATE TABLE notes (_id INTEGER PRIMARY KEY AUTOINCREMENT,text LONGTEXT);sqlite> select * from notes;select * from notes;1|testeComo podemos ver, a primeira entrada do nosso DB est l, ento sinal que o QuickNotesProvider est funcionando corretamente!No prximo artigo, iremos usar o provider para ler os dados j gravados no DB para mostr-los ao usurio. At l!

Criando uma ListActivity27 de novembro de 201039 comentriosHoje aprenderemos a usar uma ListActivity para mostrar ao usuario uma lista com as anotaes que ele inseriu em nossa aplicao QuickNotes.ListActivity? O que isso?A ListActivity uma classe filha daActivitycujo objetivo mostrar ao usurio uma Lista (umaListView). Em suma, umaActivitycom alguns mtodos para gerenciamento de listas, criada com o intuito de facilitar a criao de telas com essa configurao, muito comuns nas aplicaes android.O primeiro passo para criar uma Activity desse tipo assegurar que o layout XML a ser usado por ela possui um elemento ListView (afinal, estamos criando uma ListActivity!). Alm disso, preciso que seu id seja@id/android:list.Adequando o layout da nossa aplicao, temos:view plaincopy to clipboardprint?1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Depois disso, o prximo fazer a nossa classe MainActivity ser uma classe filha da ListActivity:public class MainActivity extends ListActivityE ento, inicializar a ListView no mtodo onCreate. Mas para isso precisaremos de umAdapter.AdaptersAdaptersso classes responsveis por fazer o que chamado de bind: Receber os dados de um Cursor (ou de alguma outra fonte de dados) e coloc-los nos seus respectivos lugares no layout da Activity.Para Activitys complexas, tipicamente so criadas subclasses da classeCursorAdapter(Adapter dedicado a tratar cursores). No nosso caso, em que temos um layout bastante simples, suficiente o uso doSimpleCursorAdapter.No cdigo abaixo eu mostro como usar este adapter, com uma explicao sobre seus parmetros:view plaincopy to clipboardprint?1. ListAdapteradapter=newSimpleCursorAdapter(2. //Oprimeiroparametroehocontext.3. this,4. //Osegundo,olayoutdecadaitem.5. R.layout.list_item,6. //Oterceiroparametroehocursorquecontemosdados7. //aseremmostrados8. mCursor,9. //oquartoparametroehumarraycomascolunasdo10. //cursorqueseraomostradas11. newString[]{QuickNotesProvider.Notes.TEXT},12. //oquintoparametroehumarray(comomesmo13. //tamanhodoanterior)comoselementosque14. //receberaoosdados.15. newint[]{R.id.text});16. 17. setListAdapter(adapter);Um dos parmetros recebidos pelo contrutor daSimpleCursorAdapter o layout dos itens da lista, que definimos da seguinte forma:view plaincopy to clipboardprint?1. 2. 3. 4. 5. E por fim, a nossa Activity principal fica assim:view plaincopy to clipboardprint?1. packagebr.com.felipesilveira.quicknotes;2. 3. importandroid.app.ListActivity;4. importandroid.os.Bundle;5. importandroid.util.Log;6. importandroid.view.View;7. importandroid.view.View.OnClickListener;8. importandroid.widget.Button;9. importandroid.widget.EditText;10. importandroid.widget.ListAdapter;11. importandroid.widget.SimpleCursorAdapter;12. importandroid.content.ContentValues;13. importandroid.content.Intent;14. importandroid.database.Cursor;15. 16. publicclassMainActivityextendsListActivity{17. 18. privatestaticfinalStringTAG="QuickNotesMainActivity";19. privateCursormCursor;20. 21. /**Calledwhentheactivityisfirstcreated.*/22. @Override23. publicvoidonCreate(BundlesavedInstanceState){24. super.onCreate(savedInstanceState);25. 26. Log.d(TAG,"CriandoaMainActivity");27. 28. setContentView(R.layout.main);29. 30. Intenti=newIntent(this,WelcomeActivity.class);31. startActivity(i);32. 33. ButtoninsertButton=(Button)findViewById(R.id.insert_button);34. insertButton.setOnClickListener(mInsertListener);35. 36. //adicionandoum'Hint'aoEditbox.37. EditTexteditBox=(EditText)findViewById(R.id.edit_box);38. editBox.setHint("Novanota...");39. 40. mCursor=this.getContentResolver().41. query(QuickNotesProvider.Notes.CONTENT_URI,null,null,null,null);42. 43. ListAdapteradapter=newSimpleCursorAdapter(44. //Oprimeiroparametroehocontext.45. this,46. //Osegundo,olayoutdecadaitem.47. R.layout.list_item,48. //Oterceiroparametroehocursorquecontemosdados49. //aseremmostrados50. mCursor,51. //oquartoparametroehumarraycomascolunasdo52. //cursorqueseraomostradas53. newString[]{QuickNotesProvider.Notes.TEXT},54. //oquintoparametroehumarray(comomesmo55. //tamanhodoanterior)comoselementosque56. //receberaoosdados.57. newint[]{R.id.text});58. 59. setListAdapter(adapter);60. }61. 62. /*63. *DefinindoumOnClickListenerparaoboto"Inserir"64. */65. privateOnClickListenermInsertListener=newOnClickListener(){66. publicvoidonClick(Viewv){67. EditTexteditBox=(EditText)findViewById(R.id.edit_box);68. addNote(editBox.getText().toString());69. editBox.setText("");70. }71. };72. 73. /*74. *Mtodoresponsvelporinserirumregistronocontentprovider75. */76. protectedvoidaddNote(Stringtext){77. ContentValuesvalues=newContentValues();78. values.put(QuickNotesProvider.Notes.TEXT,text);79. 80. getContentResolver().insert(81. QuickNotesProvider.Notes.CONTENT_URI,values);82. }83. }Executando a Activity, temos a seguinte tela, com a lista das notas que o usurio digitou!

DICA: Tenha muito cuidado ao projetar uma lista. Lembre-se que um usurio pode inserir mil, dez mil registros! O qeu aconteceria nessa situao? A performance nesses casos um fator a ser muito trabalhado e testado. Mas isso fica para um prximo artigo. At l!

Parte 3 Testando sua aplicao

Trabalhando com Unit Tests em Android13 de maio de 201116 comentriosOl pessoal.Meu nome Athila Santos. Eu trabalho com o Felipe em desenvolvimento Android na Motorola e vou comear a ajud-lo na publicao de artigos sobre Android para este blog.O meu primeiro artigo ser sobre Unit Tests.Para quem no sabe, Unit Tests so testes realizados pelo proprio desenvolvedor ou analista de teste, visando testar a menor parte testvel de um sistema.No entanto, testes realizados envolvendo contato com o dispositivo podem ser realizados por qualquer pessoa que utilize a aplicao. O que ns, developers, queremos testar um determinado trecho de cdigo, estado de classes etc. Para tanto, vamos desenvolver APLICAES responsveis, unicamente, por testar a nossa aplicao. bom frisar que os Unit Tests so parte essencial do ciclo de desenvolvimento de um projeto. Para uma app pequena como a QuickNotes pode parecer perda de tempo, mas grandes projetos no sobrevivem sem que os desenvolvedores gastem um bom tempo desenvolvendo Unit Tests decentes.A plataforma Java nos fornece uma excelente ferramenta para desenvolvimento de Unit Tests. a JUnit. Para ficar ainda melhor, Android tambm nos fornece todo um framework declasses em complemento s j existentes no framework do JUnit.Dada esta introduo, mos obra!Neste artigo, vamos testar apenas a UI da Activity principal do QuickNotes.Passo 1 Criar o projeto de teste para o QuickNotes.No Eclipse, clique com o boto direito no seu projeto QuickNotes -> New -> OtherExpanda a pasta Android e selecione Android Test Project.Preencha os campos como na figura 1 (ao selecionar o projeto QuickNotes no campo An existing Android Project, os campos seguintes sero preenchidos automaticamente.

Clique em Finish e seu projeto ir aparecer no Package Explorer.Passo 2 Criar sua classe de test case.Com o boto direito, clique no projeto QuickNotesTest -> New -> ClassPreencha os campos conforme a figura 2. (a classe android.test.ActivityInstrumentationTestCase2 uma classe presente no framework de testes do Android que nos prov algumas APIs muito teis para interagir com a UI de uma Activity). Ela parametrizada com o nome da classe que ser testada por esta classe.

Com a classe de teste criada, vamos implement-la.A primeira coisa que uma classe de teste precisa de um construtor. No construtor padro de qualquer classe de teste que tenha como pai a classe ActivityInstrumentationTestCase2, ns precisamos chamar o construtor desta passando como parametro o pacote da classe sendo testada e uma instancia representando tal classe (.class). Para o nosso caso, o construtor ter apenas isso. Portanto:view plaincopy to clipboardprint?1. publicMainActivityTest(){2. super("com.exemplos.quicknotes",MainActivity.class);3. }O mtodo setUp() um mtodo herdado de uma das classes pai e destinado inicializao do estado da classe de teste. Este mtodo executado ANTES DE CADA TEST CASE, sempre. No nosso caso, vamos us-lo para pegar os elementos de UI da nossa MainActivity:view plaincopy to clipboardprint?1. @Override2. protectedvoidsetUp()throwsException{3. super.setUp();4. mActivity=getActivity();//mActivityiraguardarumainstncadaMainActivity.5. //Estachamadasoepossivelporcausadosparametrospassadosnoconstrutor.6. //eoparametropassadonadefiniodaclasse7. mEditor=(EditText)mActivity.findViewById(R.id.edit_box);8. mButton=(Button)mActivity.findViewById(R.id.insert_button);9. mList=(ListView)mActivity.findViewById(android.R.id.list);10. mAdapter=(SimpleCursorAdapter)mList.getAdapter();11. }Obviamente, voc deve criar as variveis de instncia envolvidas no mtodo:view plaincopy to clipboardprint?1. privateMainActivitymActivity;2. privateEditTextmEditor;3. privateButtonmButton;4. privateListViewmList;5. privateSimpleCursorAdaptermAdapter;Vamos tambm criar a seguinte constante na classe (ser explicado posteriormente)view plaincopy to clipboardprint?1. //Altereestevalorparaonumerodeinsercoesdetestevcdesejaexecutar2. privatestaticintNUMERO_DE_INSERCOES=10;Antes de comear a implementar os test cases, importante verificar se o estado da classe esta consistente. Para executar checagens, vamos usar APIs do framework do JUnit. Mtodos como assertTrue, assertEquals, etc so responsveis por passar ou falhar um determinado check.view plaincopy to clipboardprint?1. //Testaseoselementosdatelaforaminicializadoscorretamente2. privatevoidtestPreConditions(){3. assertTrue(mActivity!=null);4. assertTrue(mEditor!=null);5. assertTrue(mButton!=null);6. assertTrue(mList!=null);7. assertTrue(mAdapter!=null);8. assertTrue(NUMERO_DE_INSERCOES>0);9. }Agora, podemos comear a escrever nossos test cases. Cada test case um mtodo publico, sem retorno (void) e sem parametros. Tambm devem ter seu nome comeado pela palavra test. Assim, o Android Test Runner (entidade responsvel por excutar os testes) saber quais metodos ele deve executar como testes. Portanto, os test cases devem ter o seguinte padro:public void test()No nosso caso, vamos executar testes de insero de elementos na lista e verificar se o que foi digitado pelo usurio o que realmente aparece na tela.Para melhorar a exeperincia, altere o arquivo de xml que descreve o layout da MainActivity do QuickNotes (QuickNotes\res\layout\main.xml) e adicione o seguinte atributo ao ListView:android:transcriptMode=alwaysScrollou seja, deixa o elemento desta forma:view plaincopy to clipboardprint?1. 5. Isto far com que a lista role automaticamente aps uma insero, se os itens no couberem mais na tela.Portanto, nosso test case fica assim:view plaincopy to clipboardprint?1. publicvoidtestInsertIntoTheList(){2. //Comonaopodemosasseguraraordememqueostestessaoexecutados,devemos3. //verificarpre-condicoesantesdecadateste.4. testPreConditions();5. 6. for(inti=0;i Run As -> Android JUnit TestSe suas configuraes de AVD estiverem corretas, o simulador ser iniciado e o QuickNotes ser executado. Voc ver vrias entradas sendo digitadas no text field e adicionadas lista uma a uma.No Eclipse vc pode acompanhar o andamento e o resultado dos testes, como na figura abaixo.

Para efeito de demonstrao, vamos forar uma falha. Altere a seguinte linha do testcase:- assertEquals(random+rand, text);+ assertEquals(test_falha+rand, text);Agora, clique no boto Rerun Test (icone verde com uma seta amarela). Voc ver o resultado como na figura abaixo. Repare que o Eclipse te fornece a stack trace de onde ocorreu a falha. Assim, voc capaz de saber exatamente onde ocorreu a falha e corrigir o problema.

Isto termina nossa introduo aos Unit Tests em Android. No prximo post, vamos aprender como testar a consistncia de estado de uma Activity (se o usurio recebe uma ligao, por exemplo, enquanto est usando sua aplicao, como saber se sua Activity vai retornar ao estado anterior depois que a ligao se encerrar?).At l!