Está en la página 1de 82

ProgramaoparaaPlataformaAndroidAula14

Mapas
Comoobterumcer<cadoparausaraAPIdemapasdogoogle?
Comoimportarasbibliotecasnecessriasmanipulaodemapas?
Comoexibirummapanoaparelhomvel?
Comolerascoordenadasgeogrcasdeumpontonomapa?
Comoobterumendereoapar<rdeumpontonomapa?
Quaissooseventosmaiscomunsqueocorremsobremapas?

Obtendoumalicena
necessrioumcer<cadodigitalparausara
APIdemapasdogoogle.
Paraobterumcer<cado,forneaaoservidor
deauten<caoasuachavedigital.
Paragerarachavedigital:
$keytoollistkeystore~/.android/debug.keystore
Cer<catengerprint(MD5):94:1E:43:49:87:73:BB:E6:A6:88:D7:20:F1:8E:B5:98

Useopasswordannimo(vazio).

Obtendoumalicena
Depossedachavedigital,bastainformlaao
servidordeauten<cao:
heps://developers.google.com/maps/
documenta<on/android/v1/mapsapisignup
precisoumacontanogoogle.

Obtendoumalicena

AAPIdeMapasv2
Existeumanovaversodabibliotecade
mapas,quepermitearenderizaodemapas
3D.
EssanovaversochamaseGoogleMaps
Androidv2.
NestecursoestaremosvendoGoogleMaps
Androidv1.

UsandoasAPIsdoGoogle
MapasnosopartedabibliotecaAndroid
padro.
Parauslos,precisomontaroprojetocoma
APIdoGoogle.

Eprecisoindicarocaminhoparaasclasses
apropriadasnomanifesto:
<uses-library android:name="com.google.android.maps" />

Usandoabibliotecademapas
<?xmlversion="1.0"encoding="um8"?>
<manifestxmlns:android="hep://schemas.android.com/apk/res/android"
package="com.aula14"android:versionCode="1"android:versionName="1.0">
<usespermissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/>
<usespermissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>
<usespermissionandroid:name="android.permission.INTERNET"/>
<applica<onandroid:icon="@drawable/icon"android:label="@string/app_name">
<ac<vityandroid:name=".MyMapAc<vity"android:label="@string/app_name">
<intentlter>
<ac<onandroid:name="android.intent.ac<on.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intentlter>
</ac<vity>
<useslibraryandroid:name="com.google.android.maps"/>
</applica<on>
<usessdkandroid:minSdkVersion="2"/>
</manifest>
AndroidManifest.xml

Criandoumlayoutparamapas
<?xmlversion="1.0"encoding="um8"?>
<LinearLayoutxmlns:android="hep://schemas.android.com/apk/res/android"
android:id="@+id/frame"android:orienta<on="ver<cal"
android:layout_width="ll_parent"android:layout_height="ll_parent">
<com.google.android.maps.MapView
android:id="@+id/map"
android:apiKey="0mryOfB7UH2GtZ_mxHxG3cXwnkwu0FMW60611g"
android:layout_width="ll_parent"
android:layout_height="ll_parent"
android:clickable="true"/>
</LinearLayout>
a a chave
main.xml

Ess
s
que obtemo
E essa a
a
r
u
t
a
via assin
biblioteca que

.
digital
contm a API
de mapas.

MapAc<vity
publicclassMapsAc<vityextendsMapAc<vity{
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
protectedbooleanisRouteDisplayed(){
returnfalse;
}
}
MapsAc<vity.java

mos
a
s
u
e
u
q
r
o
P
o layout
relativo?

Zooming

<?xmlversion="1.0"encoding="um8"?>
<Rela?veLayoutxmlns:android="hep://schemas.android.com/apk/res/android"
android:id="@+id/frame"android:orienta<on="ver<cal"
android:layout_width="ll_parent"android:layout_height="ll_parent">
<com.google.android.maps.MapView
android:id="@+id/map"
android:apiKey="0mryOfB7UH2GtZ_mxHxG3cXwnkwu0FMW60611g"
android:layout_width="ll_parent"
android:layout_height="ll_parent"
android:clickable="true"/>
<LinearLayoutandroid:id="@+id/zoom"
android:layout_width="wrap_content"
so
android:layout_height="wrap_content"
Mas preci
android:layout_alignParentBoFom="true"
tambm
android:layout_centerHorizontal="true"
atualizar a
/>
ividade.
t
a
</Rela<veLayout>
map.xml

ModicandoaA<vidade
De onde
publicvoidonCreate(BundlesavedInstanceState){
vem essa
super.onCreate(savedInstanceState);
constante?
setContentView(R.layout.main);
mapView=(MapView)ndViewById(R.id.mapView);
LinearLayoutzoomLayout=(LinearLayout)ndViewById(R.id.zoom);
ViewzoomView=mapView.getZoomControls();
zoomLayout.addView(zoomView,
newLinearLayout.LayoutParams(
Podemos
LayoutParams.WRAP_CONTENT,
amar o
r
g
o
r
p
LayoutParams.WRAP_CONTENT)
m via
o
o
z
);
ventos.
e
mapView.displayZoomControls(true);
}
MapsAc<vity.java

ControledeZoom
Bastacolocarofoco
sobreatelademapa,
queoscontroladores
dezoomaparecem.

ModicandoaA<vidade
De onde
publicvoidonCreate(BundlesavedInstanceState){
vem essa
super.onCreate(savedInstanceState);
constante?
setContentView(R.layout.main);
mapView=(MapView)ndViewById(R.id.mapView);
LinearLayoutzoomLayout=(LinearLayout)ndViewById(R.id.zoom);
ViewzoomView=mapView.getZoomControls();
zoomLayout.addView(zoomView,
newLinearLayout.LayoutParams(
Podemos
LayoutParams.WRAP_CONTENT,
amar o
r
g
o
r
p
LayoutParams.WRAP_CONTENT)
m via
o
o
z
);
ventos.
e
mapView.displayZoomControls(true);
}
MapsAc<vity.java

ControlesdeZoom
Podemosusarolayoutan<go,eprogramaro
zoomemJava:
<?xmlversion="1.0"encoding="um8"?>
<LinearLayoutxmlns:android="hep://schemas.android.com/apk/res/android"
android:id="@+id/frame"
android:layout_width="ll_parent"
android:layout_height="ll_parent"
android:orienta<on="ver<cal">
<com.google.android.maps.MapView
android:id="@+id/map"
android:layout_width="ll_parent"
android:layout_height="ll_parent"
android:apiKey="0mryOfB7UH2GtZ_mxHxG3cXwnkwu0FMW60611g"
android:clickable="true"/>
</LinearLayout>

ControlesdeZoom
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.ac<vity_main);
mapView=(MapView)ndViewById(R.id.map);
mapView.setBuiltInZoomControls(true);
}
possvel
s
posicionar o
controles em o
es d
outras part
mapa.

PosicionandoosControles
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.ac<vity_main);
mapView=(MapView)ndViewById(R.id.map);
mapView.setBuiltInZoomControls(true);
ZoomBueonsControllerzbc=
mapView.getZoomBueonsController();
ViewGroupcontainer=zbc.getContainer();
for(inti=0;i<container.getChildCount();i++){
Viewchild=container.getChildAt(i);
if(childinstanceofZoomControls){
FrameLayout.LayoutParamslp=
(FrameLayout.LayoutParams)child.getLayoutParams();
lp.gravity=Gravity.RIGHT|Gravity.BOTTOM;
child.requestLayout();
break;
}
}
}

ZoomviaEventos
MapsAc<vity.java

publicbooleanonKeyDown(intkeyCode,KeyEventevent){
MapControllermc=mapView.getController();
switch(keyCode){
caseKeyEvent.KEYCODE_3:
mc.zoomIn();
break;
caseKeyEvent.KEYCODE_1:
mc.zoomOut();
break;
}
returnsuper.onKeyDown(keyCode,event);
}

ModosdeMapa
Existemdiferentesformasdevisualizaode
mapas:
que faz cada
mapView.setSatellite(true)

O
uma dessas

chamadas?

mapView.setStreetView(true)

Como
poderamos
program-las
via eventos?

MapsAc<vity.java

@Override
publicbooleanonKeyDown(intkeyCode,KeyEventevent){
MapControllermc=mapView.getController();
switch(keyCode){
o
caseKeyEvent.KEYCODE_1: Ser que n olocar
c
poderamos
mc.zoomOut();
opes em
s
a
s
s
e
break;
a de
ma caixinh
u
caseKeyEvent.KEYCODE_2:
dilogo?
mc.zoomIn();
break;
caseKeyEvent.KEYCODE_3:
mapView.setSatellite(true);
break;
caseKeyEvent.KEYCODE_4:
mapView.setSatellite(false);
break;
}
returnsuper.onKeyDown(keyCode,event);
}

CaixadeOpes
MapsAc<vity.java

@Override
publicbooleanonKeyDown(intkeyCode,KeyEventevent){
MapControllermc=mapView.getController();
Insiraummenude
switch(keyCode){
opesnomapa.
caseKeyEvent.KEYCODE_0:
Apertandoatecla"0"
essemenudever
showOp?onsDialog();
seraberto.
break;
caseKeyEvent.KEYCODE_1:
mc.zoomOut();
a
Usamos um
break;
caixa de
caseKeyEvent.KEYCODE_2:
dilogo no
mc.zoomIn();
Sudoku.
break;

MapsAc<vity.java

privatevoidshowOp<onsDialog(){
Stringop?ons[]={"0:showop?ons","1:zoomout",
"2:zoomin","3:satelliteon","4:satelliteo"};
newAlertDialog.Builder(this).setTitle("KeyOp<ons").setItems(op?ons,
newDialogInterface.OnClickListener(){
publicvoidonClick(DialogInterfacedialoginterface,inti){
MapControllermc=mapView.getController();
switch(i){
A frmula
case1:
no muda
mc.zoomOut();break;
muito.
case2:
Precisamo
mc.zoomIn();break;
s
d
e um
case3:
arranjo de
mapView.setSatellite(true);break;
opes.
case4:
mapView.setSatellite(false);break;
}
E de um
dialoginterface.cancel();
escutador de
}
eventos de
}).show();
clique.
}

MapsAc<vity.java

privatevoidshowOp<onsDialog(){
Stringop<ons[]={"0:showop<ons","1:zoomout",
"2:zoomin","3:satelliteon","4:satelliteo"};
newAlertDialog.Builder(this).setTitle("KeyOp?ons").setItems(op<ons,
newDialogInterface.OnClickListener(){
publicvoidonClick(DialogInterfacedialoginterface,inti){
MapControllermc=mapView.getController();
Interface
switch(i){
fluente:
case1:
cadeias de
mc.zoomOut();break;
chamadas.
case2:
mc.zoomIn();break;
case3:
mapView.setSatellite(true);break;
case4:
mapView.setSatellite(false);break;
}
dialoginterface.cancel();
}
}).show();
}

Indicandoumpontogeodsico
Porpadro,Androidinicializaomapatendoos
EstadosUnidoscomocentro.
Podeseinformarnovascoordenadasparao
programa,usandoafunoanimateTo.
Quais so as
s
coordenada
de Belo

Horizonte?

Indicandoumpontogeodsico
Porpadro,Androidinicializaomapatendoos
EstadosUnidoscomocentro.
Podeseinformarnovascoordenadasparao
programa,usandoafunoanimateTo.
Quais so as
s
coordenada
de Belo

Horizonte?

MapControllermc=mapView.getController();
Stringcoordinates[]={"19.919133","43.938667"};
doublelat=Double.parseDouble(coordinates[0]);
doublelng=Double.parseDouble(coordinates[1]);
GeoPointp=newGeoPoint(
(int)(lat*1E6),
(int)(lng*1E6));
mc.animateTo(p);
mc.setZoom(17);
mapView.invalidate();
MapsAc<vity.java

Indicandoumpontogeodsico
Porpadro,Androidinicializaomapatendoos
EstadosUnidoscomocentro.
Podeseinformarnovascoordenadasparao
programa,usandoafunoanimateTo.
Stringcoordinates[]={"19.919133","43.938667"};
doublelat=Double.parseDouble(coordinates[0]);
doublelng=Double.parseDouble(coordinates[1]);
GeoPointp=newGeoPoint(
(int)(lat*1E6),
(int)(lng*1E6));
mc.animateTo(p);
mc.setZoom(17);
mapView.invalidate();

Desenhandobitmaps
Podeseadicionarmarcadores
sobreomapa.
IssofeitoviaOverlays.Estes
soobjetosquepodemser
desenhadossobreummapa.
Mas onde
deixamos
nossos
marcadores
mesmo?

Desenhandobitmaps
Podeseadicionarmarcadores
sobreomapa.
IssofeitoviaOverlays.Estes
soobjetosquepodemser
desenhadossobreummapa.

Crie o evento tecla


5, para mostrar
um marcador em
BH.

Overlays

p um
GeoPoint,
declaradado
globalmente.

classMapOverlayextendscom.google.android.maps.Overlay{
@Override
publicbooleandraw(Canvascanvas,MapViewmapView,
booleanshadow,longwhen){
super.draw(canvas,mapView,shadow);
PointscreenPts=newPoint();
mapView.getProjec<on().toPixels(p,screenPts);
Bitmapbmp=BitmapFactory.decodeResource(getResources(),
R.drawable.push_pin3);
canvas.drawBitmap(bmp,screenPts.x,screenPts.y50,null);
returntrue;
}
}
MapsAc<vity.java

AdicionandoumOverlayaoMapa
caseKeyEvent.KEYCODE_5:
Stringcoordinates[]={"19.919133","43.938667"};
doublelat=Double.parseDouble(coordinates[0]);
doublelng=Double.parseDouble(coordinates[1]);
p=newGeoPoint((int)(lat*1E6),(int)(lng*1E6));
mc.animateTo(p);
mc.setZoom(17);
MapOverlaymapOverlay=newMapOverlay();
List<Overlay>listOfOverlays=mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
mapView.invalidate();
break;
MapsAc<vity.java

Escalaoops!
bem
No era
isso que
s de
o
m
a

r
a
t
gos
fazer.
Existem
muitas formas
de desenhar
bitmaps.

Podemos usar
matrizes.

Matrizes
MapsAc<vity.java

publicbooleandraw(Canvascanvas,
MapViewmapView,booleanshadow,longwhen){
super.draw(canvas,mapView,shadow);
PointscreenPts=newPoint();
mapView.getProjec<on().toPixels(p,screenPts);
Bitmapbmp=BitmapFactory.decodeResource(
getResources(),R.drawable.push_pin3);
Matrixmatrix=newMatrix();
matrix.postScale(0.3F,0.3F);
matrix.postTranslate(180.0F,260.0F);
canvas.drawBitmap(bmp,matrix,null);
returntrue;
}

VriosOverlays
Existeumacadeiade
overlaysassociadaaum
mapa.
Podemosinserirnovos
elementosaessacadeia,
paraadicionarmais
funcionalidadesaonosso
mapa.

VriosOverlays
MapsAc<vity.java

caseKeyEvent.KEYCODE_5:
Stringcoordinates[]={"19.919133","43.938667"};
doublelat=Double.parseDouble(coordinates[0]);
doublelng=Double.parseDouble(coordinates[1]);
p=newGeoPoint((int)(lat*1E6),(int)(lng*1E6));
mc.animateTo(p);
mc.setZoom(17);
MapOverlaymapOverlay=newMapOverlay();
List<Overlay>listOfOverlays=mapView.getOverlays();
listOfOverlays.clear();
Quantos
listOfOverlays.add(mapOverlay);
overlays
mapView.invalidate();
temos, nesse
break;
ponto?

ComoRemoveroOverlay?
caseKeyEvent.KEYCODE_6:{
List<Overlay>listOfOverlays=mapView.getOverlays();
listOfOverlays.clear();
mapView.invalidate();
break;
}

EventosdeToque
Podemosadicionarmaisumoverlayaonosso
mapa,parasermoscapazesdecapturar
eventosdetoque.
m
Seria bo
as
r
a
r
t
s
o
m
as
d
a
n
e
d
r
coo
.
do ponto

Como obter
essas
coordenadas?

Como m
ostrar
essas
coorden
adas?

MapsAc<vity.java

EventosdeToque

classOnTouchOverlayextendscom.google.android.maps.Overlay{
@Override
publicbooleanonTouchEvent(Mo<onEventevent,MapViewmapView)
{
if(event.getAc?on()==Mo?onEvent.ACTION_UP){
GeoPointp=mapView.getProjec<on().fromPixels((int)event.getX(),
(int)event.getY());
Toast.makeText(getBaseContext(),
p.getLa?tudeE6()/1E6+","+p.getLongitudeE6()/1E6,
Toast.LENGTH_SHORT).show();
}
returnfalse;
E esse cdigo
,
O que esse
ta? o que ele faz?
}
cdigo deno
}

AdicionandoonovoOverlay
@Override
Mas, ateno!

publicvoidonCreate(BundlesavedInstanceState){
O Evento 5 es
t
super.onCreate(savedInstanceState);
removendo o
setContentView(R.layout.map);
overlay!!!
mapView=(MapView)ndViewById(R.id.map);
LinearLayoutzoomLayout=(LinearLayout)ndViewById(R.id.zoom);
ViewzoomView=mapView.getZoomControls();
zoomLayout.addView(zoomView,newLinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
mapView.displayZoomControls(true);
OnTouchOverlayovly=newOnTouchOverlay();
List<Overlay>listOfOverlays=mapView.getOverlays();
listOfOverlays.add(ovly);
}
MapsAc<vity.java

MantendoalistadeOverlays
caseKeyEvent.KEYCODE_5:
Stringcoordinates[]={"19.919133","43.938667"};
doublelat=Double.parseDouble(coordinates[0]);
doublelng=Double.parseDouble(coordinates[1]);
p=newGeoPoint((int)(lat*1E6),(int)(lng*1E6));
mc.animateTo(p);
mc.setZoom(17);
MapOverlaymapOverlay=newMapOverlay();
List<Overlay>listOfOverlays=mapView.getOverlays();
//listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
mapView.invalidate();
break;
MapsAc<vity.java

MantendoalistadeOverlays
caseKeyEvent.KEYCODE_5:
Stringcoordinates[]={"19.919133","43.938667"};
doublelat=Double.parseDouble(coordinates[0]);
doublelng=Double.parseDouble(coordinates[1]);
p=newGeoPoint((int)(lat*1E6),(int)(lng*1E6));
mc.animateTo(p);
mc.setZoom(17);
MapOverlaymapOverlay=newMapOverlay();
List<Overlay>listOfOverlays=mapView.getOverlays();
//listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
mapView.invalidate();
break;

LendoEndereos
Emvezdeobterascoordenadasgeodsicas
deumcertolocal,podemosobteroendereo
daquelelocal,quandovlido.

publicbooleanonTouchEvent(Mo<onEventevent,MapViewmapView){
if(event.getAc<on()==Mo<onEvent.ACTION_UP){
GeoPointp=mapView.getProjec<on().fromPixels((int)event.getX(),
(int)event.getY());
GeocodergeoCoder=newGeocoder(getBaseContext(),Locale.getDefault());
try{
List<Address>addresses=geoCoder.getFromLoca<on(
p.getLa<tudeE6()/1E6,p.getLongitudeE6()/1E6,1);
Stringadd="";
if(addresses.size()>0){
for(inti=0;i<addresses.get(0).getMaxAddressLineIndex();i++)
add+=addresses.get(0).getAddressLine(i)+"\n";
}
Toast.makeText(getBaseContext(),add,Toast.LENGTH_SHORT).show();
}catch(IOExcep<one){
e.printStackTrace();
}
returntrue;
}
returnfalse;
}
MapsAc<vity.java

publicbooleanonTouchEvent(Mo<onEventevent,MapViewmapView){
if(event.getAc<on()==Mo<onEvent.ACTION_UP){
GeoPointp=mapView.getProjec<on().fromPixels((int)event.getX(),
(int)event.getY());
Modifique esse
GeocodergeoCoder=newGeocoder(getBaseContext(),Locale.getDefault());
overlay, para que ele:
try{
I) informe a
List<Address>addresses=geoCoder.getFromLoca<on(
coordenada
p.getLa<tudeE6()/1E6,p.getLongitudeE6()/1E6,1);
quando o dedo
Stringadd="";
if(addresses.size()>0){
tocar a tela.
for(inti=0;i<addresses.get(0).getMaxAddressLineIndex();i++)
II) Informe o
add+=addresses.get(0).getAddressLine(i)+"\n";
endereo quando
} o dedo deixar a
Toast.makeText(getBaseContext(),add,Toast.LENGTH_SHORT).show();
tela.
}catch(IOExcep<one){
e.printStackTrace();
}
returntrue;
}
returnfalse;
}

publicbooleanonTouchEvent(Mo<onEventevent,MapViewmapView){
GeoPointp=mapView.getProjec<on().fromPixels((int)event.getX(),
(int)event.getY());
if(event.getAc<on()==Mo<onEvent.ACTION_UP){
GeocodergeoCoder=newGeocoder(getBaseContext(),Locale.getDefault());
try{
List<Address>addresses=geoCoder.getFromLoca<on(
p.getLa<tudeE6()/1E6,p.getLongitudeE6()/1E6,1);
Stringadd="";
if(addresses.size()>0){
for(inti=0;i<addresses.get(0).getMaxAddressLineIndex();i++)
add+=addresses.get(0).getAddressLine(i)+"\n";
}
Toast.makeText(getBaseContext(),add,Toast.LENGTH_SHORT).show();
}catch(IOExcep<one){e.printStackTrace();}
}elseif(event.getAc<on()==Mo<onEvent.ACTION_DOWN){
Toast.makeText(getBaseContext(),
p.getLa<tudeE6()/1E6+","+p.getLongitudeE6()/1E6,
Toast.LENGTH_SHORT).show();
}
returnfalse;
}
MapsAc<vity.java

OndeEstou?
Mapaselocalizadoressobons
companheiros.
Crie uma atividade
de mapa que
posicione a tela no
ponto em que o
emulador se
encontra
geograficamente,
logo que a atividade
comea.

Que passos
de
essa ativida
envolve?

OndeEstou?
Mapaselocalizadoressobons
companheiros.
Que passos
de
essa ativida
envolve?

Crie uma atividade


de mapa que
Precisamos
posicione a tela no
obter a
ponto em que o
localizao
emulador se
s de
o
encontra
m
e
t
E
mapa
o
r
e
geograficamente,
v
mo
s
o
m
e
c
e
uele
q
a
a
r
a
logo que a atividadeCom o a
p
obtend
nto.
o
p
comea.
alizao
loc

Comoobteralocalizaoatual?
privateGeoPointgetCurrentLoca<on(){
Loca<onManagermgr=(Loca<onManager)getSystemService(LOCATION_SERVICE);
Criteriacriteria=newCriteria();
Stringbest=mgr.getBestProvider(criteria,true);
Loca<onloca<on=mgr.getLastKnownLoca<on(best);
doublelat;
doublelng;
m ter
o
b
Agora preciso
e
r
p
m
e
s

if(loca?on!=null){
posicionar o mapa
um plano de
lat=loca?on.getLa?tude();
no
o
s
a
sobre o ponto em
c
,
p
u
k
c
ba
lng=loca?on.getLongitude();
obter que estamos. Como
l
e
v

s
s
o
p
a
j
se
}else{
or!
d
a
z
fazer isso?
i
l
a
c
o
l
m
u
lat=19.879133;
lng=43.961667;
}
GeoPointpoint=newGeoPoint((int)(lat*1E6),(int)(lng*1E6));
returnpoint;
}
WhereAreAc<vity.java

PosicionandooMapa
WhereAreAc<vity.java

privatevoidmoveToLoca<on(GeoPointgp,intzoomFactor){
MapControllermc=mapView.getController();
mc.animateTo(gp);
mc.setZoom(zoomFactor); Jogo da
memria: o
mapView.invalidate();
que essa
}
chamada faz?

Precisamos
desenhar um
e
alfinete sobr
a tela.

Queremos
cdigo
resavel.

ia o
r
e
s
l
a
Qu
jeto
o
r
p
r
o
melh
se
para es ?
a
problem

ObjetosMarcadores
@Override
Mtodos que
publicvoidonCreate(BundlesavedInstanceState){
acabamos de
criar.
...criaomapa,habilitaozoom,etc
...
GeoPointcurrentLoca?on=getCurrentLoca?on();
moveToLoca?on(currentLoca?on,17);
O que objetos
MarkerOverlayovly=newMarkerOverlay(this);
ovly.addCoordinate(currentLoca?on);
List<Overlay>listOfOverlays=mapView.getOverlays();
listOfOverlays.add(ovly);
E como
}
r
WhereAreAc<vity.java

implementa
essa classe?

dessa classe
sabem fazer?
O que esse
cdigo est
fazendo?

MarkerOverlay.java

Porque
precisamos de
um contexto?

publicclassMarkerOverlayextends
com.google.android.maps.Overlay{
privateList<GeoPoint>coords;
privateContextcontext;
Triste estria: Java no
publicMarkerOverlay(Contextct){
possui herana mltipla.
this.context=ct;
Se possusse, poderamos
coords=newArrayList<GeoPoint>();
estender tanto Overlay
}
quanto alguma lista.
publicvoidaddCoordinate(GeoPointcoord){
coords.add(coord);
}
@Override
publicbooleandraw(Canvascanvas,MapViewmapView,
booleanshadow,longwhen){
Como ser a
...
implementao
}
de draw?
}

DesenhandoMarcadores
@Override
publicbooleandraw(Canvascanvas,MapViewmapView,
booleanshadow,longwhen){
super.draw(canvas,mapView,shadow);
for(GeoPointgp:coords){
PointscreenPts=newPoint();
mapView.getProjec<on().toPixels(gp,screenPts);
Bitmapbmp=BitmapFactory.decodeResource(context.getResources(),
R.drawable.push_pin3);
Matrixmatrix=newMatrix();
Onde fica o
matrix.postScale(0.3F,0.3F);
nosso
matrix.postTranslate(100.0F,130.0F);
marcador?
canvas.drawBitmap(bmp,matrix,null);
}
returntrue;
}
MarkerOverlay.java

AndroidManifest.xml
<?xmlversion="1.0"encoding="u?8"?>
<manifestxmlns:android="hEp://schemas.android.com/apk/res/android"
package="com.aula14"android:versionCode="1"android:versionName="1.0">
<usespermissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/>
<usespermissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>
<usespermissionandroid:name="android.permission.INTERNET"/>
<applica<onandroid:icon="@drawable/icon"android:label="@string/app_name">
<ac<vityandroid:name=".MapsAcVvity"android:label="@string/app_name">
<intentlter>
<ac<onandroid:name="android.intent.acVon.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intentlter>
</ac<vity>
<ac?vityandroid:name=".WhereAreAc3vity"android:label="@string/where_app">
<intentlter>
<ac?onandroid:name="android.intent.ac3on.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intentlter>
</ac?vity>
<useslibraryandroid:name="com.google.android.maps"/>
</applica<on>
<usessdkandroid:minSdkVersion="2"/>
</manifest>

AgendadeEndereos
Queremos construir um catlogo de
endereos. Essa aplicao possui duas
partes:
I) Um coletor de endereos, que d
para o usurio uma interface de
mapa. Clicando em pontos dessa
interface o coletor abre uma caixa
de dilogo em que o usurio pode
entrar com informaes sobre o
local.
II) Um visualizador de endereos.
Trata-se de uma lista que exibe as
informaes armazenadas na
agenda.

O que um
endereo?

Como
armazenar
endereos?
Quantas
vises
teremos?
Como coletar
endereos?

Endereos
Endereossotuplasformadas
porquatroelementos:
Umrtulo,paraajudaremsua
classicao
Umastringdescrevendo
informaessobreolocal
Uminteirorepresentandouma
la<tude
Uminteirorepresentandouma
longitude

O que um
endereo?

Como
armazenar
endereos?

publicclassAddressDataextendsSQLiteOpenHelper{
privatesta<cnalStringDATABASE_NAME="events.db";
privatesta<cnalintDATABASE_VERSION=1;
publicAddressData(Contextctx){
super(ctx,DATABASE_NAME,null,DATABASE_VERSION);
}
publicvoidonCreate(SQLiteDatabasedb){
db.execSQL("CREATETABLE"+TABLE_NAME
+"("+_ID+"INTEGERPRIMARYKEYAUTOINCREMENT,"
+LON+"INTEGER,"
Qual a melhor
+LAT+"INTEGER,"
forma de
+LABEL+"TEXTNOTNULL,"
declarar as
constantes?
+INFO+"TEXT);");
}
@Override
publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){
db.execSQL("DROPTABLEIFEXISTS"+TABLE_NAME);
onCreate(db);
}
}
AddressData.java

InterfacesdeConstantes
Constants.java
publicinterfaceConstants{
publicsta<cnalStringTABLE_NAME="events";
publicsta<cnalStringLABEL="label";
publicsta<cnalStringINFO="info";
publicsta<cnalStringLON="lon";
publicsta<cnalStringLAT="lat";
Quantas
}
importsta<candroid.provider.BaseColumns._ID;
importsta<ccom.etc.etc.etc.Constants.INFO;
importsta<ccom.etc.etc.etc.Constants.LABEL;
importsta<ccom.etc.etc.etc.Constants.LAT;
importsta<ccom.etc.etc.etc.Constants.LON;
importsta<ccom.etc.etc.etc.Constants.TABLE_NAME;
AddressData.java

vises
teremos?

Como coletar
endereos?

Vises
Para que
serve cada
viso?

Quantas
vises
teremos?
Como coletar
endereos?

A<vidadePrincipal
publicclassAddressBookAc<vityextendsMapAc<vity{
publicsta<cAddressDataaddrs;
classOnTouchOverlayextendscom.google.android.maps.Overlay{
@Override
publicbooleanonTouchEvent(Mo?onEventevent,MapViewmapView){
...
Para que
}
servir essa
}
camada?
@Override
publicvoidonCreate(BundlesavedInstanceState){
...
}
@Override
O que o mtod
o
protectedbooleanisRouteDisplayed(){
onCreate faz
?
returnfalse;
}
}
AddressBookAc<vity.java

CriandoaAgenda
@Override
publicvoidonCreate(BundlesavedInstanceState){
if(addrs==null){
Quais so
addrs=newAddressData(this);
nossas
coordenadas
}
iniciais?
super.onCreate(savedInstanceState);
setContentView(R.layout.ac<vity_main);
mapView=(MapView)ndViewById(R.id.map);
mapView.setBuiltInZoomControls(true);
OnTouchOverlayovly=newOnTouchOverlay();
List<Overlay>listOfOverlays=mapView.getOverlays();
listOfOverlays.add(ovly);
moveToIni?alCoordinate();
}

Movendoparaumpontoespecco
privatevoidmoveToIni<alCoordinate(){
Stringcoordinates[]={"19.919133","43.938667"};
doublelat=Double.parseDouble(coordinates[0]);
doublelng=Double.parseDouble(coordinates[1]);
p=newGeoPoint((int)(lat*1E6),(int)(lng*1E6));
MapControllermc=mapView.getController();
mc.animateTo(p);
Quais eventos
mc.setZoom(17);
r
ta
Como cole
produzem

?
mapView.invalidate();
s
endereo
dados?
}

AddressBookAc<vity.java

privatenalintaddrLbl=1;
classOnTouchOverlayextendscom.google.android.maps.Overlay{
@Override
publicbooleanonTouchEvent(Mo<onEventevent,MapViewmapView){
if(event.getAc<on()==Mo<onEvent.ACTION_DOWN){
Intentintent=newIntent(AddressBookAc<vity.this,
GetAddrLabelAc<vity.class);
GeoPointp=mapView.getProjec<on().fromPixels((int)event.getX(),
(int)event.getY());
intent.putExtra(LAT,p.getLa?tudeE6());
O que esse
intent.putExtra(LON,p.getLongitudeE6()); mtodo faz?
startAc?vityForResult(intent,addrLbl);
}
Que informa
returnfalse;
es
Qual o layout
e
s
t
a
m
os
}
da outra
passando ou
tra
}
atividade?
atividade?

ColetadeEndereos
Como criar
esse layout?

getlbl.xml
<?xmlversion="1.0"encoding="u?8"?>
<LinearLayout
xmlns:android="hEp://schemas.android.com/apk/res/android"
android:orienta<on="verVcal"
android:layout_width="ll_parent"
android:layout_height="ll_parent"
android:minWidth="200dip"
android:padding="10dip">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Label:"
android:textSize="15sp"/>
<EditText
android:id="@+id/label_txt"
android:layout_width="ll_parent"
android:layout_height="wrap_content"
android:editable="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="NotaseObservacoes:"
android:textSize="15sp"/>
<EditText
android:id="@+id/info_txt"
android:layout_width="ll_parent"
android:layout_height="wrap_content"
android:editable="true"/>
<Bueon
android:id="@+id/conrm_info"
android:text="Ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

Podemos usar um
tema para deixar a
atividade com um
jeito de caixa de
dialogo.

<ac<vity
android:name=".GetAddrLabelAc<vity"
android:theme="@android:style/Theme.Dialog">
</ac<vity>
E como ser
a
atividade?

ColetandooEndereo
publicclassGetAddrLabelAc<vityextendsAc<vity{
privateEditTextinfoBox,labelBox;
publicnalvoidonCreate(nalBundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.getlbl);
infoBox=(EditText)ndViewById(R.id.info_txt);
labelBox=(EditText)ndViewById(R.id.label_txt);
nalIntentmyIntent=getIntent();
Como ser o
//eventodobotoaqui!!!
tratamento
}
de eventos?
}
GetAddrLabelAc<vity.java

RetornandoaA<vidade
BueonconrmBueon=(Bueon)ndViewById(R.id.conrm_info);
conrmBueon.setOnClickListener(newView.OnClickListener(){
publicvoidonClick(nalViewview){
Bundlebundle=newBundle();
O que um
StringlabelStr=labelBox.getText().toString();
bundle?
bundle.putString(INFO,labelStr);
StringinfoStr=infoBox.getText().toString();
bundle.putString(LABEL,infoStr);
O que esse
bundle.putInt(LAT,myIntent.getIntExtra(LAT,0)); mtodo
est
bundle.putInt(LON,myIntent.getIntExtra(LON,0)); fazendo?
IntentmIntent=newIntent();
mIntent.putExtras(bundle);
setResult(RESULT_OK,mIntent);
Quem recebe
nish();
essas
}
informaes?
});
GetAddrLabelAc<vity.java

onAc<vityResult
AddressBookAc<vity.java

protectednalvoidonAc<vityResult(nalintrequestCode,
nalintresultCode,nalIntentintent){
super.onAc<vityResult(requestCode,resultCode,intent);
if(requestCode==this.addrLbl){
De onde vem
Bundleextras=intent.getExtras();
esse objeto?
StringinfoStr=extras.getString(INFO);
StringlabelStr=extras.getString(LABEL);
intlat=extras.getInt(LAT);
intlon=extras.getInt(LON);
Temos de
entar
m
le
p
im
addAddress(infoStr,labelStr,lat,lon);
sse mtodo.
e
}
Onde essa
}
informao
foi criada?

AdicionandoEventos
AddressBookAc<vity.java

privatevoidaddAddress(Stringinfo,Stringlabel,intlat,intlon){
SQLiteDatabasedb=addrs.getWritableDatabase();
ContentValuesvalues=newContentValues();
values.put(LAT,lat);
values.put(LON,lon);
values.put(INFO,info);
values.put(LABEL,label);
db.insertOrThrow(TABLE_NAME,null,values);
}

AddressBookAc<vity.java
classOnTouchOverlayextendscom.google.android.maps.Overlay{
@Override
publicbooleanonTouchEvent(Mo<onEventevent,MapViewmapView){ Por que no
passamos
if(event.getAc<on()==Mo<onEvent.ACTION_DOWN){
esses dados
Intentintent=newIntent(AddressBookAc<vity.this,
diretamente?
GetAddrLabelAc<vity.class);
GeoPointp=mapView.getProjec<on().fromPixels((int)event.getX(),
(int)event.getY());
intent.putExtra(LAT,p.getLa?tudeE6());
intent.putExtra(LON,p.getLongitudeE6());
AddressBookAc<vity.java
startAc?vityForResult(intent,addrLbl);
}
protectednalvoidonAc?vityResult(nalintrequestCode,
returnfalse;
nalintresultCode,nalIntentintent){
}
super.onAc<vityResult(requestCode,resultCode,intent);
a
}
estar
t
if(requestCode==this.addrLbl){
o
m
o
C
Bundleextras=intent.getExtras();
o?

a
c
i
l
p
a
StringinfoStr=extras.getString(INFO);
StringlabelStr=extras.getString(LABEL);
intlat=extras.getInt(LAT);
O que seria
intlon=extras.getInt(LON);
um bom
addAddress(infoStr,labelStr,lat,lon);
teste?
}
}

MostrandoosEventos
AddressBookAc<vity.java

@Override
publicbooleanonKeyDown(intkeyCode,KeyEventevent){
switch(keyCode){
caseKeyEvent.KEYCODE_ENTER:
showEvents(getEvents());
break;
}
returnsuper.onKeyDown(keyCode,event);
}
e
esse
o
d
n
a
u
Q
ser
o
t
n
e
v
e
do?
a
r
a
p
s
i
d

Qual a maneira
mais simples de
implementar
esse mtodo?

qu
Lembra os de
em
ainda t
ntar
e
m
e
l
p
im
o.
a
r
e
p
o
essa

RecuperandoDadosArmazenados
AddressBookAc<vity.java

privatesta<cString[]FROM={_ID,LABEL,INFO,LAT,LON,};
privateCursorgetEvents(){
SQLiteDatabasedb=AddressBookAc<vity.addrs.getReadableDatabase();
Cursorcursor=db.query(TABLE_NAME,FROM,null,null,null,null,null);
startManagingCursor(cursor);
returncursor;
}
Como imprimir
os dados
recuperados?

MostrandoosEventos
privatevoidshowEvents(Cursorcursor){
while(cursor.moveToNext()){
Log.v("showinf",cursor.getString(cursor.getColumnIndex(INFO)));
Log.v("showlbl",cursor.getString(cursor.getColumnIndex(LABEL)));
Log.v("showlat",cursor.getString(cursor.getColumnIndex(LAT)));
Log.v("showlon",cursor.getString(cursor.getColumnIndex(LON)));
}
}
AddressBookAc<vity.java
E como exibir
esses eventos
em uma lista?

Que evento
ar
m
a
h
c
a
i
r
e
v
de
a lista?

Oops:Manifesto!
<ac<vity
android:name=".AddressBookAc<vity"
android:label="@string/<tle_ac<vity_main">
<intentlter>
<ac<onandroid:name="android.intent.ac<on.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intentlter>
</ac<vity>
<ac<vity
android:name=".GetAddrLabelAc<vity"
android:theme="@android:style/Theme.Dialog">
</ac<vity>

AdicionandomaisumEvento
@Override
publicbooleanonKeyDown(intkeyCode,KeyEventevent){
switch(keyCode){
caseKeyEvent.KEYCODE_0:
Intentintent=newIntent(AddressBookAc<vity.this,AddressList.class);
llIntent(intent,getEvents(),"DATA");
startAc<vity(intent);
break;
caseKeyEvent.KEYCODE_ENTER:
showEvents(getEvents());
Como passar os
break;
dados a serem
}
exibidos para a
returnsuper.onKeyDown(keyCode,event);
atividade lista?
}
AddressBookAc<vity.java

PassandoListasdeDados
AddressBookAc<vity.java

privatevoidllIntent(Intentintent,Cursorcursor,Stringname){
ArrayList<String>list=newArrayList<String>();
while(cursor.moveToNext()){
Stringdata="";
data+=cursor.getString(cursor.getColumnIndex(INFO));
data+=","+cursor.getString(cursor.getColumnIndex(LABEL));
data+="("+cursor.getString(cursor.getColumnIndex(LAT));
data+=","+cursor.getString(cursor.getColumnIndex(LON))+")";
list.add(data);
}
Para que
intent.putStringArrayListExtra("DATA",list); servir
essa
}
constante?

DisparandoA<vidades
@Override
publicbooleanonKeyDown(intkeyCode,KeyEventevent){
switch(keyCode){
caseKeyEvent.KEYCODE_0:
Intentintent=newIntent(AddressBookAc<vity.this,AddressList.class);
llIntent(intent,getEvents(),"DATA");
Qual a diferena
startAc?vity(intent);
entre
break;
startActivity e
caseKeyEvent.KEYCODE_ENTER:
startActivityFor
showEvents(getEvents());
Result?
break;
}
returnsuper.onKeyDown(keyCode,event);
Precisamos
implementar o
}
AddressBookAc<vity.java

visualizador.

LayoutdaLista

Como ser o
layout dessa
atividade?

addresslist.xml

LayoutdaLista

<?xmlversion="1.0"encoding="u?8"?>
<LinearLayout
xmlns:android="hEp://schemas.android.com/apk/res/android"
android:layout_width="ll_parent"
android:layout_height="ll_parent">
<!Notebuiltinidsfor'list'and'empty'>
<ListView
android:id="@android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/empty"/>
</LinearLayout>

No esqueam
as constantes.

Como ser a
atividade?

AddressList.java

ListAc<vity
Quem
preencheu
esses dados?

publicclassAddressListextendsListAc<vity{
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.addresslist);
Intentintent=getIntent();
ArrayList<String>entries=intent.getStringArrayListExtra("DATA");
this.setListAdapter(newArrayAdapter<String>(this,R.layout.row,entries));
}
Precisamos
}
definir o
layout de uma
linha.

AddressList.java

ListAc<vity

publicclassAddressListextendsListAc<vity{
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.addresslist);
Intentintent=getIntent();
ArrayList<String>entries=intent.getStringArrayListExtra("DATA");
this.setListAdapter(newArrayAdapter<String>(this,R.layout.row,entries));
}
row.xml
}
<?xmlversion="1.0"encoding="UTF8"?>
<TextViewandroid:id="@+id/text1"
xmlns:android="hep://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

Exerccio:adicionandoumMenu
Modifique a agenda de
endereos para que ela
utilize um menu para criar
a lista de endereos. Esse
menu deve possuir uma
opo: Show in list, que
quando selecionada exibe a
atividade AddressList.

AdicionandoumMenu
AddressBookAc<vity.java

privatesta<cnalintSHOW_LIST=1;
publicbooleanonCreateOp<onsMenu(Menumenu){
menu.add(Menu.NONE,SHOW_LIST,Menu.NONE,"Showinlist");
returntrue;

publicbooleanonOp<onsItemSelected(MenuItemitem){
switch(item.getItemId()){
caseSHOW_LIST:
Intentintent=newIntent(AddressBookAc<vity.this,AddressList.class);
llIntent(intent,getEvents(),"DATA");
startAc<vity(intent);
returntrue;
default:
;
}
returnfalse;

Exerccio:visualizandomarcadores
Modifique o menu da
agenda de endereos para
que ele contenha mais duas
opes:
I) Markers ON: coloca um
marcador sobre cada
endereo armazenado
no banco de dados.
II) Markers OFF: remove
os marcadores.

AddressBookAc<vity.java

UmaDicaparaoMenu

@Override
publicbooleanonOp<onsItemSelected(MenuItemitem){
switch(item.getItemId()){
caseSHOW_LIST:
Intentintent=newIntent(AddressBookAc<vity.this,AddressList.class);
llIntent(intent,getEvents(),"DATA");
startAc<vity(intent);
returntrue;
caseSHOW_MARKERS:
MarkerOverlayovly=newMarkerOverlay(this);
setMarkers(ovly);
mapView.getOverlays().add(ovly);
mapView.invalidate();
returntrue;
caseHIDE_MARKERS:
mapView.getOverlays().clear();
mapView.invalidate();
privatevoidsetMarkers(MarkerOverlayovly){
returntrue;
Cursorcursor=getEvents();
default:
while(cursor.moveToNext()){
;
intlat=cursor.getInt(cursor.getColumnIndex(LAT));
intlon=cursor.getInt(cursor.getColumnIndex(LON));
}
ovly.addCoordinate(newGeoPoint(lat,lon));
returnfalse;
}
}
}