You are on page 1of 54

Material para estudos e revisao: Android 4.

4 (KitKat)
Liuri Loami Ruyz Jorge liuri.usp@gmail.com
2 de janeiro de 2014


SUMARIO

Sumario
1

Requisitos

Introduca o
2.1 Arquitetura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4
5

Projeto de Aplicaca o Android


3.1 Principais Componentes do Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5
6

Activities, Layouts, Widgets e Listeners


4.1 Activities . . . . . . . . . . . . . . .
4.2 Layouts em XML . . . . . . . . . .
4.3
. . . . . . . . . . . . . . . . . . . .
4.4 Layouts - Exemplo 1 . . . . . . . .
4.5 Layouts - Exemplo 2 . . . . . . . .
4.6 Layouts - Exemplo 3 . . . . . . . .
4.7 Layouts - Exemplo 4 . . . . . . . .
4.8 Layouts - Exemplo 5 . . . . . . . .
4.9 Listeners de Eventos . . . . . . . .
4.10 Listeners - Exemplo . . . . . . . . .

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

6
6
7
7
8
9
9
10
11
12
13

Usando Intents
5.1 Usando o Intent com Activities . .
5.2 Intent - Exemplo 1 . . . . . . . . . .
5.3 Usando Intents para passar dados
5.4 Intent - Exemplo 2 . . . . . . . . . .
5.5 Abrindo outros aplicativos . . . . .
5.6 Intent - Exemplo 3 . . . . . . . . . .

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

14
14
14
16
17
19
19

Persistencia de dados
6.1 Usando o SharedPreferences
6.2 Persistencia - Exemplo 1 . .
6.3 Usando o SQLite . . . . . .
6.4 SQLite - Exemplo 1 . . . . .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

21
21
22
24
25

HTTP e JSON
7.1 HTTP . . . . . . . . . . . .
7.2 JSON . . . . . . . . . . . .
7.3 HTTP e JSON - Exemplo 1
7.4 HTTP e JSON - Exemplo 2

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

30
30
30
30
33

Threads e AsyncTasks
8.1 Threads e Handlers . . . . . . . .
8.2 Threads e Handlers - Exemplo 1 .
8.3 Threads e Handlers - Exemplo 2 .
8.4 AsyncTasks . . . . . . . . . . . .
8.5 AskyncTasks - Exemplo 1 . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

34
34
35
36
37
37

Services e BroadCastReceivers
9.1 Servicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.2 Manifest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.3 Classe Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

39
39
40
40

.
.
.
.

Liuri Loami Ruyz Jorge liuri.usp@gmail.com


SUMARIO

10 Notificacoes

10.1 Dialogs . . . . . . . . . . .
10.2 Dialogs - Exemplo 1 . . . .
10.3 Notifications . . . . . . . .
10.4 Notifications - Exemplo 1

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

42
42
42
45
45

11 Mapas e GPS
11.1 Utilizando o GPS . .
11.2 GPS - Exemplo 1 . . .
11.3 Usando o MapView .
11.4 MapView - Examplo

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

47
47
47
50
50

12 Multimedia
12.1 Reproduca o de Mdia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12.2 Utilizando o MediaPlayer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

53
53
53

.
.
.
.

.
.
.
.

.
.
.
.

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

INTRODUC
AO

Requisitos

Antes do incio dos estudos para desenvolvimento Android, e necessario que o estudante tenha uma base
solida
em Java e em XML.

Introduca o
Android e um sistema operacional (SO) baseado em Linux para dispositivos moveis;

Desenvolvido pela Open Handset Alliance, liderado pela Google;


A Open Handset Alliance sao as companhias que dao suporte direto a` plataforma Android;
Fabricantes de dispositivos: HTC, LG, Motorola, Sansung, ..;
Operadoras: Nextel, T-Mobile, Telefonica, Telecom Italia, ..;
Semicondutores: Broadcom, Intel, Nvidia, Synaptics, ..;
Software: Google, eBay, LivingImage, ..;
Atualmente na versao 4.4 (KitKat), lancada em Outubro de 2013;
Google Play:
Loja da Google para distribuica o de aplicacoes,
jogos, filmes, musicas
e livros;

Anteriormente chamada Android Market;


Os produtos podem ser vendidos de graca ou a um custo;
Desde 2013, ha mais de 1 milhao de aplicacoes
disponveis na loja, com mais de 50 bilhoes
de
downloads.
Middleware ou mediador:
Transporta informacoes
de alto nvel com os de baixo nvel;
e dados entre modulos

Seu objetivo e mascarar a heterogeneidade e fornecer um modelo de programaca o mais produtivo


para os programadores de aplicativos;
Sao sistemas de software que se executam entre as aplicacoes
e os sistemas operacionais.
Desenvolvimento de aplicacoes
para dispositivos Android e feito com a programaca o em Java;
Smartphone:
Smartphones sao uma evoluca o dos celulares comuns;
Sao mais caros que os celulares, geralmente maiores em tamanho, com telas sensveis ao toque e
possuem um sistema operacional complexo, como o Android, o iOS ou Windows Phone;
Em outras palavras, smartphones sao celulares com a complexidade tecnologica
de computadores;

Possuem varias aplicacoes


como navegadores web, GPS, Camera, telas de alta resoluca o, entre outras
coisas;
Entre os SOs para Smartphones temos Symbian, Linux, Windows Mobile, Windows Phone, iOS,
Blackberry OS;
Vantagens do uso do Android:
Soluca o para os diferentes tipos de hardware;
Redes abertas;
Possui codigo
aberto.

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

ANDROID
PROJETO DE APLICAC
AO

2.1

Arquitetura

Figura 1: Arquitetura do sistema Android.

Projeto de Aplicaca o Android


Antes de tudo, deve-se:
Instalar o ambiente de desenvolvimento Java (JDK) e Android (Android SDK);
Instalar a IDE Eclipse e o ADTPlugin (para a programaca o Android dentro desse editor);
Criar uma maquina virtual Android (Android Virtual Device) atraves do Eclipse.
No momento da criaca o de um novo projeto Android, entre outras etapas, devem ser realizadas duas
escolhas:
Build SDK: Qual a versao padrao (mais recente) do Android a ser utilizada para o aplicativo;
Minimum Required SDK: Qual a mnima versao do Android que podera rodar o aplicativo.
As pastas sao organizadas da seguinte maneira:
src: E a pasta onde fica o codigo
fonte da nossa aplicaca o. No nosso projeto, essa pasta so possui

um arquivo, nomeDaActivity.java;
gen: Pasta onde ficam os arquivos gerados automaticamente pelo Eclipse. Nao deve ser feito
nenhum tipo de alteraca o manual dentro dessa pasta;
assets: Pasta onde ficam os arquivos de mdia usados pela aplicaca o. Pode ser quaisquer tipos como
vdeos, sons, imagens, etc;
bin: Pasta onde ficam os arquivos compilados pelo Eclipse. Em geral, nao deve se mexer nessa
pasta tambem;

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

ACTIVITIES, LAYOUTS, WIDGETS E LISTENERS

res: Abreviaca o de resources, esta pasta e dividida em varias outras, com propositos
diferentes.

As pastas que comecam com o sufixo drawable sao destinadas a armazenar imagens que sao
usadas na aplicaca o, como cones, por exemplo;
A pasta layout se destina a armazenar os arquivos XML que representam o layout das telas da
aplicaca o;
A pasta values tambem se destina a armazenar XMLs que serao usados na aplicaca o.
AndroidManifest.xml: E o arquivo que guarda a configuraca o de um aplicativo Android.

3.1

Principais Componentes do Framework

O framework do Android possui varios componentes. Os principais sao:


Activities - E o componente que representa a tela, na qual o usuario interage com a aplicaca o;
Services - E o componente responsavel por rodar tarefas em background. Em geral sao tarefas mais
longas, rodadas em background para nao prejudicar a responsividade da aplicaca o;
Broadcast receivers - E um componente responsavel por responder a eventos do sistema. Os eventos
podem ser de variados tipos, por exemplo, uma localizaca o foi encontrada pelo GPS, ou que a bateria
esta acabando, etc;
Intents - E o componente que inicia os demais (activities, services e receivers). A criaca o de uma nova
activity ou service e realizada atraves dos intents;
Content providers - Componente responsavel por gerenciar dados da aplicaca o. Caso voce queira
compartilhar os dados da sua aplicaca o com outras, voce so consegue faze-lo atraves de um content
provider. Porem, mesmo quando a informaca o e usada somente na sua aplicaca o e nao e compartilhada com as demais, e possvel usar um content provider para organizar a forma como os dados
sao consultados.

Activities, Layouts, Widgets e Listeners

4.1

Activities

Activity e o componente responsavel por mostrar uma tela ao usuario;


Sempre que voce quiser criar uma nova tela na aplicaca o, devera criar uma classe que herda de Activity;
Entre os principais metodos da activity estao os que sao responsaveis pelo seu ciclo de vida;
O ciclo de vida de uma activity se refere a ordem em que os metodos sao chamados desde a sua criaca o,
ate o seu final, quando a activity e destruda. Estes metodos sao:
onCreate - E chamado quando a activity e criada;
onStart - E chamado apos
o onCreate, e antes da activity se tornar visvel para o usuario;
onResume - E chamado apos
o onStart, quando a activity se torna visvel para o usuario;
onPause - E chamado apos
o onResume, quando a activity esta para perder a visibilidade para outra
activity;
onStop - E chamado quando a activity nao esta mais visvel para o usuario;
onDestroy - E chamado quando a activity esta prestes a ser destruda.

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

ACTIVITIES, LAYOUTS, WIDGETS E LISTENERS

4.2

Layouts em XML

As interfaces da aplicaca o sao definidas em arquivos XML que ficam na pasta res/layout. Todos os
arquivos de layout devem ficar nesta pasta, voce nao pode agrupa-los em outra pasta;
A ligaca o entre a interface em XML e seus elementos com o codigo
Java da activity e feita atraves

de um arquivo especial, com o nome apenas de R.java que fica na pasta gen. Esse arquivo e gerado
automaticamente, e voce nao deve fazer alteracoes
manuais nele. O nome R e como uma abreviaca o
para resources;
@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState ) ;
setContentView ( R. layout .main ) ;
}

No exemplo acima, o metodo setContentView serve para definir qual sera o conteudo
da activity. Ao

passar como parametro R.layout.main estamos dizendo que o conteudo


da activity esta definido no

arquivo main.xml da pasta res/layout;


Existem dois tipos de elementos no XML de um layout, os containers e os widgets;
Um container e um elemento que agrega varios outros elementos, sejam eles outros containers ou
widgets;
Widgets sao os elementos isolados, como textos, botoes,
caixas de texto, etc;

Uma coisa em comum entre todos os elementos XML e que eles precisam obrigatoriamente dos atributos
layout width e layout height para indicar a largura e altura do elemento, respectivamente;
Em vez de valores absolutos (em pixels) e comum ver os valores match parent para indicar que deve
ter o mesmo tamanho do elemento que o contem ou wrap content para indicar que deve ter o mesmo
tamanho do conteudo

do elemento;
Entre os containers temos:

4.3
LinearLayout - Possui um atributo orientation que pode receber o valor vertical ou horizontal que
indica que os elementos filhos devem ser agrupados na vertical ou horizontal;
RelativeLayout - E um layout que permite posicionar os elementos filhos de maneira relativa, um
em relaca o ao outro;
FrameLayout - E um tipo de layout bem simples, que permite adicionar apenas um elemento. Se
adicionar mais elementos, eles irao ser desenhados sobre os outros, parcialmente ou totalmente;
TableLayout - Como o nome sugere, serve para criar tabelas. Voce deve adicionar elementos do
tipo TableRow, e nestes elementos adicionar as celulas que deseja mostrar.
Entre os diversos widgets temos:
TextView - Usado para mostrar textos na tela;
EditText - Usado para que o usuario digite alguma entrada;
Button - Usado para que o usuario execute acoes
atraves de cliques;
Checkbox - Usado para que o usuario marque opcoes;

RadioButton - O mesmo que acima, mas permite marcar apenas uma opca o;
Spinner - Usado para que o usuario selecione uma opca o (combo box).
ImageView - Usado para mostrar imagens na tela.
Liuri Loami Ruyz Jorge liuri.usp@gmail.com

ACTIVITIES, LAYOUTS, WIDGETS E LISTENERS

4.4

Layouts - Exemplo 1

Crie um novo projeto com o nome testes1. O nome do pacote deve ser com.projeto3.android.testes1
(costuma-se usar o inverso do endereco do site mais alguns nomes na frente) e o nome da activity
MainLayout;
Na pasta res/layouts delete qualquer arquivo que existir e crie um arquivo chamado linear.xml com o
seguinte conteudo:

<?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:orientation =" vertical ">
<TextView
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" Nome: " />
<EditText
android:layout_width =" match_parent "
android:layout_height =" wrap_content " />
<Button
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:text ="Ver mensagem " />
</ LinearLayout >

No incio de todos os arquivos xml deve haver essa primeira linha especificando a sua codificaca o
e a versao utilizada;
Deve-se respeitar os padroes
de identaca o para tabulaca o;
No exemplo apresentado, foram inseridos os widgets de tipo TextView, EditText e Button dentro de um container do tipo LinearLayout, onde todos os elementos sao inseridos em sequencia
verticalmente;
O atributo android:text define o texto a ser mostrado;
O atributo android:orientation serve para definir a orientaca o (vertical ou horizontal) do container
(layout) LinearLayout;
O atributo xmlns e utilizado para definir algum namespace no arquivo. Usado, nesse caso, para
obter os tipos de containers e widgets disponveis para Android juntamente com os seus atributos.
A seguir, edite o arquivo MainActivity.java para que ele fique com o seguinte conteudo:

package com. projeto3 . android . testes1 ;


import android .app. Activity ;
import android .os. Bundle ;
public class MainActivity extends Activity {
@Override
public void onCreate ( Bundle savedInstanceState ) {
super. onCreate ( savedInstanceState );
setContentView (R. layout . linear );
}
}

Apos
isso, rode e teste a aplicaca o.

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

ACTIVITIES, LAYOUTS, WIDGETS E LISTENERS

4.5

Layouts - Exemplo 2

Edite o arquivo linear.xml, deixando-o igual ao codigo


abaixo:

<?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:orientation =" vertical ">
<TextView
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" @string / name_label " />

<!-- Edite essa linha -->

<EditText
android:layout_width =" match_parent "
android:layout_height =" wrap_content " />
<Button
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:text =" @string / see_message " />

<!-- Edite essa linha -->

</ LinearLayout >

Em seguida edite o arquivo strings.xml presente em res/values:


<?xml version ="1.0" encoding ="utf -8" ?>
<resources >
<string name=" app_name ">Exemplo </ string >
<string name=" name_label ">Nome :</ string >
<string name=" see_message ">Ver mensagem </ string >
</ resources >

O arquivo strings.xml armazena textos (strings) que sao utilizadas pela aplicaca o;
Nao e recomendavel que os textos a serem mostrados na tela fiquem em outros arquivos;
Para utilizar essas strings armazenadas deve-se utilizar @string/nomeDaString;
Alem das strings utilizadas, o arquivo deve conter uma string chamada app name contendo o nome
do aplicativo.

4.6

Layouts - Exemplo 3

Agora crie um novo arquivo de layout chamado relative.xml com o seguinte conteudo:

<?xml version ="1.0" encoding ="utf -8" ?>


<RelativeLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
android:layout_width =" match_parent "
android:layout_height =" match_parent " >
<TextView
android:id ="@+id/ name_label_text "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_alignParentLeft ="true"
android:layout_alignParentTop ="true"
android:textSize ="24 dp"
android:text =" @string / name_label " />
<EditText
android:id ="@+id/ name_edit_text "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

ACTIVITIES, LAYOUTS, WIDGETS E LISTENERS

android:inputType ="text"
android:layout_toRightOf ="@id/ name_label_text " />
<Button
android:id ="@+id/ see_message_buttom "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_alignParentRight ="true"
android:layout_below ="@id/ name_edit_text "
android:text =" @string / see_message " />
</ RelativeLayout >

O atributo android:id identifica um determinado widget da aplicaca o por meio de um nome;


No momento da atribuica o de um novo id deve-se utilizar @+id/nomeDoID;
Para se referenciar um widget pelo seu id (ja existente), deve-se utilizar @id/nomeDoID;
No container RelativeLayout os widgets sao inseridos em posicoes
relativas (e nao absolutas) em
relaca o a outros widgets ja inseridos ou ao proprio
container;

Edite novamente o arquivo MainActivity.java:


package com. projeto3 . android . testes1 ;
import android .app. Activity ;
import android .os. Bundle ;
public class MainActivity extends Activity {
@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout . relative );
// Edite essa linha
}
}

Rode a aplicaca o e veja o resultado.

4.7

Layouts - Exemplo 4

Salve uma imagem com o nome imagem.png na pasta res/drawable-hdpi


Crie um novo arquivo de layout chamado frame.xml:
<?xml version ="1.0" encoding ="utf -8" ?>
<FrameLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
android:layout_width =" match_parent "
android:layout_height =" match_parent " >
<ImageView
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:src =" @drawable / imagem "
android:layout_gravity =" center " />
<TextView
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_gravity ="top| center_horizontal "
android:text =" @string / image_label "
android:textStyle ="bold"
android:textSize ="30 dp" />
</ FrameLayout >

A disposica o de um elemento em um container de tipo RelativeLayout e realizada apenas atraves


do seu alinhamento com o mesmo (topo, esquerda, direita, base ou quinas);
Liuri Loami Ruyz Jorge liuri.usp@gmail.com

10

ACTIVITIES, LAYOUTS, WIDGETS E LISTENERS

Por isso, torna-se difcil a inserca o de mais do que um elemento dentro desse tipo de container sem
que eles se sobreponham;
O atributo android:textStyle e utilizado para tornar um texto negrito (bold) e/ou italico (italic);
Para um texto negrito e italico usa-se como valor para esse atributo: bold | italic (sem aspas);
O atributo android:textSize especifica o tamanho da fonte. Sendo que o valor pode ser especificado
usando as mais diferentes unidades existentes (cm, px, dp, ..)
O atributo android:src usado no widget de tipo ImageView (para a visualizaca o da imagem) deve
conter o nome da imagem png na forma @drawable/nomeDaImagem.
Acrescente a seguinte linha ao arquivo strings.xml:
<string name=" image_label ">Teste com Imagem </ string >

Edite o arquivo MainActivity.java:


package com. projeto3 . android . testes1 ;
import android .app. Activity ;
import android .os. Bundle ;
public class MainActivity extends Activity {
@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout . frame );
// Edite essa linha
}
}

Execute o projeto.

4.8

Layouts - Exemplo 5

Crie um novo arquivo chamado table.xml com o seguinte conteudo:

<?xml version ="1.0" encoding ="utf -8" ?>


<TableLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
android:layout_width =" match_parent "
android:layout_height =" match_parent "
android:stretchColumns ="true" >
<TableRow >
<TextView
android:layout_column ="1"
android:text ="Nome"
android:padding ="3dip"
android:textStyle ="bold" />
<TextView
android:text =" Sobrenome "
android:padding ="3dip"
android:textStyle ="bold" />
</ TableRow >
<TableRow >
<TextView
android:layout_column ="1"
android:text =" Alexandre "
android:padding ="3dip"
android:textStyle ="bold" />
<TextView
android:text =" Macedo "
android:padding ="3dip"

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

11

ACTIVITIES, LAYOUTS, WIDGETS E LISTENERS

android:textStyle ="bold" />


</ TableRow >
<TableRow >
<TextView
android:layout_column ="1"
android:text =" Rafael "
android:padding ="3dip"
android:textStyle ="bold" />
<TextView
android:text =" Cosentino "
android:padding ="3dip"
android:textStyle ="bold" />
</ TableRow >
</ TableLayout >

No container de tipo TableLayout divide-se a tela em linhas e colunas;


O atributo do container android:stretchColumns com valores true/false especifica se as colunas
devem ou nao ocupar toda a largura da tela;
Linhas sao especificadas com as tags TableRow;
O numero

de colunas ocupadas por um elemento deve ser especificado com o atributo android:layout column;
O atributo android:padding especifica o espacamento do elemento entre o restante da tela.
Edite o arquivo MainActivity.java para utilizar o layout recem-criado e teste a aplicaca o.

4.9

Listeners de Eventos

Lidam com as interacoes


do usuarios com a tela;
Primeiramente, para utilizar um widget que foi definido no layout, devemos busca-lo e fazer referencia
no nosso codigo
Java. Para isso, e utilizado o metodo findViewById:

Button button = ( Button ) findViewById (R.id. nomeBotao1 );


TextView label = ( TextView ) findViewById (R.id. nomeLabel1 );

Sempre deve-se fazer um cast para o elemento que queremos, pois o metodo retorna objetos do tipo
View;
O parametro recebido se refere ao id que foi dado ao elemento no XML. (Lembre-se que o arquivo R.java
faz a ligaca o entre o XML e o codigo
Java);

Entre os principais metodos que podem ser utilizados nesses listeners estao o getEditableText().getString()
(para obter o texto contido no elemento) ou setText(String str) (para alterar o texto do elemento);
Apos
a obtenca o do objeto, podemos adicionar listeners, como no exemplo abaixo:
Button button = ( Button ) findViewById (R.id. see_message_buttom );
button . setOnClickListener (new OnClickListener () {
@Override
public void onClick (View arg0) {
// Faz alguma coisa
}
});

Dessa maneira, sempre que o botao for clicado, o metodo onClick sera chamado;
Existem varios tipos de listeners, todos sempre comecando com o sufixo on indicando depois qual tipo de
evento eles estarao escutando.

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

12

ACTIVITIES, LAYOUTS, WIDGETS E LISTENERS

4.10

Listeners - Exemplo

Crie um novo projeto Android, da mesma forma que o item anterior. Use como nome para o projeto
Testes1Parte2. O nome do pacote deve ser com.projeto3.android.testes1parte2 e o nome da activity deve
ser MainActivity;
Na pasta res/layouts crie um arquivo chamado main.xml:
<?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:orientation =" vertical ">
<TextView
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" @string / name_label " />
<EditText
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:id ="@+id/ name_edit_text " />
<Button
android:id ="@+id/ see_message_buttom "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:text =" @string / see_message " />
<TextView
android:id ="@+id/ show_message_text "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:layout_gravity =" center "
android:layout_marginTop ="20 dp"
android:text =" @string / hello_message "
android:textSize ="24 dp"
android:textStyle ="bold"
android:visibility =" invisible " />
</ LinearLayout >

O atributo android:visibility e utilizado para se ocultar um elemento. Seus possveis valores sao
visible (visvel), invisible (invisvel, mas ocupando espaco no layout) e gone (invisvel, mas nao
ocupando espaco).
Edite o arquivo strings.xml:
<?xml version ="1.0" encoding ="utf -8" ?>
<resources >
<string name=" app_name ">Exemplo </ string >
<string name=" name_label ">Nome :</ string >
<string name=" see_message ">Ver mensagem </ string >
<string name=" hello_message ">Ol
a , %1$s!</ string >
</ resources >

O valor %1$s para strings e utilizado para realizar a sua substituica o por alguma outra no decorrer
da execuca o.
Edite o arquivo MainActivity.java:
package com. projeto3 . android . testes1parte2 ;
import android .app. Activity ;
import android .os. Bundle ;

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

13

USANDO INTENTS

import android .view.View;


import android . widget .*;
public class MainActivity extends Activity

@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout . linear );
final EditText nameEditText =
( EditText ) findViewById (R.id. name_edit_text );
Button seeMessageButton =
( Button ) findViewById (R.id. see_message_buttom );
final TextView showMessageText =
( TextView ) findViewById (R.id. show_message_text );
seeMessageButton . setOnClickListener (new View. OnClickListener () {
@Override
public void onClick (View view) {
String name = nameEditText . getEditableText (). toString ();
showMessageText . setText ( getString (R. string . hello_message , name ));
showMessageText . setVisibility (View. VISIBLE );
}
});
}
}

Rode a aplicaca o e veja o resultado final.

Usando Intents
Intents sao objetos responsaveis por passar informacoes,

como se fossem mensagens, para os principais


componentes da API do Android, como as Activities, Services e BroadCast Receivers;
Para que um destes componentes seja instanciado, e necessario que seja criado um Intent, mesmo quando
nao temos nenhuma informaca o para passar para o componente criado;
Quando usado em conjunto com Intent Filters podemos ate iniciar uma Activity de outros aplicativo, ou
o inverso, deixar que um outro aplicativo inicie uma das nossas Activities.

5.1

Usando o Intent com Activities

Para iniciar uma nova Activity e necessario usar o metodo startActivity() presente no objeto Context, ou
na Activity;
Intent intent = new Intent (this , NewActivity .class );
startActivity ( intent );

No exemplo acima, estamos iniciando uma Activity cujo nome e NewActivity;


O primeiro parametro que passamos para o construtor do Intent e o contexto, no caso this se refere a`
propria
Activity atual, que esta chamando a proxima.

5.2

Intent - Exemplo 1

Crie um novo projeto Android, da mesma forma que no captulo anterior. Use como nome para o
projeto Testes2. O nome do pacote deve ser com.projeto3.android.testes2 e o nome da activity deve ser
MainActivity;
Liuri Loami Ruyz Jorge liuri.usp@gmail.com

14

USANDO INTENTS

Na paste res/layouts crie um arquivo chamado main.xml:


<?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:orientation =" vertical ">
<Button
android:id ="@+id/ main_button "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" @string / next_screen " />
</ LinearLayout >

O arquivo res/values/strings.xml deve ficar com o seguinte conteudo:

<?xml version ="1.0" encoding ="utf -8" ?>


<resources >
<string name=" app_name ">Intents </ string >
<string name=" next_screen ">Pr
o xima tela </ string >
</ resources >

O arquivo MainActivity.java deve ficar como o abaixo:


package com. projeto3 . android . testes2 ;
import
import
import
import
import
import

android .app. Activity ;


android . content . Intent ;
android .os. Bundle ;
android .view.View;
android .view.View. OnClickListener ;
android . widget . Button ;

public class MainActivity extends Activity {


@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main );
Button button = ( Button ) findViewById (R.id. main_button );
button . setOnClickListener (new OnClickListener () {
public void onClick (View v) {
Intent intent = new Intent ( MainActivity .this , SecondActivity . class );
startActivity ( intent );
}
});
}
}

Crie um arquivo XML na pasta layouts chamado second.xml com o conteudo


abaixo:

<?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:orientation =" vertical " >
<TextView
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" @string / second_screen " />
</ LinearLayout >

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

15

USANDO INTENTS

Adicione a seguinte linha no arquivo strings.xml:


<string name=" second_screen ">Nova tela </ string >

Crie uma nova classe chamada SecondActivity que herda Activity (para definir uma nova activity):
package com. projeto3 . android . testes2 ;
import android .app. Activity ;
import android .os. Bundle ;
import android . widget . EditText ;
public class SecondActivity extends Activity {
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout . second );
}
}

Os nomes das activities devem ser adicionados no arquivo AndroidManifest.xml, para isso adicione a
seguinte tag dentro da tag application:
<activity android:name =". SecondActivity " />

Apos
isso, rode a aplicaca o e veja o resultado.

5.3

Usando Intents para passar dados

No exerccio anterior, foi instanciada uma nova Activity, mas nao foi passada nenhuma informaca o para
ela. Isso pode ser feito utilizando o metodo putExtra do Intent.
Intent intent = new Intent (this , NewActivity . class );
intent . putExtra (" curso ", " Android ");
intent . putExtra (" total ", 25);

Este metodo tem overloading, logo podemos passar diferentes tipos;


Podemos passar tipos primitivos e Strings;
O primeiro parametro indica qual a chave que estamos usando para a informaca o. O segundo e o valor
da informaca o que estamos passando;
Do outro lado, na Activity que esta sendo criada, podemos obter os valores atraves do Bundle que pode
ser obtido a partir do metodo getExtras presente no Intent:
protected void onCreate ( Bundle savedInstanceState ) {
super. onCreate ( savedInstanceState );
setContentView (R. layout . some_layout );
Bundle extras = getIntent (). getExtras ();
String curso = extras . getString (" curso ");
int total = extras . getInt (" total ");
..
}

Um Bundle e um mapeamento de varios valores de tipos diferentes atraves de strings como chaves.

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

16

USANDO INTENTS

5.4

Intent - Exemplo 2

Edite o arquivo second.xml para:


<?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:orientation =" vertical " >
<TextView
android:id ="@+id/ name_label "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" @string /name" />
<EditText
android:id ="@+id/ name_edit_text "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:inputType =" textCapWords " />
<TextView
android:id ="@+id/ age_label "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" @string /age" />
<EditText
android:id ="@+id/ age_edit_text "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:inputType =" number " />
<Button
android:id ="@+id/ next_button "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" @string / next_screen " />
</ LinearLayout >

O arquivo res/values/strings.xml devera ficar com o seguinte conteudo:

<?xml version ="1.0" encoding ="utf -8" ?>


<resources >
<string name=" app_name ">Intents </ string >
<string name=" next_screen ">Proxima tela </ string >
<string name="name">Nome </ string >
<string name="age">Idade </ string >
<string name=" user_name ">Nome: %1s</ string >
<string name=" user_age ">Idade: %1s</ string >
</ resources >

A seguir, edite o arquivo SecondActivity.java:


package com. projeto3 . android . testes2 ;
import
import
import
import
import
import
import

android .app. Activity ;


android . content . Intent ;
android .os. Bundle ;
android .view.View;
android .view.View. OnClickListener ;
android . widget . Button ;
android . widget . EditText ;

public class SecondActivity extends Activity {


@Override

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

17

USANDO INTENTS

protected void onCreate ( Bundle savedInstanceState ) {


super . onCreate ( savedInstanceState );
setContentView (R. layout . second );
final EditText nameEditText =
( EditText ) findViewById (R.id. name_edit_text );
final EditText ageEditText =
( EditText ) findViewById (R.id. age_edit_text );
Button button = ( Button ) findViewById (R.id. next_button );
button . setOnClickListener (new OnClickListener () {
@Override
public void onClick (View v) {
String name = nameEditText . getEditableText (). toString ();
String age = ageEditText . getEditableText (). toString ();
Intent intent =
new Intent ( SecondActivity .this , ThirdActivity . class );
intent . putExtra ("name", name );
intent . putExtra ("age", age );
startActivity ( intent );
}
});
}
}

Crie um novo arquivo XML na pasta de layouts chamado third.xml:


<?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:orientation =" vertical " >
<TextView
android:id ="@+id/name"
android:layout_width =" match_parent "
android:layout_height =" wrap_content " />
<TextView
android:id ="@+id/age"
android:layout_width =" match_parent "
android:layout_height =" wrap_content " />
</ LinearLayout >

Adicione a seguinte entrada no arquivo strings.xml:


<string name=" second_screen ">Nova tela </ string >

Crie uma nova classe chamada ThirdActivity que herda Activity e possui o conteudo
abaixo:

package com. projeto3 . android . testes2 ;


import android .app. Activity ;
import android .os. Bundle ;
import android . widget . TextView ;
public class ThirdActivity extends Activity {
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout . third );

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

18

USANDO INTENTS

Bundle extras = getIntent (). getExtras ();


String name = extras . getString ("name");
String age = extras . getString ("age");
TextView nameTextEdit = ( TextView ) findViewById (R.id.name );
TextView ageTextEdit = ( TextView ) findViewById (R.id.age );
nameTextEdit . setText ( getString (R. string .user_name , name ));
ageTextEdit . setText ( getString (R. string .user_age , age ));
}
}

Adicione a nova activity no AndroidManifest.xml:


<activity android:name =". ThirdActivity " />

Apos
isso rode a aplicaca o e faca alguns testes.

5.5

Abrindo outros aplicativos

E possvel abrir outros aplicativos utilizando intents. Para isso, e necessario passar uma flag que chamamos de action;
Dependendo do tipo de action que passarmos, um novo aplicativo sera aberto para executar a aca o;
Este tipo de intent e chamado de implcito, porque nao e especificado qual a activity que sera aberta;
Apenas passamos uma aca o e o sistema decidira qual activity devera ser utilizada em cada caso.

5.6

Intent - Exemplo 3

Crie um novo projeto Android, da mesma forma que no captulo anterior. Use como nome para o projeto
Testes2Parte2. O nome do pacote deve ser com.projeto3.android.testes2parte2 e o nome da activity deve
ser MainActivity;
Na paste res/layouts crie um arquivo chamado main.xml:
<?xml version ="1.0" encoding ="utf -8" ?>
<LinearLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
xmlns:tools =" http: // schemas . android .com/ tools "
android:layout_width =" match_parent "
android:layout_height =" match_parent "
android:orientation =" vertical " >
<Button
android:id ="@+id/ view_site_button "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" @string / view_site_label " />
<Button
android:id ="@+id/ send_email_button "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" @string / send_email_label " />
<Button
android:id ="@+id/ make_call_button "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" @string / make_call_label " />
</ LinearLayout >

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

19

USANDO INTENTS

O arquivo strings.xml devera ficar como o abaixo:


<?xml version ="1.0" encoding ="utf -8" ?>
<resources >
<string name=" app_name ">Intents </ string >
<string name=" title_activity_main ">MainActivity </ string >
<string name=" view_site_label ">Ver site </ string >
<string name=" send_email_label ">Enviar email </ string >
<string name=" make_call_label ">Fazer ligac

a o </ string >


</ resources >

A seguir, edite o arquivo MainActivity.java:


package com. projeto3 . android . testes2 ;
import
import
import
import
import
import
import

android .app. Activity ;


android .os. Bundle ;
android .net.Uri;
android . content . Intent ;
android .view.View;
android .view.View. OnClickListener ;
android . widget . Button ;

public class MainActivity extends Activity {


@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout . main2 );
Button viewSiteButton = ( Button ) findViewById (R.id. view_site_button );
Button sendEmailButton = ( Button ) findViewById (R.id. send_email_button );
Button makeCallButton = ( Button ) findViewById (R.id. make_call_button );
viewSiteButton . setOnClickListener (new OnClickListener () {
@Override
void onCreate (View v) {
Intent intent =
new Intent ( Intent . ACTION_VIEW , Uri. parse ("http :// projeto3 .com");
startActivity ( intent );
}
});
sendEmailButton . setOnClickListener (new OnClickListener () {
@Override
void onCreate (View v) {
Intent intent = new Intent ( Intent . ACTION_SEND );
intent . setType (" plain /text");
intent . putExtra ( Intent . EXTRA_EMAIL ,
new String [] {" contato@projeto3 .com"});
startActivity ( Intent . createChooser (intent , " Enviar email "));
}
});
makeCallButton . setOnClickListener (new OnClickListener () {
@Override
void onCreate (View v) {
Intent intent = new Intent ( Intent . ACTION_DIAL ,
Uri. parse ("tel :1234 -5678 ");
startActivity ( intent );
}
});
}
}

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

20

PERSISTENCIA
DE DADOS

Apos
isso, adicione a seguinte linha dentro da tag <manifest> e fora da tag <application>, para permitir
que a aplicaca o realize chamadas:
<uses - permission android:name =" android . permission . CALL_PHONE " />

Persistencia de dados
A API do Android oferece diferentes opcoes
quando se trata de salvar dados para serem usados posteriormente;
Qual a opca o e mais apropriada depende do tipo de informaca o que sera salva e da disponibilidade que
queremos que ela tenha;
Existem 4 tipos de armazenamento possveis:
Shared Preferences:
E um tipo de armazenamento que utiliza chave/valor;
Indicado principalmente para configuracoes
e dados isolados;
SQLite:
Banco de dados privado que pode ser utilizado pelo seu aplicativo;
E o mais indicado quando temos varias informacoes
com a mesma estrutura, que podem ser
organizadas em tabelas e serem consultadas;
Internal Storage:
Armazena os dados na memoria
interna do aparelho;

Os dados armazenados sao privados da sua aplicaca o e nao podem ser acessados por outros
aplicativos ou pelo usuario;
External Storage:
Armazena em um SD, que pode ser externo ou interno do aparelho;
Os arquivos armazenados no SD sao visveis para todos;
O usuario pode alterar os arquivos quando conecta o USB a um computador.

6.1

Usando o SharedPreferences

Abaixo esta um exemplo de como utilizar o SharedPreferences para ler informacoes:

SharedPreferences prefs = getSharedPreferences (nome , modo );


String algumaString = prefs . getString (chave , null );
int algumInt = prefs . getInt ( outraChave , 0);

Voce obtem o SharedPreferences chamando o metodo getSharedPreferences, passando para ele uma string,
que sera a chave para indicar o SharedPreferences da sua aplicaca o;
O modo indica a permissao do SharedPreferences. Se passar 0, indica modo privado;
Para ler os dados, e so chamar o metodo get correspondente ao tipo de informaca o desejada. O segundo
parametro do metodo e o valor a ser retornado se a chave nao for encontrada;
O SharedPreferences so armazena tipos primitivos e Strings;
O segundo parametro do metodo get indica o valor a ser retornado caso a chave nao seja encontrada;
Para salvar os dados no SharedPreferences e necessario usar um editor. Veja o exemplo abaixo:

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

21

PERSISTENCIA
DE DADOS

SharedPreferences prefs = getSharedPreferences (nome , modo );


Editor editor = prefis .edit;
editor . putString (" curso "," Android ");
editor . commit ();

Obtemos o editor chamando o metodo edit();


Adicionamos informacoes
chamando o metodo put() correspondente ao tipo que estamos armazenando;
E necessario chamar o metodo commit() no final, senao as alteracoes
nao serao salvas.

6.2

Persistencia - Exemplo 1

Crie um novo projeto Android. Use como o nome do projeto Testes3. O nome do pacote deve ser
com.projeto3.android.testes3 e o nome da activity deve ser MainActivity;
Na pasta res/layouts crie um arquivo chamado main.xml:
<?xml version ="1.0" encoding ="utf -8" ?>
<RelativeLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
xmlns:tools =" http: // schemas . android .com/ tools "
android:layout_width =" match_parent "
android:layout_height =" match_parent " >
<TextView
android:id ="@+id/ welcome_message "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_centerHorizontal ="true"
android:layout_centerVertical ="true" />
<Button
android:id ="@+id/ add_name_button "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_below ="@id/ welcome_message "
android:layout_centerHorizontal ="true" />
</ RelativeLayout >

Edite o arquivo /res/values/strings.xml:


<?xml version ="1.0" encoding ="utf -8" ?>
<resources >
<string name=" app_name ">SharedPrefs </ string >
<string name= title_activity_main ">MainActivity </ string >
<string name=" type_your_name ">Digite o seu nome </ string >
<string name="save">Salvar </ string >
</resources >

A seguir, edite o arquivo MainActivity.java:


package com. projeto3 . android . testes3 ;
import
import
import
import
import
import
import
import

android .app. Activity ;


android . content . Intent ;
android . content . SharedPreferences ;
android .os. Bundle ;
android .view.View;
android .view.View. OnClickListener ;
android . widget . Button ;
android . widget . TextView ;

public class MainActivity extends Activity {


final static String APP_PREFS = " app_prefs ";
final static String USERNAME_KEY = " username ";

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

22

PERSISTENCIA
DE DADOS

@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main );
}
@Override
protected void onResume () {
super . onResume ();
SharedPreferences prefs = getSharedPreferences (APP_PREFS , MODE_PRIVATE );
String username = prefs . getString ( USERNAME_KEY , null );
TextView message = ( TextView ) findViewById (R.id. welcome_message );
Button addNameButton = ( Button ) findViewById (R.id. add_name_button );
if ( username != null) {
message . setText ("Bem vindo , " + username + "!");
addNameButton . setText (" Trocar de Nome");
} else {
message . setText ("Voc
e n
a o cadastrou seu nome ..");
addNameButton . setText (" Adicionar nome");
}
addNameButton . setOnClickListener (new OnClickListener () {
@Override
public void onClick (View v) {
Intent intent = new Intent ( MainActivity .this , AddNameActivity . class );
startActivity ( intent );
}
});
}
}

Crie um novo arquivo na pasta layouts chamado add name.xml:


<?xml version ="1.0" encoding ="utf -8" ?>
<RelativeLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
android:layout_width =" match_parent "
android:layout_height =" match_parent " >
<EditText
android:id ="@+id/ name_edit_text "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:inputType =" textCapWords "
android:hint =" @string / type_your_name "
android:layout_centerHorizontal ="true"
android:layout_marginTop ="20 dp" />
<Button
android:id ="@+id/ add_name_button "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_below ="@id/ name_edit_text "
android:layout_centerHorizontal ="true"
android:layout_marginTop ="20 dp"
android:text =" @string /save" />
</ RelativeLayout >

O atributo android:inputType especifica qual o tipo de entrada que o campo de texto aceitara. O
valor textCapWords e um texto normal com a inicial de todas as palavras maiusculas.

Crie uma nova classe chamada AddNameActivity que herda Activity e possui o conteudo
abaixo:

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

23

PERSISTENCIA
DE DADOS

package com. projeto3 . android . testes3 ;


import
import
import
import
import
import
import
import

android .app. Activity ;


android .os. Bundle ;
android . content . SharedPreferences ;
android . content . SharedPreferences . Editor ;
android .view.View;
android .view.View. OnClickListener ;
android . widget . Button ;
android . widget . EditText ;

public class AddNameActivity extends Activity {


private SharedPreferences prefs ;
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout . add_name );
prefs = getSharedPreferences ( MainActivity .APP_PREFS , MODE_PRIVATE );
final EditText name = ( EditText ) findViewById (R.id. name_edit_text );
Button saveButton = ( Button ) findViewById (R.id. add_name_button );
saveButton . setOnClickListener (new OnClickListener () {
@Override
public void onClick (View v) {
String username = name. getEditableText (). toString ();
Editor editor = prefs . editor ();
editor . putString ( MainActivity . USERNAME_KEY , username );
editor . commit ();
finish ();
}
});
}
}

O metodo finish() encerra a Activity.


Adicione as activities no AndroidManifest e teste a aplicaca o.
PAREI DE CORRIGIR AQUI!!

6.3

Usando o SQLite

O SQLite e um banco de dados bem simples que consome poucos recursos, bastante usado em dispositivos
embarcados;
Para utilizar o SQLite, e necessario que voce crie uma subclasse de SQLiteOpenHelper;
Em seguida e necessario sobrescrever os metodos OnCreate() e OnUpgrade();
O metodo OnCreate() e chamado quando ainda nao existe um banco de dados, nele voce deve incluir os
comandos para criar tabelas e inicializar qualquer tipo de dados, se preciso;
O metodo OnUpgrade() e chamado quando a versao da base de dados e alterada, e nele voce deve incluir
quaisquer comandos relacionados a` alteraca o do esquema, como alteracoes
em tabelas e colunas;
O SQLiteOpenHelper oferece dois metodos que serao muito usados, o getWritableDatabase() e getReadableDatabase();
Estes metodos retornam uma instancia de SQLiteDatabase, que e utilizada para fazer consultas aos
dados;
Liuri Loami Ruyz Jorge liuri.usp@gmail.com

24

PERSISTENCIA
DE DADOS

Os metodos que sao usados para as consultas aos dados sao insert(), update() e delete();
Tambem sao usados os metodos query() e rawQuery(). O primeiro oferece uma interface para criar
consultas, enquanto o segundo permite utilizar SQL diretamente;
O resultado de uma consulta e um objeto do tipo Cursor, que permite iterar sobre os dados.

6.4

SQLite - Exemplo 1

Crie um novo projeto Android. Use como nome para o projeto Testes4. O nome do pacote deve ser
com.projeto3.android.testes4 e o nome da activity deve ser MainActivity;
Na pasta res/layouts crie um arquivo main.xml:
<?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:orientation =" vertical ">
<ListView
android:id =" @android:id /list"
android:layout_width =" match_parent "
android:layout_height =" wrap_content " />
<TextView
android:id =" @android:id / empty "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text =" @string / no_notes " />
</ LinearLayout >

O arquivo res/values/strings.xml deve ficar igual ao abaixo:


<?xml version ="1.0" encoding ="utf -8" ?>
<resources >
<string name=" app_name ">SQLite </ string >
<string name=" title_activity_main ">MainActivity </ string >
<string name="add">Adicionar </ string >
<string name=" no_notes ">Nenhuma anotac

a o </ string >


<string name=" write_a_note ">Escreva uma anotac

a o </ string >


<string name="save">Salvar </ string >
</ resources >

Crie uma nova classe chamada CustomSQLiteOpenHelper com o seguinte conteudo:

package com. projeto3 . android . testes4 ;


import android . content . Context ;
import android . database . sqlite . SQLiteDatabase ;
import android . database . sqlite . SQLiteOpenHelper ;
public class CustomSQLiteOpenHelper extends SQLiteOpenHelper {
public static final String TABLE_NOTES = " notes ";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_NOTES = " _note ";
private static final String DATABASE_NAME = " notes .db";
private static final int DATABASE_VERSION = 1;
// Database creation sql statement
private static final String DATABASE_CREATE =
" create table " + TABLE_NOTES + "(" + COLUMN_ID
+ " integer primary key autoincrement , "

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

25

PERSISTENCIA
DE DADOS

+ COLUMN_NOTES + " text not null );";


public CustomSQLiteOpenHelper ( Context context ) {
super (context , DATABASE_NAME , null , DATABASE_VERSION );
}
@Override
public void onCreate ( SQLiteDatabase database ) {
database . execSQL ( DATABASE_CREATE );
}
@Override
public void onUpgrade ( SQLiteDatabase database ,
int oldVersion , int newVersion ) {
database . execSQL ("DROP TABLE IF EXISTS " + TABLE_NOTES );
onCreate ( database );
}
}

Crie uma classe Note com o seguinte conteudo:

package com. projeto3 . android . testes4 ;


public class Note {
private long id;
private String note;
@Override
public String toString () {
return note;
}
public long getId () {
return id;
}
public void setId (long id) {
this.id = id;
}
public String getNote () {
return note;
}
public void setNote ( String note) {
this.note = note;
}
}

Crie uma classe chamada NotesDao com o seguinte conteudo:

package com. projeto3 . android . testes4 ;


import java.util. ArrayList ;
import java.util.List;
import
import
import
import
import

android . content . ContentValues ;


android . content . Context ;
android . database . Cursor ;
android . database . SQLException ;
android . database . sqlite . SQLiteDatabase ;

public class NotesDao {


private SQLiteDatabase database ;
private String [] columns = { CustomSQLiteOpenHelper .COLUMN_ID ,
CustomSQLiteOpenHelper . COLUMN_NOTES };

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

26

PERSISTENCIA
DE DADOS

private CustomSQLiteOpenHelper sqliteOpenHelper ;


public NotesDao ( Context context ) {
sqliteOpenHelper = new CustomSQLiteOpenHelper ( context );
}
public void open () throws SQLException {
database = sqliteOpenHelper . getWritableDatabase ();
}
public void close () {
sqliteOpenHelper . close ();
}
public Note create ( String note) {
ContentValues values = new ContentValues ();
values .put( CustomSQLiteOpenHelper . COLUMN_NOTES , note );
long insertId = database . insert ( CustomSQLiteOpenHelper . TABLE_NOTES ,
null , values );
Cursor cursor = database . query ( CustomSQLiteOpenHelper . TABLE_NOTES ,
columns , CustomSQLiteOpenHelper . COLUMN_ID
+ " = " + insertId , null , null , null , null );
cursor . moveToFirst ();
Note newNote = new Note ();
newNote . setId ( cursor . getLong (0));
newNote . setNote ( cursor . getString (1));
cursor . close ();
return newNote ;
}
public void delete (Note note) {
long id = note. getId ();
database . delete ( CustomSQLiteOpenHelper . TABLE_NOTES ,
CustomSQLiteOpenHelper . COLUMN_ID + " = " + id , null );
}
public List <Note > getAll () {
List <Note > notes = new ArrayList <Note >();
Cursor cursor = database . query ( CustomSQLiteOpenHelper . TABLE_NOTES ,
columns , null , null , null , null , null );
cursor . moveToFirst ();
while (! cursor . isAfterLast ()) {
Note note = new Note ();
note. setId ( cursor . getLong (0));
note. setNote ( cursor . getString (1));
notes .add(note );
cursor . moveToNext ();
}
cursor . close ();
return notes ;
}
}

Edite o arquivo res/menu/main.xml (ou crie um, se nao existir). Deixe-o com o conteudo
abaixo:

<menu xmlns:android =" http: // schemas . android .com/apk/res/ android ">


<item android:id ="@+id/ add_note "
android:title =" @string /add"
android:showAsAction =" ifRoom " />
</menu >

A seguir edite o conteudo


do arquivo MainActivity.java:

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

27

PERSISTENCIA
DE DADOS

package com. projeto3 . android . testes4 ;


import java.util.List;
import
import
import
import
import
import

android .app. ListActivity ;


android . content . Intent ;
android .os. Bundle ;
android .view.Menu;
android .view. MenuItem ;
android . widget . ArrayAdapter ;

public class MainActivity extends ListActivity {


private NotesDao dao;
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main );
dao = new NotesDao (this );
dao.open ();
}
@Override
protected void onResume () {
dao.open ();
super . onResume ();
List <Note > notes = dao. getAll ();
ArrayAdapter <Note > adapter =
new ArrayAdapter <Note >(this ,
android .R. layout . simple_list_item_1 , notes );
setListAdapter ( adapter );
}
@Override
protected void onPause () {
dao. close ();
super . onPause ();
}
@Override
public boolean onCreateOptionsMenu (Menu menu) {
getMenuInflater (). inflate (R.menu.main , menu );
return true;
}
@Override
public boolean onOptionsItemSelected ( MenuItem item) {
if (item. getItemId () == R.id. add_note ) {
Intent intent = new Intent (this , AddNoteActivity . class );
startActivity ( intent );
}
return super . onOptionsItemSelected (item );
}
}

Crie um novo arquivo na pasta layouts chamado add note.xml:


<?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:orientation =" vertical " >
<EditText
android:id ="@+id/ note_text "
android:layout_width =" match_parent "

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

28

PERSISTENCIA
DE DADOS

android:layout_height =" wrap_content "


android:inputType =" textMultiLine "
android:hint =" @string / write_a_note " />
<Button
android:id ="@+id/ save_note_button "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:hint =" @string /save" />
</ LinearLayout >

Crie uma nova classe chamada AddNoteActivity:


package com. projeto3 . android . testes4 ;
import
import
import
import
import
import

android .app. Activity ;


android .os. Bundle ;
android .view.View;
android .view.View. OnClickListener ;
android . widget . Button ;
android . widget . EditText ;

public class AddNoteActivity extends Activity {


private NotesDao dao;
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout . add_note );
dao = new NotesDao (this );
dao.open ();
Button saveButton = ( Button ) findViewById (R.id. save_note_button );
final EditText noteText = ( EditText ) findViewById (R.id. note_text );
saveButton . setOnClickListener (new OnClickListener () {
@Override
public void onClick (View v) {
String note = noteText . getEditableText (). toString ();
dao. create (note );
finish ();
}
});
}
@Override
protected void onResume () {
dao.open ();
super . onResume ();
}
@Override
protected void onPause () {
dao. close ();
super . onPause ();
}
}

Lembre-se de adicionar os nomes as activities no AndroidManifest.xml;


Rode a aplicaca o e veja os resultados.

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

29

HTTP E JSON

HTTP e JSON
E muito comum um aplicativo fazer requisicoes
HTTP para fazer consultas a webservices;
Dessa forma, um aplicativo pode integrar ate diferentes servicos em uma unica

interface.

7.1

HTTP

Para fazer requisicoes


HTTP, a API do Android oferece duas alternativas (ambas nao mais recomendadas):
A primeira e utilizando a classe DefaultHttpClient, do projeto Apache;
Tambem existe a classe AndroidHttpClient que e um subtipo do DefaultHttpClient ja configurado
para valores otimizados no Android.
O metodo recomendado e utilizar a classe HttpURLConnection, que e desenvolvido e suportado pelo
Google.
URL url = new URL("http :// www. android .com/");
// Exemplo de URL para ser acessada
HttpURLConnection urlConnection = ( HttpURLConnection ) url. openConnection ();
try {
InputStream in = new BufferedInputStream ( urlConnection . getInputStream ());
// Leitura dos dados aqui ..
} finally {
urlConnection . disconnect ();
}

7.2

JSON

JSON ganhou muita forca nos ultimos


anos como o formato mais utilizado no retorno de webservices,

devido a sua simplicidade em comparaca o com XML;


O Android possui bibliotecas padrao para lidar com JSON;
Existem duas classes que sao utilizadas com este proposito,
JSONObject e JSONArray. A primeira serve

para lidar com um objeto em JSON, enquanto a segunda e usada em arrays de objetos JSON.
JSONObject json = new JSONObject ( jsonString );
try {
String campo1 = json. getString (" campoObrigatorio ");
String campo2 = json. optString (" campoOpcional ", null );
JSONObject objeto = json. getJSONObject (" objetoAninhado ");
} catch ( JSONException e) {
e. printStackTrace ();
}

7.3

HTTP e JSON - Exemplo 1

Crie um novo projeto Android. Use como nome para o projeto Testes5. O nome do pacote deve ser
com.projeto3.android.testes5, e o nome da activity deve ser MainActivity;
Na pasta res/layouts crie um arquivo chamado main.xml. Ele deve conter o seguinte conteudo:

<?xml version ="1.0" encoding ="utf -8" ?>


<LinearLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
xmlns:tools =" http: // schemas . android .com/ tools "
android:layout_width =" match_parent "
android:layout_height =" match_parent "
android:orientation =" vertical "
android:padding ="16 dp"
android:background ="# FFCCCC " >

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

30

HTTP E JSON

<TextView
android:id ="@+id/ name_label "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:textSize ="20 dp"
android:textColor ="#064 E83"
android:paddingBottom ="8dp"
android:textStyle ="bold" />
<TextView
android:id ="@+id/ address_label "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:textColor ="#6 C6C6C " />
<TextView
android:id ="@+id/ city_label "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:textColor ="#6 C6C6C " />
<TextView
android:id ="@+id/ phone_label "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:textColor ="#6 C6C6C " />
<TextView
android:id ="@+id/ likes_label "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:textColor ="#6 C6C6C " />
</ LinearLayout >

O arquivo res/values/strings.xml devera ficar igual ao abaixo:


<?xml version ="1.0" encoding ="utf -8" ?>
<resources >
<string name=" app_name ">HttpAndJson </ string >
<string name=" title_activity_main ">HttpAndJson </ string >
<string name=" name_label ">Telefone: %1$s</ string >
<string name=" address_label ">Telefone: %1$s</ string >
<string name=" city_label ">Telefone: %1$s</ string >
<string name=" phone_label ">Telefone: %1$s</ string >
<string name=" likes_label ">Telefone: %1$s</ string >
</ resources >

Crie uma classe chamada MainActivity:


package com. projeto3 . android . testes5 ;
import
import
import
import
import
import

java.io. BufferedReader ;
java.io. IOException ;
java.io. InputStream ;
java.io. InputStreamReader ;
java.net. HttpURLConnection ;
java.net.URL;

import org.json. JSONException ;


import org.json. JSONObject ;
import
import
import
import
import

android .app. Activity ;


android .os. Bundle ;
android .os. StrictMode ;
android .view.Menu;
android . widget . TextView ;

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

31

HTTP E JSON

public class MainActivity extends Activity {


@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main );
TextView
TextView
TextView
TextView
TextView

nameText = ( TextView ) findViewById (R.id. name_label );


phoneText = ( TextView ) findViewById (R.id. phone_label );
addressText = ( TextView ) findViewById (R.id. address_label );
cityText = ( TextView ) findViewById (R.id. city_label );
likesText = ( TextView ) findViewById (R.id. likes_label );

StrictMode . ThreadPolicy policy = new StrictMode . ThreadPolicy . Builder ().


permitAll (). build ();
StrictMode . setThreadPolicy ( policy );
String response = makeRequest ("http :// graph . facebook .com/ vovozuzu ");
try {
JSONObject json = new JSONObject ( response );
String name = json. getString ("name");
String phone = json. getString (" phone ");
int likes = json. getInt (" likes ");
String address = json. getJSONObject (" location "). getString (" street ");
String city = json. getJSONObject (" location "). getString ("city");
nameText . setText (name );
phoneText . setText ( getString (R. string . phone_label , phone ));
addressText . setText ( getString (R. string . address_label , address ));
cityText . setText ( getString (R. string . city_label , city ));
likesText . setText ( getString (R. string . likes_label , likes ));
} catch ( JSONException e) {
e. printStackTrace ();
}
}
private String makeRequest ( String urlAddress ) {
HttpURLConnection con = null;
URL url = null;
String response = null;
try {
url = new URL( urlAddress );
con = ( HttpURLConnection ) url. openConnection ();
response = readStream (con. getInputStream ());
} catch ( Exception e) {
e. printStackTrace ();
} finally {
con. disconnect ();
}
return response ;
}
private String readStream ( InputStream in) {
BufferedReader reader = null;
StringBuilder builder = new StringBuilder ();
try {
reader = new BufferedReader (new InputStreamReader (in ));
String line = null;
while (( line = reader . readLine ()) != null) {
builder . append (line + "\n");
}
} catch ( IOException e) {
e. printStackTrace ();
} finally {
if ( reader != null) {
try {
reader . close ();

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

32

HTTP E JSON

} catch ( IOException e) {
e. printStackTrace ();
}
}
}
return builder . toString ();
}
}

OBS: Se ocorrer algum erro com as linhas iniciadas por StrictMode.., a versao mnima do SDK devera
ser alterada para uma mais recente (mnimo SDK 9);
Adicione permissao para internet no AndroidManifest.xml adicionando a seguinte linha:
<uses - permission android:name =" android . permission . INTERNET "/>

Rode a aplicaca o e veja o resultado.

7.4

HTTP e JSON - Exemplo 2

Ainda utilizando o projeto anterior..


Na pasta res/values crie um arquivo chamado colors.xml:
<?xml version ="1.0" encoding ="utf -8" ?>
<resources >
<color name=" light_red "># FFCCCC </ color >
<color name="blue">#064 E83 </ color >
<color name="gray">#6 C6C6C </ color >
</ resources >

Na pasta res/values crie um arquivo chamado dimens.xml:


<?xml version ="1.0" encoding ="utf -8" ?>
<resources >
<dimen name=" padding_small ">8dp </ dimen >
<dimen name=" padding_medium ">8dp </ dimen >
<dimen name=" padding_large ">16 dp </ dimen >
<dimen name=" title_size ">20 dp </ dimen >
</ resources >

Edite novamente o arquivo main.xml nas linhas marcadas abaixo:


<?xml version ="1.0" encoding ="utf -8" ?>
<LinearLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
xmlns:tools =" http: // schemas . android .com/ tools "
android:layout_width =" match_parent "
android:layout_width =" match_parent "
android:orientation =" vertical "
android:padding =" @dimen / padding_large "
<!-- Edite aqui -->
android:background =" @color / light_red " >
<!-- Edite aqui -->
<TextView
android:id ="@+id/ name_label "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:textSize =" @dimen / title_size "
android:textColor =" @color /blue"
android:paddingButtom =" @dimen / padding_medium "
android:textStyle ="bold" />
<TextView
android:id ="@+id/ address_label "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:textColor =" @color /gray" />

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

<!-- Edite aqui -->


<!-- Edite aqui -->
<!-- Edite aqui -->

<!-- Edite aqui -->

33

THREADS E ASYNCTASKS

<TextView
android:id ="@+id/ city_label "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:textColor =" @color /gray" />

<!-- Edite aqui -->

<TextView
android:id ="@+id/ phone_label "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:textColor =" @color /gray" />

<!-- Edite aqui -->

<TextView
android:id ="@+id/ likes_label "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:textColor =" @color /gray" />

<!-- Edite aqui -->

</ LinearLayout >

Rode a aplicaca o. O resultado devera ser o mesmo.

Threads e AsyncTasks
No Android, existe uma thread principal que e responsavel por desenhar a tela e lidar com os eventos
de toque na tela;
Esta thread e conhecida como UI thread (User Interface Thread), ou tambem como main thread;
Se o desenvolvedor nao utilizar nenhum tipo de concorrencia, todo o codigo
que escrever ira rodar nesta

thread principal;
Isso se torna um problema para tarefas que levam muito tempo a serem executadas, pois enquanto a
tarefa esta sendo executada, a interface para de responder a eventos, como toques feito pelo usuario;
Se houver qualquer processamento que ocupe a UI thread por mais de 5 segundos, a aplicaca o ira receber
automaticamente um ANR (Application not responding), e o sistema ira fechar a aplicaca o;
Por isso, qualquer processamento mais lento deve ser feito em outras threads para nao ocupar a UI thread.

8.1

Threads e Handlers

No Android e suportado o mesmo tipo de concorrencia dos demais aplicativos Java;


Podemos utilizar threads, que executam objetos do tipo Runnable;
O unico
porem, e que nao podemos alterar nada relativo a UI dentro destas threads que rodam em

background;
Apenas a UI thread e que pode alterar a UI;
Para contornar esse problema podemos utilizar Handlers;
Um Handler e um objeto que possui o metodo post(Runnable). O Runnable que e passado ao metodo
post e executado posteriormente dentro da main thread e por isso pode realizar alteracoes
na interface
da aplicaca o;
Outra alternativa que nao envolve criar um Handler e utilizar o metodo runOnUiThread(Runnable), que
pertence a Activity. O Runnable que e passado a este metodo tambem e executado dentro da main thread.

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

34

THREADS E ASYNCTASKS

8.2

Threads e Handlers - Exemplo 1

Crie um novo projeto Android. Use como nome para o projeto Testes6. O nome do pacote deve ser
com.projeto3.android.testes6 e o nome da activity, MainActivity;
Na pasta res/layouts crie um arquivo chamado main.xml:
<?xml version ="1.0" encoding ="utf -8" ?>
<RelativeLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
android:layout_width =" match_parent "
android:layout_height =" match_parent " >
<ProgressBar
android:id ="@+id/ progress_bar "
style ="? android:attr / progressBarStyleHorizontal "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:layout_centerInParent ="true"
android:indeterminate =" false "
android:max ="10"
android:padding ="8dp" />
<Button
android:id ="@+id/ start_button "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_below ="@id/ progress_bar "
android:layout_centerHorizontal ="true"
android:text =" @string / start " />
</ RelativeLayout >

Edite o arquivo res/values/strings.xml:


<?xml version ="1.0" encoding ="utf -8" ?>
<resources >
<string name=" app_name ">Threads </ string >
<string name=" title_activity_main ">MainActivity </ string >
<string name=" start ">Iniciar </ string >
</ resources >

Edite o arquivo MainActivity.java:


package com. projeto3 . android . testes6 ;
import
import
import
import
import
import
import

android .app. Activity ;


android .os. Bundle ;
android .os. Handler ;
android .view.View;
android .view.View. OnClickListener ;
android . widget . Button ;
android . widget . ProgressBar ;

public class MainActivity extends Activity {


private Handler handler ;
private ProgressBar progress ;
private Button button ;
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main );
progress = ( ProgressBar ) findViewById (R.id. progress_bar );
startButton = ( Button ) findViewById (R.id. start_button );
handler = new Handler ;
startButton . setOnClickListener (new OnClickListener () {
Runnable runnable = new Runnable () {

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

35

THREADS E ASYNCTASKS

@Override
public void run () {
for (int i = 1; i <= 10; i++) {
final int value = i;
try {
Thread . sleep (1000);
} catch ( InterruptedException e) {
e. printStackTrace ();
}
handler .post(new Runnable () {
@Override
public void run () {
progress . setProgress ( value );
}
}
}
new Thread ( runnable ). start ();
}
});
}
}

Apos
isso rode a aplicaca o e veja o resultado.

8.3

Threads e Handlers - Exemplo 2

Ainda utilizando o projeto anterior..


Edite novamente o arquivo MainActivity.java:
package com. projeto3 . android . testes6 ;
import
import
import
import
import
import
import

android .app. Activity ;


android .os. Bundle ;
android .os. Handler ;
android .view.View;
android .view.View. OnClickListener ;
android . widget . Button ;
android . widget . ProgressBar ;

public class MainActivity extends Activity {


private ProgressBar progress ;
private Button button ;
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main );
progress = ( ProgressBar ) findViewById (R.id. progress_bar );
startButton = ( Button ) findViewById (R.id. start_button );
startButton . setOnClickListener (new OnClickListener () {
@Override
public void onClick (View v) {
Runnable runnable = new Runnable () {
@Override
public void run () {
for (int i = 1; i <= 10; i++) {
final int value = i;
try {
Thread . sleep (1000);
} catch ( InterruptedException e) {
e. printStackTrace ();
}
runOnUiThread (new Runnable () {
@Override

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

36

THREADS E ASYNCTASKS

public void run () {


progress . setProgress ( value );
}
});
}
}
};
new Thread ( runnable ). start ();
}
});
}
}

8.4

AsyncTasks

Outra alternativa para utilizar concorrencia no Android e utilizar AsyncTasks;


Um AsyncTask e um objeto que encapsula em uma interface simples o uso de threads;
Uma AsyncTask deve implementar obrigatoriamente o metodo doInBackground(), que exatamente a
tarefa que esta sendo executada em background;
Caso seja necessario alguma atualizaca o na interface, e so sobrescrever o metodo onPostExecute(). Tudo
que estiver dentro deste metodo e executado na UI thread;
Outro metodo interessante que pode ser sobrescrito e o metodo onPreExecute() que e executado antes
do doInBackground() e que tambem e executado na UI thread.

8.5

AskyncTasks - Exemplo 1

Crie um novo projeto Android. Use como nome para o projeto Testes7. O nome do pacote deve ser
com.projeto3.android.testes7 e o nome da activity, MainActivity;
Na pasta res/layouts crie um arquivo chamado main.xml:
<?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 =" wrap_content "
android:orientation =" vertical " >
<Button
android:id ="@+id/ start_button "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:onClick =" downloadPicture "
android:text =" @string / start_image_download " />
<ImageView
android:id ="@+id/ image_view "
android:layout_width =" match_parent "
android:layout_height =" match_parent " />
</ LinearLayout >

Edite o arquivo res/values/strings.xml:


<?xml version ="1.0" encoding ="utf -8" ?>
<resources >
<string name=" app_name ">AskyncTasks </ string >
<string name=" title_activity_main ">MainActivity </ string >
<string name=" start_image_download ">Iniciar download da imagem </ string >
<string name=" download ">Download </ string >
<string name=" downloading ">downloading </ string >
</ resources >

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

37

THREADS E ASYNCTASKS

Edite o arquivo MainActivity.java:


package com. projeto3 . android . testes7 ;
import
import
import
import
import

java.io. IOException ;
java.io. InputStream ;
java.net. HttpURLConnection ;
java.net. MalformedURLException ;
java.net.URL;

import
import
import
import
import
import
import
import
import
import

android .app. Activity ;


android .app. ProgressDialog ;
android . graphics . Bitmap ;
android . graphics . BitmapFactory ;
android .os. AsyncTask ;
android .os. Bundle ;
android .view.View;
android .view.View. OnClickListener ;
android . widget . Button ;
android . widget . ImageView ;

public class MainActivity extends Activity {


private
private
private
private

ProgressDialog dialog ;
Button startButton ;
ImageView imageView ;
DownloadImageTask task;

@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main );
imageView = ( ImageView ) findViewById (R.id. image_view );
startButton = ( Button ) findViewById (R.id. start_button );
startButton . setOnClickListener (new OnClickListener () {
@Override
public void onClick (View v) {
dialog = ProgressDialog .show( MainActivity .this ,
getString (R. string . download ), getString (R. string . downloading ));
task = new DownloadImageTask ();
task. execute (" https :// www. google .com/ images /srpr/ logo11w .png");
}
});
}
@Override
protected void onDestroy () {
if ( dialog != null && dialog . isShowing ()) {
dialog . dismiss ();
dialog = null;
}
if (task != null) {
task. cancel (true );
}
super . onDestroy ();
}
private class DownloadImageTask extends AsyncTask <String , Void , Bitmap > {
@Override
protected Bitmap doInBackground ( String ... params ) {
try {
return downloadBitmap ( params [0]);
} catch( IOException e) {
e. printStackTrace ();
}

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

38

SERVICES E BROADCASTRECEIVERS

return null;
}
@Override
protected void onPreExecute () {
super. onPreExecute ();
dialog .show ();
}
@Override
protected void onPostExecute ( Bitmap result ) {
super. onPostExecute ( result );
dialog . dismiss ();
if ( result != null) {
imageView . setImageBitmap ( result );
}
}
private Bitmap downloadBitmap ( String url) throws IOException {
URL imageUrl = null;
try {
imageUrl = new URL(url );
} catch ( MalformedURLException e) {
e. printStackTrace ();
return null;
}
Bitmap bitmapImage = null;
try {
HttpURLConnection conn = ( HttpURLConnection ) imageUrl . openConnection ();
conn. setDoInput (true );
conn. connect ();
InputStream is = conn. getInputStream ();
bitmapImage = BitmapFactory . decodeStream (is );
} catch ( IOException e) {
e. printStackTrace ();
}
return bitmapImage ;
}
}
}

Adicione permissao para internet no AndroidManifest.xml adicionando a seguinte linha:


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

Rode a aplicaca o e veja o resultado.

Services e BroadCastReceivers

9.1

Servicos

Servicos sao aplicacoes


que executam, em geral, processos longos em background desprovidos de
interface;
Uma aplicaca o, por exemplo, pode requisitar a um servico para fazer um download ou mesmo executar
uma musica
enquanto o usuario interage com a interface ou mesmo sai da aplicaca o host;

A aplicaca o e o Servico podem ainda se comunicar entre si;


Por padrao, um servico sempre e executado na Thread principal da aplicaca o host;
Porem, isto pode ser configurado para que o servico inicie outras threads quando e chamado evitando
assim que a interface trave durante uma execuca o que consuma muito processamento;

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

39

SERVICES E BROADCASTRECEIVERS

9.2

Manifest

Para criar um servico e preciso declarar o nome da classe no Manifest.


<manifest ... >
...
<application ... >
<service android:name =". ExemploDeServico " />
..
</ application .. >
</ manifest >

O servico pode ser utilizado por qualquer aplicaca o atraves de um Intent;


Se o servico a ser implementado for apenas util para a aplicaca o que o contem, entao e preciso explicitar
que o servico e privado no Manifest;
<manifest ... >
...
<application ... >
<service
android:name =". ExemploDeServico "
android:exported =" false " />
..
</ application .. >
</ manifest >

9.3

Classe Service

Para criar um servico e preciso implementar uma extensao da classe Service e sobreescrever alguns
metodos de callback:
onStartCommand() - Metodo que inicia um servico indefinidamente. O servico apenas termina
quando o metodo stopSelf() e executado a partir do proprio
servico ou quando o metodo stopSer
vice() e executado a partir de outra aplicaca o;
onBind() - Metodo que e chamado pelo sistema para associar o servico a uma aplicaca o. Ele
deve prover uma interface de comunicaca o entre ambos. Este metodo deve ser implementado
obrigatoriamente, logo, se o servico nao for desenhado para suportar Bind entao o metodo onBind
deve devolver null;
onCreate() - Metodo chamado pelo sistema no momento da criaca o do servico e pode ser utilizado
para realizar pre configuracoes;

onDestroy() - Metodo chamado pelo sistema quando o servico for destruido e pode ser utilizado
para liberar recursos utilizados.
Abaixo temos uma implementaca o simples de um servico:
public class ExampleService extends Service {
@Override
public void onCreate () {
// Metodo executado no momento em que o servic
o
e criado
}
@Override
public int onStartCommand ( Intent intent , int flags , int startId ) {
// Execuc

a o do servic
o ;
return START_STICKY ;
}
@Override
public IBinder onBind ( Intent intent ) {
// Sem suporte a bindind

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

40

SERVICES E BROADCASTRECEIVERS

return null;
}
@Override
public void onDestroy () {
// Metodo executado no momento em que o servic
o
e destruido
}
}

O metodo onStartCommand() devolve um inteiro. Este valor indica como o sistema deve continuar o
servico caso o sitema o mate. Existem 3 valores possveis:
START NOT STICKY - Nao reinicia o servico a menos que hajam Intents a serem entregues;
START STICKY - Reinicia o servico, mas nao continua a partir do Intent que estava em execuca o
mas apenas para os que estavam pendentes;
START REDELIVER INTENT - Reinicia o servico retomando a partir do Intent que estava em
execuca o.
A thread que executa o servico e a thread principal da aplicaca o host;
Caso o servico ocupe muito processamento e preciso que o servico utilize uma nova thread evitando
assim travamentos na interface;
No exemplo abaixo, a classe do servico foi modificada para executar sua tarefa em uma thread separada.
public class ExampleService extends Service {
private Looper mServiceLooper ;
private ServiceHandler mServiceHandler ;
// Handler que executa de fato a tarefa do servic
o em uma thread separada
private final class ServiceHandler extends Handler {
public ServiceHandler ( Looper looper ) {
super( looper );
}
@Override
public void handleMessage ( Message msg) {
// Implementac

a o da tarefa do servic
o
..
// Parando explicitamente o servic
o
stopSelf (msg.arg1 );
}
}

@Override
public void onCreate () {
// Criando a thread respons
a vel pela execuc

a o da tarefa
HandlerThread thread = new HandlerThread (" ServiceStartArguments ", Process . THREAD_PRIORITY_BACKGROUND );
thread . start ();
// Obtendo o Looper da thread e passando como par
a metro para o Handler
mServiceLooper = thread . getLooper ();
mServiceHandler = new ServiceHandler ( mServiceLooper );
}
@Override
public int onStartCommand ( Intent intent , int flags , int startId ) {
Toast . makeText (this , " service starting ", Toast . LENGTH_SHORT ). show ();
// Para cada chamada ao servic
o enfileiramos uma tarefa no Handler
Message msg = mServiceHandler . obtainMessage ();
msg.arg1 = startId ;
mServiceHandler . sendMessage (msg );

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

41

10

NOTIFICAC
OES

// Se o servic
o morrer a partir deste ponto , reinicializar
return START_STICKY ;
}
@Override
public IBinder onBind ( Intent intent ) {
// Sem suporte a Binding
return null;
}
@Override
public void onDestroy () {
Toast . makeText (this , " service done", Toast . LENGTH_SHORT ). show ();
}
}

10

Notificacoes

10.1

Dialogs

O metodo mais indicado para mostrar avisos ao usuario e usando dialogs;


Para criar um dialog no Android, cria-se uma classe estendendo a classe DialogFragment;
Ao criar uma subclasse de DialogFragment, deve-se sobreescrever os metodos onCreate() e onCreateView() para a criaca o de um dialogo customizado;
Outra opca o, para dialogos simples, e sobreescrever-se o metodo onCreateDialog().

10.2

Dialogs - Exemplo 1

Crie um novo projeto Android. Use como nome para o projeto Testes8. O nome do pacote deve ser
com.projeto3.android.testes8 e o nome da activity, MainActivity;
Na pasta res/layouts crie um arquivo chamado main.xml:
<?xml version ="1.0" encoding ="utf -8" ?>
<LinearLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
xmlns:tools =" http: // schemas . android .com/ tools "
android:layout_width =" match_parent "
android:layout_height =" match_parent "
android:orientation =" vertical " >
<Button
android:id ="@+id/ show_progress_dialog_button "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:padding ="5dp"
android:layout_margin ="8dp"
android:text =" @string / show_progress_dialog " />
<Button
android:id ="@+id/ show_alert_dialog_button "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:padding ="5dp"
android:layout_margin ="8dp"
android:text =" @string / show_alert_dialog " />
<Button
android:id ="@+id/ show_custom_dialog_button "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

42

10

NOTIFICAC
OES

android:padding ="5dp"
android:layout_margin ="8dp"
android:text =" @string / show_custom_dialog " />
</ LinearLayout >

Copie uma imagem para a pasta drawable-hdpi com o nome imagem.png;


Na pasta res/layouts crie um arquivo chamado custom dialog.xml com o seguinte conteudo:

<?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:orientation =" vertical " >
<ImageView
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:src =" @drawable / imagem "
android:layout_gravity =" center_horizontal "
android:padding ="8dp"
android:contentDescription =" @string /logo" />
</ LinearLayout >

O atributo android:contentDescription define um texto breve que resume o conteudo


do elemento.

O arquivo res/values/strings.xml devera ficar com o seguinte conteudo:

<?xml version ="1.0" encoding ="utf -8" ?>


<resources >
<string name=" app_name ">Notificac

o es </ string >


<string name=" title_activity_main ">MainActivity </ string >
<string name=" attention ">Atenc

a o </ string >


<string name=" which_button_gonna_press ">Qual bot
a o voc
e ir
a apertar ?</ string >
<string name="yes">Sim </ string >
<string name=" pressed_yes ">Pressionou sim </ string >
<string name="no">N
a o </ string >
<string name=" pressed_no ">Pressionou n
a o </ string >
<string name="wait">Aguarde ... </ string >
<string name=" studying ">Estudando ..! </ string >
<string name=" show_progress_dialog ">Mostrar Progress Dialog </ string >
<string name=" show_alert_dialog ">Mostrar Alert Dialog </ string >
<string name=" show_custom_dialog ">Mostrar Custom Dialog </ string >
<string name="logo">Logo </ string >
</ resources >

Edite o arquivo MainActivity.java com o seguinte conteudo:

package com. projeto3 . android . testes8 ;


import
import
import
import
import
import
import
import
import
import
import
import
import

android .app. Activity ;


android .app. AlertDialog ;
android .app. Dialog ;
android .app. DialogFragment ;
android .app. ProgressDialog ;
android . content . DialogInterface ;
android .os. Bundle ;
android .view. LayoutInflater ;
android .view.View;
android .view.View. OnClickListener ;
android .view. ViewGroup ;
android . widget . Button ;
android . widget . Toast ;

public class MainActivity extends Activity {

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

43

10

NOTIFICAC
OES

@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main );
Button progressButton = ( Button ) findViewById (R.id. show_progress_dialog_button );
Button alertButton = ( Button ) findViewById (R.id. show_alert_dialog_button );
Button customButton = ( Button ) findViewById (R.id. show_custom_dialog_button );
progressButton . setOnClickListener (new OnClickListener () {
@Override
public void onClick (View v) {
DialogFragment dialog = ProgressDialogFragment . newInstance ();
dialog .show( getFragmentManager (), " progress ");
}
});
alertButton . setOnClickListener (new OnClickListener () {
@Override
public void onClick (View v) {
DialogFragment dialog = AlertDialogFragment . newInstance ();
dialog .show( getFragmentManager (), " alert ");
}
});
customButton . setOnClickListener (new OnClickListener () {
@Override
public void onClick (View v) {
DialogFragment dialog = CustomDialogFragment . newInstance ();
dialog .show( getFragmentManager (), " custom ");
}
});
}
public static class AlertDialogFragment extends DialogFragment {
public static AlertDialogFragment newInstance () {
AlertDialogFragment frag = new AlertDialogFragment ();
return frag;
}
@Override
public Dialog onCreateDialog ( Bundle savedInstanceState ) {
AlertDialog dialog = new AlertDialog . Builder ( getActivity ()). create ();
dialog . setTitle ( getActivity (). getString (R. string . attention ));
dialog . setMessage ( getActivity (). getString (R. string . which_button_gonna_press ));
dialog . setButtom ( DialogInterface . BUTTON_POSITIVE ,
getActivity (). getString (R. string .yes), new DialogInterface . OnClickListener () {
@Override
public void onClick ( DialogInterface dialog , int which ) {
Toast . makeText ( getActivity (), R. string . pressed_yes ,
Toast . LENGTH_SHORT ). show ();
}
});
dialog . setButtom ( DialogInterface . BUTTON_NEGATIVE ,
getActivity (). getString (R. string .no), new DialogInterface . OnClickListener () {
@Override
public void onClick ( DialogInterface dialog , int which ) {
Toast . makeText ( getActivity (), R. string . pressed_no ,
Toast . LENGTH_SHORT ). show ();
}
});
return dialog ;
}
}
public static class ProgressDialogFragment extends DialogFragment {

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

44

10

NOTIFICAC
OES

public static ProgressDialogFragment newInstance () {


ProgressDialogFragment frag = new ProgressDialogFragment ();
return frag;
}
@Override
public Dialog onCreateDialog ( Bundle savedInstanceState ) {
Dialog dialog = new ProgressDialog ( getActivity ());
dialog . setTitle (R. string .wait );
return dialog ;
}
}
public static class CustomDialogFragment extends DialogFragment {
public static CustomDialogFragment newInstance () {
CustomDialogFragment frag = new CustomDialogFragment ();
return frag;
}
@Override
public void onCreate ( Bundle savedInstanceState ) {
super. onCreate ( savedInstanceState );
}
@Override
public View onCreateView ( LayoutInflater inflater , ViewGroup container , Bundle savedInstanceState ) {
View v = inflater . inflate (R. layout . custom_dialog , container , false );
getDialog (). setTitle (R. string . studying );
return v;
}
}
}

Rode a aplicaca o e veja o resultado.

10.3

Notifications

Outro tipo de notificaca o e conhecido como Status Bar Notifications, que sao aqueles alertas que aparecem
na barra de status;
Existem diversos tipos de alertas que podem ser criados, mas em todos os casos deve-se utilizar a classe
NotificationManager para enviar as notificacoes
para o sistema;
Para construir uma notificaca o, e utilizado o Notification.Builder() que possui diferentes metodos que
customizam o conteudo
e a aparencia da notificaca o.

10.4

Notifications - Exemplo 1

Crie um novo projeto Android. Use como nome para o projeto Testes9. O nome do pacote deve ser
com.projeto3.android.testes9 e o nome da activity, MainActivity;
Na pasta res/layouts crie um arquivo chamado main.xml:
<?xml version ="1.0" encoding ="utf -8" ?>
<RelativeLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
android:layout_width =" match_parent "
android:layout_height =" match_parent " >
<Button
android:id ="@+id/ create_notification_button "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:text =" @string / create_notification "

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

45

10

NOTIFICAC
OES

android:layout_centerInParent ="true" />


</ RelativeLayout >

Na pasta res/layouts crie um arquivo chamado notification.xml com o seguinte conteudo:

<?xml version ="1.0" encoding ="utf -8" ?>


<RelativeLayout xmlns:android =" http: // schemas . android .com/apk/res/ android "
android:layout_width =" match_parent "
android:layout_height =" match_parent " >
<TextView
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:layout_centerInParent ="true"
android:text =" @string / notification_activity_description "
android:gravity =" center_horizontal " />
</ RelativeLayout >

O arquivo res/values/strings.xml devera ficar com o seguinte conteudo:

<resources >
<string name=" app_name ">Notificac

o es </ strings >


<string name=" title_activity_main ">MainActivity </ strings >
<string name=" new_notification ">Nova notificac

a o </ strings >


<string name=" notification_content ">Conte
u do descrevendo a notificac

a o .</ strings >


<string name=" create_notification ">Criar notificac

a o </ strings >


<string name=" notification_activity_description ">Esta tela foi aberta a partir da notificac

a o .</ string >


</ resouces >

Crie um arquivo chamado NotificationActivity.java com o seguinte conteudo:

package com. projeto3 . android . testes9 ;


import com. projeto3 . android . testes9 ;
import android .app. Activity ;
import android .os. Bundle ;
public class NotificationActivity extends Activity {
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout . notification );
}
}

Edite o arquivo MainActivity.java com o seguinte conteudo:

package com. projeto3 . android . testes9 ;


import
import
import
import
import
import
import
import
import

android .app. Activity ;


android .app. Notification ;
android .app. NotificationManager ;
android .app. PendingIntent ;
android . content . Intent ;
android .os. Bundle ;
android .view.View;
android .view.View. onClickListener ;
android . widget . Button ;

public class MainActivity extends Activity {


@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main );

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

46

11

MAPAS E GPS

Button createNotification = ( Button ) findViewById (R.id. create_notification_button );


createNotification . setOnClickListener (new OnClickListener () {
@Override
public void onClick (View v) {
Intent intent = new Intent ( MainActivity .this , NotificationActivity . class );
PendingIntent pendingIntent = PendingIntent . getActivity ( MainActivity .this , 0, intent , 0);
Notification notification = new Notification . Builder ( MainActivity .this)
. setContentTitle ( getString (R. string . new_notification ))
. setContentText ( getString (R. string . notification_content ))
. setSmallIcon (R. drawable . ic_action_search )
. setContentIntent ( pendingIntent )
. getNotification ();
notification . flags |= Notification . FLAG_AUTO_CANCEL ;
NotificationManager notificationManager = ( NotificationManager )
getSystemService ( NOTIFICATION_SERVICE );
notificationManager . notify (0, notification );
}
});
}
}

Apos
isso rode a aplicaca o e veja o resultado.

11

Mapas e GPS
Uma das vantagens para o desenvolvimento de aplicativos para dispositivos moveis
e a possibilidade de

se usar a informaca o da localizaca o do usuario.

11.1

Utilizando o GPS

Para utilizar o GPS, e necessario utilizar a classe LocationManager;


Esta classe permite obter a localizaca o do usuario, registrar listeners de localizaca o, etc;
Para obter uma posica o, e necessario escolher um Location Provider. O provider define como a posica o
do usuario sera obtida:
Network: Utiliza as antenas de rede e Wi-Fi para determinar a posica o do usuario. E mais rapido
em geral do que o GPS, e funciona melhor em ambientes fechados tambem;
GPS: Utiliza o sistema de GPS do aparelho para determinar a posica o. A precisao nesse caso e
melhor do que utilizando network.
Para utilizar o GPS, e necessario incluir a permissao ACCESS FINE LOCATION. Para usar apenas a
rede e necessario incluir a permissao ACCESS COARSE LOCATION;
E possvel usar um objeto do tipo Criteria para auxiliar que tipo de provider sera utilizado;
Com este objeto definimos parametros como precisao, velocidade de resposta, etc, e ele se encarrega de
escolher o provider mais adequado.

11.2

GPS - Exemplo 1

Crie um novo projeto Android. Use como nome para o projeto Testes10. O nome do pacote deve ser
com.projeto3.android.testes10 e o nome da activity, MainActivity;
Na pasta res/layouts crie um arquivo chamado main.xml:
Liuri Loami Ruyz Jorge liuri.usp@gmail.com

47

11

MAPAS E GPS

<?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:orientation =" vertical " >
<LinearLayout
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:layout_marginTop ="40 dp"
android:orientation =" horizontal " >
<TextView
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_marginLeft ="10 dp"
android:layout_marginRight ="5dp"
android:text =" @string / latitude_label "
android:textSize ="20 dp" />
<TextView
android:id ="@+id/ latitude_text "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:text =" @string / unknown "
android:textSize ="20 dp" />
</ LinearLayout >
<LinearLayout
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:orientation =" horizontal " >
<TextView
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_marginLeft ="10 dp"
android:layout_marginRight ="5dp"
android:text =" @string / longitude_label "
android:textSize ="20 dp" />
<TextView
android:id ="@+id/ longitude_text "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:text =" @string / unknown "
android:textSize ="20 dp" />
</ LinearLayout >
</ LinearLayout >

Edite o arquivo AndroidManifest.xml. Ele devera conter o seguinte conteudo:

<?xml version ="1.0" encoding ="utf -8"?>


<manifest xmlns:android =" hhtp: // schemas . android .com/apk/res/ android "
package ="com. projeto3 . android . testes10 "
android:versionCode ="1"
android:versionName ="1.0" >
<uses -sdk
android:minSdkVersion ="9"
android:targetSdkVersion ="18" />
<!-- Acrescente essas 3 linhas -->
<uses - permission android:name =" android . permission . INTERNET " />
<uses - permission android:name =" android . permission . ACCESS_FINE_LOCATION " />
<uses - permission android:name =" android . permission . ACCESS_COARSE_LOCATION " />

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

48

11

MAPAS E GPS

<application
android:icon =" @drawable / ic_launcher "
android:label =" @string / app_name "
android:theme =" @style / AppTheme " >
<activity
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 >

O arquivo res/values/strings.xml devera ficar com o seguinte conteudo:

<resources >
<string name=" app_name ">LocationApi </ string >
<string name=" point_label ">%.4f</ string >
<string name=" location_not_available ">Local n
a o dispon
vel </ string >
<string name=" latitude_label ">Latitude: </ string >
<string name=" longitude_label ">Longitude: </ string >
<string name=" unknown ">desconhecido </ string >
</ resources >

Edite o arquivo MainActivity.java com o seguinte conteudo:

package com. projeto3 . android . testes10 ;


import
import
import
import
import
import
import
import
import
import

android .app. Activity ;


android . content . Context ;
android . location . Criteria ;
android . location . Location ;
android . location . LocationListener ;
android . location . LocationManager ;
android .os. Bundle ;
android .util.Log;
android . widget . TextView ;
android . widget . Toast ;

public class MainActivity extends Activity implements LocationListener {


private static final String TAG = " MainActivity ";
private
private
private
private

TextView latituteText ;
TextView longituteText ;
LocationManager locationManager ;
String provider ;

@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main );
latituteText = ( TextView ) findViewById (R.id. latitude_text );
longituteText = ( TextView ) findViewById (R.id. longitude_text );
locationManager = ( LocationManager ) getSystemService ( Context . LOCATION_SERVICE );
Criteria criteria = new Criteria ();
provider = locationManager . getBestProvider (criteria , false );
Location location = locationManager . getLastKnownLocation ( provider );
if ( location != null) {
Log.d(TAG , " Provider " + provider + " foi selecionado .");
onLocationChanged ( location )
} else {
latitudeText . setText (R. string . location_not_available );

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

49

11

MAPAS E GPS

longituteText . setText (R. string . location_not_available );


}
}
@Override
protected void onResume () {
super . onResume ();
locationManager . requestLocationUpdates (provider , 400 , 1, this );
}
@Override
protected void onPause () {
super . onPause ();
locationManager . removeUpdates (this );
}
@Override
public void onLocationChanged ( Location location ) {
double lat = location . getLatitude ();
double lng = location . getLongitude ();
latitudeText . setText ( getString (R. string . point_label , lat ));
longitudeText . setText ( getString (R. string . point_label , lng ));
}
@Override
public void onStatusChanged ( String provider , int status , Bundle extras ) {
}
@Override
public void onProviderEnabled ( String provider ) {
Toast . makeText (this , "Novo provider " + provider , Toast . LENGTH_SHORT ). show ();
}
@Override
public void onProviderDisabled ( String provider ) {
Toast . makeText (this , " Provider desabilitado " + provider , Toast . LENGTH_SHORT ). show ();
}
}

Rode novamente a aplicaca o e veja os resultados.

11.3

Usando o MapView

E possvel mostrar mapas na aplicaca o usando o MapView;


Para isso, e necessario utilizar um target com suporte a` Google APIs e incluir a seguinte tag no AndroidManifest.xml:
<uses - permission android:name =" android . permission . INTERNET " />

Tambem e necessario ter uma chave cadastrada no Google Maps API, para que a aplicaca o possa ter
acesso ao Maps API do Google.

11.4

MapView - Examplo

Crie um novo projeto Android. Use como nome para o projeto Testes11. O nome do pacote deve ser
com.projeto3.android.testes11 e o nome da activity, MainActivity;
Edite o arquivo AndroidManifest.xml e deixe-o com o seguinte conteudo:

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

50

11

MAPAS E GPS

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


package ="com. projeto3 . android . testes11 "
android:versionCode ="1"
android:versionName ="1.0" >
<uses -sdk
android:minSdkVersion ="8"
android:targetSdkVersion "15" />
<uses - permission android:name =" android . permission . INTERNET " />
<application
android:icon =" @drawable / ic_launcher "
android:label =" @string / app_name "
android:theme =" @style / AppTheme " >
<uses - library android:name ="com. google . android .maps" />
<activity
android:name =". MainActivity "
android:label =" @string / title_activity_main " >
<intent - filter >
<action android:name =" android . intent . action .MAIN" />
<category android:name =" android . intent . category . LAUNCHER " />
</intent - filter >
</ activity >
</ application >
</ manifest >

Crie um arquivo chamado CustomItemizedOverlay com o seguinte conteudo:

package com. projeto3 .com. testes11 ;


import java.util. ArrayList ;
import
import
import
import
import

android .app. AlertDialog ;


android .app. AlertDialog . Builder ;
android . content . Context ;
android . graphics . drawable . Drawable ;
android . widget . Toast ;

import com. google . android .maps. ItemizedOverlay ;


import com. google . android .maps. OverlayItem ;
public class CustomItemizedOverlay extends ItemizedOverlay < OverlayItem > {
private ArrayList < OverlayItem > mOverlays = new ArrayList < OverlayItem >();
private Context context ;
public CustomItemizedOverlay ( Context context , Drawable defaultMarker ) {
super ( boundCenterBottom ( defaultMarker ));
this. context = context ;
}
public void addOverlay ( OverlayItem overlay ) {
mOverlays .add( overlay );
}
@Override
protected OverlayItem createItem (int i) {
return mOverlays .get(i);
}
@Override
public int size () {
return mOverlays .size ();
}
protected boolean onTap (int index ) {

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

51

11

MAPAS E GPS

OverlayItem item = mOverlays .get( index );


AlertDialog . Builder dialog = new AlertDialog . Builder ( context );
dialog . setTitle (item. getTitle ());
dialog . setMessage (item. getSnippet ());
dialog .show ();
return true;
}
}

Insira uma imagem PNG na pasta res/drawable-hdpi com o nome logo.png;


Edite o arquivo main.xml:
<?xml version ="1.0" encoding ="utf -8" ?>
<com. google . android .maps. MapView xmlns:android =" http: // schemas . android .com/apk/res/ android "
android:id ="@+id/ mapview "
android:layout_width =" match_parent "
android:layout_height =" match_parent "
android:apiKey ="API KEY AQUI"
android:clickable ="true" />

Edite o arquivo MainActivity.java:


package com. projeto3 . android . testes11 ;
import java.util.List;
import
import
import
import
import
import

android . content . Context ;


android . graphics . drawable . Drawable ;
android . location . Location ;
android . location . LocationListener ;
android . location . LocationManager ;
android .os. Bundle ;

import
import
import
import
import
import
import

com. google . android .maps. GeoPoint ;


com. google . android .maps. MapActivity ;
com. google . android .maps. MapController ;
com. google . android .maps. MapView ;
com. google . android .maps. MyLocationOverlay ;
com. google . android .maps. Overlay ;
com. google . android .maps. OverlayItem ;

public class MainActivity extends MapActivity {


private
private
private
private

MapController mapController ;
MapView mapView ;
CustomItemizedOverlay itemizedOverlay ;
MyLocationOverlay myLocationOverlay ;

public void onCreate ( Bundle bundle ) {


super . onCreate ( bundle );
setContentView (R. layout .main );
mapView = ( MapView ) findViewById (R.id. mapview );
mapView . setBuiltInZoomControls (true );
mapView . setSatellite ( false );
mapController = mapView . getController ();
mapController . setZoom (14);
myLocationOverlay = new MyLocationOverlay (this , mapView );
mapView . getOverlays (). add( myLocationOverlay );
List <Overlay > mapOverlays = mapView . getOverlays ();
Drawable drawable = this. getResources (). getDrawable (R. drawable .logo );
itemizedOverlay = new CustomItemizedOverlay (this , drawable );
GeoPoint point = new GeoPoint ( -23570794 , -46690747);
OverlayItem overlayItem = new OverlayItem (point , " Projeto3 ", "Bla , bla , bla");

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

52

12

MULTIMEDIA

itemizedOverlay . addOverlay ( overlayItem );


mapOverlaysadd ( itemizedOverlay );
}
@Override
protected boolean isRouteDisplayed () {
return false ;
}
}

Rode a aplicaca o e veja o resultado.

12

Multimedia

12.1

Reproduca o de Mdia

O framework de multimedia do Android e capaz de reproduzid os tipos mais comuns de mdia;


Com ele, e possvel reproduzir a udio de vdeos puros ou codificados a partir do sistema de arquivos ou
mesmo atraves da internet;
Sao utilizadas duas classes para a reproduca o de mdia:
MediaPlayer - Principal classe de reproduca o de audio e vdeo;
AudioManager - Manipula as entradas e sadas de audio do dispositivo.
Dependendo das funcionalidades da aplicaca o, sera necessario modificar o AndroidManifest para habilitar as permissoes
necessarias:
Caso seja necessario utilizar o MediaPlayer como player de um stream atraves da internet, entao
deve-se adicionar a permissao de acesso a` internet:
<uses - permission android:name =" android . permission . INTERNET " />

Caso o player precise manter a tela sem esmaecer ou manter o processador sem entrar em modo
de economia de energia, entao e preciso adicionar a seguinte permissao para que os metodos
MediaPlayer.setScreenOnWhilePlaying() ou MediaPlayer.setWakeMode() sejam executados:
<uses - permission android:name =" android . permission . WAKE_LOCK " />

12.2

Utilizando o MediaPlayer

O MediaPlayer e um dos componentes de mdia mais importantes do framework do Android;


Uma instancia dessa classe e capaz de buscar, decodificar e reproduzir conteudos
de a udio e vdeo

exigindo pouca configuraca o;


Principais funcoes
da classe MediaPlayer:
MediaPlayer.setDataSource() - Seleciona a mdia (caminho do arquivo local ou remoto) a ser reproduzida;
MediaPlayer.prepare() - Prepara (decodifica, pre-armazena, etc) a mdia, transformando-a em a udio
puro pronto para ser reproduzido;
MediaPlayer.start() - Inicia a reproduca o do a udio;
MediaPlayer.pause() - Pausa a reproduca o do a udio;
MediaPlayer.stop() - Encerra a reproduca o do a udio;

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

53

12

MULTIMEDIA

mediaPlayer.setAudioStreamType() - Define o tipo de mdia que sera reproduzido. Para arquivos


de musica
passa-se como parametro a constante AudioManager.STREAM MUSIC.

Abaixo temos o trecho de um codigo


que reproduz um arquivo de a udio puro localizado em res/raw/.

Neste caso, utilizou-se como entrada o recurso de a udio da propria


aplicaca o:

MediaPlayer mediaPlayer = MediaPlayer . create (context , R.raw. arquivo_som_puro );


mediaPlayer . start ();

No caso acima, como o arquivo contem som puro, nao existe a necessidade de nenhuma preparaca o
(decodificaca o) para ser reproduzido. Contudo, serao raras as vezes em que o arquivo de a udio nao
estara codificado;
Para reproduzir os tipos mais comuns de arquivos de a udio, procede-se conforme o exemplo abaixo:
// Localizac

a o do arquivo de m
dia
URI myUri = Uri. parse (" localizacaoAqui ");
// Criando um Player
MediaPlayer mediaPlayer = new MediaPlayer ();
um arquivo de m
// Definindo que o tipo de stream e
u sica
mediaPlayer . setAudioStreamType ( AudioManager . STREAM_MUSIC );
// Fazendo com que o player encontre o arquivo de entrada
mediaPlayer . setDataSource ( getApplicationContext (), myUri );
// Preparando a m
u sica para ser reproduzida
mediaPlayer . prepare ();
// Iniciando a reproduc

ao
mediaPlayer . start ();

Liuri Loami Ruyz Jorge liuri.usp@gmail.com

54

You might also like