introdução à programação em android

101
Introdução a Progração Android

Upload: armindo-macedo

Post on 13-Apr-2017

53 views

Category:

Education


2 download

TRANSCRIPT

Page 1: Introdução à programação em android

Introdução a Progração Android

Page 2: Introdução à programação em android

Por

Carlos Silva e Pedro Veloso

(iteração 1)

Sobre

Este livro é distribuído livremente sobre a licença Creative Commons Attribution-

ShareAlike 3.0 Unported License .

Resumidamente este licença permite que o trabalho seja distribuído e reutilizado

livremente. Caso existam trabalhos derivados deste, esses mesmos trabalhos deverão ser

tornados acessíveis à comunidade livremente. Este resumo não invalida a leitura da versão

completa da licença, para tal consulte a página da licença referida em cima.

Autoria

Este livro é fruto do trabalho conjunto de Carlos Silva e Pedro Veloso. Este trabalho

ia inicialmente ser realizado com o intuito de produzir um livro para venda por uma editora,

mas infelizmente o tempo dos autores não permitiu progredir conforme esperavam sendo

que abandonamos essa modalidade e decidimos aproveitar o trabalho realizado e distribuir

o mesmo livremente sem qualquer tipo de custo para benefício de todos os potenciais

interessados.

Page 3: Introdução à programação em android

Dito isto, pedimos a compreensão do leitor sobre o facto de que este livro se encontra

incompleto. Os primeiros 4 capítulos sendo os essenciais encontram-se maioriatariemente

completos. Os capítulos 5 e 7 não se encontram completos nem revistos pelo que optamos

pela sua exclusão. No entanto não existe relação directa entre capítulos a partir do 4º cap.

pelo que o leitor poderá tirar partido dos mesmo sem recear quebras de maior na linha de

aprendizagem.

Imagem da capa de autoria de Sara Lima.

Futuro e Donativos

Esta é a 1ª versão que tornamos disponível ao público. Dependendo da recepção da

mesma, da futura disponibilidade dos autores e/ou eventuais contribuições externas

poderão existir novas versões deste documento. Para tal consulte a página que os

autores dedicaram a esse propósito no fórum androidPT.

Para ajudar os autores pondere fazer um donativo; consulte a página em cima para ver o

impacto dos donativos.

De momento os autores aceitam donativos na forma de Bitcoin para o seguinte endereço:

1GcxrHzcRGnxjYB4Liz1GbpiYaFTw9je3v

QR Code do endereço Bitcoint apresentado em cima

Page 4: Introdução à programação em android
Page 5: Introdução à programação em android

Índice Sobre .................................................................................................................................... 2

Autoria .............................................................................................................................. 2

Futuro e Donativos ............................................................................................................ 3

Introdução à plataforma Android .......................................................................................... 8

As Origens ........................................................................................................................ 8

Visão sucinta das várias versões de Android .................................................................... 10

a. Android 1.0 ........................................................................................................... 10

b. Android 1.1 ........................................................................................................... 10

c. Android 1.5 ........................................................................................................... 10

d. Android 1.6 ........................................................................................................... 11

e. Android 2.0, 2.0.1, 2.1 .......................................................................................... 12

f. Android 2.2 ........................................................................................................... 13

g. Android 2.3, 2.3.1, 2.3.2, 2.3.3, 2.3.4, 2.3.5, 2.3.6, 2.3.7 ..................................... 14

h. Android 3.0, 3.1 e 3.2 ............................................................................................ 16

i. Android 4.0 ........................................................................................................... 18

j. Android 4.1 ........................................................................................................... 19

O que é e o que não é ..................................................................................................... 20

Componentes Base .......................................................................................................... 21

Fragmentação ................................................................................................................. 22

Instalação do eclipse ....................................................................................................... 23

Instalação do ADT ........................................................................................................... 24

Configuração do SDK ....................................................................................................... 27

IntelliJ IDEA ..................................................................................................................... 27

MOTODEV Studio ............................................................................................................. 28

2.6 Android Studio .......................................................................................................... 28

Page 6: Introdução à programação em android

Android Debug Bridge ..................................................................................................... 30

DDMS .............................................................................................................................. 31

Emulador ......................................................................................................................... 32

Outras ferramentas ......................................................................................................... 34

k. Draw 9-patch ......................................................................................................... 34

l. Hierarchy Viewer .................................................................................................... 34

m. Monkey ............................................................................................................... 35

n. ProGuard ............................................................................................................... 35

o. Zipalign ................................................................................................................. 35

p. Outros ................................................................................................................... 35

Desenvolver para plataformas móveis .............................................................................. 36

Componentes aplicacionais de Android ........................................................................... 37

q. Activity .................................................................................................................. 38

r. Service ................................................................................................................... 38

s. Broadcast Receiver ................................................................................................. 38

t. Content Provider .................................................................................................... 38

Ciclo de vida de uma Activity ........................................................................................... 39

Gestão de recursos .......................................................................................................... 41

Android Manifest ............................................................................................................. 45

u. Uses-permission .................................................................................................... 46

v. Permission ............................................................................................................. 46

w. Uses-sdk ............................................................................................................. 47

x. Uses-configuration ................................................................................................. 48

y. Uses-feature........................................................................................................... 48

z. Supports-screens ................................................................................................... 49

aa. Application ......................................................................................................... 49

Classe application ........................................................................................................... 50

O que são views .............................................................................................................. 53

Page 7: Introdução à programação em android

Layouts ........................................................................................................................... 54

Menus ............................................................................................................................. 63

Caixas de Diálogo ........................................................................................................... 71

bb. AlertDialog ......................................................................................................... 73

cc. Progressdialog .................................................................................................... 78

dd. CustomDialog ..................................................................................................... 80

Toasts e Notificações ...................................................................................................... 82

Intents – O que são e como utilizar ................................................................................. 87

Usar Intents de Sistema ................................................................................................... 89

Mais sobre Actions .......................................................................................................... 90

Intent Extras .................................................................................................................... 90

Notas Finais sobre Intents ............................................................................................... 93

Modelo De Segurança Aplicacional .................................................................................. 94

Permissões e Descrição ................................................................................................... 95

Assinar uma aplicação com um Certificado Digital ........................................................... 98

Page 8: Introdução à programação em android

111 Introdução à plataforma Android

Neste primeiro capítulo iremos falar um pouco da história de como tudo começou e o porquê

da importância do programador perceber sucintamente a evolução da plataforma.

As Origens

As origens primordiais da plataforma Android remetem para o ano de 2003. Nessa altura o

conceito de smartphone era muito diferente do atual, o Symbian e o Windows CE eram as escolhas

de eleição para qualquer fabricante que quisesse produzir dispositivos que encaixassem neste

conceito de equipamento móvel. Inicialmente a plataforma foi desenvolvida pela Android Inc.,

sendo que após 22 messes de existência, em Agosto de 2005 a Google compra esta empresa e

fica com todos os direitos de desenvolvimento da plataforma. A liderar esta empresa, e sendo

também co-fundador da Danger Inc. estava um homem de nome Andy Rubin, cuja visão e talento

demonstrados fizeram que aquando a compra a Google lhe atribuísse a chefia da sua divisão

móvel, posição na qual continua a ocupar até à data presente.

Em 2003 Andy Rubin falou de 2 pontos que viriam a ser fundamentais na estipulação das

bases da plataforma: dispositivos que tirem proveito da localização do utilizador para lhe oferecer

informação de qualidade e agregação de informação de várias tipos para melhor servir

consumidores mais “tecnologicamente informados”.

Desde essa data a Google tinha iniciado então o desenvolvimento do Android, no entanto em

Janeiro de 2007 um evento particular mudou a realidade do mercado radicalment1

e, o

aparecimento do primeiro iPhone. O iPhone e a genialidade de marketing da Apple trouxeram

consigo uma mudança fundamental de mercado, fizeram com que o público em geral visse os

Smarthphones como uma necessidade, sendo que até então este tipo de dispositivos era quase

que exclusivamente usados no contexto empresarial ou por pessoas com gosto por gadgets.

1

Page 9: Introdução à programação em android

No entanto sua filosofia tal como tudo na Apple segue uma forma de controlo única e

centralizada, querendo isto dizer que só a Apple escolhe que fabricantes fabricam as peças do

iPhone, só eles podem construir dispositivos com o seu sistema operativo, e aquando do

aparecimento do mesmo outras limitações existiam como o facto de só uma operadora nos

Estados Unidos poder comercializar o mesmo. Ora, a Google não encarou isto como um desafio,

mas sim como uma oportunidade. Qualquer limitação que um sistema concorrente tenha é uma

vantagem para um que não tenha essas mesmas limitações. É fácil de conceber a ideia de que

com tantos fabricantes existentes no mercado global esta visão monopolista em que só 1

fabricante e 1 operador móvel podem oferecer algo deste teor e qualidade aos consumidores não

vai de encontro aos seus planos de perdurar no mercado, sendo que algo teria de ser feito para

acompanhar a nova variável de mercado. Desta forma, em Novembro de 2007 a Google

juntamente com 34 outros membros fundam a Open Handset Alliance (geralmente chamada

pelo acrónimo OHA), com um objetivo muito claro: criar uma plataforma livre que permita

qualquer fabricante/operadora produzir dispositivos e serviços com capacidades avançadas num

equipamento móvel, criando uma base uniforme e sobre standards da indústria que permitam a

todos fabricar dispositivos que interajam bem com qualquer outro dispositivo independentemente

da marca, modelo ou fabricante. A OHA tomou o Android, que foi então liberadi livremente pela

Google, como base para o seu desenvolvimento sendo que todos os membros da OHA contribuem

para a gestão e melhoria da plataforma. Entre os membros fundadores estão, para além da

própria Google, a HTC, Samsung Electronics, LG, Motorola, Sony, Texas Instruments, Marvell

Technology, Nvidia Corporation, Intel Corporation, Qualcomm, Synaptics, entre outros grandes

nomes da indústria. É por isso que em qualquer dispositivo Android existente em comercialização

hoje em dia, o código fonte que deu origem a esse equipamento tem contribuições de todas essas

marcas e mais algumas, sendo que presentemente a OHA conta com mais de 80 membros.

Finalmente, a revolução começa a ser aparente quando a 12 de Novembro de 2007 uma versão

beta da SDK de Android é lançada ao público, tendo-se tornado possível a partir desse momento

começar a aprender a programar para a mesma. No entanto o primeiro dispositivo comercial a ser

lançado com Android só veria a luz do dia no ano seguinte, em Setembro de 20082

.

2 Lançamento do HTC Dream, também conhecido por HTC G1.

Page 10: Introdução à programação em android

Visão sucinta das várias versões de Android

De modo a que o leitor compreenda de que funcionalidades de sistema pode usufruir, é

importante perceber quando é que estas foram introduzidas na história da plataforma Android. Só

desse modo consegue garantir agilmente qual a versão mínima de Android que a sua aplicação

deverá suportar. Nos capítulos seguintes o leitor descobrirá como é possível manter

compatibilidade com dispositivos que possuem versões de Android mais antigas e que não

possuem APIs necessárias de modo a usufruir de uma funcionalidade concreta mas não vital da

sua aplicação, e como dinamizar e gerir todo esse processo. Para já, convidamos-lo a dar uma

vista de olhos pelas versões existentes de Android, sendo que nem este texto compreende toda a

informação necessária, nem o leitor precisará em instância alguma de saber de côr esta

informação. A mesma é aqui apresentada como conveniência para quando se deparar com a

necessidade de averiguar diferenças entre versões de Android.

a. Android 1.0

Nome de código: Android

Esta versão de Android foi distribuída aquando do início da venda do HTC G1, o primeiro

smartphone comercial com Android. A sua data de disponibilidade para o público é portanto

coincidente com a comercialização efetiva do dispositivo que teve lugar em Outubro de 2008.

b. Android 1.1

Nome de código: Bender

Esta versão foi lançada como uma atualização para o G1 a 9 de Fevereiro de 2009, embora

poucos detalhes. Entre outras, trouxe a possibilidade de referenciação de bibliotecas externas no

Manifest de Android, muitas correções sendo a maioria relativa ao cliente de correio electrónico e

foi adicionado o suporte inicial para testes de JUnit únicos a Android.

c. Android 1.5

Nome de código: Cupcake

Page 11: Introdução à programação em android

A versão Cupcake pode ser considerada um major release3

, apesar da numeração parecer indicar

o contrário. Foi lançada em Abril de 2009, e teve 4 revisões4

desde então.

Entre as novidades destacam-se os seguintes pontos:

Gravação de Vídeo

Upload de conteúdo para o Youtube e Picasa diretamente do dispositivo

Novo teclado no ecrã, com previsão de texto

Suporte para Bluetooth AD2P e suporte para AVRCP

Novos widgets e pastas para popular o ambiente de trabalho

Transições animadas

Suporte extensivo para localização de língua de sistema, até aqui só existia Inglês e Alemão, sendo

que passaram a ser suportadas mais de 20 línguas oficialmente

Suporte para dispositivos de densidades diferentes

Muitas APIs melhoradas desde geo-localização, métodos de introdução, e framework visual

A título de curiosidade, a partir desta versão os nomes de código das versões de Android passaram a

ser baseados de doces de culinária para além da primeira letra seguir a ordem crescente do alfabeto.

d. Android 1.6

Nome de código: Donut

A versão Donut constituiu uma minor release5

, sendo que o seu foco principal foi a uniformização

e re-estruturação de algumas partes da framework visual, assim como correção de falhas

presentes na versão anterior. Foi lançado em Setembro de 2009 e teve 3 revisões desde então.

3 Major Release: lançamento que constitui um aumento e alteração significativa da API face

à existente

4 Uma revisão (revision) constitui correções a uma API existente, geralmente de teor de

segurança ou estabilidade. Numa revisão a API manten-se a mesma do ponto de vista do

programador.

5 Minor Release: em contraste com a Major Release, uma minor release não constitui uma

mudança significativa da API

Page 12: Introdução à programação em android

Entre as novidades destacam-se os seguintes pontos:

Android Market melhorado

Aplicação da câmara e galeria melhoradas

Introdução da procura por voz

Suporte para CDMA/EVDO, 802.1x, VPNs e motor de texto-para-voz (TTS - Text-To-Speech)

Suporte para ecrãs com resolução WVGA

Melhorias de performance na câmara e aplicação de procura

Suporte para Gestos no Ecrã

e. Android 2.0, 2.0.1, 2.1

Nome de código: Eclair

A versão Eclair de Android foi uma major release, e a sua numeração foi um pouco confusa. O

lançamento inicial foi em Outubro de 2009, sendo que só 1 dispositivo Android chegou

oficialmente a ter esta versão do Eclair, o Motorola Droid, na altura a versão 2.0 do mesmo. A

razão pela qual houveram outras versões Eclair prende-se com o produção do Nexus One, um

dispositivo que iria ser comercializado pela Google e o qual já estava em desenvolvimento

internamente na altura que o Motorola Droid foi lançado. Assim em Janeiro de 2010 surge o

Nexus One que trouxe consigo a versão 2.1 do Eclair. Entre estas duas datas existiu ainda uma

outra versão, a 2.0.1, que foi uma atualização para o Motorola Droid, sendo que teve pouca

relevância no panorama global. Já o mesmo não se pode dizer do Nexus One, cujo objetivo

principal do telemóvel não era tanto ser um sucesso de vendas mas sim elevar o patamar e criar

um telemóvel modelo sobre os quais os fabricantes se deveriam apoiar quando

conceptualizassem novos dispositivos Android, e a verdade é que funcionou pois vejam-se que

até dispositivos de baixo custo como o Sapo A5 têm uma semelhança característica com o Nexus

One, tanto a nível de design como de funcionalidades base. Um dos outros objetivos do Nexus

One foi construir um telemóvel moderno que oferecesse uma base sólida para quem quiser ter

um telemóvel de desenvolvimento em Android, sendo que com isto ficou a promessa que este

dispositivo seria atualizado pelo menos durante 2 anos com as últimas versões de Android.

Entre as novidades introduzidas pela versão Eclair destacam-se os seguintes pontos:

Page 13: Introdução à programação em android

Otimizações de performance do hardware

Suporte para mais resoluções e densidades

Interface visual renovada

Novo Browser com suporte para HTML5

Nova lista de contactos

Melhor rácio de contraste

Google Maps melhorado

Suporte oficial para Microsoft Exchange

Suporte para flash da câmara fotográfica

Zoom Digital

Suporte para Multi-Toque

Teclado virtual melhorado

Suporte para Bluetooth 2.1 e outras melhorias na stack de Bluetooth

Live Wallpapers (panos de fundo animados)

O browser embebido em aplicações passa a ter uma gestão de recursos separada do browser do

telemóvel

Suporte para Ant

Suporte para Virtual Android Keys – ou seja, os botões nativos de Android tais como Home ou

Search passam a poder ser emulados virtualmente ao invés de serem apenas referenciados pela

tecla física

f. Android 2.2

Nome de código: Froyo

Esta versão foi uma das principais novidades do evento Google I/O de 2010, mais concretamente

a 20 de Maio. Nesta altura o Android tinha já conquistado uma posição relevante no cenário

global de smartphones e o mundo estava de olhos postos nas novidades que iriam ser anunciadas

pela Google no evento. Apesar da Google ter assinalado esta como uma minor release a mesma

contem uma panóplia de novidades não menos importantes:

Melhoria de performance geral, com introdução de JIT (Just-In-Time compiler)

Page 14: Introdução à programação em android

Melhorias na gestão de memória

Integração do motor de javascript V8 do Chrome no browser, resultando num aumento

considerável de performance do mesmo

Melhorado suporte do Microsoft Exchange

Launcher de aplicações melhorado

Suporte oficial para tethering, e funcionalidade de ponto-de-acesso móvel

Adicionado suporte oficial para desligar a conexão ao operador móvel

Atualizado Android Market - incluído suporte para updates automáticos

Suporte para Adobe Flash 10.1 (Só para arm v7)

Melhorias no teclado virtual - possibilidade de swiping para mudança de língua e

disposição do teclado

Suporte para telefonemas e partilha de contactos via Bluetooth

Suporte para GIFs animados no Browser

Suporte para instalar aplicações para o cartão de memória (apps2sd)

Introduzido suporte para OpenGL ES 2.0

Introduzida API do AudioManager

Suporte para motores de TTS externos

Várias novidades nas permissões aplicacionais em consequência das novas funcionalidades

introduzidas

g. Android 2.3, 2.3.1, 2.3.2, 2.3.3, 2.3.4, 2.3.5, 2.3.6, 2.3.7

Nome de código: Gingerbread

Mais uma vez, uma versão de Android caracteriza uma família de versões sobre o mesmo nome

de código. O Gingerbread surge inicialmente trazido por mais um dispositivo Nexus, neste caso

o Nexus S apresentado oficialmente a 10 de Dezembro de 2010. Trouxe consigo a versão de

Android 2.3.

A versão 2.3 de Gingerbread trouxe as seguintes principais novidades:

Page 15: Introdução à programação em android

Suporte para o formato de vídeo WebM

Copiar-Colar melhorado

Suporte para resolução 1366×768 Px

Introduzido novo look para Android Market

Goggle Maps atualizado, contendo a nova funcionalidade de visualizar uma camada

unicolor de Edifícios 3D sobre o mapa

Novo tema visual, com fundos a preto e elementos visuais em tons de verde

Suporte para Near-Field Communication (leitor NFC)

Suporte nativo para câmara frontal

Suporte para protocolo SIP

Motor de Garbage Collect redesenhado, agora mais rápido

Drivers gráficos atualizados, com melhor performance para OpenGL ES (incluindo

também uma interface para Khronos EGL )

Suporte para o sensor Giroscópio

Várias bibliotecas internas atualizadas, e aperfeiçoamentos ao Just In Time Compiler

(JIT).

As versões 2.3.1, 2.3.2 e 2.3.5, 2.3.6 e 2.3.7 são tidas como revisões, e portanto não obtiveram

uma versão de API diferente ou alterações de SDK relevantes.

A versão 2.3.3 foi lançada a 9 de Fevereiro de 2011 e foi considerada uma minor release pois

adicionou algumas coisas à funcionalidade que requeriam alterações na API tais como suporte

para mais normas de NFC (near-field-communication) entre outras pequenas melhorias a nível

multimédia.

A versão 2.3.4 foi lançada a 4 de Maio de 2011. Como habitualmente neste mês esta versão trata-

se da extensão de funcionalidades que foi apresentada no Google I/O de 2011, tento trazido

essencialmente pequenas correções e suporte a dispositivos USB (funcionalidade conhecida

como USB Host). Esta funcionalidade permite a comunicação com dispositivos USB, tais como PEN

drives, Joysticks, teclados e ratos USB, etc, e com isto foi também introduzido o Android ADK

Page 16: Introdução à programação em android

(Accessory Development Kit) que permite tirar partido desta funcionalidade e extender o seu uso

para novos tipos de periféricos.

h. Android 3.0, 3.1 e 3.2

Nome de código: Honeycomb

Esta versão de Android é exclusiva a Tablets!

Com o lançamento da versão Honeycomb a plataforma encontrou-se dividida em 2 partes

fundamentais, a versão de Android para Smartphones e a versão para Tablets. Patente a esta

fragmentação está o trabalho tardio do conceito de tablet como um dos focos da plataforma, e

quando finalmente se pretendeu fazer uma versão de Android para este novo formato os

programadores da plataforma foram deparados com um conceito muito diferente de dispositivo

que não enquadrava bem na mesma filosofia e parâmetros que os smartphones. No entanto a

plataforma está construída de forma que uma aplicação possa, mediante algumas alterações e

cuidados no desenvolvimento de aplicações, tornar possível a mesma aplicação executar tanto

numa como noutra, este dinamismo e como lidar com o mesmo será explicado neste livro

também. Para já fica a referência de que esta divergência da plataforma foi dissimilidada com o

aparecimento da iteração seguinte da plataforma, pelo que as diferenças de programação para

Smartphones e Tablets tenderão a diminuar com o passar do tempo.

O Honeycomb 3.0 surge com a apresentação do Motorola Xoom a Fevereiro de 2011. Entre as

principais novidades destacam-se as seguintes:

Interface gráfica redesenhada com tablets em mente. Inúmeras mudanças visuais, desde

inclusão da System Bar, Action Bar de aplicações persistente, nova aplicação de Launcher,

etc

Nova vista de aplicações recentes

Teclado virtual melhorado (agora suporta atalhos com a tecla CTRL, etc)

Page 17: Introdução à programação em android

Aplicações atualizadas: Browser de Internet, Contactos, Câmara, Galeria, Email

Acesso nativo às funcionalidades de aceleração por Hardware para gráficos 3D e 2D

Suporte para processadores de múltiplos núcleos

Suporte para a framework 3D Renderscript

Suporte nativo para Live Streaming HTTP (formato m3u)

Suporte para framework de Digital Rights Management (DRM)

Suporte para Media/Picture Transfer Protocol (MTP/PTP) sobre ligação USB

Suporte para Bluetooth A2DP e perfis de HSP

Suporte para Drag & Drop de elementos visuais

Melhoramentos e novas funcionalidades de animação nativas

Suporte para Fake Touch

Suporte para conversação de vídeo no Google Talk

Em pleno Google I/O de 2011, mais concretamente a 10 de Maio de 2011 é anunciada

oficialmente a versão 3.1 de Honeycomb, sendo que se trata de uma minor release, e apresenta

as seguintes novidades:

Suporte nativo para USB ( USB Host )

Suporte para MTP (Media-Transfer-Protocol) e PTP (Picture-Transfer-Protocol)

Suporte para RTP (Real-time Transport Protocol), um protocolo de streaming de conteúdos

muito utilizado

Widgets de tamanho variável (embora já existissem soluções no Android Market para

cumprir este objetivo, o suporte não era nativo)

Melhorias e novidades nas frameworks de Animação e Interface de Utilizador em geral

Wi-Fi Lock - Aplicações podem escolher que o Wi-Fi não entre em modo de hibernação

quando o dispositivo fica em modo adormecido (tipicamente ao desligar o ecrã), útil para

manter ligação ativa numa comunicação SIP por exemplo

Suporte para áudio FLAC e raw ADTS AAC

Suporte para a tag de <video> de HTML5 e outras melhorias no Browser

Page 18: Introdução à programação em android

Tal como referido anteriormente para a versão 2.3.4 de Gingerbread, também a versão 3.1

suporta a nova ADK de Android.

A Julho de 2011 é apresentada a versão 3.2 de Honeycomb, que fica marcada pela correções de

falhas e pela introdução de algumas novas funcionalidades, entre quais se destacam as seguintes:

Suporte para novo hardware, de modo a suportar novos tipos de tablets

Introduzido modo de Zoom de compatibilidade, de modo a que mais aplicações que foram

feitas para telemóvel sejam possíveis de executar no tablet

Sincronismo de media a nível do cartão SD - dispositivos com suporte a cartões SD passam

a suportar carregamento direto de ficheiros de media a partir do cartão

Re-Introdução do suporte para montar cartões SD tinha sido removido no 3.0)

Adicionado suporte nativo para desenvolvimento para resoluções de TV (por exemplo:

720p)

Suporte para redes HSPAP

i. Android 4.0

Nome de código: Ice-Cream Sandwich

A versão Ice-Cream Sandwich foi lançada a 19 de Outubro de 2011, e trouxe a tão aguardada

união de tablets com smartphones em Android, contituindo assim um patamar importante na

uniformização e redução de fragmentação da plataforma. A versão 4.0 de Android é uma major

release, e conta com as seguintes novidades:

Novo launcher e app drawer

Introdução formal do padrão de desenho (design pattern): Action Bar de aplicação

Widgets redimensionáveis

Page 19: Introdução à programação em android

Novo ecrã de bloqueio, com novas opções

Possibilidade de ter

Suporte para Fake Touch (já presente também em Honeycomb)

Novo teclado virtual, com melhorias de layout e várias melhorias a nível de detecção

de erros ortográficos

Melhorias no sistema de reconhecimento de voz

Visualização e gestão de fluxo de dados de rede das aplicações instaladas

Aplicação dedicada à integração com Redes Sociais

Novo calendário, e melhorias na disponibilização de serviços de calendário a outras

aplicalções de sistema

Edição de fotos a partir da galeria

Nova aplicação de câmara

Reconhecimento de face, e elementos faciais

Suporte para Wi-Fi direct e Bluetooth HDP (possibilidade de integração com qualquer

dispositivo certificado pela Continua)

Partilha de dados por NFC (Android Beam)

Novas APIs de ligações VPN

j. Android 4.1

Nome de código: JellyBean

Interface mais fluída e com melhor tempo de resposta (adicionados VSync e Triple

Buffering)

Adicionadas novas funcionalidades e API de Acessibilidade

Suporte para Texto Bi-Direcional

Page 20: Introdução à programação em android

Suporte para instalação de Keymaps para suportar teclados externos

Notificações expansíveis e agrupáveis

Widgets auto-ajustáveis

Fotos de contactos em alta resolução

Controlo de hardware de vibração de dispositivos conectados (Rumble Pak, etc)

Multicast DNS Discovery e melhorado Wi-Fi Direct

API para aceder à listagem de low-level codecs

Suporte para Áudio por USB

Suporte para áudio multi-canal até 5.1 AAC

Reencaminhamento de áudio, Media Router e Audio Chainning adicionados

Melhoramentos de performance de Renderscript e novo suporte para texturas

Motor V8 e WebView atualizados para melhorar performance e permitir captura de media

de HTML5 e deteção correta de field-type

Introduzido Google Cloud Messaging (GCM) para envio de mensagens pequenas em

multicast

Encriptação de aplicações pagas

Atualização inteligente de aplicações - apenas as componentes novas das aplicações são

transferidas nas atualizações e não a aplicação nova na totalidade

Melhor integração de serviços do Google+

O que é e o que não é

Existe alguma confusão por parte de alguns programadores, e mesmo utilizadores, do que é

realmente a plataforma Android. Uma das principais confusões é em relação à linguagem de

programação da plataforma. Realmente a linguagem usada para programar para Android é Java,

mas Android não é baseado na plataforma Java ME. Como tal, não é possível correr aplicações

Java compiladas para Java ME (como é o caso de algumas aplicações para terminais Nokia) em

Page 21: Introdução à programação em android

Android. Isto porque a máquina virtual de Java que executa o código em Android é a Dalvik VM,

que é uma VM6

otimizada para terminais móveis.

Android também não é simplesmente uma camada aplicacional, sendo que define muito mais que

isso. Quando se fala em Android como plataforma, estamos a falar desde o Kernel que corre no

dispositivo (Linux), até às Aplicações em si passando por bibliotecas nativas, bibliotecas da API, e

como é óbvio, a camada Aplicacional e de Serviços fornecidos pela plataforma aos

programadores.

Outra grande confusão, é se o Android é um telemóvel. Para além de todo o software que a

plataforma Android define, também faz parte da plataforma um design de referência para os

fabricantes de terminais se basearem para o desenvolvimento dum novo terminal, mas não há

uma rigidez nos componentes que têm de ser aplicados nesses terminais. Por isso, a plataforma

possibilita aos fabricantes a utilização da plataforma Android em vários tipos de terminais, desde

terminais de gama baixa até aos topo de gama da marca, sendo que Android pode ser utilizado

até em equipamentos que não dispõe de uma utilização para tele-comunicações como em

eletrodomésticos inteligentes, etc.

Componentes Base

A componente mais importante de toda a plataforma, é provavelmente a Dalvik VM. Esta máquina

virtual é a responsável pela execução de todo o código Java que faz parte da plataforma Android.

Foi criada por um programador da Google (Dan Bornstein) com o intuito de ser “base” da

plataforma. É também bastante diferente das Java VMs que são usadas normalmente noutros

sistemas operativos pois esta está especialmente otimizada para que os programas possam ser

interpretados duma forma rápida e eficaz e ao mesmo tempo usando pouca memória.

Como já deve ser do seu conhecimento, o Kernel usado pela plataforma é o Kernel Linux. Este

conta com algumas alterações para que todo o software possa executar sem problemas. Algumas

destas alterações incluídas no Kernel são:

Android Debug Bridge (adb): Usado para aceder ao terminal via USB ou TCP/IP e poder

obter informações de sistema como logs, aceder à shell do terminal, enviar e receber

ficheiros, etc.

6 Máquina Virtual

Page 22: Introdução à programação em android

Low Memory Killer: Componente do Kernel que gere a memória do terminal. É este o

componente responsável por terminar aplicações quando o terminal precisa de memória

livre para executar alguma coisa.

IPC Binder: Esta parte do Kernel é responsável por uma parte muito importante da

plataforma. Quando as aplicações precisam de falar entre si, por vezes podem precisar de

algo mais completo que uma simples chamada de um Intent (mais à frente veremos o que

é). Para isto existe este serviço que possibilita os programadores “falarem” diretamente

com outras aplicações instaladas.

Numa arquitetura Linux, precisamos de algo que ligue o Kernel às aplicações. A esta biblioteca

chamamos LibC e a mais usada nas tecnologias de informação é a GNU LibC. Na plataforma

Android no entanto, esta biblioteca foi substituída pela BIONIC C Library. A BIONIC C é uma

versão muito reduzida e otimizada, com partes da biblioteca C de *BSD e partes da GNU LibC para

Linux, e ainda funcionalidades que lhe são únicas. Muitas coisas foram alteradas e reduzidas de

forma a que todos os pedidos ao Kernel sejam feitos o mais rápido possível e sem haver uma

preocupação com otimizações específicas. Muitas otimizações utilizadas na LibC de Linux por

exemplo, seriam demasiado pesadas para serem executadas em terminais com pouca memória e

com escassos recursos de processamento, logo o seu custo/benefício seria nulo.

Fragmentação

A fragmentação é um “problema” criado pela plataforma devido a ser bastante maleável, e

portanto poder adaptar-se quase a qualquer tipo de terminal. Acontece que muitas vezes os

fabricantes e/ou as operadoras lançam terminais para o mercado que depois acabam por não lhes

dar suporte a nível de atualizações do Sistema Operativo, mesmo após a Google disponibilizar

novas versões da plataforma. Com isto cria-se uma dor de cabeça para os programadores porque

se quiserem suportar o máximo de terminais possíveis para a sua aplicação têm de ter em conta

vários aspetos para não quebrarem a compatibilidade com os terminais mais antigos. Assim

temos por exemplo aplicações que suportam APIs desde a versão 1.5 até à versão mais atual de

Android mas que recorrem a vários “truques” para que isto seja possível. Num capítulo mais à

frente este assunto será abordado novamente numa perspetiva de perceber o que um

programador pode fazer para resolver e lidar com este problema.

Page 23: Introdução à programação em android

222 1CCOOMMOO CCOONNFFIIGGUURRAARR OO

AAMMBBIIEENNTTEE DDEE

DDEESSEENNVVOOLLVVIIMMEENNTTOO

Como plataforma e ambiente de desenvolvimento para Android, a Google adotou o ambiente

Eclipse, desenvolvendo um plugin chamado Android Developer Tools Plugin for Eclipse (ADT).

Neste capítulo vai ver como instalar e configurar corretamente o Eclipse para desenvolvimento para

a plataforma Android, sendo que as introções aqui presentes cobrem os 3 sistemas operativos mais

usados, Windows, Linux e MacOS X.

Instalação do eclipse

O 1º passo caso esteja num ambiente Windows ou MacOS X, é ir ao website oficial do Eclipse7

e

fazer a transferência da última versão disponível para programação em Java (com o título Eclipse

IDE for Java Developers, tal como é ilustrado na figura 2.1). Ter em atenção a versão do sistema

operativo, se é 32bits ou 64bits e fazer download da versão apropriada. No caso de estar a usar

Linux, pode também utilizar o método anteriormente descrito para Windows/MacOS X, ou então

usar o sistema de instalação de aplicações da sua distribuição (apt-get, emerge, yum, rug, etc).

FFIIGGUURRAA 22..1 –– Transferência do Eclipse para Java

7 http://www.eclipse.org

Page 24: Introdução à programação em android

Após a transferência ter concluído, basta descomprimir o ficheiro que guardou para a aplicação

ficar pronta a usar. Pode fazê-lo por exemplo para o seu Ambiente de Trabalho. Após isto feito,

pode abrir o Eclipse pela 1ª vez. Neste altura ser-lhe-á também perguntado onde fica definido o

seu workspace8

.

Instalação do ADT

Com o Eclipse aberto, selecione o menu Help e em seguida escolha a opção Install New Software.

Ser-lhe-á apresentada uma janela semelhante à da figura 2.2 .

FFIIGGUURRAA 22..22 –– Janela de instalação de plugins do Eclipse

Na janela apresentada deverá então pressionar o botão Add para adicionar um repositório. Na

caixa de dialogo que irá aparecer preencha o campo Name com ADT e o campo Location com o

valor https://dl-ssl.google.com/android/eclipse/ , tal como é evidenciado pela figura 2.3.

8 Workspace é o local onde os projectos do eclipse ficam guardados. Este mecanismo é

prático pois permite por exemplo ter vários workspaces se estiver a trabalhar em diferentes

contextos, e dessa forma agrupar e separar o trabalho convenientemente.

Page 25: Introdução à programação em android

FFIIGGUURRAA 22..33 –– Adicionar o repositório do plugin de Android

O Eclipse irá então procurar no novo repositório inserido os plugins disponíveis para serem

instalados. Quando terminar irão estar disponíveis novas opções para instalação dentro do grupo

Developer Tools tal como está na figura 2.4. Pode simplesmente selecionar todas e clicar em Next.

FFIIGGUURRAA 22..44 –– Componentes do plugin de Android

Na fase seguinte o Eclipse apenas nos diz que software nós escolhemos para instalação e se tudo

está conforme para a executar. Basta pressionar o botão Next novamente para passarmos à fase

Page 26: Introdução à programação em android

onde lhe é dada a conhecer as licenças dos Plugins que vai instalar no Eclipse. No fim de aceitar

as licenças, só tem de pressionar o botão Finish e a instalação iniciar-se-á.

Durante a instalação, vai-lhe aparecer um aviso acerca de conteúdo que vai ser instalado mas que

não está assinado digitalmente, semelhante ao que é apresentado na figura 2.5. Este aviso é

normal nesta instalação.

FFIIGGUURRAA 22..55 –– Aviso de assinaturas digitais

No final da instalação vai-lhe ser pedido para reiniciar o Eclipse para aplicar as alterações

efetuadas pela instalação do Plugin. Clique então em reiniciar. Após o Eclipse iniciar novamente,

veremos que o ADT já está instalado, visto que lhe deverá ser mostrada uma janela a pedir para

fazermos a transferência da SDK9

para desenvolver em Android.

Nesta altura selecione as duas opções disponíveis debaixo da opção Install new SDK e escolha o

local onde quer guardar toda a SDK, tal como evidenciado na figura 2.6. Finalmente, apenas

necessita de pressionar Finish.

FFIIGGUURRAA 22..66 –– Transferência da SDK de Android

Mais uma vez, o Eclipse vai analisar o que é necessário instalar e mostra-nos essa informação. De

notar que esta instalação já é o próprio ADT a fazer e não o Eclipse visto estarmos a instalar

versões da SDK de Android que nada têm a ver com o Eclipse em si. A esta altura apenas

necessita de aceitar todas as e carregar em Install.

9 Sofware Development Kit

Page 27: Introdução à programação em android

A partir deste momento, tem o ambiente de desenvolvimento completamente preparado para

começar a desenvolver aplicações Android usando o Eclipse.

Configuração do SDK

Dentro da aplicação de configuração do SDK Android, que pode ser aberta clicando no botão que

se encontra na barra superior do Eclipse (ver figura 2.7). Esta aplicação do SDK serve para instalar

várias versões da API de Android, fazer atualizações quando saem novas versões e também

instalar outros componentes não obrigatórios do SDK.

FFIIGGUURRAA 22..77 –– Iniciar o SDK Manager

Ao abrir o configurador do SDK, este tentará automaticamente atualizar as versões que tem

instaladas e instalar mais alguma coisa que lhe seja útil para o desenvolvimento. Pode instalar

ainda documentação de cada API e as APIs da Google (para utilização do Google Maps, etc). Os

itens relativos a ARM EABI v7a System Image são as imagens dos emuladores para testar as

aplicações no PC de desenvolvimento.

Sugestão: Instale sempre a documentação, e para o âmbito deste livro, instale também as Google APIs.

IntelliJ IDEA

É também possível usar o ItelliJ IDEA como ambiente de desenvolvimento. A última versão

gratuita disponível no website do IntelliJ 10

já é compatível com o desenvolvimento para Android

usando a SDK oficial.

10 http://www.jetbrains.com/idea/

Page 28: Introdução à programação em android

MOTODEV Studio

O MOTODEV Studio 11

é um IDE baseada em Eclipse e no plugin ADT que foi referido

anteriormente, e com o acréscimo de algumas ferramentas extra para auxiliar certas tarefas que

de outra forma requeriam trabalho manual do programador. Entre estas contam-se ferramentas

para melhor suporte a localização de conteúdos (mesma aplicação em várias línguas), gestão

integrada de bases de dados sqlite, snippets de código, etc.

Não entraremos em pormenor de como instalar e configurar corretamente o MOTODEV Studio

visto não ser oficialmente suportado ficando portanto o leitor encarregue de o instalar e

configurar para desenvolvimento Android caso assim o deseje.

2.6 Android Studio

Desde Maio de 2013 que o IDE oficial de Android passou a ser o AndroidStudio. Este IDE não é

mais do que uma versão do IntelliJ IDEA com um conjunto de tecnologias limitado ao espectro

Android e Google App Engine. Como na altura da escrita deste livro ainda não existia o dito IDE,

deixamos aqui o link para a página do mesmo para que possa descubrir mais.

11 http://developer.motorola.com/docstools/motodevstudio

Page 29: Introdução à programação em android
Page 30: Introdução à programação em android

333 2FFEERRRRAAMMEENNTTAASS DDOO

3SSDDKK DDEE AANNDDRROOIIDD

No capítulo anterior vimos como podemos configurar o ambiente de desenvolvimento, cujo cenário

típico passa por instalar a SDK de Android e uma IDE (que embora aconselhado não é obrigatória para o

desenvolvimento), mas no entanto a SDK de Android fornece um conjunto muito mais extenso de

ferramentas para auxiliar o desenvolvimento aplicacional que vai muito para além de simplesmente permitir

a compilação do software.

Android Debug Bridge

O Android Debug Bridge (ADB) é uma aplicação de cliente-servidor que se comparte em 3

componentes:

1) Uma aplicação Servidor que corre na máquina de desenvolvimento, à qual os dispositivos e

emuladores se ligam para intercomunicação

2) Um Daemon que corre em plano de fundo no dispositivo de testes ou emulador

3) Uma aplicação cliente, que corre na máquina de desenvolvimento e permite a interação do

programador com a componente Servidor que corre também ela na máquina de

desenvolvimento

Para o programador esta aplicação é usada para uma panóplia de casos possíveis. Esta

componente é usada abstratamente sempre que o vai ao ecrã de Debug do Eclipse para operar

com o DDMS12

por exemplo. A um nível operacional mais baixo pode também usar a ferramenta

de linha de comandos "adb" que se encontra presente da diretoria /platform-tools da raiz de

instalação do SDK. Esta ferramenta de linha de comandos permite iniciar e terminar a componente

12 Componente do plugin de Android e do SDK, explicado em detalhe mais à frente neste

capítulo

Page 31: Introdução à programação em android

de servidor que executa na máquina de desenvolvimento, assim como tirar partido de uma

instância deste já em execução para interação com o dispositivo.

Tal como o nome sugere, o Android Debug Bridge tem como principal objetivo auxiliar o

processo de depuração da aplicação. A utilização mais vulgar e comum é feita com recurso à

opção logcat. Esta opção permite ver e filtrar em tempo real toda a informação de depuração que

é emitida pelo terminal. Em Android existe uma class dedicada exclusivamente à tarefa de

depuração de nome Log. Sempre que o programador invocar esta class terá de especificar o tipo

de severidade do registo que vai fazer (Warning, Error, Debug, Verbose, Info, etc) e a tag sobre a

qual faz esse registo, deste modo ao usar a opção logcat é-nos possível filtrar por aplicação, tag e

severidade de registo.

DDMS

O Dalvik Debug Monitor Bridge (DDMS) é a ferramenta visual de depuração que vem juntamente

com o SDK de Android. O DDMS recai na ligação estabelecida pelo daemon de ADB para abstrair a

comunicação com o dispositivo (ou instância de emulador).

A ferramenta pode ser aberta dentro do Eclipse (mediante instalação prévia do plugin de

desenvolvimento Android) da seguinte forma: clicar no menu Window na barra de ferramentas, e

de seguida escolher as opções Open Perspective > Other... > DDMS . A vista resultante será

semelhante à da figura 3.1. O DDMS pode alternativametne ser executado separadamente do

Eclipse sendo que se encontra na diretoria tools com o nome ddms (ou ddms.exe se se tratar do

sistema operativo Windows).

Page 32: Introdução à programação em android

FFIIGGUURRAA 33..2 –– Vista DDMS no Eclipse

Emulador

O emulador de Android é baseado na tecnologia de código aberto QEMU dado à sua versatilidade

de permitir emular processadores Advanced RISC Machine (ARM) e Intel x86, que por sua vez é

abstraído pelo Android Virtual Device (AVD). Um AVD é uma instância de emulador criada com

recurso ao SDK Manager. A sua criação e manuseamento podem ser feitos tanto por linha de

comandos ou através do editor visual para o efeito (que também integra com o plugin de

Android).

Dada a diversidade de equipamentos físicos existentes o AVD é uma exelente ferramena para

combater essa têndencia uma vez que torna possível criar várias instâncias virtuais que simulam

equipamentos com características de hardware distintas. Entre os atributos que são

parametrizáveis contam-se a descriminação do tamanho de ecrã, memória RAM disponível e

versão do sistema operativo (com ou sem suporte para Google APIs).

Para criar um AVD através do Eclipse, primeiro tem de abrir o gestor de AVDs através do botão

para o efeito (ver figura 3.2).

Page 33: Introdução à programação em android

FFIIGGUURRAA 33..22 –– Gestor de AVDs

De seguida clica no botão New para criar uma nova AVD, e é-lhe apresentado um formulário

semelhante ao da figura 3.3, o qual como pode ver já preenchemos os campos com uma AVD ao

nosso gosto. Poderá e deverá criar tantas AVDs quantas achar necessárias para testar as suas

aplicações em condições variadas. Após criar a instância de AVD esta ficará disponível no gestor

tal como é apresentado na figura 3.4.

FFIIGGUURRAA 33..33 –– Formulário de criação de um AVD

Page 34: Introdução à programação em android

FFIIGGUURRAA 33..44 –– Janela de gestão de AVDs existentes

Se o leitor pretender criar um AVD semelhante ao anterior pela linha de comandos, a sua sintaxe

seria:

android create avd -n emulador_ics -t 2 -c 32M

Onde -n diz respeito ao parâmetro do nome, -t ao identificador único da AVD, -c ao tamanho do

cartão de memória a criar. Se o leitor quisesse habilitar suporte para Snapshots bastaria passar a

opção -A.

Outras ferramentas

As ferramentas referidas em até agora são de uso comum e genérico seja qual for a escala ou

contexto (empresarial, didático, etc) do desenvolvimento que o programador se deparar. No

entanto existem outras ferramentas de uso específico que passamos agora a referir.

k. Draw 9-patch

Ferramenta para criar e visualizar um tipo de imagem única a Android, usualmente denominadas

por imagens 9-patch.

l. Hierarchy Viewer

Page 35: Introdução à programação em android

Permite visualizar a hierarquia de desenho das Views e Layouts de Android, o leitor perceberá

melhor a utilidade desta ferramenta nos próximos capítulos. Esta ferramenta também integra com

o Eclipse.

m. Monkey

Permite gerar e enviar eventos de input pseudo-aleatórios para o dispositivo, serve

essencialmente para uma despistagem rápida de eventos relacionadas com a interação do

utilizador.

n. ProGuard

Otimização e ofuscação do código gerado por pré-compilação. A ofuscação renomeia Classes,

parâmetros e métodos.

o. Zipalign

Otimiza o tamanho final do .APK gerado pela compilação através da compressão de ficheiros de

imagem presentes na aplicação.

p. Outros

Para mais informações consultar a documentação oficial relativa às ferramentas da SDK Android

na página respetiva13

.

13 http://developer.android.com/guide/developing/tools/index.html

Page 36: Introdução à programação em android

444 4FFUUNNDDAAMMEENNTTOOSS

AAPPLLIICCAACCIIOONNAAIISS

Neste capítulo damos-lhe a conhecer as bases aplicacionais da plataforma. Entender os tópicos que

iremos falar é essencial para que o leitor se sinta à vontade com os capítulos seguintes e consiga

capturar a essência do funcionamento do sistema operativo Android.

1

Desenvolver para plataformas móveis

Quando se trata de desenvolver para Android, ou qualquer plataforma móvel em geral, existem

certas considerações que devem ser tidas em conta. Em particular os smartphones actuais são

máquinas muito capazes e completas que incorporam desde câmara de vídeo a receptor de GPS,

várias formas de conectividade, entre outras, mas parte do uso que as aplicações dão a este

conjunto de capacidades para que exista uma experiência agradável para o utilizador e bem

integrada com o sistema.

O primeiro ponto que vamos falar é talvez o mais evidente que se trata da boa gestão de

recursos do dispositivo. Os terminais móveis pela própria natureza que têm são dispositivos que

têm uma bateria cujo consumo pode variar largamente consoante a velocidade de relógio do

processador, tempo de uso de certas capacidades do hardware (receptores de sinal, sensores, etc)

e estado de operação, sendo que todas estas variáveis são afectadas pelas aplicações que estão a

executar no dispositivo a um dado momento.

Deste modo é importante que uma aplicação feita para este tipo de terminais seja o mais eficiente

possível na gestão desses recursos. Uma consideração importante a ter é que o Android é uma

plataforma multitarefa14

, sendo que a qualquer momento o utilizador pode decidir comutar entra

14 Multitarefa é a capacidade de um sistema operativo executar vários processos em

simultaneo

Page 37: Introdução à programação em android

a sua e outra qualquer aplicação ou mesmo premir o botão de energia para colocar o dispositivo

em standby.

Um outro ponto importante é a capacidade de resposta da aplicação, e este é talvez o ponto

mais habitualmente desprezado por programadores iniciantes à plataforma. Por capacidade de

resposta entende-se que ao disputar uma acção de carácter moroso o dispositivo não fique

bloqueado durante mais do que meros segundos na aplicação sem o utilizador poder intaragir

com o terminal. Neste caso o ideal é fazer esse tipo de tarefas num processo no plano de fundo e

providenciar notificações ao utilizador para que este tenha a percepção do progresso dessa

operação, mas ao mesmo tempo poder continuar a interagir com a aplicação em áreas que não

requeiram que o resultado da operação demorada tenha terminado. Por exemplo, se o utilizador

estiver no Browser, certamente quer poder transitar para uma nova página enquanto uma

transferência de um ficheiro que foi entretanto iniciada seja efectuada em segundo plano.

Nas aplicações móveis, mais do que nas aplicações de computador pessoal, é necessário ter em

vista a organização visual da informação. Como o ecrã de um dispositivo móvel pode ser muitas

vezes inferior em resolução comparativamente ao ecrã de um computador as aplicações deverão

ser pensadas tendo em conta esse fator. Com uma boa organização do layout da página consegue

encapsular em pequenas áreas muita informação útil, mas atenção para não reduzir nem

compactar a informação em demasia porque senão o utilizador poderá ficar confuso pela

proximidade da mesma, e ao mesmo tempo se no meio dessa informação houverem

componentes que respondem ao toque não convém que 2 elementos deste tipo estejam

demasiado próximos porque senão irá causar muitos “falsos toques” por parte do utilizador.

As considerações aqui faladas são de um âmbito genérico em Android, sendo que a mais

discussões de melhores práticas serão expostas ao longo do livro conforme se encaixem no

contexto do capítulo em que se inserem.

Componentes aplicacionais de Android

As componentes de uma aplicação são os blocos básicos de construção da mesma. A SDK de

Android fornece vários blocos diferentes, sendo que através de cada um destes o sistema

consegue interagir com sua aplicação. Nem todos estes têm um caráter de interacção direta do

utilizador como poderá compreender de seguida.

Uma aplicação pode ser constituída por vários destes blocos, e estes blocos são comunicáveis

entre si na maioria dos casos.

Page 38: Introdução à programação em android

q. Activity

Uma Activity é um ecrã da aplicação, o análogo a uma Janela no Windows (ou Form noutras

linguagens/sistemas). É aqui que habitualmente se produz e elabora a componente de interacção

visual de uma aplicação.

r. Service

Um Service como o nome sugere é um serviço. Não contem um frontend visual como a Activity, e

serve geralmente para efectuar tarefas potencialmente demoradas em plano de fundo.

Geralmente é usado como estrutura de suporte às várias Activities de uma aplicação, tratando de

coisas como a comunicação com a ligação à Internet, atualizações periódicas de conteúdos, e

inter-comunicação entre aplicações.

s. Broadcast Receiver

Um Broadcast Receiver é uma componente que reage a eventos/sinais de sistema. No processo

de instalação de uma aplicação em Android, o instalador procura pelas componentes deste tipo e

insere numa tabela de sistema as referências sobre a que tipo de eventos aquela aplicação reage.

Entre eventos deste tipo enviados pelo sistema operativo podem-se contar coisas como a

mudança da hora actual, alteração do estado da bateria, alteração das condições de conectividade

(passou a ter ligação, ficou sem ligação, etc), entre muitos outros. Desse modo, a título de

exemplo, é possível produzir uma aplicação que tenha uma componente deste tipo e que cada

vez que o sistema envia um sinal de que se perdeu ligação à rede, é adiada a atualização de

conteúdos via rede até que o sinal de ligação restabelecida seja enviado e mais uma vez recebido

pela nossa componente de Broadcast Receiver, desse modo fazendo uma gestão inteligente de

quando é que a aplicação vai executar código relativo à tentativa de obtenção de atualizações

periódicas. Este e outros exemplos de gestão inteligente com recurso a Broadcast Receivers serão

estudados em mais detalhe em capítulos posteriores do livro.

t. Content Provider

Um Content Provider é uma forma de providenciar informação da nossa aplicação a outras

aplicações instaladas no sistema operativo. Isto permite criar um eco-sistema muito poderoso

assim que o leitor de aperceber de que forma esta componente pode ser utilizada e das diversas

aplicações que atualmente já tiram ou permitem tirar partido desta capacidade. Um exemplo de

uma aplicação com uma componente deste género é a aplicação de Contactos (Contacts)

presente na generalidade de terminais Android. Esta aplicação fornece um Content Provider para

Page 39: Introdução à programação em android

que qualquer outra aplicação possa saber quais os contactos guardados no dispositivo, e iterar

sobre a listagem dos mesmos.

A componente de Content Provider fornece deste modo uma forma geral e abstrata de fornecer os

conteúdos da aplicação em que se insere, esta forma genérica segue sempre a mesma estrutura

tornando fácil o uso desta componente por outras aplicações. Ao mesmo tempo, a implementação

de como a informação que está a ser fornecida é da escolha do programador, que pode mesmo

controlar que tipo de informação é fornecida e a forma como esta está guardada no dispositivo

(podendo mesmo estar na nuvem ao invés de fisicamente no dispositivo por exemplo).

Ciclo de vida de uma Activity

Tal como já foi referido o Android é um sistema operativo multitarefa, e tendo sido concebido

nesse sentido desde o inicio do seu desenvolvimento consta de uma gestão inteligente e eficaz de

processos, sendo que isto acarreta consequências à forma como se programam aplicações na

plataforma.

As Activities contam com um conjunto de métodos de callback 15

que devem ser usados na

construção lógica de aplicações. O diagrama apresentado de seguida pela figura 4.1 ilustra o ciclo

de vida de uma Activity e os métodos que callback (onStart, onPause, etc) que são chamados

aquando a ocorrência de cada uma das condições que lhes precedem.

15 Métodos chamados automaticamente pelo sistema face a um acontecimento específico

Page 40: Introdução à programação em android

FFIIGGUURRAA 44..3 –– Ciclo de vida de uma Activity

Para ilustrar uma estrutura de uma Activity deixamos em baixo um excerto de código de uma

Activity do Hello World típico de Android. Neste momento não é necessário que o leitor perceba já

toda a estrutura do código aqui ilustrado, serve apenas para se começar a ambientar com a

sintaxe

Page 41: Introdução à programação em android

import android.app.Activity;

import android.os.Bundle;

public class TestActivity extends Activity {

/** Método de Callback chamado quando a Activity é criada inicialmente. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//Definir a layout da Activity baseada no ficheiro main.xml

setContentView(R.layout.main);

}

}

Gestão de recursos

Uma das grandes potencialidades a nível de programação da plataforma Android é a sua fácil

gestão e utilização de recursos (Resources). Facilmente identificáveis visto estarem sobre o

directório /res do projecto, é aqui que tudo aquilo o que não é código Java fica guardado,

incluindo imagens.

Como se pode ver pela figura 4.2, existem vários sub-diretórios dentro do directório /res quando

se cria um projeto Android no Eclipse, servindo para categorizar os recursos que lá estão e para

que a plataforma Android os possa otimizar e usar da melhor maneira possível tendo em conta a

sua finalidade.

Cada “agrupamento” de recursos é dividido em duas partes: o tipo e o qualificador, podendo

haver mais do que 1 qualificador. Na figura 4.2 podemos constatar que existem 5 grupos de

recursos, sendo que apenas existem 3 tipos diferentes: drawable, layout e values. Estes são

habitualmente os 3 tipos de recursos mais usados na plataforma, embora hajam mais com outros

propósitos. A tabela 4.1 mostra todos os tipos de recusos que existem.

Page 42: Introdução à programação em android

FFIIGGUURRAA 44..22 –– Resources de um projecto novo no Eclipse

NOME DESCRIÇÃO DE USO

animator Defenições de animações do tipo property

anim Animações do tipo tween

color

Usado para definição de cores ou para definições de Listas de Estado de Cor

(Color State Lists) que são usadas para definição de uma cor para um estado

(selecionado, pressionado, etc)

drawable

Onde são guardadas todas as imagens (incluindo definições em xml como

podem ser por exemplo as animações frame-by-frame) que serão usadas no

projeto

layout Define os layouts da interface com o utilizador

menu Definem o conteúdo dos menus aplicacionais bem como da Action Bar nas

versões mais recentes de Android (Honeycomb e Ice Cream Sandwich)

values

Este tipo é especial visto que pode albergar vários tipos de recursos dentro de

si, sendo o mais importante o tipo Strings que é um ficheiro xml com um nome

específico (strings.xml), que define os vários textos para uso no projecto.

Os outros recursos que poderão ser inseridos neste tipo serão falados ao

longo do livro quando pertinente

Tabela 44..1 –– Tipos de Resources disponíveis

Page 43: Introdução à programação em android

Conhecendo então os tipos de recursos que podem ser utilizados, resta saber o que são

exatamente os qualificadores. Queremos realçar desde já que não é necessário para a definição

de um grupo de recursos, o uso de um ou qualquer qualificador nesse grupo. Como é visível na

imagem em cima, os tipos layout e values não têm qualquer qualificador, e o tipo drawable está

dividido em 3 grupos por 3 qualificadores: hdpi, mdpi e ldpi. Estes 3 qualificadores dizem

respeito aos DPI 16

do ecrã onde a aplicação está a executar a um dado momento: 240dpi, 160dpi

e 120dpi respetivamente. Esta divisão é particularmente útil quando queremos que a nossa

aplicação não perca qualidade gráfica dum tipo de ecrã para outro.

Os qualificadores são então usados para diferenciar o mesmo recurso mas para outro tipo ou

outra utilização da aplicação. Por exemplo, para traduzir uma aplicação para Português, bastaria

criar um grupo com o nome values-pt, e criar um ficheiro com o nome strings.xml lá dentro

como os mesmos valores existentes no string.xml global (que se encontra dentro do grupo de

nome “values” apenas) mas com a tradução dos textos de cada valor para Português. Também

bastante utilizados são os qualificadores land e port que dizem respeito às orientações do ecrã

na Horizontal (Landscape) e na Vertical (Portrait) respetivamente. Com estes qualificadores, pode

definir um layout duma Activity específico para quando o ecrã se encontra na horizontal, e outra

para quando está na vertical.

Uma grande potencialidade dos qualificadores é que o pode agrupar vários associando-os a um

tipo de recurso. Por exemplo, se quiser definir um layout para quando um terminal estiver em

com um orientação horizontal (landscape) e que tenha um ecrã considerando largo (large)17

,

então pode definir o layout dentro dum grupo com o nome “layout-large-land”. Deste modo pode

abstrair uma Activity que usa sempre o mesmo código Java do seu aspecto visual de acordo com o

terminal em que está a executar, sendo que a própria plataforma decide que layout utilizar pois

escolherá o grupo que melhor se encaixar nas especificações do dispositivo. No código seguinte

pode ver este exemplo.

16 Pontos por polegada (Dots Per Inch)

17 Mínimo de resolução de 640 x 480 px

Page 44: Introdução à programação em android

Ficheiro: HelloWorldActivity.java

public class HelloWorldActivity extends Activity {

/** Método de Callback chamado quando a Activity é criada inicialmente. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

}

FFIIGGUURRAA 44..33 –– Resources do projecto HelloWorld

Para aceder aos recursos que guarda dentro do projeto a partir do código Java, utiliza-se a classe

R que é gerada automaticamente pelo ADT quando cria, apaga, ou altera algum recurso dentro da

directoria /res. No caso dos layouts, podem ser acedidos fazendo referência a R.layouts, e estes

são todos os layouts definidos nos recursos do projecto, não havendo qualquer filtragem ou

diferenciação sobre estes tendo em conta os qualificadores usados na sua definição.

A função para definir a UI duma Activity é a setContentView(int value). Como se pode ver

então pelo código em cima, aquela Activity usa um Layout com o nome main . Este recurso diz

respeito ao main.xml que está presente na figura 4.3 . Pode constatar que existem 3 grupos de

layout cada um com um main.xml lá dentro, desde modo é a plataforma que decide qual destes

Page 45: Introdução à programação em android

vai usar em tempo de execução. Procurará primeiro o um que se aplique à condição e/ou

especificação atual do dispositivo, e caso não seja aplicável irá então usar a versão que se aplica a

todos os outros casos, definida em /layout.

É aconselhada a leitura da página relativa a este assunto na documentação oficial para mais

informações : http://developer.android.com/guide/topics/resources/providing-

resources.html#AlternativeResources .

Android Manifest

O Android Manifest é onde é definida a aplicação. Contém as definições das Activities, Services,

Broadcast Receivers, permissões, compatibilidade com versões de Android, entre outros aspectos

para que tanto o Android Market e o dispositivo possam filtrar aplicações por compatibilidade,

para gerir acessos a recursos da própria aplicação e gerir também acessos da aplicação a recursos

do sistema e/ou de outras aplicações.

A definição do Manifest é feita através dum ficheiro chamado AndroidManifest.xml que se

encontra na raiz do projecto. Este ficheiro é composto pela tag <manifest> com vários atributos

sendo que o package, versionCode e versionName são obrigatórios. A diferença entre os dois

últimos é que o primeiro é usado internamente pela plataforma (e pelo Android Market) para

controlo de versões e pode ser qualquer número inteiro (p.e. 25), não tendo qualquer relação com

o versionName que é somente uma “descrição verbal” da versão para o utilizador ver (p.e. “1.0.5

Beta”). O atributo package é o package name que foi atribuído à aplicação quando esta foi

criada.

Após um package name ser utilizado com uma assinatura digital no Android Market, este

package name fica reservado para uso exclusivo e as atualizações consecutivas terão de conter a

mesma assinatura digital. Guarde a sua assinatura digital num local seguro, tanto para não ser

roubada como para não a perder.

Um AndroidManifest.xml muito básico teria o seguinte aspecto:

<manifest xmlns:android="http://schemas.android.com/apk/res/android”

package="org.hello_world"

android:versionCode="1"

Page 46: Introdução à programação em android

android:versionName="1.0" >

</manifest>

Dentro da tag manifest podem existir várias outras, algumas obrigatórias como a application e

outras opcionais como por exemplo a uses-feature. Apresentamos de seguida as tags mais

usadas que podem ser inseridas dentro da tag manifest, bem como um exemplo sucinto da sua

utilização.

Consulte o manual online para esclarecimentos adicionais bem como todas a opções possíveis para

tags e atributos em http://developer.android.com/guide/topics/manifest/manifest-intro.html

u. Uses-permission

Esta tag diz à plataforma Android que a aplicação necessita de uma ou mais permissões para

executar corretamente. Num capítulo mais adiante iremos falar mais aprofundadamente a questão

das permissões em Android. Uma permissão que é usada muito frequentemente é a

android.permission.INTERNET, que dá permissão de uma aplicação aceder à internet. Necessária

para aceder a um WebService para obtenção de dados por exemplo.

As permissões de sistema são todas as que começam por android.permission, todas as outras são

permissões de outras aplicações que declararam no seu Manifest uma nova permissão usando a

tag permission para que outras aplicações podessem aceder a dados e/ou recursos dela.

Exemplo de uso:

<uses-permission android:name="android.permission.INTERNET"/>

v. Permission

Como falado anteriormente, esta tag serve para declarar, e deste modo proteger, o acesso a

alguns dados ou serviços disponibilizados pela aplicação a outras aplicações. A permissão pode

ter vários níveis de alerta para o utilizador, mediante a importância do recurso que estará a ser

acedido por outra aplicação. Por exemplo, se uma aplicação decidir partilhar um serviço que

possibilita a outra aplicação o acesso a uma palavra-passe introduzida pelo utilizador, esta

permissão deve ser tida em conta aquando da instalação da aplicação que a usa, e portanto,

Page 47: Introdução à programação em android

considerada perigosa visto disponibilizar dados pessoais. Os níveis de alerta são os seguintes:

normal, dangerous, signature, signatureOrSystem.

Exemplo de uso:

<permission android:name="org.hello_world.SHARE_PASSWORD"

android:label="@string/share_hello_password"

android:protectionLevel="dangerous"

android:description="@string/share_hello_password_desc" />

w. Uses-sdk

Esta tag define vários aspetos da aplicação em relação ao SDK usada para a criar. Pode conter 3

atributos: minSdkVersion, targetSdkVersion, e maxSdkVersion. O primeiro é usado para dizer

que versão de SDK é a mínima para aplicação executar corretamente. É muito útil para criar uma

aplicação compatível com versões anteriores do SDK. Se este atributo não for definido, ele toma

automaticamente o valor 1, fazendo a aplicação compatível com todas as versões de Android até

à especificada em maxSdkVersion caso esta exista. Se a aplicação usar APIs apenas definidas em

versões superiores de Android, a aplicação irá terminar anormalmente durante a sua execução

por não ter o suporte às APIs necessárias no terminal. É portanto extremamente recomendado o

teste da aplicação desde a minSdkVersion até à targetSdkVersion.

O targetSdkVersion, define a SDK com a qual a aplicação foi compilada e em qual foi

efetivamente testada. Se durante o desenvolvimento da aplicação está a ser usada a versão da

SDK 4.0 (14), é garantido que a aplicação vai funcionar sobre esta versão de Android visto ter sido

compilada com ela.

O maxSdkVersion é um atributo raramente usado pois não tem muita lógica o seu uso na

generalidade dos casos, visto a plataforma garantir a retro-compatibilidade das aplicações antigas

em versões de Android mais recentes. Portanto uma aplicação com um targetSdkVersion=”7”

(Android 2.1), vai funcionar da mesma forma na versão de SDK 14 (Android 4.0). No entanto é

possibilitado ao programador que a sua aplicação só seja executada em terminais até uma

determinada versão de Android e para isso deve usar este atributo.

Exemplo de uso:

Page 48: Introdução à programação em android

<uses-sdk android:minSdkVersion="7"

android:targetSdkVersion="14" />

x. Uses-configuration

Com esta tag, define-se que tipo de hardware, nomeadamente em termos de controlo do

utilizador, uma aplicação necessita. Existem 5 atributos que podem ser definidos dentro desta tag

que são: reqFiveWayNav, reqHardKeyboard, reqKeyboardType, reqNavigation,

reqTouchscreen. A mair parte dos atributos explicam-se automaticamente pelo nome deles

tirando o reqFiveWay que diz respeito a um controlo como um D-Pad, ou uma TrackBall18

, que

permita ao utilizador o input direcional (cima, baixo, esquerda, direita) e clique; o atributo

reqNavigation não diz respeito à navegação GPS mas sim a algo parecido com o reqFiveWay,

mas especificando exatamente que tipo de controlo se quer (D-Pad, TrackBall, …).

Este atributo tem a particularidade de se poder definir múltiplas vezes, significando que a

aplicação suporta vários formas de input do utilizador. Como exemplo, uma aplicação que

necessite dum touchscreen que possa ser usado por uma caneta stylus e um teclado QWERTY ou

um teclado numérico, teria esta definição:

<uses-configuration android:reqTouchScreen="stylus"

android:reqKeyboardType="qwerty" />

<uses-configuration android:reqTouchScreen="stylus"

android:reqKeyboardType="twelvekey" />

y. Uses-feature

Esta tag é usada para definir que hardware, e em alguns casos que stack de software, a aplicação

necessitará para funcional corretamente e ainda se é mesmo necessária ou não. Existem muitas

18 Esta característica de hardware é pouco comum na generalidade dos novos dispositivos

Android, e portanto de carácter opcional.

Page 49: Introdução à programação em android

possibilidades para esta tag, e descreve-las todas aqui seria demasiado extenso, mas por exemplo

uma aplicação que tire fotografias que incorpore “geo-tagging” (localização da fotografia nos

metadados da mesma) caso exista sistema de localização no dispositivo, necessitará pelo menos

de usar a câmara e obter a localização. Como tal necessitaria de declarar no seu Manifest, que usa

uma câmara e que usará um sistema de localização se disponível. Seria então definido assim:

<uses-feature android:required="false"

android:name="android.hardware.location"/>

<uses-feature android:required="true"

android:name="android.hardware.camera"/>

z. Supports-screens

Esta tag explicar-se a sim mesma. Serve simplesmente para definir que tipo de ecrãs a aplicação

suporta. Se uma aplicação poder funcionar em todo o tipo de ecrãs, a definição seria assim:

<supports-screens android:largeScreens="true"

android:xlargeScreens="true" android:smallScreens="true"

android:normalScreens="true" android:anyDensity="true" />

aa. Application

Aqui define-se a aplicação em si, que Activities fazem parte dela, Services, Receivers, Providers,

etc. Todo um conjunto de componentes e propriedades, que interligados entre si formam a

aplicação.

Exemplo de uso:

<application

android:icon="@drawable/ic_launcher"

Page 50: Introdução à programação em android

android:label="@string/app_name" >

<activity android:label="@string/app_name"

android:name=".HelloWorldActivity" >

<intent-filter >

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

Classe application

A classe Application serve para manter um estado global sobre a aplicação em si. Pode ser

usada muito facilmente, acabando muitas vezes por ser bastante útil para partilhar objetos e

propriedades entre vários componentes ( Services, Activities, etc). Para a usar tem que a definir no

AndroidManifest.xml dentro da tag <application> como elemento. Por exemplo:

<application android:name=".MyApp">

[…]

</application>

Seguindo o exemplo declarado no AndroidManifest em cima, deverse-á criar uma classe que por

sua vez estende a classe Application com o nome “MyApp”. De notar que esta classe é instanciada

primeiro que qualquer outro objeto da aplicação ficando portanto desde logo disponível para ser

usada quando necessário pelo programador. Como exemplo, se quiser partilhar um valor por toda

a aplicação e para evitar ter que definir esse valor em todas as classes que o requerem, poderia

proceder da seguinte forma:

public class MyApp extends Application {

Page 51: Introdução à programação em android

private static MyApp singleton;

private int mSharedNumber = 5;

public static MyApp getInstance() {

return singleton;

}

@Override

public void onCreate() {

super.onCreate();

singleton = this;

}

public int getSharedNumber() {

return mSharedNumber;

}

}

Utilizando o princípio dos singletons19

, em que cada classe só poderá ter uma única instanciação,

podemos muito facilmente obter o desejado: o acesso ao valor partilhado em qualquer

componente da aplicação. Portanto, num caso típico em que fosse necessário aceder ao valor

partilhado, teria simplesmente que fazer o seguinte:

int x = MyApp.getInstance().getSharedNumber();

Claro que este tipo de utilização serve para partilhar um ou mais objetos por toda a aplicação

usando exatamente o mesmo método, e não está limitado ao uso deste exemplo.

A classe Application, pode também controlar a forma de como e quando libertar memória quando

o Sistema está a precisar. A plataforma avisa todas as aplicações em execução que precisa de

memória, para que estas removam alguns dos seus objetos evitando assim ser terminadas pelo

sistema, mas cabe ao utilizador especificar o comportamento desta ação. Para tal, basta substituir

(override) a função onLowMemory() na classe Application criada. Exemplo:

19 http://en.wikipedia.org/wiki/Singleton_pattern

Page 52: Introdução à programação em android

@Override

public void onLowMemory() {

// Limpar alguns objetos de memória

}

Page 53: Introdução à programação em android

555 5CCAAMMAADDAA DDEE UUII DDEE

AANNDDRROOIIDD ––

6CCOONNCCEEIITTOOSS BBAASSEE

Neste capítulo damos-lhe a conhecer as bases aplicacionais da plataforma

Neste capítulo irá ficar com uma noção das componentes Interface Gráfica (GUI ou apenas UI) da

plataforma Android, como se relacionam entre elas, e de como usar alguns sistemas de alerta (caixas de

diálogo, notificações) usando as ferramentas base que a plataforma disponibiliza.

O que são views

Views são o elemento base das aplicações Android e basicamente são tudo o que se vê no ecrã.

Existem também algumas Views que não se vêm como são o caso dos Layouts como verá a

seguir. Portanto, caixas de texto (TextView), caixas de entrada de texto (EditText), imagens

(ImageView), botões (Button), listas (ListView), etc., são tudo views que podem ser usadas numa

aplicação Android e que compõem a interface para o utilizador.

Uma aplicação Android usará as Views que necessitar para alcançar o seu objetivo e não há

nenhuma que seja de uso obrigatóri, até porque por exemplo existem aplicações que correm nos

terminais como serviços e que não têm qualquer interação direta com o utilizador, portanto essas

não usarão Views.

Uma View é portanto a classe base duma grande parte das classes disponíveis na plataforma e

sendo base define várias coisas que é importante saber e que é comum a todas as Views:

Posição

Tamanho

Propriedades básicas comuns (Visibilidade, Focus, etc.)

Desenho da View

Eventos

Page 54: Introdução à programação em android

Existem muitas mais propriedades que são comuns a todas as Views, mas estas são as que mais

se usam no desenho e construção da interface. É sempre necessário ter em conta o tamanho que

vai ocupar no ecrã, o seu posicionamento relativo a outras Views, como são organizadas no ecrã

(usando vários tipos de Layouts), se está visível para o utilizador ou se é invisível ficando visível

após algo acontecer na aplicação, isto tudo para que o utilizador tenha uma experiência de

utilização do terminal e especialmente da aplicação que se está a cria, fluída e que não seja

confusa. Outro aspeto muito especial das Views é o tratamento de eventos, por exemplo:

“OnTouch” e “OnFocus”. Estes exemplos mais genéricos e comuns a todas as Views, fazem parte

da classe mãe View, mas outras Views descendentes (directa ou indiretamente) desta classe

adicionam novos eventos que muitas vezes vão ser usados, como por exemplo o OnKeyDown da

View de nome TextView.

FFIIGGUURRAA 55..44 -- Exemplo de algumas Views dentro da mesma Layout

(TextView, Button, EditText, ImageView, CalendarView)

Layouts

Layouts são Views especiais que vão organizar outras Views de maneira a que fiquem dispostas

da forma que deseja no ecrã. É um conjunto de Layouts que define como uma Activity ou um

Widget mostram o seu conteúdo. Pode-se dizer portanto que os Layouts são o esqueleto onde

todas as outras Views vão assentar.

Para maior facilidade e portabilidade, todos os Layouts devem ser definidos em ficheiros XML,

contudo é possível criar um Layout completamente em código mas este caso não vai ser coberto

neste livro. A questão da portabilidade é bastante importante porque estando definido o Layout

em XML, facilmente se agarra nesse ficheiro e se adapta para outro tipo de terminal ou para

vários tipos de display (como por exemplo Portrait vs. Landscape), já para não falar que permite

Page 55: Introdução à programação em android

tirar partido da seleção adquada do layout correto que é fornecido pela gestão de recursos como

foi apresentada em capítulos anteriores.

Em tempo de edição, algo que achará bastante útil quando é desenhado um Layout usando o

Eclipse é o Outline que normalmente se encontra no lado direito quando se está a editar um

ficheiro. Quando o ficheiro é um XML que define um Layout, o Outline mostra a estrutura do

Layout sendo fácil visualizar a estrutura que estamos a criar.

FFIIGGUURRAA 55..22 -- Estrutura do ficheiro main.xml de um HelloWorld

Existem então vários tipos de Layouts e neste capítulo serão abordadosos mais usados nas

aplicações bem um exemplo para cada.

O Layout mais simples de todos é o FrameLayout. É o mais simples porque a organização dele é

muito básica: Todas as Views descendentes deste Layout, são posicionadas no topo superior

esquerdo do Layout ficando portanto umas por cima das outras caso haja mais que uma. É

particularmente útil para espaços vazios numa Activity, que pode ser posteriormente preenchido

com uma imagem que pode variar, por exemplo, consoante algo que tenha sido selecionado.

FFIIGGUURRAA 55..33 -- FrameLayout com duas imagens

Provavelmente, o Layout mais utilizado em Android é o LinearLayout. Basicamente este Layout

permite dispor as Views descendentes todas seguidas umas às outras podendo ser orientado

vertical ou horizontalmente de acordo com a escolha do programador, bastando para isso

Page 56: Introdução à programação em android

alterar o atributo android:orientation para vertical ou horizontal respetivamente. A figura 5.4

evidencia a forma como a orientação afecta a disposição visual.

FFIIGGUURRAA 55..44 -- Duas LinearLayout com a mesma definição,

mas orientações diferentes

Outro Layout que é útil é o TableLayout. Este layout tem como principal característica a de

organizar as suas Views descendentes num formato tabular; para o efeito o TableLayout é

axuliado com outra View que é a TableRow. Ao usar ambas pode então criar Layouts que se cuja

disposição dos elementos se pareçam com uma tabela. Ainda que sendo uma tabela, há coisas

que não se conseguem fazer como por exemplo expandir uma célula para ocupar várias colunas

(como em HTML). Em baixo ver a figura 5.5 e o exemplo 5.1 que corresponde ao código XML que

deu origem ao resultado da dita figura.

A tabela criada terá tantas colunas quantas a linha com mais colunas tiver, e não

apresentará qualquer tipo de linhas de separação entre as células.

Page 57: Introdução à programação em android

FFIIGGUURRAA 55..55 -- Outline e resultado dum TableLayout

EEXXEEMMPPLLOO 55..11

<?xml version="1.0" encoding="utf-8"?>

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/tableLayout1"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:stretchColumns="1" >

<TableRow

android:id="@+id/tableRow1"

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

<TextView

android:id="@+id/textView1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Linha1 Coluna1" />

<TextView

android:id="@+id/textView2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

Page 58: Introdução à programação em android

android:layout_gravity="right"

android:text="Linha1 Coluna2" />

</TableRow>

<TableRow

android:id="@+id/tableRow2"

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

<TextView

android:id="@+id/textView1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Linha2 Coluna1" />

<TextView

android:id="@+id/textView2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="right"

android:text="Linha2 Coluna2" />

</TableRow>

</TableLayout>

Outro tipo de layout bastante popular é o RelativeLayout. Deverá evitar o seu uso se for possivél

produzir o mesmo efeito com recurso a outro tipo de Layout visto que pode ficar completamente

diferente daquilo que deseja dependendo do tipo de ecrã do terminal, e também porque se tiver

muitos descendentes deste Layout o código torna-se mais difícil de ler. Este tipo de Layout

funciona posicionando os seus descendentes relativos uns aos outros. Por exemplo, diz-se que

uma determinada TextView está à esquerda duma EditText. A associação é feita com recurso à

propriedade android:id que o programador define manualmente. Sabendo isto, às vezes poder-

se-à deparar com o problema de dependência circular que é quando dois descendentes deste

Layout se referenciam um ao outro tornando assim impossível a criação do Layout. No entanto,

Page 59: Introdução à programação em android

consegue ser um Layout que é bom de usar em casos simples em que o posicionamento relativo é

essencial.

O exemplo da figura 5.6 (investigue o código que o originou no exemplo 5.2) poderia ser obtido

com recurso exclusivo a LinearLayout, sendo que nesse caso teria de conter 1 LinearLayout mãe, e

2 LinearLayout filhos para cada linha. Ou seja, o 1º trataria da disposição vertical e os outros dois

da disposição horizontal de componentes.

FFIIGGUURRAA 55..66 -- Outline e resultado dum RelativeLayout

EEXXEEMMPPLLOO 55..22

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/relativeLayout1"

android:layout_width="fill_parent"

android:layout_height="fill_parent" >

<TextView

android:id="@+id/textView1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentLeft="true"

android:text="TextView1" />

<EditText

android:id="@+id/editText1"

android:layout_width="fill_parent"

Page 60: Introdução à programação em android

android:layout_height="wrap_content"

android:layout_alignParentTop="true"

android:layout_toRightOf="@+id/textView1"

android:inputType="textPersonName" />

<TextView

android:id="@+id/textView2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@+id/editText1"

android:text="TextView2" />

<EditText

android:id="@+id/editText2"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_alignLeft="@+id/editText1"

android:layout_alignParentRight="true"

android:layout_alignTop="@+id/textView2"

android:inputType="textPassword" />

</RelativeLayout>

Com o ICS20

veio um novo Layout que veio resolver algumas dificuldades que existiam quando se

tentavam criar certos tipos de layouts com o Layouts existentes até então. Este novo tipo, o

GridLayout, tenta juntar o melhor de dois mundos, do LinearLayout e do TableLayout (ambos

falados anteriormente). Consegue-se por exemplo, alinhar Views quer verticalmente quer

horizontalmente com outras Views (alinhar e não posicionar como no RelativeLayout). Consegue-

se também criar layouts mais complexos sem ter uma estrutura demasiado complexa, que acaba

comprometer a performance.

20 Ice Cream Sandwich

Page 61: Introdução à programação em android

Sendo baseado no LinearLayout, consegue-se muitas vezes simplesmente renomear a tag

LinearLayout por GridLayout e obter a mesma IU21

que estava anteriormente mas com todas as

otimizações disponibilizadas pelo GridLayout.

Umas das melhorias que traz relativamente ao TableLayout, é a possibilidade das Views

descendentes poderem ocupar mais que uma célula (Span) .

Para uma descrição mais extensa deste novo Layout, sugere-se a leitura (em Inglês) da seguinte

publicação no Blog dos Android Developers: http://android-developers.blogspot.com/2011/11/new-layout-

widgets-space-and-gridlayout.html

FFIIGGUURRAA 55..77 -- Outline e resultado dum GridLayout (código no exemplo 5.3)

EEXXEEMMPPLLOO 55..33

<?xml version="1.0" encoding="utf-8"?>

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/gridLayout1"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:columnCount="4" >

<TextView

android:id="@+id/textView1"

android:layout_column="0"

android:layout_columnSpan="2"

21 Interface de Utilizador

Page 62: Introdução à programação em android

android:layout_row="1"

android:text="Nome de Utilizador" />

<EditText

android:id="@+id/editText1"

android:layout_column="3"

android:layout_gravity="fill_horizontal"

android:layout_row="1"

android:inputType="textEmailAddress" >

</EditText>

<TextView

android:id="@+id/textView2"

android:layout_column="1"

android:layout_gravity="right"

android:layout_row="3"

android:text="Password" />

<EditText

android:id="@+id/editText2"

android:layout_column="3"

android:layout_gravity="fill_horizontal"

android:layout_row="3" />

<Space

android:layout_width="1dp"

android:layout_height="21dp"

android:layout_column="0"

android:layout_gravity="fill_horizontal"

android:layout_row="0" />

<Space

android:layout_width="21dp"

Page 63: Introdução à programação em android

android:layout_height="1dp"

android:layout_column="0"

android:layout_row="0" />

<Space

android:layout_width="10dp"

android:layout_height="1dp"

android:layout_column="2"

android:layout_gravity="fill_horizontal"

android:layout_row="0" />

<Space

android:layout_width="1dp"

android:layout_height="10dp"

android:layout_column="0"

android:layout_gravity="fill_horizontal"

android:layout_row="2" />

</GridLayout>

Menus

Existem dois tipos de Menus em Android, os contextuais (os que aparecem quando o utilizador

carrega no botão fisico de Menu do dispositivo) e os Menus de prefências (tal como o nome

sugere são os menus da preferências da aplicação).

Os menus fazem parte de quase todas as aplicações Android e são uma ferramenta bastante útil

quando queremos adicionar funcionalidades variadas dentro da mesma Activity. Existem dois

tipos de menus: Contextuais e de Preferências, este último subdividindo-se em menus pré-

Honeycomb (Android 3.0) e menus Honeycomb ou superior. A diferença entre estes dois últimos é

a sua localização, sendo que os pré-Honeycomb aparecem na parte inferior do ecrã, e os

Honeycomb na parte superior-direita. Felizmente a API é bastante simples e muito intuitiva para a

criar todos os tipos de Menus.

Page 64: Introdução à programação em android

Para criar um Menu de Preferências pode, e deve, usar um ficheiro XML dentro da diretoria

res/menu. Para isso usa-se um pequeno assistente disponível no Eclipse acedendo ao menu File

(Ficheiro) → New (Novo) → Android XML File (Ficheiro XML Android).

FFIIGGUURRAA 55..88 -- Assistente de criação dum ficheiro XML para Menus

Deve ser selecionado o Resource Type (Tipo de Recurso) “Menu”, e dado um nome ao ficheiro

que termine em .xml .

É aconselhado usar o nome da Activity no nome do ficheiro para mais fácil identificação do menu.

Após clicar em Finish (Concluir), irá ser levado para a área de edição do novo ficheiro XML que irá

definir um Menu para ser usado numa Activity. Como exemplo, use o conteúdo do exemplo 5.4.

EEXXEEMMPPLLOO 55..44

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@+id/menu_partilhar"

android:icon="@android:drawable/ic_menu_share"

android:title="@string/partilhar" />

Page 65: Introdução à programação em android

<item android:id="@+id/menu_ajuda"

android:icon="@android:drawable/ic_menu_help"

android:title="@string/ajuda" />

<item android:id="@+id/menu_guardar"

android:icon="@android:drawable/ic_menu_save"

android:title="@string/guardar" />

</menu>

Portanto agora, para se usar o menu na Activity que se deseja basta fazer Inflate (inflacionar no

sentido de usar o XML para contruir as componentes visuais), tal como demonstrado no exemplo

5.5.

EEXXEEMMPPLLOO 55..55

/* Cria um menu para esta Activity a partir dum XML */

@Override

public boolean onCreateOptionsMenu(Menu menu) {

MenuInflater inflater = getMenuInflater();

inflater.inflate(R.menu.menusactivity_menu, menu);

return true;

}

Da próxima vez que for executada a aplicação num terminal (ou emulador), pode-se pressionar a

tecla Menu que um menu como o da figura 5.9 aparecerá no ecrã:

Page 66: Introdução à programação em android

FFIIGGUURRAA 55..99 -- Screenshot do Menu criado acima

O menu criado não executa nada, ou seja, apenas diz ao sistema, que quando a tecla Menu for

pressionada, o menu que deve aparecer é aquele, composto por 3 botões, com aquele texto e

aquelas imagens. Para que quando se clique num botão seja executado algum código tem que se

definir um novo método na classe que define a Activity em questão que se chama

OnOptionsMenuSelected. Este método de Callback é sempre executado quando é pressionado

um botão presente no menu, neste caso, no botão “Partilhar”, “Ajuda” ou “Guardar”. Em suma a

estrutura do processamento do toque dos botões será semelhante ao apresentado no exemplo

5.6.

EEXXEEMMPPLLOO 55..66

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case R.id.menu_partilhar: {

/* Executar o cód respetivo */

return true;

}

Page 67: Introdução à programação em android

case R.id.menu_ajuda: {

/* Executar o cód respetivo */

return true;

}

case R.id.menu_guardar: {

/* Executar o cód respetivo */

return true;

}

}

return false;

}

Como cada opção do menu tem um código (um valor do tipo constante Integer) atrbuído,

podemos usar uma estrutura switch/case para facilmente saber que botão foi pressionado e

assim executar o código adequado. A razão do método retornar um valor do tipo Boolean serve

para saber se aquele clique foi ou não tratado. Devolvendo false, o sistema é informado que a

Activity não tratou o clique e então vai percorrer toda a hierarquia de Views até alguém o tratar.

Se for retornado true, então quer dizer que a Activity tratou o clique e o sistema não precisa de

fazer mais nada para tratar aquele clique.

Agora já consegue criar um menu e executar algo quando é dispoltado um evento de toque em

alguma das suas opções, mas e se for preciso alterar a disponibilidade das opções consoante um

determinado estado da aplicação? Num exemplo prático, pode-se ter uma opção de criar uma

nova entrada num histórico apenas se não estiver em modo de edição de uma entrada.

Contrariamente ao que se possa pensar, editar o object Menu no método onCreateOptionsMenu

para ativar ou desativar uma opção não irá funcionar, isto porque este método só é executado

quando é pressionada a tecla Menu pela primeira vez nas versões de Android pré-Honeycomb, ou

assim que a Activity é criada em Honeycomb ou superior, pelo que só é executado uma única vez.

Tem-se então outro método para controlar o Menu sempre que ele é aberto que é a

OnPrepareOptionsMenu.

EEXXEEMMPPLLOO 55..77

Page 68: Introdução à programação em android

@Override

public boolean onPrepareOptionsMenu(Menu menu) {

Random generator = new Random(System.currentTimeMillis());

int x = generator.nextInt(10);

MenuItem BotaoPartilhar = menu.findItem(R.id.menu_partilhar);

BotaoPartilhar.setEnabled(x < 5);

return true;

}

No exemplo 5.7, o botão partilhar vai ficar ativo 50% das vezes que for pressionado a tecla Menu.

Para isso, é gerado um número aleatório entre 0 e 9:

Random generator = new Random(System.currentTimeMillis());

int x = generator.nextInt(10);

Depois vai-se buscar o objeto que identifica o botão que quer controlar:

MenuItem BotaoPartilhar = menu.findItem(R.id.menu_partilhar);

E por fim, ativar ou desativar conforme o valor obtido em cima aleatoriamente:

BotaoPartilhar.setEnabled(x < 5);

Como já se deve ter apercebido, a API Android é bastante simples e fácil de entender, e agora vem

mais um exemplo disso mesmo. Para transformar o menu anterior numa opção de destaque em

Honeycomb ou superior basta adicionar o seguinte atributo a cada Item definido no ficheiro XML

correspondente ao menu:

android:showAsAction="ifRoom"

ifRoom Coloca a opção do menu destacado na Action

Page 69: Introdução à programação em android

Bar caso haja espaço nesta de maneira a não

colidir com outras Views nela existentes

withText

Caso a opção seja colocada num local de

destaque, colocar também texto. (caso

contrário, apenas o icon irá aparecer)

TTAABBEELLAA 55..22 –– Valores mais utilizados no atributo

Se adaptar o exemplo de menu anterior para Honeycomb ou superior, ficaria semelhante ao

exemplo 5.8.

EEXXEEMMPPLLOO 55..88

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@+id/menu_partilhar"

android:icon="@android:drawable/ic_menu_share"

android:title="@string/partilhar"

android:showAsAction="ifRoom|withText" />

<item android:id="@+id/menu_ajuda"

android:icon="@android:drawable/ic_menu_help"

android:title="@string/ajuda"

android:showAsAction="ifRoom" />

<item android:id="@+id/menu_guardar"

android:icon="@android:drawable/ic_menu_save"

android:title="@string/guardar"

android:showAsAction="" />

</menu>

Note as alterações aos elementos Item e os respetivos valores do exemplo 5.8. Quando executado

num terminal Honeycomb, é produzido este resultado:

Page 70: Introdução à programação em android

FFIIGGUURRAA 55..1100 -- Screenshot do Menu criado em Honeycomb

Para comparação, fica um screenshot na figura 5.11 do mesmo menu mas sem as alterações para

Honeycomb ou superior, ou seja, sem o atributo android:showAsAction .

FFIIGGUURRAA 55..1111 -- Screenshot do Menu sem alterações criado em Honeycomb

Mais diferente ainda, é se a aplicação não estiver a ser compilada com um SDK Android 3.0 ou

superior. Nesse caso o resultado seria semelhante ao da figura 5.12.

Page 71: Introdução à programação em android

FFIIGGUURRAA 55..1122 -- Screenshot do Menu compilado para uma versão Android pré-Honeycomb

Caixas de Diálogo

As caixas de diálogo são normalmente utilizadas para alertar o utilizador de que algo está para

acontecer mas que precisa de uma decisão da sua parte. São também usadas quando ocorre

algum problema e o utilizador tem de ser notificado disso.

Em Android, temos a possibilidade de criar vários tipos de caixas de diálogo consoante a sua

finalidade, no entanto a maneira de criar e mostar qualquer desses tipos (que irá ver já de

seguida) é sempre a mesma. Os métodos a ter em conta são:

protected Dialog onCreateDialog(int id)

protected void onPrepareDialog(int id, Dialog dialog)

O primeiro método é responsável pela criação do objeto do tipo Dialog. É portanto executado

apenas uma vez mesmo que a caixa de diálogo seja mostrada várias vezes durante a utilização da

aplicação. O segundo método permite que a caixa de diálogo seja alterada antes de ser mostrada

ao utilizador, por exemplo, quando se quer ativar ou desativar um botão na caixa de diálogo

consoante algo esteja ativo na aplicação, e é executado sempre que a caixa de diálogo é

mostrada.

Sendo que os dois métodos em cima referidos fazem parte do ciclo de criação da caixa de diálogo

e apresentação ao utilizador, existem dois métodos para esconder a caixa de diálogo novamente:

dismiss()

dismissDialog(int id)

Page 72: Introdução à programação em android

A diferença entre os dois métodos, é que o primeiro é usado dentro do objeto do tipo Dialog, e o

segundo, dentro dum objeto do tipo Activity. Qualquer um dos dois produz o mesmo efeito que é

esconder a caixa de diálogo.

Para mostrar a caixa de diálogo em si, basta usar o método showDialog(int id).

A melhor forma de implementar os métodos de criação da caixa de diálogo é através do uso de

uma estrutura switch … case. Usando esta estrutura pode duma forma muito simples e percetível

criar Dialogs. Começa-se por definir uma (ou mais) variável global com um Id único de maneira a

identificar a caixa de diálogo, tal como ilustrado no exemplo 5.9.

EEXXEEMMPPLLOO 55..99

private static final int DIALOG_HELLO_WORLD = 0;

Depois é só implementar pelo menos o método de criação do Dialog em si, tal como ilustrado no

exemplo 5.10.

EEXXEEMMPPLLOO 55..1100

@Override

protected Dialog onCreateDialog(int id) {

Dialog dialog;

switch (id) {

case DIALOG_HELLO_WORLD: {

// Criar o Dialog aqui

break;

}

default:

dialog = null;

}

return dialog;

}

Page 73: Introdução à programação em android

Com isto feito, apenas falta ver como criar o objeto Dialog. Como falado anteriormente existem

vários tipos de caixas de diálogo em Android, sendo elas:

AlertDialog

ProgressDialog

CustomDialog

bb. AlertDialog

A classe AlertDialog é muito mais genérica do que o nome faz parecer, sendo capaz de criar

qualquer tipo de caixa de diálogo e não apenas algo do tipo “Alerta”.

Para dar um exemplo de como é fácil e útil este tipo de caixa de diálogo, seguem-se três

exemplos bastante comuns: mensagem com resposta (sim/não); lista de itens dos quais o

utilizador deve escolher um; lista de itens dos quais o utilizador deve escolher vários ou nenhum.

No exemplo 5.11 é apresentada uma mensagem de resposta (sim/não), o resultado visual

produzido será semelhante ao da figura 5.13.

EEXXEEMMPPLLOO 55..1111

private Dialog criarDialogoComMessagem() {

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("Olá Mundo")

.setMessage("O dia está bom?")

.setCancelable(false)

.setIcon(android.R.drawable.ic_dialog_info)

.setPositiveButton("Sim", new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int which) {

// Fazer alguma coisa com este clique

dialog.dismiss();

}

})

.setNegativeButton("Não, new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int which) {

// Fazer alguma coisa com este clique

Page 74: Introdução à programação em android

dialog.dismiss();

}

});

return builder.create();

}

FFIIGGUURRAA 55..1133 -- AlertDialog com dois botões de resposta

Como pode ver é bastante simples criar um caixa de diálogo. Começamos por criar um objeto do

tipo AlertDialog.Builder que recebe como parâmetro um objeto do tipo Context, que neste caso é

o contexto da Activity atual. Depois é criada a caixa de diálogo atribuindo-lhe um título e uma

mensagem. O método setCancelable serve para prevenir o utilizador de pressionar a tecla Back e

deste modo cancelar a caixa de diálogo. Neste caso prevenimos o utilizador de o fazer de modo

que vai ter sempre de responder “Sim” ou “Não” para prosseguir com a utilização da aplicação, a

menos que a volte a iniciar do zero. De seguida é atribuído um icone à caixa de diálogo e por fim,

criam-se os dois botões de resposta, “Sim” e “Não”. É possível também criar um botão Neutral

(setNeutralButton) mas que não foi usado neste exemplo. No caso de ter decidido que o

utilizador pode cancelar a caixa de diálogo, em vez de criar um botão para poder detetar quando

o utilizador “cancela”, deve ser usado o método setOnCancelListener como ilustrado no exemplo

5.12.

EEXXEEMMPPLLOO 55..1122

private Dialog criarDialogoComMessagemCancelavel() {

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("Olá Mundo")

Page 75: Introdução à programação em android

.setMessage("O dia está bom?")

.setCancelable(true)

.setIcon(android.R.drawable.ic_dialog_info)

.setPositiveButton("Fechar", new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int which) {

// Fazer alguma coisa com este clique

dialog.dismiss();

}

})

.setOnCancelListener(new DialogInterface.OnCancelListener() {

public void onCancel(DialogInterface dialog) {

// Utilizador pressionou a tecla BACK cancelando a caixa de diálogo

dialog.dismiss();

}

});

return builder.create();

}

Veja agora um outro exemplo onde é apresentada uma caixa com uma lista de opções em que o

utilizador pode escolher uma destas. O código é igualmente simples, e pode ser visto no exemplo

5.13 e o respetivo resultado visual produzido na figura 5.14.

EEXXEEMMPPLLOO 55..1133

private Dialog criarDialogoComTresOpcoes() {

final String[] opcoes = { "Ontem", "Hoje", "Amanhã" };

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("Escolha uma opção")

.setItems(opcoes, new DialogInterface.OnClickListener() {

Page 76: Introdução à programação em android

public void onClick(DialogInterface dialog, int which) {

// O item selecionado foi o opcoes[which]

dialog.dismiss();

}

});

return builder.create();

}

FFIIGGUURRAA 55..1144 -- Caixa de diálogo com 3 opções

Como pôde constatar, foi bastante simples a criação duma caixa de diálogo com uma lista de

opções. Foi usado um objeto do tipo AlertDialog.Builder novamente para ajudar na criação da

caixa, e usado o método setItems() para associação da lista de itens a um Array com as opções

pretendidas, bem como atribuir um método de Callback que é executado quando o utilizador

seleciona uma das opções.

Por fim o exemplo 5.14 mostra como criar uma caixa de diálogo smelhante à anterior mas com a

possibilidade de escolha múltipla.

EEXXEEMMPPLLOO 55..1144

private Dialog criarDialogoComMultiplaEscolha() {

final String[] opcoes = { "Ontem", "Hoje", "Amanhã" };

AlertDialog.Builder builder = new AlertDialog.Builder(this);

Page 77: Introdução à programação em android

builder.setTitle("Escolha uma opção")

.setMultiChoiceItems(opcoes, null, new

DialogInterface.OnMultiChoiceClickListener() {

public void onClick(DialogInterface dialog, int which, boolean isChecked) {

// A opção opcoes[which] ficou isChecked

}

})

.setPositiveButton("OK", new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int which) {

// Utilizador carregou no OK

dialog.dismiss();

}

});

return builder.create();

}

Como se pode reparar, é muito parecido ao exemplo anterior mudando basicamente na chamada

ao método setMultiChoiceItems() em vez do setItems(), produzindo então a caixa de diálogo da

figura 5.15.

FFIIGGUURRAA 55..1155 -- Caixa de diálogo de escolha múltipla

Page 78: Introdução à programação em android

cc. Progressdialog

As ProgressDialog são aquelas aquelas caixa de diálogo que aparecem quando está a acontecer

alguma coisa em plano de fundo. São usadas para indicar ao utilizador que algo está a acontecer,

geralmente associado a alguma tarefa que demore algum tempo a ser efetuada e cuja execução

da aplicação deve ficar parada até que tenha terminado, e deste modo o utilizador não pensa que

a aplicação bloqueou, percebendo que está efetivamente a acontecer algo.

Existem esencialmente dois tipos destas caixas de diálogo: caixa de progresso indefinido e de

progresso definido. A primeira é usado quando a operação tem duração indefinida e portanto

está-se simplesmente à espera que a tarefa acabe; a segunda é quando a tarefa tem um tempo

de duração que pode ser estimado no inicio da operação, por exemplo quando se carregam 10

imagens, sabe-se que vão ser carregadas 10, logo é um processo finito e facilmente representado

de forma percentual.

Como verá de seguida são ambos fáceis de criar. O primeiro exemplo é para uma caixa de

progresso infinito, veja o exemplo 5.15 e a figura 5.16 que lhe é correspondente.

EEXXEEMMPPLLOO 55..1155

private Dialog criarProgressoInfinito() {

ProgressDialog dialog = new ProgressDialog(this);

dialog.setMessage("A carregar... Por favor espere.");

dialog.setIndeterminate(true);

dialog.setCancelable(false);

return dialog;

}

FFIIGGUURRAA 55..1166 -- Caixa de Progresso de tempo indefinido

Page 79: Introdução à programação em android

Como pode verificar é ainda mais simples de criar que os anteriores AlertDialog. O método que

define que o progresso é indeterminado percence ao objecto ProgressDialog e é o

setIndeterminate().

Uma forma alternativa de criar a mesma caixa de progresso sem ter de usar o método normal

(descrito no inicio do capítulo) seria como ilustrado no exemplo 5.16.

EEXXEEMMPPLLOO 55..1166

ProgressDialog.show(this, "", "A carregar... Por favor espere.", true, false);

O método de acesso estático show() leva como parâmetros um Context, um título para a caixa,

uma mensagem, se é indeterminado ou não e se é cancelável pelo utilizador ou não. Consegue-se

portanto substituir um método inteiro com 5 linhas. Todas as chamadas aos outros métodos

(showDialog(), onCreateDialog(), etc.) também podem ser chamados de forma estática,

simplificando o trabalho do programador.

O outro tipo de caixas de progresso é o finito, ou seja quando se sabe à partida quanto “tempo”

irá demorar a tarefa que está a ser realizada. Nesse caso substituiria-se o argumento de

setIndeterminate() por false, e poder-se-ia especificar o número de tarefas a realizar tal como

ilustrado no exemplo 5.17 (figura 5.17 ilustra o resultado desse exemplo).

EEXXEEMMPPLLOO 55..1177

private Dialog criarProgressoFinito() {

ProgressDialog dialog = new ProgressDialog(this);

dialog.setMessage("A carregar... Por favor espere.");

dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

dialog.setIndeterminate(false);

dialog.setCancelable(false);

dialog.setMax(10);

return dialog;

}

Page 80: Introdução à programação em android

FFIIGGUURRAA 55..1177 -- Caixa de Progresso de tempo definido

A grande diferença para a caixa de progresso indefinido é o uso obrigatório do método

setProgressStyle() e a utilização do método setMax(). O primeiro tem de ser sempre chamado

para que a caixa de progresso tenho a aparência de uma barra horizontal e não de um progresso

circular, ou seja não basta alterar o parâmetro do método setIndeterminate() para False. O

método setMax() serve apenas para mostrar um pequeno contador com a posição corrente e a

posição máxima bem como para calcular a percentagem.

A atualização deste tipo de caixa de progresso fica a cargo do programador não sendo algo

automático. No entanto, isso irá ser discutido mais à frente no capitulo 12 (Processamento

Paralelo).

dd. CustomDialog

Este tipo de caixas de diálogos são para ser usadas quando os outros dois tipos não servem a

propósito pretendido do programado por alguma razão. Aqui o aspeto duma caixa de diálogo é

definido manualmente e segue a mesma metodologia de construção que uma Layout, ou seja

preferêncialmente será feito em XM. O exemplo 5.18 define uma ImageView com uma TextView

ao lado, usando um LinearLayout com orientação horizontal. O exemplo 5.19 por sua vez

demonstra como utilizar a caixa de dialogo do definida no exemplo 5.18. O resultado visual será

semelhante ao da figura 5.18.

EEXXEEMMPPLLOO 55..1188

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:padding="5dip"

android:orientation="horizontal" >

Page 81: Introdução à programação em android

<ImageView

android:id="@+id/imageView1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:src="@drawable/ic_launcher" />

<TextView

android:id="@+id/textView1"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="Olá, isto é um CustomDialog" />

</LinearLayout>

EEXXEEMMPPLLOO 55..1199

private Dialog criarCustomDialog() {

Dialog dialog = new Dialog(this);

dialog.setTitle("Exemplo");

dialog.setContentView(R.layout.custom_dialog);

return dialog;

}

Page 82: Introdução à programação em android

FFIIGGUURRAA 55..1188 -- Caixa de Dialogo personalizada

Toasts e Notificações

A plataforma Android fornece várias formas de alertar o utilizador que algo aconteceu ou está

para acontecer. As que mais se usam normalmente são os Toasts, pequenas mensagens que

aparecem na parte inferior do ecrã centradas, e as notificações que são mensagens que aparecem

na barra de estado (no topo no caso de smartphones, e no canto inferior direito, no caso de

tablets).

Os dois tipos têm objetivos diferentes. Os Toasts usam-se para mensagens curtas e rápidas e

quando se tem a certeza que o utilizador está a olhar para o ecrã naquele momento. Isto porque

o Toast apenas fica visível no ecrã durante 1 ou 3 segundos (dependendo a construção do Toast),

logo se o utilizador não estiver a olhar para o ecrã naquele momento, é possível que ele não veja

a mensagem que a aplicação lhe está a transmitir. As Notificações, são usadas quando se quer

alertar o utilizador duma coisa que aconteceu ou que vai acontecer, mas que não se consegue

garantir que o utilizador está a olhar para ecrã ou então quando é preciso uma resposta do

utilizador para aquele evento. Um exemplo de quando isto acontece é quando se recebe um SMS

ou um email. É gerada uma notificação que o utilizador tem que ver e tomar conhecimento e só

depois é que ela desaparece.

Tudo o que é preciso para criar um Toast e mostrá-lo ao utilizador é uma linha de código, tal

como demonstrado no exemplo 5.20, e o resultado visual resultante será similar ao da figura

5.19.

EEXXEEMMPPLLOO 55..2200

Toast.makeText(this, "Bom dia!", Toast.LENGTH_SHORT).show();

FFIIGGUURRAA 55..1199 -- Exemplo de um Toast

Page 83: Introdução à programação em android

Como pôde verificar, a criação é mesmo muito simples. Usar o método makeText() da classe

Toast com 3 parâmetros: Context (a Activity atual), a mensagem a mostrar, e a duração. A

duração pode ser LENGTH_SHORT ou LENGTH_LONG, que o primeiro representa 1 e o segundo 3

segundos. Depois, basta chamar o método show() que mostra efetivamente a mensagem no ecrã.

Já as Notificações, são um pouco mais complicadas de usar em comparação com os Toasts mas

visto que têm objetivos completamente diferentes é normal que assim seja. Desta forma dão-se

bastantes possibilidades aos programadores para fazerem o que precisam sem ter de se

complicar muito o código.

Para começar, as Notificações são criadas normalmente por Serviços22

que correm em

background, porque estes estão sempre a correr no dispositivo mesmo quando está em standby,

permitindo assim que as Notificações sejam sempre geradas. Também podem ser lançados

dentro duma Activity, mas neste caso apenas podem ser criadas quando a aplicação está a ser

mostrada ao utilizador, portanto se algo acontece que fosse preciso gerar uma Notificação e a

aplicação não estivesse aberta não seria possível notificar o utilizador; por exemplo: As

Notificações de SMSs recebidos são sempre geradas, quer o terminal esteja em standby ou não.

Isto porque são lançadas por um Serviço que está a correr em background, caso contrário, apenas

quando abri-se a aplicação para ver SMSs, é que recebia notificações.

Portanto, para criar uma notificação são usados 4 passos:

1. Obter uma referência para o NotificationManager, que é um processo de sistema

que gere as notificações:

NotificationManager notificationManager = (NotificationManager)

getSystemService(Context.NOTIFICATION_SERVICE);

2. Criar uma um objeto do tipo Notification:

Notification notificacao = new Notification(R.drawable.ic_launcher, "Olá Android",

System.currentTimeMillis());

notificacao.flags |= Notification.FLAG_AUTO_CANCEL;

22 Discutidos em pormenor no capítulo 16

Page 84: Introdução à programação em android

Esta alteração das flags é necessária para a notificação desaparecer assim que

utilizador clica nela. Se, por oposição, a notificação for fixa (nunca desaparece),

basta usar a flag FLAG_NO_CLEAR.

3. Criar um PendingIntent para ser executado quando o utilizador clicar na notificação,

e atribuir um título e uma mensagem:

Intent intentALancar = new Intent(this, ActividadeNotificacao.class);

PendingIntent intentConteudo = PendingIntent.getActivity(this, 0, intentALancar, 0);

notificacao.setLatestEventInfo(getApplicationContext(), "Título", "Exemplo de

notificação", intentConteudo);

4. Avisar o NotificationManager da nova notificação:

private static final int NOTIFICATION_EXEMPLO = 0;

notificationManager.notify(Main.NOTIFICATION_EXEMPLO, notificacao);

A notificação resultante terá um aspect semelhante ao da figura 5.20.

FFIIGGUURRAA 55..2200 -- Notificação presente na barra de notificações

Page 85: Introdução à programação em android

No 1º passo, utilizou-se o método getSystemService() para obter uma referência ao serviço de

sistema NOTIFICATION_SERVICE. foi criado o objeto que representa a Notificação em si. O 1º e 2º

parâmetros são referentes ao conteúdo que aparece na barra de estado quando a notificação é

mostrada (um ícone e uma mensagem de texto). O 3º parâmetro é quando mostrar a notificação,

sendo que pode ser num tempo futuro ou de imediato. No 3º passo, é criado o PendingIntent que

vai ser executado quando o utilizador clicar na notificação e é associado à notificação

anteriormente criada, juntamente com um título e uma mensagem. No 4º e último passo, é

passada a informação ao NotificationManager de que existe uma nova notificação do tipo

NOTIFICATION_EXEMPLO que deve ser mostrada na barra de estado. Se por acaso acontecer a

aplicação gerar uma nova notificação sem o utilizador ver a anterior o NotificationManager

automaticamente remove a anterior e substitui pela nova.

Usando este método, pode-se ainda alterar outros aspetos da notificação, como adicionar o som

de notificações por omissão:

notificacao.defaults |= Notification.DEFAULT_SOUND;

Ou usar um ficheiro de som definido pelo programar:

notificacao.sound = Uri.parse("file:///sdcard/sons/som.mp3");

Pode ainda forçar a vibração do terminal:

notificacao.defaults |= Notification.DEFAULT_VIBRATE;

Ou ainda fazer a luz de notificação do terminal acender:

notificacao.defaults |= Notification.DEFAULT_LIGHTS;

A partir da versão Honeycomb da plataforma Android foi disponibilizada aos programadores uma

nova forma de criar as notificações, muito parecida com a forma como se criam os as Caixas de

Diálogos. Neste caso é usando a classe Notification.Builder. O exemplo 5.21 mostra um exemplo

de como pode criar uma notificação igual à anterior usando este novo mecanismo.

EEXXEEMMPPLLOO 55..2211

private void criarNotificacaoNovoMetodo() {

Intent intentALancar = new Intent(this, ActividadeNotificacao.class);

PendingIntent intentConteudo = PendingIntent.getActivity(this, 0, intentALancar, 0);

Page 86: Introdução à programação em android

Notification.Builder builder = new Notification.Builder(this);

builder.setSmallIcon(R.drawable.ic_launcher)

.setTicker("Olá Android")

.setWhen(System.currentTimeMillis())

.setAutoCancel(true)

.setContentTitle("Título")

.setContentText("Exemplo de notificação")

.setContentIntent(intentConteudo);

NotificationManager notificationManager = (NotificationManager)

getSystemService(Context.NOTIFICATION_SERVICE);

notificationManager.notify(Main.NOTIFICATION_EXEMPLO, builder.getNotification());

}

Como pode constatar o código é mais simples e mais fácil de ler comparado com o outro anterior.

O único problema é que esta classe (Notification.Builder) só existe em terminais que estejam a

correr a versão Honeycomb ou superior de Android, portanto é necessário ter cuidado quando se

decide usar esta nova classe.

Page 87: Introdução à programação em android

666 7CCOOMMUUNNIICCAAÇÇÃÃOO EENNTTRREE

CCOOMMPPOONNEENNTTEESS

Neste capítulo serão apresentadas várias peças fundamentais à construção de aplicações em

Android, a comunicação entre componentes. Por componentes entenda-se as várias Activities,

Services e todas as outras constituintes que podem ser os blocos de uma aplicação.

Intents – O que são e como utilizar

O conceito de Intent pode ser visto como um mecanismo genérico de invocação de componentes,

embora em Android o seu uso seja tão versátil que é melhor explicado pelo tipo de invocações

possíveis. Um Intent pode ser usado para invocar componentes da sua aplicação, tal como de uma

Activity passar para outra ou iniciar um Service, mas também pode ser usada para invocar

aplicações externas que estejam presentes no sistema operativo, assim como para comunicar com

componentes especificas destas ou do próprio Android, tal como evocar um Alarme.

Neste sentido pode ser dito que um Intent consome uma ação e produz um efeito. Os dados

dessa acção terão influência no tipo de efeito que é produzido. O conceito de Intent está presente

até nas mais simples aplicações, de facto já lidou com eles ainda que talvez não se recorde em

que momento. Veja o simples exemplo de quando se define uma Activity tal como a que

definimos nos capítulos anteriores. O exemplo 6.1 mostra o código de declaração de uma simples

Activity e o exemplo 6.2 ilustra a respectiva entrada que seria colocada no AndroidManifest para

esta Activity que sendo a única na aplicação é também o ponto de entrada da mesma. Como pode

ver no Manifest é feito uso da sintaxe <intent-filter>, ou seja no Manifest é declarado não só que

uma Activity existe mas também certos aspectos relacionados com a sua inicialização.

EEXXEEMMPPLLOO 66..11

import android.app.Activity;

import android.os.Bundle;

Page 88: Introdução à programação em android

public class SimpleActivity extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

EEXXEEMMPPLLOO 66..22

<activity

android:name=".SimpleActivity"

android:label="@string/app_name" >

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

De modo generico para iniciar a Activity declarada no exemplo apresentado a partir de uma outra

Activity bastaria enunciar um Intent cuja ação é inicar a dita Activity, isto poderia ser feito de

forma simples, tal como é ilustrado no exemplo 6.3.

EEXXEEMMPPLLOO 66..33

String action = “com.livroandroid.cap6.SimpleActivity”;

Intent myIntent = new Intent(action);

startActivity(myIntent);

Page 89: Introdução à programação em android

Usar Intents de Sistema

Do que já foi explicado sobre o funcionamento de Intents, faz todo o sentido que no sistema

operativo existam certas componentes a tirar partido deste mecanismo, a estes chama-se

usualmente Intents de Sistema. São apresentados de seguida 3 exemplos do uso destes (exemplo

6.4), para informações sobre todos os intents de sistema disponíveis a um dado momento visite a

página oficial23

. Nestes exemplos na definição do objecto do tipo Intent é passado o tipo de

Action (ação a realizar), e de seguida é especificado o tipo de dados (setData) para esse mesmo

Intent, tal como já deve estar a adivinhar os dados dizem respeito ao tipo de ação. Finalmente ao

invocar o método startActivity é iniciado o Intent especificado.

É também introduzido neste exemplo o conceito de URI. A definição de dados do Intent não

guarda na verdade os dados mas sim um apontador para os mesmos. Nesse sentido um URI

funciona de forma semelhante a um URL num browser de Internet, ou seja, é um endereço do

local onde os dados se encontram, dessa forma para passar dados pelo método setData tem de

os encapsular com URI.parse de modo a obter um URI para esses dados específicos.

EEXXEEMMPPLLOO 66..44

Intent openWebpage = new Intent(Intent.ACTION_VIEW);

openWebpage.setData(Uri.parse("http://www.google.pt"));

startActivity(openWebpage);

Intent dialNumber= new Intent(Intent.ACTION_DIAL);

dialNumber.setData(Uri.parse("tel:118"));

startActivity(dialNumber);

Intent openGmaps= new Intent(Intent.ACTION_VIEW);

openGmaps.setData(Uri.parse("geo:39.63,-7.84?z=6"));

startActivity(openGmaps);

23 http://developer.android.com/guide/appendix/g-app-intents.html

Page 90: Introdução à programação em android

Mais sobre Actions

As Actions tal como vimos no exemplo 6.4 indicam o tipo de ação a realizar, mas é o tipo de

dados juntamente com a Action que fornecem ao sistema operativo a informação necessária para

este saber qual a componente a executar. Note que o exemplo de abrir a página web e um

endereço no Google Maps ambos usam a ACTION_VIEW. Nas aplicações de destino é no Android

Manifest que é declarado o tipo de dados que uma dada componente aceita. Veja agora o

exemplo 6.5. Aqui estamos a definer que a Activity de nome TestActivity pode ser iniciada

sempre que alguma aplicação inicie uma Action do tipo ACTION_VIEW em que o tipo de dados

seja do tipo http, ou seja esta Activity passaria a funcinar de forma semelhante ao browser de

Android para páginas http.

EEXXEEMMPPLLOO 66..55

<activity android:name="TestActivity">

<intent-filter>

<action android:name="android.intent.action.VIEW">

<data android:scheme="http" />

</action>

</intent-filter>

</activity>

Para mais informações sobre que formatos de Intent-Filter existem e das combinações possível

consulte a documentação oficial24

.

Intent Extras

Para além dos dados de URI, um Intent também pode conter informações adicionais às quais se

dão o nome de Extras. Os Extras são informações do tipo pares chave-valor. Os valores podem

ser tipos básicos de Java ou objectos de classes que implementem a interface

android.os.Parcelable. A informação contida nos extras é contida por um objecto do tipo Bundle,

os exemplos 6.6 e 6.7 demonstram como se pode tirar partido desta funcionalidade. Aqui temos

duas Activities (uma em cada exemplo), a primeira fornece uma caixa de diálogo em que aguarda

pela introdução de texto do utilizador e assim que este toca no botão ‘Seguinte’ é iniciada uma

nova Activity (a do exemplo 6.6) que recebe o texto introduzido pelo utilizador na Activity

anterior. Este exemplo demonstra assim sucintamente um dos casos tipicos de utilização de

Extras, a transição de dados temporários entre componentes dentro de uma aplicação. O

24 http://developer.android.com/guide/topics/intents/intents-filters.html

Page 91: Introdução à programação em android

exemplo 6.6 tem um aspeto semelhante ao da figura 6.1, e o código aqui exibido encontra-se

dentro do bloco de ação do botão, como a esta altura já tem um entendimento da estrutura de tal

código não é mostrado o código todo da Activity em questão, no entanto pode consultar o código

fonte fornecido com o livro, onde encontrará estes exemplos em projectos de aplicações

completas e funcionais prontas a testar e modificar. De modo análogo o exemplo 6.7 tem o

aspecto da figura 6.2, e o seu código encontrar-se-á compreendido no método OnCreate da

Activity em que se insere.

EEXXEEMMPPLLOO 66..66

EditText userInput = (EditText) findViewById(R.id.et_typeanything);

Intent nextActivity = new Intent(ExtrasExample1.this,

ExtrasExample2.class);

nextActivity.putExtra("TEXTO_A_TRANSITAR", userInput.getText().toString());

startActivity(nextActivity);

EEXXEEMMPPLLOO 66..77

Bundle extras = getIntent().getExtras();

if (getIntent().hasExtra(PREVIOUS_VALUE)){

TextView tv1 = (TextView) findViewById(R.id.tv_extra_from_previous);

tv1.setText(extras.getString(PREVIOUS_VALUE));

}

Page 92: Introdução à programação em android

FFIIGGUURRAA 66..5 –– Exemplo 6.6

FFIIGGUURRAA 66..22 –– Exemplo 6.7

Page 93: Introdução à programação em android

Notas Finais sobre Intents

Para terminar este capítulo serão referidas algumas informações de ambito genérico que

extendem aquilo que foi dito ao longo do capítulo.

Tal como já foi referido em capítulos anteriores o Android possui várias componentes

aplicacionais, neste caítulo vimos ainda que para iniciar uma Activity com um intent pode ser

utilizado o método startActivity. De modo análogo é também possível iniciarem-se Services (com

o método startService) ou enviar Broadcasts de sistema (com o método sendBroadcast), ambos

consomem um Intent como parâmetro em semelhança ao startActivity.

Existe um tipo especial de Intent, de nome PendingIntent, que serve essencialmente para

agendar a execução de um Intent num tempo futuro, este mecanismo é habitualmente usado com

o gestor de alarmes de Android, sendo que este Intent é estudado em detalhe no capítulo 16.

Page 94: Introdução à programação em android

777 8SSEEGGUURRAANNÇÇAA

AAPPLLIICCAACCIIOONNAALL

Neste capítulo ser-lhe-á explicado o modelo de segurança aplicacional de Android, uma parte

fundamental do sistema operativo e muito relevante à programação de aplicações na plataforma.

Este modelo é estendido desde a fase de desenvolvimento até à instalação final da aplicação em

cada dispositivo.

Modelo De Segurança Aplicacional

Para melhor perceber este modelo é necessário falar um pouco de como o Android funciona. Quando uma

aplicação é instalada em Android é-lhe associada um utilizador único no sistema operativo, isto garante que

a não ser que o utilizador explicitamente assim especifique, os dados da aplicação apenas poderão ser lidos

pela própria (exceptuando se os dados forem guardados em armazenamento externo ou se a aplicação

executar num dispositivo em que as aplicações podem usufruir de permissões de utilizador Root, o que não

acontece por omissão).

Para que uma aplicação seja instalável esta tem de estar assinada de por um certificado digital, isto garante

que assim que surja um update da aplicação este só possa ser instalado se a aplicação contiver a mesma

assinatura digital, isto garante a fidelidade da mesma.

A API de Android é extremamente poderosa e abrangente, e algumas funcionalidades fornecidas pelo

sistema aos programadores poderiam ser utilizadas para uso mal intencionado. De modo a controlar o

acesso a estas funcionalidades e de certo modo a passar o poder de decisão para o lado do utilizador que

instalará a aplicação, em Android existe um mecanismo de permissões. De modo simples, quando uma

aplicação tenta aceder a uma funcionalidade especifica de Android deverá ter declarado no seu Manifest

que fará uso dessa funcionalidade. Deste modo, em tempo de instalação o utilizador será notificado de que

a aplicação necessita da respectiva permissão, tal como evidenciado na figura 7.1. Se a permissão não for

declara no Manifest e o programador fizer uso da mesma, a aplicação fechará abruptamente lançando uma

excepção relacionada com o facto de não ter declaro essa permissão no Manifest.

Page 95: Introdução à programação em android

FFIIGGUURRAA 77..11 –– Exemplo de aviso de permissões de aplicação aquando instalação da mesma

Permissões e Descrição

Tal como referimos anteriormente para usar várias funcionalidades do sistema é necessária a

inclusão de uma permissão no ficheiro Android Manifest da aplicação. São apresentadas de

seguida algumas das permissões existentes mais usadas. Algumas permissões só existem a partir

de determinada versão de Android, como é o caso da permissão para usar a funcionalidade NFC

que só existe a partir da versão Gingerbread de Android. Para uma consulta integral de todas as

permissões existentes e a sua descrição consulte a documentação oficial25

. No final é apresentado

um exemplo de como são adicionadas estas permissões ao projecto.

25 http://developer.android.com/reference/android/Manifest.permission.html

Page 96: Introdução à programação em android

ACCESS_NETWORK_STATE

Acesso ao estado de conectividade atual do dispositivo

ACCESS_COARSE_LOCATION Acesso à localização aproximada do utilizador (tem

apenas em conta as células de rede e rede Wi-Fi nas

imediações do dispositivo)

ACCESS_FINE_LOCATION Acesso à localização exacta do utilizador (tem em conta a

capacidade de recepção de GPS do dispositivo)

BATTERY_STATS Acesso ao estado da(s) bateria(s) do dispositivo

BLUETOOTH Acesso às capacidades de envio e recepção de dados via

Bluetooth

BLUETOOTH_ADMIN

Acesso à capacidade de procura e emparelhamento com

outros dispositivos Bluetooth

CAMERA Acesso à(s) Câmara(s) do dispositivo

INTERNET Acesso a comunicação de rede em geral

NFC Acesso à funcionalidade de Near Field Communication

READ_CALENDAR Acesso ao calendário do utilizador do dispositivo

READ_CONTACTS Acesso à lista de contactos do utilizador do dispositivo

READ_PROFILE Acesso à informação de Perfil do utilizador Google

SET_WALLPAPER Acesso à capacidade de definir um fundo no Launcher

VIBRATE Acesso à capacidade de vibração do dispositivo

Quadro 7.1 –– Permissões aplicacionais de Android mais frequentemente usadas

Estas permissões tal como referido são declaradas no Android Manifest que como sabe se

encontra na raiz de qualquer projecto Android. A figura 7.2 ilustra como pode declarar

permissões a partir da interface visual do Manifest no Eclipse, e o exemplo 7.1 mostra o aspecto

de tais definições quando vista a um nível de edição XML.

Page 97: Introdução à programação em android

FFIIGGUURRAA 77..22 –– Adicionar permissões ao Manifest através da interface visual

EEXXEEMMPPLLOO 77..11

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.livroandroid.capitulo8"

android:versionCode="1"

android:versionName="1.0" >

<uses-sdk android:minSdkVersion="15" />

<uses-permission android:name="android.permission.INTERNET"/>

<application

android:icon="@drawable/ic_launcher"

android:label="@string/app_name" >

<activity

Page 98: Introdução à programação em android

android:name=".MainActivity"

android:label="@string/app_name" >

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

</manifest>

Neste último exemplo note que a especificação da permissão é feita neste linha de código:

<uses-permission android:name="android.permission.INTERNET"/>

Assinar uma aplicação com um Certificado Digital

Tal como foi referido na introdução deste capítulo uma aplicação para ser instalada num

dispositivo tem de ser assinada digitalmente com um certificado. Pode não estar ciente disso, mas

até agora todas as aplicações que testou tanto no seu dispositivo ou num emulador estavam

digitalmente assinadas com um certificado que foi gerado automaticamente aquando a instalação

da SDK. Ora este certificado digital não deverá ser o que é usado para a publicação de aplicações

no Google Play, pois se mais tarde voltar a instalar o SDK o certificado gerado será diferente e

nessa altura se já não tiver o certificado gerado anteriormente fica impossibilitado de publicar

actualizações da aplicação. Para além disso é boa prática criar um certificado que contenha

informações sobre o autor. De seguida mostramos como é possível usar o Eclipse para criar um

certificado e assinar aplicações com este certificado digital.

Com um qualquer projecto Android aberto, clique em File > Export nos menus do Eclipse. De

seguida escolha a opção Export Android Application tal como evidenciado na figura 7.3.

Page 99: Introdução à programação em android

FFIIGGUURRAA 77..33 –– Caixa de dialogo de exportação do Projecto

De seguida clique em Next para prosseguir, ser-lhe-á pedido que selecione o projecto que

pretende exportar, clique em Browse... e escolha o nome do projecto pretendido de entre a

listagem. Clique de novo em Next, e de seguida será confrontado com um formulário em que

pode escolher um certificado existente ou criar um novo. Para o efeito didático vai criar um novo

certificado, mas lembre-se que de futuro após ter criado um certificado para uma aplicação

deverá usar sempre esse mesmo certificado para produzir a versão final dos APKs da mesma, e

em dita altura pode fazê-lo clicando no botão Browse... adjacente ao campo Location.

Para criar um novo certificado mude primeiro a opção para Create new keystore, de seguida o

botão Browse... adjacente ao campo Location permite escolher onde quer guardar o certificado e

os dois seguintes campos dizem respeito à palavra chave e confirmação da mesma com a qual

deseja proteger o certificado. A figura 7.4 mostra um exemplo de preenchimento do formulário, o

nome do certificado e a palavra passe são inteiramente à sua escolha.

Page 100: Introdução à programação em android

FFIIGGUURRAA 77..44 –– Criação de um novo Certificado Digital

De seguida ser-lhe-á apresentado um novo formulário que conterá informações sobre o autor ou

entidade responsável pelo certificado. A figura 7.5 ilustra este formulário e um exemplo de

preenchimento, os 4 primeiros campos são de preenchimento obrigatório, e é também necessário

o preenchimento de pelo menos 1 dos consecutivos campos, no exemplo apresentado foi

escolhido o Organizational Unit, mas poderia ter sido outro qualquer.

Nota: A validade do certificado deve ser no minímo de 30 anos para que as aplicações assinadas

com este sejam elegíveis para publicação no Google Play.

FFIIGGUURRAA 77..55 –– Informações do autor ou entidade na criação de um novo Certificado Digital

Clicando em Next chagará finalmente ao passo em que pode escolher o nome do caminho de

destino do APK assinado com este certificado. Se tivesse escolhido um certificado existente

Page 101: Introdução à programação em android

apenas lhe teriam sido facultadas as palavras chave do certificado e dos dados deste, e por fim

teria um ecrã para selecção do caminho de destino do APK igual ao agora apresentado.

O ficheiro APK gerado está pronto para publicação.