Você está na página 1de 44

Programação para a Plataforma Android – Aula 8

Comunicação entre A0vidades


• Como invocar uma a0vidade a par0r de outra?
• Como descrever um serviço em Android?
• Como duas a0vidades se comunicam?
• Como abrir uma página web no disposi0vo móvel?
• Como usar expressões regulares para extrair informação de texto?
• Como exibir listas de dados na tela do aparelho celular?
O Modelo Android
• O modelo de execução é composto por várias
a0vidades.
– Essas podem ser usadas como aplicações
independentes.
– Mas também ficam à disposição de outras
aplicações.
• Bem diferente de um sistema operacional
tradicional, em que cada processo não tem
qualquer vínculo com os outros.
Comunicação entre processos
• Quais aplica0vos um programa como o
MicrosoO Word pode chamar enquanto
executa?
– O MSWord pode chamar o Mozilla Firefox?
• Em Android um “aplica0vo” pode chamar
qualquer outro “aplica0vo”.
– Por que é possível essa integração em Android?
– Quais os beneVcios dessa integração?
Abrindo um Navegador
Escreva uma atividade
que possua uma caixa de
texto e um botão, e que,
tendo sido o botão
pressionado, invoque um
navegador para abrir a
URL que estiver escrita na
caixa de texto.
Layout da A0vidade
• Por agora, escrever esse layout deve ser
facinho, facinho:
Layout da A0vidade
c om o p o demos
E
invocar o
navegador a
a
partir de um
atividade?
caller.xml
<LinearLayout xmlns:android="h^p://schemas.android.com/apk/res/android"
android:id="@+id/root" android:orienta0on="ver0cal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
<Bu^on
android:id="@+id/bu^on1"
android:text="@string/okBu^onLabel"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
</LinearLayout>
Invocando o Navegador
CallerAc0vity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.caller);
((Bu^on) findViewById(R.id.bu^on1))
.setOnClickListener(new Bu^on.OnClickListener() {
public void onClick(View arg0) {
EditText t = (EditText) findViewById(R.id.text1);
String urlName = t.getText().toString();
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(urlName)); Para que
startAc@vity(intent); servem essas
} linhas de
}); código?
Permissões
• Por questões de segurança, alguns recursos do
aparelho são “privilegiados”.
– U0lizar esses recursos requer permissão.
– O canal de comunicação é um desses recursos.
– Permissões são asseguradas no manifesto
Manifesto
<?xml version="1.0" encoding="ur‐8"?>
<manifest
xmlns:android="h^p://schemas.android.com/apk/res/android"
package="com.aula8"
android:versionCode="1"
android:versionName="1.0">
<applica0on
android:icon="@drawable/icon"
android:label="@string/app_name">
...
</applica0on>
<uses‐permission
android:name="android.permission.INTERNET">
</uses‐permission>
</manifest>
Escolhendo uma A0vidade
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.caller);
((Bu^on) findViewById(R.id.bu^on1))
Existem várias
.setOnClickListener(new Bu^on.OnClickListener() {
atividades capazes
public void onClick(View
de lidar comarg0)
URLs.{
EditText t =Android
(EditText)nos
findViewById(R.id.text1);
mostra
String urlName todas elas.
= t.getText().toString();
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(urlName));
startAc0vity(intent);
}
});
Escolhendo uma A0vidade
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.caller);
((Bu^on) findViewById(R.id.bu^on1))
.setOnClickListener(new Bu^on.OnClickListener() {
public void onClick(View arg0) {
EditText t = (EditText) findViewById(R.id.text1);
String urlName = t.getText().toString();
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(urlName));
startAc0vity(intent);
}
});
A0vidades, Contextos, Intenções
• Activity é um processo que executa em
sua aplicação Android.
– Funciona como uma máquina de estados.
• Intent’s são os objetos usados para que
diferentes a0vidades possam comunicar‐se.
• Context é a classe pai de Ac0vity, e possui
métodos para passar Intents entre as
a0vidades.
Alguns métodos de Activity
• Intent getIntent()
– Esse método retorna a “intenção” com a qual a
a0vidade foi chamada. Uma a0vidade não
mantém vínculos diretos com a a0vidade que a
iniciou. Essa comunicação, em geral é feita via
Intents.
• setIntent(Intent)
– Usado para definir a intenção com a qual uma
a0vidade é chamada.
View Fonte
Escreva uma
atividade que
mostre na tela do s e r áo
Co m o
dispositivo o t d essa
lay o u
texto de uma o?
página web. aplicaçã
sourceview.xml ScrollView
<ScrollView
xmlns:android="h#p://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>

E como será a
atividade?
Visualizador de Fontes de HTML
TextViewAc0vity.java
import android.app.Ac0vity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class TextViewAc0vity extends Ac0vity {
private TextView text;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sourceview);
text = (TextView) findViewById(R.id.textView);
Intent intent = getIntent();
URL url = Useful.openPage(intent);
text.setText(Useful.htmlToString(url));
}
}
Visualizador de Fontes de HTML
TextViewAc0vity.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sourceview);
text = (TextView) findViewById(R.id.textView);
Intent intent = getIntent();
URL url = Useful.openPage(intent); O que esse
c o m a n d o faz?
text.setText(Useful.htmlToString(url));
}
E esse
Estamos comando, c
criando uma funciona?
omo
mini biblioteca
Abrindo uma página web
Useful.java m
Recursos e
o
public sta0c URL openPage(Intent intent) { Android sã
Uri data = intent.getData(); codificados
URL url = null; como URIs.
try {
url = new URL(data.getScheme(), data.getHost(), data.getPath());
} catch (MalformedURLExcep0on e) {
e.printStackTrace();
} E o host de
que
return url; O que é o uma URI, o
} esquema de é? E por últim
o, o
uma URI? que é esse
path?
Useful.java
Entendendo uma URI
public sta0c URL openPage(Intent intent) {
Uri data = intent.getData();
URL url = null;
try {
Log.v("Useful ‐ scheme", data.getScheme());
Log.v("Useful ‐ host", data.getHost());
Log.v("Useful ‐ path", data.getPath());
url = new URL(data.getScheme(), data.getHost(), data.getPath());
} catch (MalformedURLExcep0on e) {
e.printStackTrace();
} O que será
return url; impresso para
} a URI acima?
Useful.java
Entendendo uma URI
public sta0c URL openPage(Intent intent) {
Uri data = intent.getData();
URL url = null;
try {
Log.v("Useful ‐ scheme", data.getScheme());
Log.v("Useful ‐ host", data.getHost());
Log.v("Useful ‐ path", data.getPath());
url = new URL(data.getScheme(), data.getHost(), data.getPath());
} catch (MalformedURLExcep0on e) {
e.printStackTrace(); Ainda falta
} implementar
return url; htmlToString
}
10‐30 10:49:05.633: VERBOSE/ Useful ‐ scheme: h^p
10‐30 10:49:05.663: VERBOSE/ Useful ‐ host www.dcc.ufmg.br
10‐30 10:49:05.673: VERBOSE/ Useful ‐ path /~fpereira/links
Useful.java htmlToString O método anter
ior
public sta0c String htmlToString(URL url) { também possuia
String text = ""; tratamento de
BufferedReader rd = null; exceções. O que
é
try { isso?
rd = new BufferedReader
(new InputStreamReader(url.openStream()));
String line = null; Será que o
while ((line = rd.readLine()) != null) { programa compila
text += line; sem esse código de
} tratamento de
Como explic
} catch (IOExcep@on e) { ambien ar para o exceções?
te de
e.printStackTrace(); execução qu
e essa
} a t i vidade enten
de de
return text; e n d ereços web?
}
Useful.java Bibliotecas
A classe Useful
public sta0c String htmlToString(URL url) { é uma
String text = ""; biblioteca. O
BufferedReader rd = null; que é isso?
try {
rd = new BufferedReader Qual a diferen
ça
(new InputStreamReader(url.openStream())); de bibliotecas
para
String line = null;
arcabouços?
while ((line = rd.readLine()) != null) {
text += line;
} Que outras
} catch (IOExcep0on e) { bibliotecas nós
e.printStackTrace(); conhecemos?
}
return text;
}
Manifesto
manifest.xml
Que outras
<ac0vity ações nós já
android:name=".TextViewAc0vity" vimos?
android:label="@string/textViewAppName"
>
<intent‐filter>
<ac0on android:name="android.intent.ac@on.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="h^p" />
</intent‐filter>
E que outras
</ac0vity> la cate
E qua gorias já
i fe re n ç a e ntre vimos?
d
ação e
categoria?
Ainda o Manifesto
<?xml version="1.0" encoding="ur‐8"?>
<manifest xmlns:android="h^p://schemas.android.com/apk/res/android"
package="com.aula7" android:versionCode="1" android:versionName="1.0">
<applica0on android:icon="@drawable/icon" android:label="@string/app_name">
<ac@vity android:name=".CallerAc@vity" android:label="@string/app_name">
<intent‐filter>
<ac@on android:name="android.intent.ac@on.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent‐filter>
</ac@vity>
<ac@vity android:name=".TextViewAc@vity" android:label="@string/textViewAppName">
<intent‐filter>
O qu e acontece
<ac@on android:name="android.intent.ac@on.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> quando e
xistem
<data android:scheme="h]p" /> várias atividades
</intent‐filter> capazes de tratar
</ac@vity>
u m recurso?
</applica0on>
<uses‐permission android:name="android.permission.INTERNET"></uses‐permission>
</manifest>
Várias a0vidades
<?xml version="1.0" encoding="ur‐8"?>
<manifest xmlns:android="h^p://schemas.android.com/apk/res/android"
package="com.aula7" android:versionCode="1" android:versionName="1.0">
<applica0on android:icon="@drawable/icon" android:label="@string/app_name">
<ac@vity android:name=".CallerAc@vity" android:label="@string/app_name">
<intent‐filter> O que
determin
<ac@on android:name="android.intent.ac@on.MAIN" /> a o
nome de cada />
<category android:name="android.intent.category.LAUNCHER"
</intent‐filter> ícone?
</ac@vity>
<ac@vity android:name=".TextViewAc@vity" android:label="@string/textViewAppName">
<intent‐filter>
<ac@on android:name="android.intent.ac@on.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="h]p" />
</intent‐filter>
</ac@vity>
</applica0on>
<uses‐permission android:name="android.permission.INTERNET"></uses‐permission>
</manifest>
Buscas em Texto
Altere o exemplo
anterior para não
somente mostrar o
texto da página web, Sua aplicação
mas também permitir deverá exibir,
a busca de palavras em um Toast, o
nesse texto. número de
ocorrências do
Seu layout deverá
padrão
possuir uma caixa de
procurado.
texto para receber o
dado de pesquisa, um
botão para iniciar a
s
pesquisa, e uma caixa Comecemo
.
de texto contendo o pelo layout
?
texto fonte. Como seria
search.xml
<LinearLayout
android:id="@+id/LinearLayout01"
android:orienta0on="verDcal"
Layout de nosso buscador
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="h#p://schemas.android.com/apk/res/android">
<LinearLayout android:id="@+id/LinearLayout02"
android:layout_width="wrap_content"

Parte da
android:layout_height="wrap_content">
<EditText
ós já
atividade n
android:id="@+id/EditText01"
android:width="240sp"
já?
android:layout_width="wrap_content"
android:layout_height="wrap_content"> vimos, não
</EditText>
<Bu^on
android:text="@string/searchBu#onLabel"
android:id="@+id/Bu#on01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Bu^on>
</LinearLayout>
<ScrollView
xmlns:android="h#p://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
</LinearLayout>
Carregando o texto da página
TextSearchAc0vity.java
qu e o e ve nto
O
@Override ve
do botão de
public void onCreate(Bundle savedInstanceState) { azer?
f
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
text = (TextView) findViewById(R.id.textView); Como
Intent intent = getIntent(); implementa
r
URL url = Useful.openPage(intent); esse evento
?
text.setText(Useful.htmlToString(url));
final EditText tb1 = (EditText) findViewById(R.id.EditText01);

Bu^on bt = (Bu^on) findViewById(R.id.Bu^on01);


bt.setOnClickListener(...);
}
Expressões Regulares
TextSearchAc0vity.java
bt.setOnClickListener(new Bu^on.OnClickListener() {
public void onClick(View arg0) {
O que são
int counter = 0; expressões
String pa^ernStr = tb1.getText().toString(); regulares?
String htmlText = text.getText().toString();
Pa]ern pa^ern = Pa^ern.compile(pa^ernStr);
Matcher pageMatcher = pa^ern.matcher(htmlText);
while (pageMatcher.find()) {
counter++; E esse
código,
} ele faz
o quê?
Toast.makeText(TextSearchAc@vity.this,
"" + counter, Toast.LENGTH_SHORT).show();
}
});
Expressões Regulares
bt.setOnClickListener(new Bu^on.OnClickListener() { Esse nome,
public void onClick(View arg0) { “Toast”,
int counter = 0; designa um
objeto?
String pa^ernStr = tb1.getText().toString();
String htmlText = text.getText().toString();
Pa^ern pa^ern = Pa^ern.compile(pa^ernStr);
Matcher pageMatcher = pa^ern.matcher(htmlText);
while (pageMatcher.find()) {
counter++;
}
Ainda temos de
Toast.makeText(TextSearchAc0vity.this,
adicionar a
"" + counter, Toast.LENGTH_SHORT).show();
} atividade ao
}); manifesto…
Mais Manifesto
manifest.xml
<ac0vity android:name=".TextSearchAc0vity"
android:label="@string/textSearchAppName">
<intent‐filter>
<ac0on android:name="android.intent.ac0on.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="h^p" />
</intent‐filter>
</ac0vity>
Buscas de links
Crie agora uma nova
atividade, que também trata
URLs. Dessa vez, a sua
atividade deverá abrir uma
página web, e extrair todos os
links daquela página e exibí-
los em uma lista. Caso o
usuário clique em algum
desses links, então sua
atividade deverá abrir uma
página web mostrando o
conteúdo daquele endereço.
s
Comecemo
.
pelo layout
?
Como seria
Layout Pré‐Montados de Listas
public class LinkViewAc0vity extends ListAc0vity implements
AdapterView.OnItemLongClickListener, AdapterView.OnItemClickListener {
@Override
public void onCreate(Bundle savedInstanceState) { Onde essa
super.onCreate(savedInstanceState); classe foi
Intent intent = getIntent(); declarada?
URL url = Useful.openPage(intent);
String htmlText = Useful.htmlToString(url);
List<String> links = extractLinks(htmlText); Temos de
setListAdapter(new ArrayAdapter<String>(this, implementar
android.R.layout.simple_list_item_1, links)); esse método.
getListView().setTextFilterEnabled(true);
Adaptado
getListView().setOnItemClickListener(this); re
são outro s
getListView().setOnItemLongClickListener(this);
padrão d
} e
projetos.
}
LinkViewAc0vity.java
Adaptadores
• Adapter é um padrão de projetos que procura
adaptar uma interface às necessidades de
algum cliente.
– Trata‐se tão somente de uma camada em torno de
um objeto, que converte a interface desse objeto
para a interface esperada pelo cliente.

O que estava a s , e n fi m…
M d e
sendo adaptado t em o s
ainda
no exemplo p l e m e n tar
im
anterior? t r a c t L i nks
ex
Extraindo Links
LinkViewAc0vity.java
private List<String> extractLinks(String htmlText) {
Pa^ern linkPa^ern = Pa^ern.compile(
"(h]ps?|bp|file)://[‐a‐zA‐Z0‐9+&@#/%?=~_|!:,.;]*[‐a‐zA‐Z0‐9+&@#/%=~_|]",
Pa]ern.CASE_INSENSITIVE | Pa]ern.DOTALL);
Matcher pageMatcher = linkPa^ern.matcher(htmlText);
List<String> links = new ArrayList<String>();
O que quer
while (pageMatcher.find()) { r essa
E essas d i z e
links.add(pageMatcher.group());
c o n e x p r e ssão
} s tantes, o
qu e q u r e g ular?
return links; erem
} dizer?
Eventos para Tratar
LinkViewAc0vity.java
@Override Qual a
public void onCreate(Bundle savedInstanceState) { diferença entre
super.onCreate(savedInstanceState); esse tipo de
Intent intent = getIntent(); evento e esse?
URL url = Useful.openPage(intent);
String htmlText = Useful.htmlToString(url);
List<String> links = extractLinks(htmlText); t ã o v a mos
En
r
setListAdapter(new ArrayAdapter<String>(this, começa an do
android.R.layout.simple_list_item_1, links)); en t
implem
getListView().setTextFilterEnabled(true); s e t i p o de
es
getListView().setOnItemClickListener(this); evento.
getListView().setOnItemLongClickListener(this);
}
Abrindo mais páginas web
LinkViewAc0vity.java
public void onItemClick(AdapterView<?> av, View v, int pos, long id) {
String urlName = ((TextView) v).getText().toString();
Intent browserIntent = new
Intent(Intent.ACTION_VIEW, Uri.parse(urlName));
startAc0vity(browserIntent);
finish();
}
Qual atividade
será aberta por O que quer
E como abrir dizer essa
uma atividade esse tratador
de eventos? sintaxe?
específica?
Invocando uma a0vidade específica
LinkViewAc0vity.java
public boolean onItemLongClick
(AdapterView<?> av, View v, int pos, long id) {
String urlName = ((TextView) v).getText().toString();
Intent i = new Intent(this, WebViewAc@vity.class);
i.putExtra("URL", urlName);
startAc0vity(i);
return false; Temos de
} implemen tar
essa atividade!
WebView
• Android determina um layout para visões web:
web.xml
<?xml version="1.0" encoding="ur‐8"?>
<LinearLayout xmlns:android=
"h^p://schemas.android.com/apk/res/android"
android:orienta0on="ver0cal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<WebView android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
WebView
WebViewAc0vity.java

public class WebViewAc0vity extends Ac0vity {


public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.web);
WebView webview = (WebView) findViewById(R.id.webview);
webview.getSe•ngs().setJavaScriptEnabled(true);
Intent i = getIntent();
String urlName = i.getStringExtra("URL");
webview.loadUrl(urlName);
Como se dá a
}
N ão esqueçam comunicação
} icionar a entr
de ad e as
atividade ao atividades?
manifesto!
Manifesto
AndroidManifest.xml

<ac0vity
android:name=".WebViewAc0vity"
android:label="NewWebView" >
<intent‐filter>
<ac0on android:name="android.intent.ac0on.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="h^p" />
</intent‐filter>
</ac0vity>
Comunicação entre A0vidades
LinkViewAc0vity.java
public boolean onItemLongClick
(AdapterView<?> av, View v, int pos, long id) {
String urlName = ((TextView) v).getText().toString();
Intent i = new Intent(this, WebViewAc0vity.class);
i.putExtra("URL", urlName);
startAc0vity(i); WebViewAc0vity.java
return false; public class WebViewAc0vity extends Ac0vity {
} public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.web);
WebView webview = (WebView) findViewById(R.id.webview);
webview.getSe•ngs().setJavaScriptEnabled(true);
Intent i = getIntent();
String urlName = i.getStringExtra("URL");
webview.loadUrl(urlName);
}
}
Intenções Implícitas e Explicitas
• Intenções explícitas abrem uma a0vidade
específica.
– Essas intenções contêm o nome da a0vidade alvo.
– Em geral são usados para comunicação entre
a0vidades da mesma aplicação.

Intent i = new Intent(this, SomeAc'vity.class);


i.putExtra("Key", value);
startAc'vity(i);
Intenções Implícitas e Explicitas
• Intenções implícitas fazem um chamado para
qualquer a0vidade que saiba lidar com elas.
– Em geral são usados para comunicação entre
a0vidades de aplicações diferentes.
– Usam filtros para indicar a a0vidade alvo.

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlName));


startAc'vity(intent);

Você também pode gostar