Programação para a Plataforma Android Aula 13 Localização O que são serviços baseados em localização? Como usar a API de mapas do Google? Como sobrepor diferentes visões a um mapa? Como integrar o mapa aos demais componentes gráficos? Quais visões podem ser acopladas à mapas? Como usar serviços de localização sem mapas?
Onde Estou? Que recursos um smart phone pode usar para saber a própria localização?
Provedores de Localização Android suporta sensores que captam sinais de satélites do sistema Geo Posi(oning Systems (GPS). Android suporta sensores que determinam a localização do aparelho móvel via triangulação com redes de telefonia celular. Android também suporta provedores de localização baseados em redes wi fi.
Onde estou? Serviço de localização: Escreva uma aplicação que imprima em uma caixa de texto simples a localização do aparelho móvel, e o servidor de localização utilizado para determiná-la.
Permissões <?xml version="1.0" encoding="uv 8"?> <manifest xmlns:android="hzp://schemas.android.com/apk/res/android" package="com.aula13" android:versioncode="1" android:versionname="1.0"> <uses permission android:name="android.permission.access_coarse_location" /> <uses permission android:name="android.permission.access_fine_location" /> <applicabon android:icon="@drawable/icon" android:label="@string/app_name"> <acbvity android:name=".aulaacbvity13" android:label="@string/app_name"> <intent filter> <acbon android:name="android.intent.acbon.main" /> <category android:name="android.intent.category.launcher" /> </intent filter> </acbvity> </applicabon> <uses sdk android:minsdkversion="2" /> </manifest> Nós já vimos um tipo de permissão antes. Qual?
Layout Informações de localização serão impressas em uma caixa de texto. Essas informações podem ocupar uma string maior que os limites da caixa de texto. Mas, por agora, já sabemos como construir esse layout!
main.xml ScrollView Passemos agora à atividade <?xml version="1.0" encoding="uv 8"?> <ScrollView xmlns:android="hzp://schemas.android.com/apk/res/android" android:orientabon="verbcal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/output" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </ScrollView>
Abvidade de Localização public class AulaAcbvity13 extends Acbvity implements Loca.onListener { @Override public void oncreate(bundle savedinstancestate) {... @Override protected void onresume() {... O que deveria ser feito em @Override onresume? protected void onpause() {... AulaAcbvity13.java Quais eventos de localização devem existir? E o que deveria ser feito em onpause?
onresume/onpause AulaAcbvity13.java private Loca.onManager mgr; private String best; @Override protected void onresume() { super.onresume(); mgr.requestlocabonupdates(best, 15000, 1, this); @Override protected void onpause() { super.onpause(); mgr.removeupdates(this); Que tipo de objeto é esse? E por que onpause foi implementado assim? O que serão esses parâmetros? O que onresume está fazendo? Mas como será o método oncreate?
oncreate @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); Temos de implementar esse log. O que um objeto desse sabe fazer? mgr = (LocabonManager) getsystemservice(location_service); output = (TextView) findviewbyid(r.id.output); log("locabon providers:"); dumpproviders(); Criteria criteria = new Criteria(); best = mgr.getbestprovider(criteria, true); log("\nprovedor escolhido: " + best); log("\nlocalizacao (comecando com ulbma conhecida):"); Loca.on locabon = mgr.getlastknownlocabon(best); dumplocabon(locabon); O que se passa aqui?
Eventos de Localização A nossa abvidade é também um escutador de eventos de localização. Quais seriam os eventos de localização? AulaAcbvity13.java public class AulaAcbvity13 extends Acbvity implements Loca.onListener {
Eventos de Localização public void onlocabonchanged(locabon locabon) { ; public void onproviderdisabled(string provider) { ; public void onproviderenabled(string provider) { ; Como seria a implementação de cada um desses métodos? public void onstatuschanged(string provider, int status, Bundle extras) { ; AulaAcbvity13.java
Eventos de Localização public void onlocabonchanged(locabon locabon) { dumplocabon(locabon); public void onproviderdisabled(string provider) { log("\nprovedor inoperante: " + provider); public void onproviderenabled(string provider) { log("\nprovedor operante: " + provider); O que é esse parâmetro status? Temos um arranjo para criar! public void onstatuschanged(string provider, int status, Bundle extras) { log("\no estado do provedor mudou: " + provider + ", status=" + S[status] + ", extras=" + extras);
Eventos de Localização public void onlocabonchanged(locabon locabon) { dumplocabon(locabon); public void onproviderdisabled(string provider) { log("\nprovedor inoperante: " + provider); private stabc final String[] S = { "out of service", public void onproviderenabled(string provider) { "temporarily unavailable", log("\nprovedor operante: " + provider); "available" Temos de implementar os outros métodos de nossa atividade. Vocês lembram quais são eles? }; public void onstatuschanged(string provider, int status, Bundle extras) { log("\no estado do provedor mudou: " + provider +, status=" + S[status] + ", extras=" + extras);
AulaAcbvity13.java Os dump s private void log(string string) { output.append(string + "\n"); private void dumplocabon(locabon locabon) { if (locabon == null) log("\nlocabon[unknown]"); else log("\n" + locabon.tostring()); private void dumpproviders() { List<String> providers = mgr.getallproviders(); for (String provider : providers) { dumpprovider(provider); Esse método, dumpprovider, ainda precisa ser implementado.
AulaAcbvity13.java Informações de Localização private void dumpprovider(string provider) { LocabonProvider info = mgr.getprovider(provider); StringBuilder builder = new StringBuilder(); Novamente, precisamos definir alguns arranjos. builder.append("locabonprovider[").append("name=").append(info.getname()).append(",enabled=").append(mgr.isproviderenabled(provider)).append( ",getaccuracy=").append(a[info.getaccuracy() + 1]).append( ",getpowerrequirement=").append(p[info.getpowerrequirement() + 1]).append(",hasMonetaryCost=").append(info.hasMonetaryCost()).append( ",requirescell=").append(info.requirescell()).append( ",requiresnetwork=").append(info.requiresnetwork()).append( ",requiressatellite=").append(info.requiressatellite()).append( ",supportsalbtude=").append(info.supportsalbtude()).append( ",supportsbearing=").append(info.supportsbearing()).append( ",supportsspeed=").append(info.supportsspeed()).append("]"); log(builder.tostring()); O que é isso?
Informações de Localização private sta.c final String[] A = { "invalid", private void dumpprovider(string provider) { LocabonProvider info = mgr.getprovider(provider); "n/a", StringBuilder builder = new StringBuilder(); "fine", builder.append("locabonprovider[").append("name=").append(info.getname()) "coarse".append(",enabled=").append(mgr.isproviderenabled(provider)).append( ",getaccuracy=").append(a[info.getaccuracy() + 1]).append( }; ",getpowerrequirement=").append(p[info.getpowerrequirement() + 1]).append(",hasMonetaryCost=").append(info.hasMonetaryCost()).append( private sta.c final String[] P = { ",requirescell=").append(info.requirescell()).append( "invalid", ",requiresnetwork=").append(info.requiresnetwork()).append( "n/a", ",requiressatellite=").append(info.requiressatellite()).append( ",supportsalbtude=").append(info.supportsalbtude()).append( "low", ",supportsbearing=").append(info.supportsbearing()).append( "medium", ",supportsspeed=").append(info.supportsspeed()).append("]"); "high" log(builder.tostring()); };
Emulador Se tentarmos carregar a aplicação, não obteremos nenhuma informação de localização. Podemos passar essas informações pelo emulador, na tela Emulator Control View. Window > Show View > Other... > Android > Emulator Control
Simulando a Localização Se tentarmos carregar a aplicação, não obteremos nenhuma informação de localização. Podemos passar essas informações pelo emulador, na tela Emulator Control View. Window > Show View > Other... > Android > Emulator Control
Locabon Tracker Rastreador de caminho: Implemente um rastreador de caminho, que grave a sequência de posições percorridas pelo dispositivo móvel, e que imprima a distância total percorrida. Como será esse layout?
<LinearLayout xmlns:android="h;p://schemas.android.com/apk/res/android" android:id="@+id/root" android:orientabon="ver(cal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/lat" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/la;ext"/> <EditText android:id="@+id/latname" android:focusable="false" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <TextView android:id="@+id/lon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/lontext"/> <EditText android:id="@+id/lonname" android:focusable="false" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <TextView android:id="@+id/dist" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/dis;ext"/> <EditText android:id="@+id/distname" android:focusable="false" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </LinearLayout> tracker.xml Locabon Tracker Qual o modelo dessa aplicação?
Tracker.java Tracker public class Tracker extends Acbvity implements LocabonListener { private LocabonManager mgr; private List<Locabon> track; private String best; private EditText lat; private EditText lon; private EditText dist; O que é preciso ser feito no método oncreate?
Tracker.java oncreate public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.tracker); track = new ArrayList<Locabon>(); mgr = (LocabonManager) getsystemservice(location_service); Criteria criteria = new Criteria(); best = mgr.getbestprovider(criteria, true); this.lat = (EditText) findviewbyid(r.id.latname); this.lon = (EditText) findviewbyid(r.id.lonname); this.dist = (EditText) findviewbyid(r.id.distname); updateloca.on(); Como seria este método de atualizar a localização?
Atualizando a Localização Tracker.java private void updatelocabon() { Locabon locabon = mgr.getlastknownlocabon(best); lat.settext(string.valueof(locabon.getlabtude())); lon.settext(string.valueof(locabon.getlongitude())); dist.settext(computepathlength() + "m"); this.track.add(locabon); E como podemos calcular a distância percorrida?
Tracker.java Calculando distâncias private CharSequence computepathlength() { if (track.size() == 0) { return "0"; else { Locabon last = track.get(0); double dist = 0.0; for (int i = 1; i < this.track.size(); i++) { Locabon newloc = this.track.get(i); dist += last.distanceto(newloc); last = newloc; return String.valueOf(dist); Precisamos algora implementar os métodos de eventos. Vocês lembram que métodos são esses? Na verdade, precisamos de escrever somente um!
Eventos de Localização public void onlocabonchanged(locabon locabon) { ; O que escrevemos aqui? public void onproviderdisabled(string provider) { public void onproviderenabled(string provider) { public void onstatuschanged(string provider, int status, Bundle extras) {
Eventos de Localização public void onlocabonchanged(locabon locabon) { this.updatelocabon(); public void onproviderdisabled(string provider) { Mesmo que não usemos os métodos, precisamos public void onproviderenabled(string provider) { implementá-los. Por que? E o que normalmente se faz para evitar esse public void onstatuschanged(string provider, transtorno? int status, Bundle extras) {
Poupando Recursos Tracker.java @Override protected void onresume() { super.onresume(); mgr.requestlocabonupdates(best, 15000, 1, this); @Override protected void onpause() { super.onpause(); mgr.removeupdates(this); E se quiséssemos calcular a velocidade de deslocamento, o que precisaria ser feito?
Probleminha Besta Tracker.java private void updatelocabon() { Locabon locabon = mgr.getlastknownlocabon(best); lat.settext(string.valueof(locabon.getlabtude())); lon.settext(string.valueof(locabon.getlongitude())); dist.settext(computepathlength() + "m"); this.track.add(locabon); Notem que a distância somente aparece quando enviamos valores para o emulador duas ou mais vezes. A posição original não está sendo levada em consideração quando computamos a distância. Como resolver esse problema?
Easy Fix Tracker.java private void updatelocabon() { Locabon locabon = mgr.getlastknownlocabon(best); lat.settext(string.valueof(locabon.getlabtude())); lon.settext(string.valueof(locabon.getlongitude())); this.track.add(locabon); dist.settext(computepathlength() + "m"); Estamos computando a distância antes de inserirmos as coordenadas da última localização.