12. Přednáška Zjišťování polohy Google Mapy OverlayItem Zálohování Data Backup 2
3 Zjišťování polohy K získávání informací o poloze slouží třída LocationManager Typicky se zavolá její metoda requestlocationupdates() které se předá LocationListener Přes LocationListener budeme dostávat updaty, když se změní poloha.
4 Zjišťování polohy 1. // Acquire a reference to the system Location Manager 2. LocationManager locationmanager = (LocationManager) 3. this.getsystemservice(context.location_service); 4. 5. // Define a listener that responds to location updates 6. LocationListener locationlistener = new LocationListener() { 7. public void onlocationchanged(location location) { 8. // Called when a new location is found by the network 9. location provider. 10. makeuseofnewlocation(location); 11. } 12. public void onstatuschanged(string provider, int status, 13. Bundle extras) {} 14. public void onproviderenabled(string provider) {} 15. public void onproviderdisabled(string provider) {} 16.}; 17.// Register the listener with the Location Manager to 18.receive location updates 19.locationManager.requestLocationUpdates( 20. LocationManager.NETWORK_PROVIDER,0, 0, locationlistener);
5 Zjišťování polohy První argument requestlocationupdates() je zdroj polohy. To mohou být tyto konstanty třídy LocationManager: GPS_PROVIDER, NETWORK_PROVIDER, PASSIVE_PROVIDER. GPS_PROVIDER má přesnost v řádu jednotek až desítek metrů NETWORK_PROVIDER je poloha určená na základě okolních mobilních ústředen nebo WiFi sítí. Je méně přesná než GPS, ale obvykle je zjištění polohy touto metodou rychlejší
6 Zjišťování polohy Další 2 argumenty říkají, jak často se má poloha aktualizovat. Tj. jaký je minimální časový interval a jaká je minimální vzdálenost mezi jednotlivými aktualizacemi polohy. Metoda getlastknownlocation() vrátí poslední známou polohu. Pro zjišťování polohy je potřeba v manifestu deklarovat oprávnění ACCESS_FINE_LOCATION nebo ACCESS_COARSE_LOCATION, podle toho jestli se bude používat GPS nebo jenom poloha ze sítě.
7 Zjišťování polohy Většinou se requestlocationupdates() volá v onresume() a v onpause() se aktualizace polohy zruší metodou removeupdates(), aby se zbytečně nevybíjela baterie. Pokud chceme získávat aktualizace polohy bez ohledu na to jestli je naše Activity zobrazena nebo ne (např. různé GPS trackery jako RunKeeper), použijeme Service.
8 Zjišťování polohy V praxi může být zjišťování polohy trochu složitější Často je vhodné kombinovat oba hlavní zdroje polohy (GPS_PROVIDER a NETWORK_PROVIDER). Co když ale máme 5 min starou GPS polohu a 1 min starou nepřesnou polohu ze sítě? Podobné je to s rozhodováním, jestli použít poslední známou polohu (getlastknownlocation). Jak to řešit: http://developer.android.com/guide/topics/location/ obtaining-user-location.html
9 Location Polohu reprezentuje třída Location Má mimo jiné metody pro zjištění Polohy - getlatitude(), getlongitude() Přesnosti - getaccuracy() Rychlosti - getspeed() Nadm. výšky - getaltitude() GetProvider - zdroj polohy (např. GPS, NETWORK) distanceto(location) vrací vzdálenost k zadané poloze.
10 Google Mapy Google Mapu lze vložit do Android aplikace pomocí MapView, které musí být uvnitř MapActivity Aby mapa fungovala je třeba získat API klíč Mapu lze pomocí Overlay překrýt vlastní vrstvou, typicky to budou "piny" nebo zobrazení trasy
11 Nastavení projektu Google Mapy nejsou součástí Android SDK V Eclipse Project > Properties > Android nastavíme build target na Google APIs V manifestu deklarujeme, 1) že aplikace používá Google Maps knihovnu 2) oprávnění INTERNET 1. <application 2. android:name="myapplication"> 3. <uses-library 4. android:name="com.google.android.maps" /> 5.... 6. </application> 7. <uses-permission 8. android:name="android.permission.internet" /> Pokud není tato knihovna v zařízení, aplikace nepůjde nainstalovat
12 Získání API klíče Z certifikátu, kterým podepisujeme naši aplikaci vytvoříme MD5 otisk (jak na to - http://code.google.com/android/addons/google-apis/mapkey.html) Zde - http://code.google.com/android/add-ons/googleapis/maps-api-signup.html - odsouhlasíme podmínky, vložíme MD5 otisk a vygenerujeme náš API klíč Bez API klíče se nebudou načítat mapové podklady, vše ostatní bude fungovat
13 MapView V MapActivity lze vložit MapView programově nebo načíst layout, který MapView obsahuje: 1. <?xml version="1.0" encoding="utf-8"?> 2. <RelativeLayout 3. xmlns:android="http://schemas.android.com/apk/res/android" 4. android:id="@+id/mainlayout" 5. android:orientation="vertical" 6. android:layout_width="fill_parent" 7. android:layout_height="fill_parent"> 8. 9. <com.google.android.maps.mapview 10. android:id="@+id/mapview" 11. android:layout_width="fill_parent" 12. android:layout_height="fill_parent" Bez android:clickable nebude mapa reagovat na dotyky 13. android:clickable="true" 14. android:apikey="your Maps API Key" /> 15.</RelativeLayout>
14 MapView 1. public class HelloMapView extends MapActivity { 2. @Override 3. protected boolean isroutedisplayed() { 4. return false; 5. } 6.... 7. mapview = (MapView) findviewbyid(r.id.mapview); 8. mapview.setbuiltinzoomcontrols(true); mapview.setbuiltinzoomcontrols(true); zobazí tlačítka pro přiblížení a oddálení
15 MapView Metody setsatelitte(boolean), setstreetview(boolean) a settraffic(boolean) nastavují mapový podklad. Mapu lze ovládat přes MapController, ten získáme metodou MapView.getController() MapController umožňuje např.: Zoomování - zoomin(), setzoom(),... Posunout mapu - setcenter(geopoint), animateto(geopoint),...
17 ItemizedOverlay V konstruktoru naší podtřídy ItemizedOverlay tedy bude: super(boundcenterbottom(defaultmarker)); OverlayItem reprezentuje jednotlivé značky, jejich seznam si budeme udržovat v moverlays: private ArrayList<OverlayItem> moverlays = new ArrayList<OverlayItem>(); Vytvoříme metodu, pomocí které budeme přidávat značky. Aby se přidaná značka objevila na mapě,zavoláme populate() public void addoverlay(overlayitem overlay) { moverlays.add(overlay); populate(); }
18 ItemizedOverlay populate() se dotáže na naše značky tak, že volá funkce createitem(int) a size(), ty proto overridneme @Override protected OverlayItem createitem(int i) { return moverlays.get(i); } @Override protected OverlayItem size() { return moverlays.size(); } To je pro ItemizedOverlay vše, nyní ho propojíme s MapView
19 ItemizedOverlay 1. 2. 3. 4. 5. 6. 7. 8. 9. List<Overlay> mapoverlays = mapview.getoverlays(); Drawable drawable = this.getresources(). getdrawable(r.drawable.mapmarker); HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable); GeoPoint point = new GeoPoint(19240000,-99120000); OverlayItem overlayitem = new OverlayItem(point, "", ""); itemizedoverlay.addoverlay(overlayitem); mapoverlays.add(itemizedoverlay); Přidá jednu značku na mapu. Konstruktoru GeoPoint se předá latitude a longitude vynásobené 1 000 000.
20 MyLocationOverlay MyLocationOverlay je Overlay, který zobrazuje na mapě aktuální polohu. MyLocationOverlay#runOnFirstFix nastavuje co se má stát, když se poprvé získá poloha enablemylocation() a disablemylocation() zapne/vypne zjišťování polohy. Je to vhodné volat v onpause() a onresume(), aby načítání polohy probíhalo pouze když je Activity na popředí. 1. 2. 3. 4. 5. 6. 7. 8. mylocationoverlay = new MyLocationOverlay(getContext(), mapview); mylocationoverlay.runonfirstfix(new Runnable() { @Override public void run() { mapview.getcontroller().animateto(mylocationoverlay.getmylocation()); } }); mapview.getoverlays().add(mylocationoverlay);
21 Intenty map Pro zobrazení určitého místa na mapě je nejjednodušší použít Intent, který otevře Google Mapy nebo jinou mapovou aplikaci. Intent URI: geo:latitude,longitude geo:latitude,longitude?z=zoom geo:0,0?q=my+street+address geo:0,0?q=business+near+city Intent action: VIEW
22 Data Backup Android umožňuje zálohování dat do cloudu Po znovu nainstalování aplikace se její data automaticky obnoví Zálohy se ukládají na servery Googlu => mohou se tedy obnovit i pokud uživatel vymění zařízení Podporovány jsou všechny zařízení s Anroid OS >= 2.2, na kterých je nainstalován Android Market Uživatel musí mít povoleno zálohování a obnovení v nastavení systému (Ochrana osobních údajů)
23 Data Backup Pro implementaci zálohování je potřeba těchto kroků: 1. Deklarování backup agenta v AndroidManifestu pomocí atributu android:backupagent 2. Zaregistrování vaší aplikace na této stránce: http://code.google.com/intl/cs/android/backup/index.html vložení získaného klíče do AndroidManifestu 3. Definování backup agenta rozšířením třídy a BackupAgent pokud je potřeba pokročilejší kontroly nad zálohováním b) BackupAgentHelper pokud stačí základní funkčnost pro zálohování SharedPreferences nebo souborů a) 4. 5. Pro zaregistrování změny u zálohovaných souborů zavolat BackupManager.dataChanged(getPackageName()); Obnova dat probíhá automaticky při instalaci aplikace. Manuálně však lze vyžádat pomocí BackupManager.requestRestore
24 Data Backup AndroidManifest Do AndroidManifestu vložíme do tagu application: jméno třídy, která extenduje BackupAgent nebo BackupAgentHelper Tag meta data se získaným klíčem (je platný pouze pro aplikaci s daným jménem balíčku) <application android:label="@string/app_name" android:backupagent=".mybackupagent">... <meta-data android:name="com.google.android.backup.api_key" android:value="získaný klíč" /> </application>
25 Data Backup BackupAgentHelper Poskytuje funkčnost pro jednoduché zálohování lokálních souborů nebo SharedPreferences na pár řádků Pro každý typ dat stačí vytvořit 1 BackupHelper se jmény souborů v konstruktoru SharedPreferencesBackupHelper FileBackupHelper Zavoláním metody addhelper(key, helper); přidáme helper do agenta a přiřadíme mu unikátní klíč
26 Data Backup BackupAgentHelper 1. public class MyBackupAgent extends BackupAgentHelper{ @Override public void oncreate() { BackupHelper prefs = new SharedPreferencesBackupHelper(this, getdefaultsharedpreferencesname()); BackupHelper files = new FileBackupHelper(this, "fname1", "fname2"); 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.} addhelper("prefs", prefs); addhelper("files", files); super.oncreate(); } private String getdefaultsharedpreferencesname() { return getpackagename() + "_preferences"; }
27 Data Backup - BackupAgent Pokud potřebujeme kontrolu nad verzováním, zálohovat pouze část dat nebo data ze SQLite databáze Potřeba naimplementovat onbackup(oldstate, data, newstate) oldstate lokální informace o stavu poslední zálohy; používá se např pro kontrolu, jestli došlo ke změně dat data objekt, do kterého zapíšeme zálohu newstate objekt, který bude příště vrácen jako oldstate (uložíme informace o aktuální záloze) onrestore(data, appversioncode, newstate) data data, která budeme obnovovat appversioncode číslo verze aplikace při poslední záloze newstate uložíme informace o aktuální záloze
28 Data Backup testování 1. Nainstalujeme aplikaci 2. Ujistíme se, že máme povoleno zálohování a obnovení dat v systému Pokud používáme emulátor, povolíme zálohy pomocí příkazu adb shell bmgr enable true U zařízení otevřeme nastavení, ochrana os. údajů, a zaškrtneme Zálohovat moje data a Automatické obnovení 1. Otevřeme naší aplikaci a uložíme nějaká data Při změně bychom měli vždy volat datachanged() Manuálně však můžeme informovat systém o změně pomocí adb shell bmgr backup your.package.name 1. Zahájíme zálohování (abychom nemuseli čekat ) adb shell bmgr run Odinstalujeme a znovu nainstalujeme aplikaci Data zálohovaná v bodu 4 by měla být obnovena