Geavanceerde contextbepaling door middel van sensoren op een mobiel toestel
Gert-Jan De Proft en Stijn Vanoverschelde
Promotoren: prof. dr. ir. Filip De Turck, dr. ir. Tim Wauters Begeleiders: Philip Leroux, Klaas Roobroeck Masterproef ingediend tot het behalen van de academische graad van Master in de toegepaste informatica
Vakgroep Informatietechnologie Voorzitter: prof. dr. ir. Daniël De Zutter Faculteit Ingenieurswetenschappen Academiejaar 2009-2010
Voorwoord
Grote projecten zoals deze gaan typisch gepaard met een aantal obstakels: onvoorziene problemen waardoor de initiële planning niet meer klopt, misverstanden, perikelen die net voor de deadline tot grote stress leiden, etc. Bij het tot stand komen van deze masterproef was dit niet anders. Toch stonden we voor nog een aantal andere, bijkomende uitdagingen: niet alleen kregen we een voor ons volledig onbekend onderwerp om ons in te verdiepen, ook de tijdspanne om alles af te werken was behoorlijk kort. Daarnaast hadden wij nog nooit samengewerkt en kenden we elkaar nog niet bijzonder goed. Gaandeweg geraakten we echter goed op elkaar ingespeeld en ook op het vlak van programmeren ging het steeds beter. Dit laatste hebben we niet in het minst te danken aan onze begeleiders, Philip Leroux en Klaas Roobroeck, die steeds klaarstonden om ons extra uitleg te bezorgen, raad te geven en oplossingen te zoeken voor onze talrijke problemen en vragen. Zonder hen hadden we deze taak nooit tot een goed einde kunnen brengen, waarvoor we hen dan ook van harte willen bedanken.
Gert-Jan De Proft en Stijn Vanoverschelde
Toelating tot bruikleen
De auteurs geven de toelating deze masterproef voor consultatie beschikbaar te stellen en delen van de masterproef te kopiëren voor persoonlijk gebruik. Elk ander gebruik valt onder de beperkingen van het auteursrecht, in het bijzonder met betrekking tot de verplichting de bron uitdrukkelijk te vermelden bij het aanhalen van resultaten uit deze masterproef.
Gent, 28 mei 2010
Inhoudstafel
Hoofdstuk 1: Inleiding .............................................................................................................. 1 1. Situering en doelstellingen .................................................................................................... 1 2. Concrete uitwerking: use case .............................................................................................. 2 Hoofdstuk 2: Technologiestudie ................................................................................................ 4 1. Wat is Android? ..................................................................................................................... 4 A. Algemeen overzicht ........................................................................................................ 4 B. Programmeren met Android ........................................................................................... 6 2. Android sensoren ................................................................................................................ 10 A. Algemeen ...................................................................................................................... 10 B. Welke sensoren zijn voorzien? ..................................................................................... 10 C. Gebruikte en niet gebruikte sensoren .......................................................................... 14 D. Vergelijking van drie Android toestellen....................................................................... 15 Hoofdstuk 3: Architectuur ...................................................................................................... 18 1. Implementatie van de bibliotheek in applicaties ................................................................ 18 2. Communicatie van de informatie........................................................................................ 19 Hoofdstuk 4: Implementatie ................................................................................................... 22 1. Eerste problemen bij het programmeren ........................................................................... 22 2. Algoritmes en logica ............................................................................................................ 23 A. Bepalen van de lichaamsstatus ..................................................................................... 23 B. Bepalen van het transportmiddel ................................................................................. 27 C. Bepalen van het omgevingslicht ................................................................................... 32 D. Bepalen van locatie via GPS / Ingeven locatie .............................................................. 37 E. Bepalen van omgevingsgeluid....................................................................................... 42 3. Uiteindelijke implementatie van de interfaces ................................................................... 43 Hoofdstuk 5: Besluit ............................................................................................................... 44 Bibliografie ............................................................................................................................ 46
Overzicht van figuren en tabellen
1. Figuren Figuur 1: De Android Architectuur ........................................................................................ 5 Figuur 2: Verduidelijking van het begrip Azimuth ............................................................... 12 Figuur 3: Verduidelijking van het begrip Pitch .................................................................... 12 Figuur 4: Verduidelijking van het begrip Roll ...................................................................... 12 Figuur 5: De drie besproken GSM-toestellen ...................................................................... 16 Figuur 6: Implementatie van de bibliotheek ....................................................................... 19 Figuur 7: Communicatie volgens het client-servermodel ................................................... 20 Figuur 8: Communicatie via Twitter .................................................................................... 21 Figuur 9: Oorspronkelijke constructie voor het bepalen van de lichaamsstatus ................ 25 Figuur 10: Overzicht van lichtcondities ............................................................................... 36 Figuur 11: Algoritme voor locatieweergave ........................................................................ 40
2. Tabellen Tabel 1: Beschrijving van de verschillende klassen ............................................................... 3 Tabel 2: Overzicht van de verschillende transportmiddelen............................................... 27 Tabel 3: Transportmiddelen en de snelheid waardoor ze bepaald worden ....................... 31
Nota: Soms wordt er kort een technische uitleg gegeven over de code, bijvoorbeeld over specifieke methoden. Om het onderscheid te maken met de rest van de tekst, worden deze stukken weergegeven met een aangepaste (grotere) insprong aan zowel de linker- als rechterzijde van de pagina.
Hoofdstuk 1: Inleiding
1. Situering en doelstellingen Een snelle blik op de straat, reclamefolders of televisie maken het meteen overduidelijk: mobiele telefoontoestellen zijn niet meer weg te denken uit ons leven. Steeds en overal bereikbaar zijn was nog nooit zo belangrijk. Vanaf hun doorbraak in de jaren ’90 kenden mobiele telefoons wereldwijd een verbazend grote opkomst. Niet alleen werden GSM-toestellen steeds populairder en meer verspreid onder de bevolking (probeer tegenwoordig nog maar iemand te vinden zonder GSM op zak), ook nam hun complexiteit sterk toe. Waar de functionaliteit aanvankelijk beperkt was tot telefoneren en berichten versturen, werden al gauw meer geavanceerde mogelijkheden geïmplementeerd.
Voorbeelden
hiervan
zijn
het
nemen
van
foto’s,
versturen
van
multimediaberichten (MMS of Multimedia Messaging Service) en zelfs verbinding met het internet. Bovendien zijn deze toestellen al lang niet meer exclusief voorbehouden voor de rijkste onder ons, maar zijn geavanceerde GSM-toestellen tegenwoordig betaalbaar en dus ook alomtegenwoordig. Deze technologische ontwikkelingen gaan nog steeds voort tot op heden, met als ultieme uitwerking de zogenaamde ‘smartphone’. Deze kan gedefinieerd worden als “een mobiele telefoon die meer rekenvermogen en connectiviteit heeft dan een basis telefoontoestel” [1]. Deze toestellen beschikken niet alleen over een volledig besturingssysteem als platform voor ontwikkelaars, maar meestal ook over een aantal uiteenlopende sensoren. Dat onze nieuwe telefoon over deze sensoren beschikt, is één zaak, maar wat zijn we hier dan concreet mee? Wat brengen ze ons bij? Dat is meteen het opzet van deze masterproef niet enkel het aanspreken van deze sensoren, maar vooral bepalen welke informatie we hieruit kunnen afleiden. We gaan dus op zoek naar welke data de sensoren ons bieden en welke betekenis hieraan gehecht kan worden. Hiervoor maken we gebruik van het Android platform, waarover meer informatie volgt in hoofdstuk 2. Ons hoofddoel is het opstellen van een bibliotheek die betekenis geeft aan de ruwe waarden die kunnen uitgelezen worden en er enige intelligentie aan toevoegen. We denken daarbij specifiek aan andere ontwikkelaars die deze bibliotheek kunnen implementeren bij het ontwerpen van hun eigen applicaties. Op deze manier kunnen zij ook meteen gebruik maken van de concrete informatie die uit het toestel gehaald kan worden en dienen zij zelf niet meer op zoek te gaan naar hoe ze deze data moeten verwerken. Het beschikbaar stellen van de bibliotheek kan dus een belangrijke bijdrage leveren aan de gemeenschap van ontwikkelaars.
1
2. Concrete uitwerking: use case Om aan te duiden wat er zoal mogelijk is met de door ons ontwikkelde bibliotheek, willen we zelf ook al een applicatie uitwerken die hiervan gebruik maakt. Het opzet is een programma dat de status bijhoudt van je vrienden, zodat je steeds kan nagaan waar ze zijn, waar ze mee bezig zijn, etc. We hebben ons daarvoor gebaseerd op de iPhone applicatie CenceMe [2], die ook nagaat welke informatie kan afgeleid worden uit allerlei sensoren. Dit wordt dan gepubliceerd op een van de drie grootste sociale netwerksites, met name Facebook, Myspace of Twitter. Voorbeelden van wat er zoal kan achterhaald worden, is de huidige locatie, hoe de weersomstandigheden daar zijn, of je vriend(in) op dat moment naar muziek luistert, etc. CenceMe is echter uitsluitend ontwikkeld voor de iPhone en bestaat dus nog niet voor het Android platform. Deze applicatie was een inspiratiebron voor ons, maar wij zoeken niet exact hetzelfde te verwezenlijken. In onze use case willen wij meer de klemtoon leggen op het ‘tracken’ van je vrienden. Wanneer je het programma opent, krijg je een overzicht van al je vrienden, met daarbij hun lichaamsstatus, hun locatie, de status van de omgeving, enz. Zo kan je zien dat je ene vriend thuis is, hij zijn telefoon niet bij de hand heeft, de omgeving donker en helemaal stil is. Die vriend is dan hoogstwaarschijnlijk aan het slapen, dus is het niet het moment om hem te storen! Een andere vriend blijkt dan weer bij een iemand op bezoek te zijn, terwijl hij actief beweegt in een luide omgeving. Misschien zit hij wel op een feestje. Op deze manier krijg je een beeld van waar je vrienden zijn en of ze al dan niet beschikbaar zijn. Iemand waarmee je hebt afgesproken is al vijf minuten te laat, maar blijkt onderweg te zijn en in de auto te zitten; dan weet je meteen dat hij er binnenkort wel zal zijn en het bespaart je ook een telefoontje. Door al je vrienden in eenzelfde venster te zien, ben je ook meer betrokken en werkt dit efficiënter dan op een website de status van elke vriend afzonderlijk na te gaan. Deze applicatie past volgens ons bijzonder goed in het hedendaags medialandschap waar sociale netwerken en constante communicatie sterk op de voorgrond staan.
2
De concrete informatie die wij willen verzamelen en weergeven bestaat uit de volgende klassen:
Klasse
Beschrijving
Transport
Wat is het huidige transportmiddel van de gebruiker?
Lichaamsstatus
In welke positie bevindt de gebruiker zich?
Locatie
Wat is de huidige locatie? (Bvb. Thuis, op het werk, …)
Omgevingslawaai Omgevingslicht Bereikbaarheid
Hoe luid is de omgeving? Wat voor lawaai wordt waargenomen? Wat zijn de lichtcondities? (Bvb. Donker, in het zonlicht, in de schaduw, …) Welke bestemmingen kunnen vanuit de huidige locatie bereikt worden binnen een bepaalde tijdspanne?
Tabel 1: Beschrijving van de verschillende klassen.
Wij hebben echter ook al op voorhand enkele bedenkingen bij de haalbaarheid van dit concept. Idealiter is de hierboven uiteengezette use case hetgeen we willen bereiken, het is het doel waar we naartoe werken. Rekening houdend echter met ons beperkte tijdsbestek van een zestal weken, is het mogelijk dat enkele aspecten de definitieve versie niet zullen halen. In een eerste overleg met de begeleiders werd ons duidelijk dat een geïntegreerd vriendensysteem niet zo eenvoudig is als het op het eerste zicht kan lijken. Hiervoor is een server nodig die alle informatie doorgeeft aan de clients, en de implementatie kan behoorlijk tijdrovend zijn. In het geval we in tijdsnood komen, bestaat de mogelijkheid dat we ervoor kiezen om de informatie toch door te geven via een website zoals Twitter. Deze interfaces zijn namelijk zeer snel te vinden en te implementeren. Deze uitwerking is iets minder interessant dan wat we voor ogen hebben, maar deze kan later of door andere ontwikkelaars nog steeds aangepast worden. Bovendien dient het vooral om een mogelijke implementatie van onze bibliotheek te illustreren. Het opstellen daarvan blijft dus ons hoofddoel. Onze grootste prioriteit is de bibliotheek volledig in orde krijgen, zodat deze beschikbaar kan gesteld worden voor andere ontwikkelaars. Dit aspect van onze masterproef is het meest relevante voor de praktijk en verdient daarom ook het meeste aandacht.
3
Hoofdstuk 2: Technologiestudie
1. Wat is Android?
A. Algemeen overzicht Tot en met 2005 maakten mobiele telefoons gebruik van een grote waaier aan besturingssystemen zoals Microsoft’s Windows Mobile, Mobile Linux, iPhone OS en nog heel wat andere merkgebonden systemen. Geen enkel operationeel besturingssysteem kon beschouwd worden als dé standaard. De openheid en beschikbare API’s (Application Programming Interfaces) liepen sterk achterop vergeleken met de ontwikkelingsomgeving voor desktops. Deze evolutie maakte een spectaculaire bocht toen Google in 2005 besloot om Android Inc. over te nemen, een jong en onbekend bedrijfje dat onder impuls van Google startte met de ontwikkeling van het Android platform. In het najaar van 2007 vormde Google samen met enkele prominente technologieleiders de Open Handset Alliance (OHA). Deze alliantie bestaat uit 65 hardware-, software- en telecommunicatiebedrijven, die zich erop richten open standaarden voor mobiele apparaten te bevorderen. Ongeveer 3 miljard mensen zijn in het bezit van een mobiel toestel wat het tot een van de belangrijkste consumentengoederen ter wereld maakt. De voornaamste doelstelling van de OHA is dan ook om een beter toestel te bouwen dat het leven van ontelbare mensen kan verrijken. Ze willen met name de mobiele ervaringen van consumenten veranderen en er een nieuwe dimensie aangeven. Daarnaast ijvert de alliantie sterk voor openheid bij het ontwikkelen en programmeren van applicaties. De groep is er rotsvast van overtuigd dat een goede openheid tot snellere innovatie leidt en tot het beter beantwoorden van de consumentenvraag. Hun initieel gezamenlijke project was de ontwikkeling van Android, met als doel het eerste open, complete en vrije platform speciaal voor mobiele telefoons te creëren. Tot slot trachten ze hun visie waar te maken en die niet zomaar te beschouwen als een verre toekomst [3]. Deze sterke alliantie leidde uiteindelijk tot het eerste complete open source platform voor mobiele telefoons, gebaseerd op de Linux-kernel en het Java-programmeerplatform. Het is met andere woorden een compleet platform dat ontwikkelaars alles geeft wat nodig is om innovatieve toestellen, software en diensten te ontwerpen. Het werd vrijgegeven op 5 november 2007 onder de Apache licentie.
4
In deze paragraaf wordt wat dieper ingegaan op de architectuur en de verschillende componenten van het platform. De compleetheid van Android blijkt zeer sterk uit de software-stack die bestaat uit: een besturingssysteem, middleware, een gebruiksvriendelijke interface en essentiële applicaties. Om effectief applicaties te gaan ontwikkelen is een Software Development Kit (SDK) vrijgegeven. Deze kit levert de nodige middelen en API’s die noodzakelijk zijn om te ontwikkelen op het Android platform, gebruikmakend van de Java-programmeertaal. De SDK voorziet ook een plugin (ADT) voor Eclipse, waarin wij onze applicatie hebben geprogrammeerd. Gebruikmakend van de SDK en de beschikbare plug-ins is het voor iedereen mogelijk om applicaties te ontwikkelen of bijdragen te leveren aan bestaande Google-toepassingen. Om de ontwikkeling nog wat meer aan te moedigen, heeft Google zelfs een wedstrijd uitgeschreven: de Android Developer Challenge. De winnaar met de beste applicatie kan op aanzienlijk wat prijzengeld rekenen [4]. De volledige Android architectuur en de belangrijkste componenten van het Android besturingssysteem zijn te zien in Figuur 1 [4].
Figuur 1: De Android Architectuur.
5
Ten eerste voorziet Android een volledige groep van kernapplicaties (applications) zoals email, SMS, kalender, contactpersonen, enzovoort. Al deze applicaties zijn geschreven in Java. Vervolgens is er het applicatie-raamwerk (application framework), dat de ontwikkelaars de mogelijkheid geeft om zeer innovatieve en handige programma’s te ontwerpen. Men kan immers gratis gebruik maken van het hardwaretoestel, toegang krijgen tot locale informatie, achtergronddiensten uitvoeren, enzovoort. De ontwikkelaar kan met andere woorden hetzelfde raamwerk voor API’s gebruiken als de kernapplicaties. De Android architectuur is zodanig ontwikkeld dat het hergebruik van bepaalde componenten uit bestaande applicaties zeer gemakkelijk gaat. Indien bij wijze van voorbeeld een bepaalde toepassing gebruik wil maken van de bestaande contactpersonen in het toestel, dan kan dit zonder de code volledig opnieuw te moeten schrijven, maar simpelweg door de bestaande componenten te gebruiken en op te roepen. In de derde laag bevinden zich de bibliotheken (libraries) in C/C++ die door verschillende componenten van het Android systeem gebruikt worden. Een voorbeeld van een dergelijke bibliotheek is SQLite, een krachtige en relationele database waar alle toepassingen gebruik kunnen van maken. Daarnaast voorziet Android ook enkele kernbibliotheken die de basisfuncties van Java beschikbaar stellen. Deze vormen samen met de Dalvik Virtual Machine (DVM) de Android Runtime. Dalvik is zodanig geschreven dat er meerdere virtuele machines simultaan en efficiënt kunnen draaien. Iedere applicatie heeft immers zijn eigen proces. De DVM voert bestanden uit in het Dalvik Executable (.dex) formaat dat geoptimaliseerd is voor minimaal geheugengebruik. De virtuele machine is gebaseerd op het register en laat klassen, die getransformeerd zijn in het .dex-formaat en gecompileerd worden door een Java-compiler, werken. Tot slot steunt Android op Linux 2.6 voor kernprocessen zoals veiligheid, geheugen, procesmanagement, enzovoort. De Linux kernel vormt ook een soort van abstracte laag tussen de hardwarecomponenten en de rest van de softwarestapel.
B. Programmeren met Android Het programmeren voor een smartphone is totaal verschillend dan voor een desktopapplicatie. Iedereen die al in aanraking is gekomen met het ontwikkelen van programma’s voor PDA’s of telefoons zal problemen ondervonden hebben met de dimensie van dergelijke toestellen. De moeilijkheden situeren zich voornamelijk op het vlak van grootte en schaal, vanuit verschillende invalshoeken. Ten eerste zijn de schermen meestal zeer klein, wat de leesbaarheid en 6
duidelijkheid verzwakt. Ten tweede bezitten smartphones meestal geen keyboards, en indien ze toch aanwezig zijn, hebben ze meestal kleine en onhandige toetsen. Sommige toestellen zijn ook uitgerust met touchscreens die niet altijd even accuraat - grote vingers samen met een multitouchscreen is geen goede combinatie - zijn. Ten derde zijn er de CPU-snelheid en het geheugen die sterk beperkt zijn in vergelijking met normale PC’s en servers. Ten slotte is er wijdverspreid gebruik van diverse programmeertalen, afhankelijk van de keuze van de fabrikant [5] [6]. We kunnen hieruit besluiten dat het programmeren voor een telefoon een totaal andere ervaring is dan het ontwikkelen van desktopapplicaties, websites, of backend serverprocessen. De middelen zijn verschillend, het raamwerk gedraagt zich op een andere manier, kortom het ontwikkelen is sterk limitatief vergeleken met desktops. Android
probeert
deze
tekortkomingen
te
compenseren door
een vertrouwde
programmeertaal aan te bieden in combinatie met enkele bekende bibliotheken, die beide te combineren zijn in een vertrouwd programmeerprogramma (Eclipse). Het downloaden van de Software Development Kit, de Eclipse-plugin, en Android Development Tools (ADT), volstaan om aan de slag te gaan. Deze middelen voorzien een emulator waarop de zelfontwikkelde programma’s getest kunnen worden. De Android emulator vervult zijn taak door middel van een open source “processor emulator”-technologie, genaamd QEMU. De belangrijkste taak is het nabootsen van de eigenschappen van een fysiek toestel; in 90 procent van de gevallen zou een echt toestel zelfs niet noodzakelijk zijn. De emulatorbeperkingen omvatten echter USB-connecties, het maken van video’s en audio en voornamelijk het gebruik maken van de sensoren. Aangezien onze use case hoofdzakelijk werkt met behulp van sensoren waren fysieke toestellen toch een noodzaak. Men kan zich afvragen waar Android nu verschilt van het klassieke Java. Wanneer je een desktopapplicatie ontwikkelt, ben je meestal niet op de hoogte van de andere programma’s die op het zelfde moment draaien. Indien men interageert met andere programma’s gebeurt dit meestal door middel van API’s , zoals bijvoorbeeld Java Database Connectiviteit (JDBC). Android gebruikt min of meer dezelfde concepten maar dan op een andere manier verpakt, zodat de toestellen minder gevoelig zijn voor crashes. De belangrijkste eigenschap, zoals eerder al aangehaald, is dat applicaties bepaalde elementen uit andere applicaties kunnen hergebruiken. Het belangrijkste voordeel hierin is dat men de specifieke code niet hoeft te integreren in de eigen code of een link te voorzien. Het benodigde stukje code van de reeds bestaande applicatie zal simpelweg opgeroepen worden wanneer men dit wenst. Het systeem moet bijgevolg toelaten om een applicatieproces te starten wanneer een bepaald stuk daarvan nodig is en het geschikte Java object aan te maken voor dat stuk. Hieronder volgt een korte beschrijving van de voornaamste componenten die gebruikt worden in 7
Android applicaties. Deze structuur heeft een belangrijk gevolg. Er is namelijk geen enkele toegangspoort in de applicatie zoals bij degene op de meeste andere systemen. Met een toegangspoort bedoelen we bijvoorbeeld de ‘main’ functie in het vertrouwde Java. Ter vervanging bestaan de toepassingen uit enkele essentiële componenten die het systeem kan aanmaken en opstarten indien gewenst. Er zijn vier dergelijke componenten, die nu verduidelijkt worden [5] [6].
Activities Een activiteit is de belangrijkste bouwsteen in een user interface. Men kan het vergelijken met een scherm (window) of een dialoogscherm op een desktopapplicatie. Een programma kan bestaan uit één enkele activiteit maar ook uit meerdere die samen een user interface vormen. Elke activiteit is onafhankelijk van een andere en is geïmplementeerd als een subklasse van de Activity basisklasse. Activiteiten zijn opgebouwd uit verschillende views, die in een bepaalde hiërarchie worden georganiseerd. Dit wil zeggen dat elke view een bepaalde plaats in het venster inneemt en het ook die plaatsen zijn waar gebruikers interageren met de applicatie. Android voorziet standaard enkele views zoals tekstvelden, knoppen, keuzerondjes, en dergelijke meer.
Sevices Een service is niet zichtbaar en speelt zich voor onbepaalde tijd af op de achtergrond. Er is dus geen visuele interface. Services kunnen blijven werken onafhankelijk van een activiteit. Een voorbeeld ter verduidelijking: Een muziekspeler bestaat uit verschillende activities om liedjes te kiezen en af te spelen. Indien men de player verlaat, wil men uiteraard dat de muziek blijft spelen. Dit is mogelijk door de muziekspeler-activiteit een service te laten opstarten en de muziek verder te laten afspelen op de achtergrond.
Content Providers Een content provider maakt het mogelijk om data op te slaan en op te zoeken. Daarnaast zijn er methodes voorzien om die gegevens beschikbaar te stellen voor andere toepassingen. De data kunnen op verschillende manieren opgeslagen worden: in de SQLite database, in het bestandssysteem of andere. Onze use case slaat locatiegegevens in een kladblokbestand op, maar maakt geen gebruik van een content provider. In tegenstelling tot services hebben activiteiten en content providers een korte levensduur en kunnen ze op elk moment afgesloten worden.
8
Broadcast Receivers Een broadcast receiver is een onderdeel dat inkomende signalen ontvangt en daarop reageert naargelang het soort signaal. Deze signalen kunnen verzonden worden door bepaalde delen uit de systeemcode, maar ook door applicaties. Wat de systeemcode betreft gaat het bijvoorbeeld over het aangeven van de batterijstatus. In het tweede geval kan bijvoorbeeld een bericht gestuurd worden naar alle andere applicaties met de melding dat een bestand gedownload is en het nu gebruikt kan worden.
Intents Intents zijn systeemberichtjes die zich in het toestel begeven en de applicaties op de hoogte houden van de verschillende gebeurtenissen. Voorbeelden van dergelijke gebeurtenissen zijn het aansluiten van een SD card, het opstarten van een activiteit of het waarschuwen dat een SMS-bericht is aangekomen. Het is mogelijk om te reageren op deze intents alsook er zelf te creëren. In onze use case worden intents voornamelijk gebruikt om activiteiten op te starten. Bij het programmeren hoort uiteraard het ontwikkelen van een comfortabele en gebruiksvriendelijke user interface. Deze kan volledig beschreven worden in XML-bestanden die daarna geladen worden als vensters in de interface van de applicatie. Een gebruikersinterface wordt opgebouwd uit drie hoofdcomponenten. Views zijn de basisblokken waaruit een user interface is opgebouwd. Een combinatie van verschillende views leidt tot een viewgroup, en vervolgens kan een bepaalde hiërarchie gedefinieerd worden tussen die groepen. Er is ook de lay-out, die de positie van de views op het scherm specificeert. Voorbeelden van dergelijke lay-outs zijn de lineaire lay-out, tabel lay-out, relatieve layout, enz. Ten slotte bestaan er ook menu’s die opgeroepen worden door op de button “menu” te drukken. Deze menu’s zijn vooral handig om het scherm te ontlasten indien zich daar te veel functies zouden bevinden. Een ander belangrijk voordeel is dat ze de prestatieverminderende views kunnen beperken en zo de gehele applicatie ten goede komen.
9
2. Android Sensoren
A. Algemeen Toestellen die Android ondersteunen hebben standaard een tiental ingebouwde sensoren, die de ontwikkelaar de kans bieden om zeer geavanceerde applicaties te ontwikkelen. De ontwikkeling en technologische vooruitgang van mobiele toestellen hebben de laatste jaren een sterke groei gekend. Het telefoneren zelf is eerder bijzaak geworden; filmen, radio beluisteren, op het internet surfen en GPS zijn de nieuwe standaarden geworden. GSM’s evolueren naar kleine zakcomputers die steeds meer data kunnen opslaan en verwerken waarbij de aanwezige sensoren een grote rol spelen. De accuraatheid en precisie van deze sensoren nemen nog elk jaar toe, wat de ontwikkeling van meer geavanceerde toepassingen alleen maar ten goede komt. Android voorziet twee belangrijke packages waar onze applicatie gebruik van maakt. Ten eerste is er een package om de hardware van het toestel te gebruiken en de geleverde data te verkrijgen. Binnen deze hardwarepackage is een Sensor-, SensorManager-, en SensorEventklasse voorzien. De eerste groepeert de verschillende sensoren van het toestel, de manager verleent de toegang tot deze sensoren en de event-klasse vertegenwoordigt een sensorgebeurtenis en houdt informatie bij zoals het sensortype, de accuraatheid, de data zelf, en nog meer [7]. De tweede package geeft toegang tot de GPS diensten die zeer bruikbare data opleveren.
B. Welke sensoren zijn voorzien? De aanwezigheid van bepaalde sensoren is toestelgebonden. Dit impliceert dat niet alle vermelde sensoren in de SensorManager ten allen tijde voorkomen op het toestel dat men bezit. Desondanks vermeldt de API van de Android Developers website de volgende beschikbare sensoren: accelerometer, gyroscoop, licht, magnetisch veld, oriëntatie, druk, nabijheid en temperatuur. Hierna volgt een korte beschrijving van elke sensor, aangevuld met een toelichting bij de locatieservice.
Accelerometer Deze sensor geeft ons drie waarden terug die opgeslagen worden in een rij. De waarden zijn uitgedrukt in SI-eenheden (m/s²) en meten finaal de versnelling van het toestel min de zwaartekracht. De drie waarden staan voor de versnelling volgens drie assen, namelijk X, Y en Z. Uitgaande van een toestel dat vlak op een horizontale ondergrond lig,t recht tegenover de gebruiker 10
zodat het scherm leesbaar is, gaat de X-as van links naar rechts, de Y-as gaat van de gebruiker naar het toestel en de Z-as staat loodrecht op het aardoppervlak [8]. Enkele voorbeelden ter verduidelijking: Een toestel in vrije val zal volgende waardes hebben (0, 0, 0). Een toestel dat stil ligt op een tafel zal een waarde vertonen van +9,81, want de versnelling van het toestel bedraagt (0 m/s²) min de zwaartekracht (-9,81 m/s²).
Gyroscoop Een gyroscoop is een rotatiesymmetrische massa die om zijn as kan draaien. In populaire termen vertaald is een gyroscoop een tol. Bij hoge snelheid van de tol zal de as niet van zijn richting afwijken. De documentatie over deze sensor is zeer beperkt en het is niet mogelijk om er specifieke waarden uit te halen.
Lichtsensor Deze sensor geeft ons de verlichtingssterkte uitgedrukt in de SI-eenheid (lux). De verlichtingssterkte van een bepaald oppervlak komt overeen met de lichtstroom in aantal lumen dat er per vierkante meter opvalt. De uitgelezen sensorwaarden hebben een bereik van 0 tot 130 kilolux. Android voorziet zelf enkele constanten die een onderscheid maken tussen bijvoorbeeld dag en nacht, volle maan of geen maan, … Lichtstroom is de totale hoeveelheid licht die een lichtbron per seconde via alle golflengten van het zichtbaar gebied uitzendt.
Magnetisch Veld Deze sensor geeft ons terug drie waarden gebaseerd op een X-, Y- en Z-as. Alle waarden zijn uitgedrukt in de SI-eenheid micro-Tesla (µT) om het omringende magnetische veld te meten. De X-as heeft een positieve waarde in de richting van de rechterzijde van het toestel, de Y-as heeft een positieve waarde in de richting van de bovenkant en de Z-as heeft een positieve waarde in de richting van de voorkant van het toestel.
Oriëntatie De oriëntatiesensor zal opnieuw drie waarden geven die zijn uitgedrukt in graden, volgens een bepaalde hoek die het toestel aanneemt ten op zichtte van twee assen [9]. Azimut: Dit is de hoek relatief ten opzichte van het magnetische noorden. De hoek heeft een bereik van 0 tot 360 graden. 0° is gelijk aan het noorden, 90° is het oosten, 180° het zuiden en 270° staat voor het westen. Hieruit volgt dat deze waarde dienst doet als een soort kompas [10]. 11
Figuur 2: Verduidelijking van het begrip Azimut.
Pitch: De mate waarin het toestel voorwaarts of achterwaarts wordt bewogen. Deze waarden kunnen variërend van -180 tot 180 graden. Wanneer het toestel plat ligt is de Pitch 0 graden, wanneer het volledig recht staat is de hoek 90 graden [10].
Figuur 3: Verduidelijking van het begrip Pitch.
Roll: is de draaiing van het apparaat in relatie tot de linkerbenedenhoek van het scherm. Deze waarden hebben een bereik van 0 tot en met +/- 90 graden [10].
Figuur 4: Verduidelijking van het begrip Roll.
12
Druksensor Deze sensor wordt dan wel vermeld in Androids API, maar er is weinig tot geen informatie over te vinden. In onze inleidende studie hebben we heel wat bestaande applicaties onderzocht op de aanwezigheid van de druksensor, maar uiteindelijk hebben we geen enkele toepassing gevonden die één of andere drukeenheid weergeeft.
Nabijheidssensor Deze sensor meet de afstand van het toestel tot het oor in centimeters. De belangrijkste doelstelling van deze sensor is het uitschakelen van het scherm tijdens telefoongesprekken. De aanwezigheid van dergelijke sensor is sterk merk- en toestelgebonden. Bepaalde druksensors zullen enkel een binaire waarde geven in plaats van het aantal centimeters; ze geven twee statussen weer, meer bepaald dicht of ver.
Temperatuursensor In de API is niet veel vermeld over deze sensor, maar na wat onderzoek konden we ons toch een beeld vormen over de uitgelezen waarden. De temperatuursensor meet namelijk de temperatuur van de smartphone zelf, meer bepaald van de batterij in het toestel. Deze waarde mag dus zeker niet verkeerdelijk geïnterpreteerd worden als zijnde de omgevingstemperatuur [11].
GPS-service Deze service stelt de ontwikkelaar in staat om de telefoon te lokaliseren op aarde. Deze lokalisatie kan gebeuren door middel van satellieten of door gebruik te maken van een netwerk provider (WIFI). Applicaties ontvangen op deze manier periodieke updates over de geografische locatie van het toestel. Via de LocationManager is het mogelijk om de geografische coördinaten (lengtegraad en breedtegraad) van eender welke plaats te bepalen. Dit zijn slechts twee van de vele gegevens die via de GPS-dienst kunnen verkregen worden. Het is bijvoorbeeld ook mogelijk om data te verzamelen omtrent de hoogte van de locatie, de snelheid op de grond, de locatie van de satelliet zelf, de afstand tussen twee locaties, en nog veel meer. Daarnaast voorziet Android ook de mogelijkheden voor geocoding en kaartweergave. Geocoding kan op twee manieren gebeuren: voorwaartse geocoding is het opvragen van de geografische coördinaten op basis van een adres en omgekeerde geocoding is het tegenovergestelde proces.
13
C. Gebruikte en niet-gebruikte sensoren Een van de doelstellingen betreffende deze thesis was het aanspreken van de beschikbare sensoren en de verkregen waarden op een correcte wijze te interpreteren. Dit betekent een verstaanbare inhoud koppelen aan de ruwe data die voorhanden zijn. Hierbij moet een onderscheid gemaakt worden tussen de echt bruikbare en de voor ons eerder nutteloze sensoren; nutteloos in die zin dat er geen duidelijke context af te leiden valt uit de verkregen gegevens. Anderzijds waren de uitgelezen waarden soms gewoonweg niet accuraat genoeg of bleken ze geen meerwaarde te bieden aan onze applicatie. Hierbij speelde, zoals eerder vermeld, het type en de leeftijd van de beschikbare toestellen ook een significante rol. Zo zal een ouder toestel minder sensoren bezitten en minder precies zijn in vergelijking met een gloednieuw toestel. In de volgende paragrafen wordt besproken welke sensoren wij gebruikt hebben voor ons programma en welke niet. De werkelijk aangesproken sensoren waaruit wij bruikbare gegevens hebben afgeleid zijn: de accelerometer, de GPS en gedeeltelijk de lichtsensor. De bibliotheek die daarom ontwikkeld werd, moest in staat zijn om verschillende statussen op te vragen naar het voorbeeld van CenceMe (iPhone). Hier volgt een zeer kort overzicht, vermits de volledige uitleg volgt in Hoofdstuk 3: Implementatie. Een eerste status die kan opgevraagd worden is de lichaamshouding waarin een persoon zich bevindt. Om deze houding te bepalen werd gebruik gemaakt van de accelerometer, die de versnelling van het toestel meet volgens de drie assen. Deze sensor bleek de meest geschikte om de oriëntatie van het toestel te meten, relatief ten opzichte van de zwaartekracht. Dit blijkt ook uit het feit dat Android zelf gebruik maakt van deze sensor om bijvoorbeeld de schermlay-out te veranderen van portret naar landschap wanneer de GSM gedraaid wordt. Op basis van de gevonden documentatie, waaruit bleek dat de accelerometer de meest geschikte sensor is om bepaalde bewegingspatronen vast te stellen, en op basis van eigen ondervindingen konden telkens dezelfde waarden teruggevonden worden bij eenzelfde houding [12]. Een tweede belangrijke status die kan opgevraagd worden is de locatie van het toestel. Hiervoor moest gebruik gemaakt worden van het geavanceerde lokalisatiesysteem van Android; andere sensoren hebben bij deze status geen nut. Locaties kunnen in onze applicatie met behulp van dit systeem toegevoegd, verwijderd en weergegeven worden. Telkens iemand zich begeeft op een reeds toegevoegde locatie zal dit op het scherm worden weergegeven. Naast het opvragen van coördinaten en locatiegegevens is het ook mogelijk om de snelheid van het toestel te bepalen aan de hand van de GPS. Deze functie leidde tot een derde op te vragen status, namelijk het vervoermiddel. Hiermee kan aldus het transportmiddel van een persoon bepaald worden. 14
De derde en laatste sensor waar we gegevens van verwerkten, is de lichtsensor. Deze is enkel beschikbaar op de nieuwere toestellen en de accuraatheid is niet altijd even betrouwbaar. Daarom werd besloten om hier minder belang aan te hechten. Het vinden van documentatie en het programmeren zelf verliepen zeer moeizaam en de resultaten die uiteindelijk bereikt werden, waren niet van voldoende kwaliteit om deze sensor in andere statusupdates te gaan verwerken. Tot slot nog wat randgegevens over de sensoren die we niet gebruiken voor onze use case. Wat betreft de gyroscoop, de druk- en de nabijheidssensor is het niet echt mogelijk om de waarden ervan uit te lezen. Bovendien blijkt dat de documentatie en de bruikbaarheid van dergelijke sensoren zeer beperkt is. Deze drie sensoren konden eveneens weinig bijdragen tot de verdere verfijning van de aanwezige statussen in onze applicatie. Bovengenoemde argumenten leidden er dan ook toe dat we de gyroscoop, de druk- en de nabijheidssensor al buiten beschouwing lieten vooraleer we met het echte programmeerwerk startten. Het magnetische veld, de oriëntatie- en de temperatuursensor zijn wel uitleesbaar, maar om diverse redenen ook minder bruikbaar. De eerste twee zijn toepasbaar bij het creëren van een digitaal kompas, een functie die al in zeer veel toepassingen bestaat. Het zou nutteloos zijn om deze functie te gaan herkauwen in onze bibliotheek. De temperatuursensor geeft de temperatuur van de batterij weer. Een handige toepassing hiervan kan bijvoorbeeld het waarschuwen voor oververhitting zijn. Deze gegevens lijken ons ook niet echt nuttig voor onze applicatie, omdat dit voor anderen (vrienden) geen interessante informatie oplevert. In een steeds sneller evoluerende telefoonmarkt, zullen de sensoren steeds beter worden en de capaciteiten van de smartphones alleen maar toenemen. Zelfs op een tijdsspanne van één jaar tijd is er een enorm verschil tussen de uitgebrachte modellen. In het volgende gedeelte wordt een illustratie gegeven van drie verschillende types en hun specificaties.
D. Vergelijking van drie Android toestellen Android is momenteel het sterkst groeiende mobiele besturingssysteem ter wereld. Het staat momenteel op de vierde plaats met een marktaandeel van 9,6 %. Tegenwoordig komen er steeds meer en meer Android toestellen op de markt beschikbaar. Aanvankelijk was het nog goed bij te houden welke toestellen er nu precies waren en welke we konden verwachten, maar ondertussen wordt dit steeds moeilijker. Dit jaar (2010) alleen al verwacht men de lancering van 50 nieuwe modellen. 15
Bij het ontwikkelen en programmeren van onze bibliotheek was het gebruik van fysieke toestellen een noodzaak. De beschikbare emulator was immers niet in staat om de sensoren te simuleren. We kregen twee HTC toestellen in twee verschillende versies ter onze beschikking, namelijk de HTC Magic en de HTC Desire. Hierna volgt een korte vergelijking van deze toestellen en de Nexus One, de eerste telefoon door Google zelf ontwikkeld [13]. Deze staan respectievelijk afgebeeld van links naar rechts op Figuur 5.
Figuur 5: De drie besproken GSM-toestellen.
Een jaar op de mobiele markt maakt een zeer groot verschil op gebied van snelheid, geheugencapaciteit, beschikbare sensoren en dergelijke. De HTC Magic is het oudste toestel en is beschikbaar op de Nederlandse markt sinds juni 2009. De Magic heeft een processorsnelheid van 528 Mhz en een RAM-geheugen van 192 Mb. Alle sensoren buiten de licht- en nabijheidssensor zijn geïntegreerd in deze smartphone. Uit eigen ervaringen konden we toch concluderen dat dit mobiele toestel soms labiel gedrag vertoont. Op bepaalde plaatsen/momenten duurt het een aantal uur vooraleer er een mast of satelliet gevonden is, terwijl op andere het slechts enkele minuten duurt. Daarnaast verliep de connectie met een desktop, om de testprogramma’s op de telefoon te installeren, niet altijd vlekkeloos. De eerste weken werkte de verbinding helemaal niet, terwijl de laatste twee weken de applicaties perfect konden geïnstalleerd worden. Dit probleem bleek achteraf eerder computergebonden. De Nexus One en HTC Desire werden beide gelanceerd in het voorjaar van 2010. Beide toestellen hebben gelijkaardige specificaties, mede doordat de Nexus ontwikkeld is door Google zelf, in samenwerking met HTC. De processorsnelheid voor beide toestellen bedraagt 1Ghz terwijl het 16
interne geheugen ruimte voor 512Mb voorziet. Gezamenlijk leiden deze kenmerken tot een snellere werking dan de HTC Magic. Daarnaast zijn de nabijheids- en lichtsensor op deze toestellen wel aanwezig. Een algemene opmerking die geldt voor alle modellen is de korte batterijduur. Bij een normaal gebruik durft de telefoon bijna iedere dag opnieuw te moeten worden opgeladen. Vooral de WIFI-verbinding en de GPS vergen zeer veel van de batterij [13] [14].
17
Hoofdstuk 3: Architectuur
1. Implementatie van de bibliotheek in applicaties Eens de bibliotheek aangemaakt is, moet ze natuurlijk nog kunnen worden aangesproken. Wij kozen ervoor om het mogelijk te om elke bron van informatie apart aan te spreken. Niet iedere applicatie zal namelijk alle beschikbare data willen incorporeren, dus moeten ontwikkelaars kunnen kiezen welke elementen zij willen gebruiken en welke niet. Onze aanpak bestond er dan in om een aparte klasse te voorzien per gegevensbron. Er kwam met andere woorden een aparte klasse voor Transportmiddel, Lichaamsstatus, etc. In deze klasse zitten alle methoden en variabelen die nodig zijn om de sensoren uit te lezen, op deze gegevens berekeningen uit te voeren en hier de bijhorende statussen als uiteindelijke resultaat uit af te leiden. Deze statussen en eventueel andere belangrijke waarden (bijvoorbeeld gemiddelde snelheid) worden vervolgens doorgegeven naar een interface die door deze klasse geïmporteerd wordt. In de interface bevindt zich slechts een beperkt aantal methoden, namelijk om de status en belangrijke waarden op te halen. Op die manier is er dus ook een aparte interface per informatiebron. De interfaces kunnen gebruikt worden als API (Application Programming Interface). Dit wordt in de commerciële sector vaak toegepast, door de interface publiek te maken voor de klanten, maar de achterliggende klasse toch te beschermen [15]. In ons geval zou dit betekenen dat de klanten de uiteindelijke status kunnen verkrijgen door de interface te implementeren, maar de berekeningen hierachter niet te zien krijgen. Onze code is weliswaar niet beschermd en mag verspreid worden. Het gebruik van interfaces kan toch nuttig zijn wanneer ontwikkelaars (of anderen) enkel de uiteindelijke resultaten willen verkrijgen en geen aandacht moeten besteden aan de manier waarop deze bepaald worden. De uiteindelijke applicatie kan dan een bepaalde selectie van deze verschillende interfaces of klassen importeren, naargelang de noodzaak. Wil de ontwikkelaar enkel informatie over het transportmiddel waarmee de gebruiker van het GSM-toestel zich voortbeweegt, dan importeert hij enkel deze interface en/of klasse. Dit is vanzelfsprekend veel efficiënter dan een verplichting om steeds de gehele bibliotheek te moeten opnemen. Figuur 6 geeft een schematisch overzicht van de implementatie van de bibliotheek.
18
Applicatie
I
Transport Klasse
ert rte o mp
Lichaamsstatus Klasse
Locatie Klasse
Omgevingslawaai Klasse
Omgevingslicht Klasse
Bereikbaarheid Klasse
Implementeert
Implementeert
Implementeert
Implementeert
Implementeert
Implementeert
Transport Interface
Lichaamsstatus Klasse
Locatie Interface
Omgevingslawaai Interface
Omgevingslicht Interface
Bereikbaarheid Interface
Bevatten methoden en variabelen voor berekeningen
Figuur 6: Implementatie van de bibliotheek.
2. Communicatie van de informatie Het oorspronkelijke idee om de informatie, afgeleid uit de sensoren, te communiceren was om een client-servermodel in te voeren. Hierbij zou elke gebruiker die de applicatie draait een client zijn die verbonden is met de server. Elke gebruiker verzendt dan zijn informatie naar de server: telkens een status verandert, wordt deze op de server aangepast. De server houdt deze informatie bij en geeft deze continu door aan de vrienden die deze applicatie ook draaien. Vrienden worden door de gebruikers zelf toegevoegd, zodat zij controle hebben over wie hun informatie ziet. Alle gebruikers die als vrienden zijn toegevoegd, krijgen de informatie te zien. Dit wordt schematisch weergegeven in Figuur 7.
19
Tracker Server
Tracker applicatie Tracker applicatie
Tracker applicatie
Vriend 1 = verzendt eigen info naar server = ontvangt informatie van alle toegevoegde vrienden van server
Vriend 3 Vriend 2
Figuur 7: Communicatie volgens het client-servermodel.
Het uitwerken van dit principe zou echter behoorlijk complex zijn: er zou een eigen server moeten opgezet worden, protocollen moeten voorzien worden om de constante updates in te stellen, etc. Dit zou meer tijd gevergd hebben dan waarover we beschikten. Daarom maakten we na enkele weken de keuze om dit concept overboord te gooien en te werken met een minder ideale, maar wel haalbare realisatie. In plaats van zelf een server op te zetten, zullen we via de website Twitter de informatiestatus weergeven. Deze implementatie verloopt heel wat eenvoudiger, omdat we gebruik kunnen maken van een bibliotheek die gemakkelijk toegang biedt tot de Twitter API, met name JTwitter [16]. Op deze manier kan na een bepaalde tijdspanne, bijvoorbeeld 2 minuten, een nieuw bericht gepost worden met daarin de aangepaste informatie. Is er niets veranderd tegenover het vorige bericht, dan hoeft er geen nieuwe status doorgezonden te worden. Figuur 8 illustreert dit.
20
Figuur 8: Communicatie via Twitter.
Nu hier uiteengezet is hoe de bibliotheek geïmplementeerd kan worden en hoe we de afgeleide informatie communiceren aan anderen, kunnen we verder ingaan op hoe we concreet aan deze statusgegevens komen.
21
Hoofdstuk 4: Implementatie
1. Eerste problemen bij het programmeren De eerste stap bij het interpreteren van de sensoren, is natuurlijk om deze aan te spreken. Waar dit over het algemeen vlot verliep, traden er bij enkele sensoren toch wat problemen op. Deze waren te wijten aan een combinatie van ons onvertrouwd zijn met het nieuwe platform en de manier van programmeren, alsook de toestellen zelf die we nog voldoende moesten leren kennen. Hoewel de problemen steeds op te lossen vielen, zorgden ze wel voor de nodige vertragingen in onze planning. Een eerste moeilijkheid waar we mee geconfronteerd werden hield verband met de lichtsensor. Niet alleen moest deze op een andere manier aangesproken worden dan we tot dusver gedaan hadden (waarover meer volgt in punt 2.C van dit hoofdstuk), ook kregen we deze niet aan de praat. Op dit moment hadden we enkel een HTC Magic tot onze beschikking. Een applicatie die we op de Android Market vonden genaamd Sensor Dump, leest de waarden uit van de beschikbare sensoren. Deze bracht ons tot de conclusie dat dit toestel niet over een lichtsensor beschikt. We kregen vervolgens ook een HTC Desire om onze code op te testen, die wel van deze sensor was voorzien. Ook het werken met de GPS-functie verliep niet meteen zoals verwacht. Onze code die de huidige snelheid weergeeft, leek ook niet te werken op de HTC Magic. De vraag was echter of er een probleem was met de code of met het toestel zelf. Ook de Maps-applicatie, die standaard op het toestel geïnstalleerd is en ook gebruik maakt van GPS, bleek niet te werken wanneer er geen internetverbinding was. We gingen vanaf dan verder met de HTC Desire voor het werken met GPS, waarop de problemen niet voorkwamen. Nadien bleek de conclusie dat er een probleem was met het Magic-toestel ongegrond, wanneer we deze uiteindelijk ook aan de praat kregen. De reden voor onze moeilijkheden was dat de GPS eerst de positie van het toestel moet kunnen bepalen, vooraleer de huidige snelheid kan bepaald worden. Dit kan vooral op de HTC Magic een hele tijd duren. Het Desire-model slaagt er doorgaans veel sneller in om een ‘lock’ te krijgen met de satelliet, zeker wanneer er zich een SIM-kaart in het toestel bevindt. De Desire beschikt namelijk over Assisted GPS of A-GPS, waarbij de doeltreffendheid verhoogd wordt door ook gebruik te maken van andere bronnen dan satellieten [17]. In de Magic zit deze functie niet ingebouwd, waardoor positionering een pak langer duurt en minder efficiënt is.
22
Een laatste moeilijkheid voor we aan het echte programmeerwerk konden beginnen, werd ons voorgeschoteld door de integratie van het toestel (specifiek de HTC Magic) met een van onze computers. Voor het testen van code kan een emulator gebruikt worden, zodat we onder andere fouten kunnen opsporen. Wanneer we echter willen nagaan met welke toestanden de waarden van de sensoren overeenkomen, moeten we onze code kunnen draaien op een fysiek toestel. De combinatie van het Magic-toestel en één van onze eigen laptops zorgde voor problemen, doordat dit apparaat niet herkend werd. Bijgevolg kon er ook geen code van op deze computer getest worden. De oorzaak hiervoor bleek te liggen bij foutieve drivers die, eens geïnstalleerd, niet of zeer moeilijk weer te verwijderen zijn.
2. Algoritmes en logica In deze sectie volgt een overzicht van alle klassen die een bepaalde status beschrijven. Er wordt uitgelegd van welke algoritmes we gebruik maken, hoe de berekeningen gebeuren en hoe we dus concreet tot onze code gekomen zijn.
A. Bepalen van de lichaamsstatus De initiële bedoeling van deze status was om te bepalen in welke houding een persoon zich bevindt op ieder moment van de dag. Met behulp van de accelerometer kan de versnelling volgens de drie assen (X, Y en Z) in iedere mogelijke houding van het toestel bepaald worden. Via de positie van het toestel kan dan een bepaalde lichaamshouding afgeleid worden. Daarnaast zou ook gebruik gemaakt worden van de lichtsensor en de GPS om de snelheid te bepalen. Aan de hand van de snelheid kan men afleiden of een persoon al dan niet in beweging is. Dit onderscheid wordt gemaakt omdat de houding van een persoon in beweging meestal zittend zal zijn (auto, trein, fiets, bus,…); lopen en wandelen vormen hierop de uitzondering. Maar om de constructie niet overdreven ingewikkeld te maken, wordt er geen status weergegeven wanneer een persoon in beweging is. In dit geval zal de transportstatus meer bruikbare informatie opleveren, zie daarvoor punt 2.B. Het lokalisatiesysteem en daaruit de afgeleide snelheid werkten perfect op beide toestellen wat ons in staat stelde dit onderscheid te maken. Nadat vastgesteld is of een persoon al dan niet beweegt, kan een tweede onderscheid gemaakt worden. Een toestel kan zich immers in de handen van een persoon bevinden of het kan in de broekzak, handtas of ander draagmiddel vertoeven. Om dit te weten te komen zouden we gebruik maken van de lichtsensor. De luxwaarden zouden toch sterk moeten verschillen in iemands broekzak,
23
vergeleken met een toestel dat zich in de handen van de gebruiker bevindt. Maar na uitvoerige experimenten en testprogramma’s bleek dat de lichtsensor geen meerwaarde kon bieden. Op één van de toestellen was geen dergelijke sensor voorzien. Het tweede toestel had er wel één, maar de accuraatheid liet dusdanig te wensen over dat deze constructie opgegeven werd. De uiteindelijke houdingen die we wilden implementeren waren zitten, staan en liggen. Deze houdingen werden getest aan de hand van enkele testprogramma’s die de verkregen waarden weergaven op het scherm van de telefoontoestellen. Hieruit bleek al snel dat het onderscheid tussen zitten en staan zeer duidelijk kon afgebakend worden. Een toestel dat verticaal gepositioneerd is, zal zich eerder bij een rechtstaand persoon voordoen, terwijl het toestel van een zittend persoon een eerder horizontale positie zal aannemen. De derde status, het liggen van een persoon, bleek in de praktijk veel moeilijker te bepalen: de uitgelezen waarden bij een zittend en een liggend persoon verschillen immers nauwelijks of niet. Bij een neerzittend persoon zal de GSM zich ook meestal horizontaal bevinden. Daarnaast zal een persoon die neerligt het toestel meestal uit de broekzak halen en het naast zich leggen. Uiteraard is dit argument voor discussie vatbaar, want een groot aantal uitzonderingen kunnen bedacht worden. Enkele voorbeelden hiervan zijn iemand die een middagdutje doet en daarbij het toestel gewoonweg in de broekzak laat zitten of iemand die even gaat uitblazen in een park. Desondanks gaan wij er vanuit dat een toestel zich in het merendeel van de gevallen niet in de broekzak van een persoon bevindt terwijl die neerligt. Het toestel zal zich in dit geval meestal op een vlak oppervlak bevinden zoal een nachtkastje, talfel, salontafel. Deze toestand, namelijk het plat liggen van een telefoon op een vlak oppervlak is wel perfect af te leiden uit de sensorwaarden van de accelerometer. Omdat deze positie wel zeer eenduidig te bepalen is, hebben we ervoor geopteerd om de status ‘liggen’ niet in ons model op te nemen, maar wel een nieuwe status ‘vlak’ te creëren die aangeeft dat het toestel zich op een tafel of een ander vlak oppervlak bevindt. In Figuur 9 is de oorspronkelijke constructie afgebeeld. Om de uiteindelijke constructie te verkrijgen, moet men in de figuur de ‘in beweging’-clausule weglaten en vervangen door de ‘houding’-status, die dan bestaat uit zitten, staan en vlak. Hierna volgt een toelichting bij de concrete implementatie in de Java-programmeertaal.
24
In beweging?
Waar
Vals
Geen lichaamsstatus Enkel transportstatus
In broekzak?
Vals
Waar
Houding?
Staan
Zitten
Houding?
Liggen
Staan
Zitten
Liggen
Vlak
Figuur 9: Oorspronkelijke constructie voor het bepalen van de lichaamsstatus.
De programmacode die wij gebruikt hebben om de accelerometer te kunnen aanspreken is zeer sterk gebaseerd op een demo-applicatie die te vinden is op de website van IBM [18]. Deze demotoepassing leerde ons niet enkel hoe de sensoren aan te spreken, maar ook de verkregen waarden weer te geven op het scherm van een toestel. Uit dit voorbeeld bleek dat er twee cruciale elementen noodzakelijk zijn om een sensor te kunnen gebruiken. Een SensorManager (klasse), die toegang verleent tot de sensoren en een SensorListenter (interface) die geïmplementeerd moet worden door de klasse die de sensor wil gebruiken. Deze interface bezit twee methoden, namelijk onSensorChanged en onAccuracyChanged; het is deze eerste methode die in onze constructie van zeer groot belang is. Deze methode wordt immers opgeroepen zodra de uitgelezen waarden van een sensor veranderen. Om nu
25
interactie met de sensor tot stand te brengen moet de applicatie zich registreren bij de Listener; terug afmelden is nodig om de interactie stop te zetten. De SensorManager voorziet twee methodes voor deze registratie [19]. Een groot probleem bij het uitlezen van de sensorwaarden op het scherm bleek de zeer hoge gevoeligheid van de sensoren. De minste verschuiving of beweging zorgde voor een zeer snelle verandering in waarden. Vervolgens waren ook de statussen zeer variabel. Een voorbeeld ter verduidelijking: Een toestel ligt op een tafel - de status is bijgevolg ‘vlak’ – en vervolgens wordt het toestel een klein beetje verlegd op die tafel en ogenblikkelijk verandert de status in ‘zittend’, om een fractie van een seconde later terug in ‘vlak’ te veranderen. Om deze overgevoeligheid te elimineren en de realiteit beter te weerspiegelen zijn er twee mechanismen in onze algoritmes ingebouwd. Vooreerst werd het bereik van de specifieke waarden die bij een bepaalde status horen voldoende groot genomen. Concreet betekent dit dat er een duidelijke if-constructie opgemaakt werd voor de vlakke en de staande status; alle andere waarden werden beschouwd als de zittende status. De reden hiervoor is dat de waarden voor een vlakke en de staande status beter te bepalen zijn en er minder variabiliteit insluipen, vooral dan bij eerstgenoemde. Het tweede mechanisme betreft een constructie die het gemiddelde van de ingelezen waarden bepaalt. Die gemiddelden worden bekomen door arraylists aan te maken voor de drie ingelezen waarden. Telkens de sensor een verandering doorgeeft (en daarbij ook een nieuwe waarde), wordt die achteraan toegevoegd aan één van de drie lijsten. Zodra de lijst elf waarden bevat, wordt het oudste en tevens het eerste element in de lijst verwijderd en wordt een gemiddelde berekend op basis van de tien overgebleven gegevens. Wanneer de sensor opnieuw verandert, wordt de verkregen waarde wederom achteraan de lijst toegevoegd, enzovoort. Dit algoritme zorgt dat een status steeds bepaald wordt op basis van het gemiddelde van de 10 recentste waarden. Zo worden plotse uitschieters uitgevlakt en wordt de overgevoeligheid significant verminderd.
26
B. Bepalen van het transportmiddel Een tweede interessant gegeven om na te gaan, is hoe de gebruiker van het GSM-toestel zich voortbeweegt. Bij de oorspronkelijke uiteenzetting van deze klasse hadden we voor ogen om zo veel mogelijk verschillende vervoersmiddelen op te nemen. De lijst van voertuigen zag er als volgt uit:
Te voet: wandelend
Te voet: lopend
Fiets
Bromfiets
Auto
Moto
Bus
Trein
Helikopter
Vliegtuig Boot
Tabel 2: Overzicht van de verschillende transportmiddelen.
De tweede stap was dan vervolgens om te bepalen hoe we een onderscheid zouden maken tussen de verschillende vervoersmiddelen. Het meest centrale element wordt vanzelfsprekend de snelheid, aangezien de verschillen hierin het meest duidelijk en zichtbaar zijn. Een bijkomende factor is de hoogte, die gebruikt kan worden om het onderscheid te maken tussen gewone voertuigen, de helikopter en het vliegtuig. Vervolgens zou ook informatie over de omgeving een hulp kunnen zijn: geeft de GPS aan dat de gebruiker zich op water begeeft met een bepaalde snelheid, dan kunnen we ervan uitgaan dat hij zich op een boot bevindt. Heeft hij een snelheid tussen 30 en 200km/u, maar bevindt hij zich niet op een straat, dan zit hij waarschijnlijk op de trein. Als alternatief kan nagegaan worden of er een aanduiding bestaat voor treinsporen. Als laatste punt kunnen we ook rekening houden met bepaalde bewegingen die het toestel (of de gebruiker) maakt om diens transportmiddel te bepalen. Op de fiets zullen de bewegingen veel intensiever en frequenter zijn dan in de auto. Deze verschillende aspecten worden vervolgens besproken. Het snelheidsaspect werd als eerste uitgewerkt. Oorspronkelijk zagen wij twee opties om deze te berekenen: De eerste was via bewerkingen op waarden van de accelerometer. De tweede hield het invoegen van een functie in die de afstand berekent tussen twee coördinaten van de GPS binnen een bepaalde tijdspanne. Dit zelf implementeren bleek echter niet nodig, omdat er in Android al een functie voorzien is die de snelheid berekent. 27
Deze functie zit vervat in de Locatieklasse, die een geografische locatie voorstelt die op een bepaald tijdstip werd waargenomen [20]. Een locatie bestaat hier uit een lengte- en breedtegraad, een aanduiding van de tijd en indien gewenst kan er onder andere ook snelheid en hoogte mee opgevraagd worden. In onze code maken we dan gebruik van deze functie getSpeed(), die opgeroepen wordt door de LocationListener [21], volgens de methode onLocationChanged. Deze registreert wanneer de huidige locatie veranderd is, met grote precisie. De snelheid wordt uitgedrukt in meter per seconde en eens de locatie bepaald is, wordt een verandering reeds waargenomen wanneer het toestel minder dan een halve meter verplaatst wordt. Dit is meer dan voldoende voor de functionaliteit die wij willen voorzien. Om meteen goed van start te geraken, namen we de code die we vonden op een Google discussiegroep over dezelfde vraag als basis [22]. Wij baseerden onze eigen code hierop. Als aanpassing werd nog een berekening toegevoegd, die de standaardeenheid van meter per seconde omzet naar kilometer per uur. Nu we beschikken over de snelheid, kunnen we de hoogte bepalen. Zoals hierboven vermeld, bevatten de locaties van de Locatieklasse in Android onder andere ook de hoogte. Deze functie valt eenvoudig toe te voegen aan de tot hier toe geschreven code voor snelheid. Net zoals we een variabele creëerden voor snelheid, maken we er ook een aan voor de hoogte. Om deze te verkrijgen gebruiken we dan de methode getAltitude(). Vanaf de planningsfase speelde ons echter de vraag parten hoe de hoogte, vastgesteld door sensoren in het Android toestel, precies zou weergegeven worden: Wordt dit uitgedrukt ten opzichte van zeeniveau of ten opzichte van het straatniveau? Na enig experimenteren en wat opzoekwerk, kwamen we tot de conclusie dat de hoogtebepaling van de Locatieklasse gebeurt ten opzichte van zeeniveau. Dit is op zich reeds weinig bruikbaar voor ons, aangezien dit niets zegt over de huidige relatieve hoogte en dus niet gebruikt kan worden om een onderscheid te maken tussen verschillende voertuigen. Verder bleek ook dat deze waarden zeer weinig accuraat zijn en op een onduidelijke manier bijgewerkt worden: bij het afdalen en vervolgens weer stijgen, bereikt de hoogte nooit meer haar oorspronkelijke waarde. De waarden stroken eveneens niet met geografische gegevens: de echte hoogte van de huidige locatie (boven zeeniveau) verschilt bijzonder sterk van deze die het toestel aangeeft. Het enige waarvoor deze waarden dan nog te gebruiken zouden zijn, is om het onderscheid te maken tussen een vliegtuig en andere voertuigen, vermits deze zich op een veel grotere hoogte bevindt. De snelheid hiervan ligt echter ook veel hoger dan bijvoorbeeld een auto, dus brengt het weinig toegevoegde waarde om hier de hoogte ook nog bij te betrekken. Voor het andere luchtvaartuig in onze klasse, de helikopter, biedt dit geen oplossing. Aangezien deze toestellen een pak lager vliegen, valt de onnauwkeurige hoogte die door 28
de sensoren verkregen wordt niet te gebruiken om hier een goede identificatie voor te bepalen. Omdat het gebruik van de helikopter echter vrij zeldzaam is, leek het ons de beste optie om met dit voertuig geen rekening meer te houden voor onze klasse. De hoogte zal dus niet worden opgenomen, omdat ze weinig informatief en te onnauwkeurig is. Vervolgens werd nagegaan of we geografische informatie kunnen gebruiken om na te gaan of de huidige locatie al dan niet op straat, dan wel ergens op een treinspoor is. Aanvankelijk dachten we aan een integratie met Google Maps, met de hoop dat er een vorm van ‘tags’ zou bestaan die aanduiden wat een straat of wat een treinspoor is. Enig onderzoek hiernaar wees uit dat dit niet het geval was. Het principe van ‘reverse geocoding’, dat gebruikt wordt door deze applicatie, bestaat erin om van bepaalde coördinaten het concrete adres af te leiden. Dit kan voor onze doeleinden niet aangewend worden. Het gebied waar geen specifiek adres mee overeenkomt is veel te ruim en komt dus niet overeen met enkel de treinsporen. Ook voor deze laatste is geen specifieke aanduiding voorzien. Wel was er een applicatie te vinden die op Google Maps het netwerk van treinen en sporen weergeeft, maar deze was enorm regiogebonden en niet beschikbaar voor onze omgeving. Ook zou de implementatie daarvan zeer omslachtig zijn, als elke gebruiker een specifieke kaart van zijn regio moet afhalen (terwijl hij ze niet eens te zien krijgt in onze bibliotheek). Bovendien volgde deze applicatie ook de gebruiker niet, maar moest deze zelf nog zien te achterhalen waar hij zich precies bevindt. Kortom, er is geen standaardoptie aanwezig om af te leiden of we op de trein zitten. De investering om nog verder te zoeken naar een complex algoritme dat dit wel kan bepalen, leek ons dan te groot voor de toegevoegde waarde. We kozen er dan ook voor om de trein niet langer als apart element te beschouwen, maar samen met de wagen en de bus in één categorie op te nemen. Het verschil tussen een wagen en een bus valt namelijk ook niet te bepalen. Deze drie voertuigen zijn allen immers zeer gelijkend en de verschillen die bestaan zijn ook niet bijster relevant. Ook wanneer we onze vooropgestelde applicatie in gedachten nemen, doet het onderscheid ertussen weinig ter zake. Als we weten dat iemand onderweg is, specifieker nog met wagen, bus of trein, dan geeft dit meestal genoeg informatie. Een gelijkend punt valt te maken over het element Boot. Ook hiervoor hadden we graag gebruik gemaakt van informatie over de locatie (specifiek of we ons op water bevinden), maar net zoals het voorgaande werd hier in ons beperkt tijdsbestek geen informatie over teruggevonden. Als er voor de teruggegeven informatie over de huidige locatie een header aanwezig was die specificeerde of we ons op straat of boven water bevonden, was dit ideaal geweest. Dit bleek volgens ons opzoekwerk echter niet het geval. Indien we meer tijd voorhanden hadden, konden we ons onderzoek nog verder zetten in de hoop hier een oplossing voor te vinden. Op dit moment leek het ons echter een betere optie om het voertuig Boot te schrappen uit onze bibliotheek en ervoor te zorgen dat de rest wel volledig in orde was. 29
Als laatste punt valt dan nog de registratie van beweging te bespreken. Deze zou relevant kunnen zijn voor het bepalen van lopen of fietsen. Tijdens het werk aan de bepaling van positie van het toestel, viel ons al op dat dit niet zo eenvoudig is. De data van de bewegingssensor interpreteren om uit te zoeken welke beweging het toestel in de ruimte maakt, wordt voor dit geval nog extra bemoeilijkt door het feit dat het om herhaalde beweging gaat, die nooit helemaal dezelfde is. Bovendien kan het toestel zich nog in een andere positie bevinden dan wanneer we het gewoon in de broekzak meedragen: de GSM kan door de bewegingen gedraaid zijn, maar kan zich ook ergens helemaal anders bevinden zoals in een rugzak of handtas. Dit gebruiken als exclusief criterium voor een bepaald vervoersmiddel lijkt dus onverstandig. Daarnaast zijn deze verschillende toestanden ook te onderscheiden op basis van hun snelheid, vooral als we rekening houden met de gangbare omstandigheden. Een loper zal doorgaans nog minder snel voortbewegen dan een fietser (voor ons geval houden we professionele hardlopers even buiten beschouwing). Een bromfiets kan qua snelheid wel samenvallen of overlappen met een gewone fiets. De bewegingen in dit geval gebruiken om een onderscheid te maken, is ook niet optimaal. Hoewel de benen bij het rijden op een bromfiets niet bewegen, kan het toestel wel nog in beweging zijn. Denk bijvoorbeeld aan de situatie waar het los in een rugzak zit, of beweging registreert door het meedraaien bij het nemen van een bocht. Hou dan nog rekening met het feit dat tijdens het fietsen onze benen ook een tijdje bewegingsloos kunnen zijn (bij het afdalen van een helling bvb.), waardoor de status wispelturig zou kunnen verspringen tussen fiets en bromfiets als we ons op dit criterium baseren. Om deze redenen leek het ons verstandig om beide samen ook als één categorie te beschouwen, vermits ze ook vrij gelijkaardig zijn. Het enige element dat tot nu toe nog niet vermeld werd is de moto. De voorgaande argumenten gaan ook hier op. Een onderscheid maken tussen de wagen en de moto op basis van beweging biedt met andere woorden ook geen optie. Aangezien de moto qua snelheid overeenstemt met onze reeds bestaande categorie en hier conceptueel ook in past, namen we deze hier in op. De categorie van voertuigen boven 35 km/u bevat dan uiteindelijk de Moto, Wagen, Bus en Trein. Er werd gekozen om deze waarde als grens te nemen omdat er twee types van bromfiets bestaan: type A heeft in België een maximum toegelaten snelheid van 25 km/u, voor type B is dit 45 km/u [23]. Ervan uitgaande dat er niet steeds op de topsnelheid gereden wordt, werd het gemiddelde van beide types genomen. Dit valt ook te verzoenen met het gegeven dat wagens en dergelijke vaak trager rijden, bijvoorbeeld bij druk verkeer.
30
Hieronder volgt een overzicht van de verschillende voertuigen en de snelheid waardoor ze bepaald worden in onze bibliotheek.
Transportmiddel
Snelheid (km/u)
Stilstaand (geen vervoer)
[0,1[
Wandelend
[ 1 , 7.5 [
Lopend
[ 7.5 , 18 [
Fiets / Bromfiets
[ 18 , 35 [
Auto / Moto / Bus / Trein
[ 35 , 200 ]
Vliegtuig
> 200
Tabel 3: Transportmiddelen en de snelheid waardoor ze bepaald worden.
Een nevenwerking van deze methode is natuurlijk dat een snel voertuig eerst een aantal voorgaande ‘fasen’ zal doorlopen. Aangezien snelheid echter het beste middel is om een onderscheid te maken, valt dit niet volledig te vermijden. Een aanpassing die wel gebeurd is, betreft het uitmiddelen van de snelheid. In eerste instantie hielden we enkel rekening met de actuele snelheid om het transportmiddel te bepalen. Dit was echter nog meer onderhevig aan tijdelijke schommelingen, bijvoorbeeld even remmen, maar dan meteen weer verder rijden. Hoewel dit weinig accuraat is (er wordt niet echt van voertuig veranderd), zorgt dit in de oorspronkelijk voorgestelde versie van onze applicatie nog niet voor enorme problemen. De status wordt immers voortdurend bijgewerkt, dus wanneer de status voor één seconde verandert van Auto naar Lopend bijvoorbeeld, zal dit nauwelijks opgemerkt worden. We werken in de uiteindelijke versie echter met Twitter om de verschillende statussen weer te geven. Als net op dit moment wordt nagegaan of de status veranderd is tegenover de vorige, dan kan wel een incorrect vervoersmiddel doorgegeven worden (en blijven staan tot de volgende update). Daarom werd, net zoals bij het bepalen van de positie van het GSM-toestel, gewerkt met het gemiddelde van de laatste waarden. Het idee daarachter is dat het systeem dan minder onderhevig zal zijn aan een verstoring van het normale traject (namelijk uitliggers zoals plots remmen en meteen weer de snelheid opdrijven). Hier kwam enig experimenteren aan te pas om te bepalen wat het optimale aantal waarden is waarover uitgemiddeld moet worden. In eerste instantie begonnen we met 15 waarden, maar op die manier duurde het veel te lang vooraleer de huidige status bijgewerkt werd. Een voorbeeld hiervan is dat het meer dan tien seconden duurde tot het toestel aangaf dat we intussen stil stonden. Uiteindelijk kwamen we op het gemiddelde van de laatste vijf waarden: dit zorgde voor een verminderde impact 31
van tijdelijke verstoringen (zoals remmen), maar liet toch nog toe dat de status snel genoeg werd aangepast. Een laatste opmerking aangaande vervoersmiddelen gaat over het gebruik van de GPS in een vliegtuig. Op de meeste vluchten wordt gevraagd om GSM’s uit te schakelen. Tegenwoordig beschikken de meeste van deze toestellen wel over een vliegtuigmodus, maar de GPS wordt hier in het merendeel van de gevallen bij uitgeschakeld. De registratie van het vliegtuig als transportmiddel zal dus in de regel bijna niet kunnen gebeuren.
C. Bepalen van het omgevingslicht De volgende informatie die we willen afleiden is de mate van licht in de omgeving van het toestel. Vermits de lichtsensor op de Android Developer website vermeld staat bij de sensoren die we tot nu toe al uitgelezen hebben [24], namelijk de oriëntatiesensor en accelerometer, gingen we ervan uit dat deze ook op dezelfde manier kon uitgelezen worden. Voor onze eerste poging pasten we dan ook de vernoemde code als volgt aan: In de OnSensorChanged-methode, waarbij als argumenten een integer voor de sensor en een float voor de waarden werd meegegeven, stond een if-constructie, die
nagaat
of
“sensor”
gelijk
is
aan
bijvoorbeeld
“SensorManager.SENSOR_ORIENTATION”. Is dit het geval, dan worden de bijhorende waarden uitgeschreven (voor de oriëntatiesensor zijn dit er drie, overeenstemmend
met
de
drie
assen).
Dit
werd
aangepast
naar
“SensorManager.SENSOR_LIGHT” en het aantal uitgeschreven waarden werd veranderd naar slechts één (omdat de lichtsensor maar een enkele waarde doorgeeft, namelijk de geregistreerde lux-waarde). Verwacht werd dat deze kleine, logische aanpassing zou resulteren in het uitlezen van de gewenste sensor. Dit bleek echter niet het geval. Na deze wijziging te hebben aangebracht, werden helemaal geen waarden meer uitgelezen voor de aangepaste stukken code. Het gedeelte dat niet veranderd werd, werkte nog zoals voordien. Deze aanpak was dus duidelijk niet de juiste en de lichtsensor zou blijkbaar een andere manier van aanspreken vergen. Op dit moment werkten wij nog met de HTC Magic. Zoals voordien vermeld, leerde het testen met behulp van de applicatie Sensor Dump ons dat dit toestel niet over een lichtsensor beschikt. Wanneer we deze applicatie testten op de HTC Desire, bleek dat deze wel voorzien was van deze sensor. Onze aangepaste code had ook hier echter geen enkel effect, dus bleek onze aanpak nog steeds incorrect en lag het niet enkel aan het toestel. Enig 32
opzoekwerk bracht ons op een forum waar beweerd werd dat deze waarden enkel konden uitgelezen worden vanuit een locatie in het geheugen van het telefoontoestel [25]. Deze werkwijze leek niet alleen onpraktisch, maar ook onlogisch. Als de toegang tot andere sensoren wel op een rechtstreekse manier kan, dan is het onwaarschijnlijk dat de lichtsensor enkel indirect via een bestand in het geheugen toegankelijk is. Het boek “Hello, Android” van E. Burnette bracht echter uitsluitsel over dit probleem [26]. Bij onze eerste poging gebruikten we de OnSensorChanged-methode, waar een integer en een float werden meegegeven. Om toegang tot de lichtsensor te krijgen, dienen we echter een SensorEvent [27] mee te geven met deze methode. De klasse SensorEvent stelt ‘evenementen’ van sensoren voor en is dus niet enkel voorbehouden aan de lichtsensor. Er wordt allerlei informatie bijgehouden zoals de waarden die geregistreerd worden, de nauwkeurigheid ervan, etc. Door een event mee te geven aan de methode OnSensorChanged, kunnen de bijhorende gegevens ervan opgevraagd worden. Registreert de sensor opnieuw andere waarden, dan betreft dit een nieuw event met nieuwe gegevens. Nu we de gegevens van de lichtsensor vlot kunnen uitlezen, kunnen we overgaan tot de interpretatie ervan en met andere woorden betekenis toekennen aan de op zich weinig zeggende luxwaarden. Daarvoor is het natuurlijk nodig om zelf te experimenteren en de lichtwaarden op te vragen in verschillende omstandigheden. Op basis daarvan kan bepaald worden welke categorieën onderscheiden kunnen worden. Al snel viel een enorme beperking op: in lage lichtomstandigheden is de sensor bijzonder onnauwkeurig. De waarden die geregistreerd worden, variëren niet op continue basis, maar zijn gelimiteerd tot enkele constanten. Bij onze ervaringen bestonden de mogelijke opties uit 40, 90, 160, 225, 640 en 1280 lux. Het ontbreken van een meer specifieke onderverdeling is op zich al een groot nadeel, maar vooral de ondergrens ligt veel te hoog. De waarde 40 wordt uitgelezen wanneer de lichtsensor zich binnen in normale condities bevindt en er dus geen lichtbron rechtstreeks op schijnt, maar dit ook helemaal niet nodig is om normaal te kunnen zien. Diezelfde waarde krijgen we echter ook wanneer we de lichtsensor volledig afdekken of ons in volledige duisternis bevinden. Dit beperkt de functionaliteit enorm, zeker voor onze doeleinden. Aanvankelijk was het ook onze bedoeling om informatie over omgevingslicht te gebruiken voor het bepalen van andere statussen. Als we deze gegevens konden combineren met informatie over de positie van het toestel, kon zo bijvoorbeeld afgeleid worden of de GSM zich in de broekzak bevindt (als het niet vlak neerligt en de omgeving volledig donker is). Dit idee hebben we moeten laten vallen, door de lage nauwkeurigheid. Eens de lichtsensor in contact komt met daglicht, of zich dicht bij een kunstmatige 33
lamp bevindt, reageert hij wel gevoeliger. Daarom vonden we het toch de moeite om deze informatie nog op te nemen in onze bibliotheek en de lichtsensor niet volledig te schrappen. Enkel voor de combinatie met andere bronnen voor het bepalen van meer geavanceerde informatie is deze niet bruikbaar. Om al deze waarden nog preciezer te kunnen benoemen, besloten we om ook informatie over de tijd te betrekken. Een bepaalde lichtwaarde overdag, heeft een andere betekenis dan ’s nachts (door het verschil tussen dag- en kunstmatig licht). Hiervoor gingen wij als volgt te werk: Voor het weergeven van de tijd werd eerst nagegaan welke specifieke functie hiervoor instaat. Dit bracht ons bij een website waar dit probleem besproken werd [28] en die ook verwees naar de Developer website van Android over de klasse SimpleDateFormat [29]. Via de constructor kan opgegeven worden in welke vorm we de tijd op het scherm willen krijgen. In onze code werd dit dan new SimpleDateFormat("HH:mm"), zodat we enkel het uur en de minuten te zien kregen. Een nog meer nauwkeurige tijdsaanduiding is voor ons gebruik niet nodig. Bij de implementatie hiervan dook wel een probleem op: de tijd wordt eenmalig opgevraagd (bijvoorbeeld bij de start van het programma), maar wordt nadien niet meer bijgewerkt. Om dit verhelpen werd gepoogd een timer te gebruiken, die deze taak elke 10 seconden herhaalde, zoals op een bepaalde website werd aangeraden [30]. Dit bleek echter niet te lukken, want nog steeds bleef de initiële tijdsaanduiding staan. Daarom werd een eenvoudigere oplossing toegepast, waarbij deze lijn code wordt uitgevoerd in de methode onSensorChanged(). Zo wordt de tijd nagegaan telkens de lichtsensor een nieuwe waarde registreert. Dit is uiteindelijk het meest relevant voor ons, omdat we ook enkel dan de tijd willen kennen (om zo de data correct te kunnen beoordelen). De opgehaalde tijd wordt dan opgeslagen als een String, waar het dubbel punt uit wordt verwijderd zodat deze gecast kan worden naar een integer. Deze laatste kan dan vergeleken worden met vooropgestelde waarden (door middel van de operatoren kleiner dan en groter dan). De dagindeling werd ruim genomen en slechts onderverdeeld in Nacht en Dag, waarbij deze laatste de periode voorstelt tussen 07.00u en 19.00u (en Nacht gezien wordt als de resterende tijd). De bedoeling hiervan was dan ook niet om de verschillende fasen van een dag zo precies mogelijk aan te duiden, maar wel om een plaats te geven aan het verschil in betekenis tussen licht overdag en licht ’s
34
nachts. Op basis van de huidige tijd wordt de status als Dag of Nacht gezet, hetgeen bepaalt welke ifconstructie gevolgd wordt om een status toe te kennen aan de uitgelezen lux-waarden. Voor deze concrete statussen werd eerst gekeken naar de klasse SensorManager op de Android Developer website [31]. Hier staat een hele reeks van mogelijke lichtcondities beschreven met de bijhorende luxwaarden, waaronder Bewolkt, Zonlicht, Schaduw, en dergelijke. Deze komen echter helemaal niet overeen met de waarden zoals deze geregistreerd worden op ons toestel. Als illustratie hiervan, zou Schaduw overeenkomen met 20000 lux, terwijl dit bij ons beperkt blijft tot 40 of 90 lux. Het is onduidelijk hoe deze condities bepaald zijn of om welke reden ze standaard voorzien werden, maar voor ons zijn ze alleszins niet bruikbaar. Daarom stelden we zelf experimenteel vast welke data overeenkwamen met welke ervaringen van lichttoestanden. Figuur 10 geeft een volledig overzicht van de door ons bepaalde statussen volgens het tijdstip van de dag en hun overeenkomstige waarden. Er kan opgemerkt worden dat wij wel werken met categorieën in plaats van enkel de concrete waarden (constanten) die ons toestel uitleest. De reden hiervoor is dat onze bibliotheken ook gebruikt kunnen worden op andere apparaten (waar de lichtsensor mogelijk wel continue waarden weergeeft).
35
,4 0] [0
160]
, 90 ]
]90,
0]
]4 0
0] ,4 [0 , 16
] , 640
]
]90
] 80
]225
2 0, 1
,9 0]
80 12 ]64
]40
>
] 80 0 12 28 640, ] >1
, 640 ]2 2 5
Figuur 10: Overzicht van lichtcondities.
Net zoals bij de bepaling van het transportmiddel, werd ook hier nagegaan of het uitmiddelen van de waarden een gunstig effect kan hebben. Een mogelijk bijvoorbeeld is een verandering van status te vermijden wanneer een enkele lichtflits de sensor even raakt. Voor deze informatiebron bleek dit echter niet gunstig, omdat de waarden van deze sensor veel minder onderhevig zijn aan verandering dan de andere. Een lichttoestand van 90 lux kan na enkele seconden veranderen, wanneer we ons bijvoorbeeld voortbewegen, maar kan ook een uur lang dezelfde blijven. Als we hier het gemiddelde gebruiken van de laatste x waarden, dan kan dit nog een vertekend beeld geven als de meest recente toestand heel wat lager (of hoger) ligt. Een alternatieve manier, waarbij we kijken wat de meest voorkomende waarde is in de laatste reeks, lost dit probleem ook niet op. Ook hier is vooral de laatste meting van belang, aangezien deze toestand lang aangehouden kan worden. Voor uitmiddeling zorgen is bij deze sensor dus geen goede optie. We werken daarom beter enkel met de laatste waarde, hoewel de kans bestaat dat deze zeer
36
veranderlijk is en de algemene status dus geregeld zal moeten vernieuwd worden. Deze werkwijze valt nog steeds te verkiezen boven het weergeven van een incorrecte waarde.
D. Bepalen van locatie via GPS / ingeven locatie In dit onderdeel van onze applicatie maken wij gebruik van het geavanceerde locatiesysteem dat Android voorziet. De voornaamste doelstelling was om willekeurige plaatsen zelf een naam te geven en deze daarna op te slaan in onze applicatie. Nadien moest het toestel in staat zijn om deze locaties te herkennen. Hiermee bedoelen we dat een locatie wordt weergegeven telkens de gebruiker zich in een bepaalde straal rondom één van zijn toegevoegde locaties bevindt. Het spreekt voor zich dat toegevoegde locaties, ook moeten kunnen verwijderd worden. Daarnaast moeten de toegevoegde locaties op één of andere manier ook weergegeven worden op het scherm. Daarbij kunnen bepaalde gegevens zoals straat, stad en land via geocoding opgevraagd worden. Tot slot dient het mogelijk te zijn om een tijdsduur en transportmiddel in te geven, op basis waarvan de applicatie dan een gebied weergeeft dat binnen het ingegeven tijdstip en met het ingegeven vervoermiddel te bereiken is. Stel bijvoorbeeld dat een persoon zich op het Sint-Pietersplein bevindt en dat hij de applicatie vraagt welke bestemmingen te voet te bereiken zijn in maximum 10 minuten. De applicatie zou deze vraag dan beantwoorden door een cirkel te tekenen rondom de huidige locatie. Het oppervlak van deze cirkel zou dan de bereikbare zone voorstellen. Deze functie werd op voorhand echter als optioneel aanzien wegens de beperkte tijd. Hierna wordt dieper ingegaan op deze vier basisfunctionaliteiten en de uiteindelijke implementatie. De eerste functie, het toevoegen van locaties, is de meest cruciale aangezien de andere verrichtingen helemaal niet mogelijk zijn zonder deze. Vooraleer er plaatsen kunnen verwijderd en weergegeven worden, moet het uiteraard mogelijk zijn om de door de gebruiker gewenste locaties op te slaan in het toestel. In onze applicatie verloopt het toevoegen in vier stappen: 1)
In de eerste stap heeft de gebruiker de mogelijkheid om in het menu een knop - met
het opschrift ‘toevoegen locatie’ - aan te klikken. Daarna verschijnt een venster waar gevraagd wordt een naam voor de plaats in te geven. Eens de plaatsnaam ingegeven is, kan de applicatie overgaan naar stap twee.
37
2)
In deze stap moeten de geografische coördinaten van de huidige plaats opgevraagd
worden om ook deze in de telefoon op te slaan. Het principe van het locatiesysteem is heel gelijkaardig met dat van de sensoren. Een klasse (LocationManager) om de toegang tot de GPS te krijgen en een interface (LocationListener), die gebruikt wordt om meldingen van de LocationManager te ontvangen, wanneer de locatie verandert. Deze interface voorziet ook een methode (onLocationChanged) die wordt opgeroepen telkens men van locatie verandert. Ook hier moet de LocationListener eerst worden geregistreerd bij de LocationManager service vooraleer deze methodes kunnen gebruikt worden. Daarnaast bestaat er een locatieklasse om alle gegevens betreffende een bepaalde plaats bij te houden; via twee methodes uit deze klasse kunnen de breedtegraad (getLatitude) en de lengtegraad (getLongitude) opgevraagd worden [32]. 3)
Met deze coördinaten kunnen we overgaan naar stap drie: de geocoding. Deze
methode bestaat in twee vormen, voorwaartse en achterwaartse geocoding en maakt gebruik van een internetverbinding. Onze applicatie maakt gebruik van het achterwaartse systeem, namelijk het verkrijgen van adresgegevens op basis van de lengte- en breedtegraad. De voorwaartse geocoding doet net het omgekeerde. Android heeft een aparte klasse (Geocoder) voorzien waarin zich een methode bevindt om een lijst van mogelijke adressen te bekomen door beide coördinaten als argumenten mee te geven. Vervolgens kunnen allerhande data omtrent de huidige plaats opgevraagd worden zoals straat, provincie, landcode, enzovoort. Wij hebben er voor gekozen om enkel de straatnaam (en een bepaald bereik van huisnummers), de stad en postcode, het land en de geografische coördinaten uit de beschikbare gegevens te filteren, naast de zelf toegekende plaatsnaam. Om de toegevoegde locaties op een geordende manier bij te houden, is er een nieuwe klasse (ToegevoegdeLocaties) aangemaakt die in staat is bovenstaande gegevens bij te houden per locatie (object). Er werden ook voldoende toegangsmethoden voorzien om bijvoorbeeld stad, land of straat afzonderlijk te verkrijgen. 4)
In de vierde en laatste stap komt het erop aan de toegevoegde locaties op te slaan in
de telefoon. Android geeft verschillende opties om data op te slaan. De gekozen optie hangt af van de specifieke behoeften, zoals de vraag of de gegevens enkel toegankelijk zijn voor jouw applicatie of ook voor andere applicaties en hoeveel ruimte de data vereisen. Het is immers mogelijk om data op te slaan op het interne geheugen van een toestel - voor private data - maar ook op een extern geheugen, zoals een SD-kaart. Daarnaast kan ook gebruik gemaakt worden van een SQLite database om gestructureerde gegevens te bewaren of van het web om gegevens op 38
een eigen webserver te stockeren. De gegevens die onze applicatie opslaat hoeven niet noodzakelijk privaat te zijn en de grootte per locatie is beperkt tot vier String-objecten en twee doubles. De toegevoegde plaatsen worden dan ook extern opgeslagen op de SD-kaart van het toestel. Op deze kaart wordt een tekstbestand (Kladblok) gecreëerd waarbij elk gegeven op een nieuwe lijn terechtkomt. Een tweede essentiële functie die volgt op het toevoegen, is het weergeven van de locaties op een gebruiksvriendelijke manier. Om dit te verwezenlijken moeten de opgeslagen plaatsen uit het tekstbestand kunnen gelezen worden, wat gebeurt aan de hand van de zelfgecreëerde methode (inlezenPlaatsen). Bij het oproepen van deze methode worden alle bestaande locaties uit het bestand toegevoegd aan een arrayList. De data uit deze lijst wordt vervolgens gekoppeld aan een listView - een verticale lijst om items weer te geven - die Android voorziet. Op deze manier werd het mogelijk om alle toegevoegde locaties netjes onder elkaar in een lijst weer te geven. Naast deze lijst met alle toegevoegde locaties, wordt er ook een locatiestatus voorzien. Deze status toont de plaatsnaam op het scherm indien de persoon zich binnen een straal van 50 meter bevindt rondom een van de toegevoegde locaties. Het algoritme dat hiervoor gebruikt wordt, houdt ook rekening met het feit dat de stralen van twee locaties kunnen overlappen. Op dat moment zal de status die plaatsnaam weergeven waar de persoon zich het dichts bij bevindt. Het algoritme wordt hieronder ter illustratie afgebeeld en kort uitgelegd.
39
float [ ]resultaten = new float[3]; double afstand=100; for(int i=0;i
50) {status ="Locatie onbepaald";} statusview.setText("Locatie: "+status); Figuur 11: Algoritme voor locatieweergave.
In Figuur 11 zie je de rij resultaten, waarbij op positie nul de afstand tussen twee locaties wordt bijgehouden. Afstand staat voor een initiële grenswaarde, uitgedrukt in meters. De variabele coördinaten is een arraylist met daarin de toegevoegde locaties. De variabelen lat en lon staan voor respectievelijk de huidige breedtegraad en lengtegraad. In de for-lus wordt voor elke toegevoegde locatie de afstand tussen die locatie en de huidige locatie berekend, indien deze afstand kleiner blijkt dan de initiële drempel van 100 meter dan zal deze berekende afstand de nieuwe grens worden. Het is dit mechanisme dat ervoor zorgt dat steeds de dichtstbijzijnde locatie zal weergegeven worden indien er overlapping optreedt. Ten slotte zorgt de onderste if-constructie dat een afstand groter dan 50 als “onbepaald” wordt beschouwd. De derde functie die de applicatie voorziet, is het verwijderen van een reeds toegevoegde locatie. Het toevoegen en verwijderen van bepaalde items is een veel voorkomende combinatie bij applicaties. Voorbeelden van dergelijke structuren zijn: Facebook, waar vrienden toegevoegd en verwijderd kunnen worden; digitale agenda’s waar taken kunnen toegevoegd worden maar evengoed terug verwijderd; de lijst met voorbeelden kan nog oneindig aangevuld worden. Deze functionaliteit mocht dus zeker niet ontbreken in ons programma. Via de methode 40
(verwijderenLocatie) is het mogelijk om een geselecteerde locatie in de afgebeelde lijst met een simpele menuknop te verwijderen. De programmacode om de juiste lijnen in het tekstbestand te verwijderen is voornamelijk gebaseerd op een voorbeeldprogramma van de website Javadb [33] [34]. De laatste functie die we in de applicatie wilden implementeren was de zogenaamde cirkel van bereikbaarheid die varieerde naargelang de ingegeven tijdsduur en transportmiddel. Deze is uiteindelijk niet geïntegreerd in onze applicatie en bibliotheek om verscheidene redenen. De hoofdreden voor het weglaten is het korte tijdsbestek - meer bepaald zes weken - waarin deze thesis moest voltooid worden. Binnen deze zes weken hebben we enkele basisdoelen vooropgesteld met eventueel enkele extra functies, die bij voldoende tijd konden geïmplementeerd worden. De focus lag voornamelijk op het toevoegen, verwijderen en weergeven van de locaties en de correcte werking hiervan, de bereikbaarheidscirkel was echter niet haalbaar. Een tweede belangrijke reden betreft de toegevoegde waarde van dergelijke cirkel. Android toestellen bevatten sowieso een snelkoppeling naar Google Maps, waarop het mogelijk is om een route uit te stippelen en de huidige positie te bepalen. Google Maps zal daarbij de geschatte tijd en afstand berekenen. Men kan zich dan de vraag stellen welke meerwaarde onze applicatie in deze context zal hebben voor de gebruiker. De meeste personen zullen immers geïnteresseerd zijn in de tijdsduur en afstand om een specifieke locatie te bereiken en minder in een te bereiken gebied binnen een bepaald tijdsinterval. Een derde argument heeft te maken met de geografische kaarten waarop onze cirkel zou komen. Om dergelijke kaarten weer te geven moet Google Maps geïntegreerd worden met de applicatie. Hiertoe voorziet Google een speciale API add-on, een uitbreiding van de Software Development Kit. Een belangrijke component hierin is de externe bibliotheek, Maps, die de ontwikkelaar een waaier aan mogelijkheden biedt om met locaties en kaarten om te gaan. In de laatste bouwfase van onze bibliotheek hebben we getracht deze integratie te bekomen, terwijl sommige basisfuncties nog niet volledig afgewerkt waren. Er moest een afweging gemaakt worden tussen een bibliotheek met enkele goed werkende functies of een bibliotheek met meerdere onafgewerkte functies. Het nijpend tijdsgebrek in combinatie met de geringe meerwaarde van deze laatste functie overtuigden ons om volluit voor optie één te gaan en aldus een sterke basis uit te bouwen. Bij het implementeren van dit locatiesysteem is er wel een nieuwe mogelijkheid opgedoken om de functionaliteit van onze bibliotheek wat te verhogen. Er is namelijk een methode (distanceBetween) voorzien in de Locationklasse die de ontwikkelaar in staat stelt om de afstand 41
tussen de huidige locatie en een opgegeven locatie te bepalen op basis van hun geografische coördinaten. Deze methode kon zeer eenvoudig ingepast worden in de reeds bestaande programmacode aangezien de coördinaten van alle toegevoegde locaties in een tekstbestand in de telefoon opgeslagen zijn. Dit leidde tot de toevoeging van een nieuwe menuknop, ‘bereken afstand’, die de afstand tussen de huidige locatie en een geselecteerde locatie uit de lijst berekent. Er moet wel vermeld worden dat deze afstand geen rekening houdt met straten, verkeer, e.d. Het is met andere woorden de afstand in vogelvlucht. Tot slot heeft het lokalisatiesysteem dat Android aanbiedt wel enkele nadelen. Wanneer een toestel zich binnen een gebouw bevindt zal de connectie met een satelliet of een bepaalde mast niet lukken. Uit eigen ervaring is gebleken dat het testen van ons systeem binnen de gebouwen van de Zuiderpoort niet mogelijk was, maar ook op andere plaatsen liep het soms fout omwille van de aanwezige infrastructuren zoals hoge gebrouwen.
E. Bepalen van omgevingsgeluid Het laatste element van de te bepalen contextinformatie betreft het geluid dat in de omgeving aanwezig is. Hiervoor werd van in het begin gepland om de microfoon die op het toestel aanwezig is te gebruiken. Onderzoek zou dan nog moeten uitwijzen op welke manier deze uitgelezen wordt en of het mogelijk is om hier decibelniveaus uit af te leiden. Over dit punt bracht de Android Developer website geen uitsluitsel: de enige informatie die wij terugvonden ging over algemene audiogegevens (zoals verschillende modes voor het belgeluid [35]) en het opnemen van geluid [36]. Over de interpretatie en verwerking van deze opnames (het bepalen van het volume), werd niets teruggevonden. Om na te gaan of dit überhaupt mogelijk was, gingen we op zoek naar bestaande applicaties met deze functionaliteit. Dit bracht ons bij het project ‘Moonblink’ [37], dat voor een hele reeks applicaties zorgde waaronder Audalyzer. Deze laatste heeft precies voor ogen wat wij willen bereiken, namelijk het analyseren van omgevingslawaai. Hier werd wel meteen bij vermeld dat de resultaten met een grote korrel zout genomen moeten worden, vermits de gevoeligheid van microfoons kan verschillen tussen individuele apparaten. Tussen modellen kunnen deze discrepanties nog veel groter worden. Daarom is het onmogelijk om accurate metingen te verkrijgen. Ook bij andere decibelmeters voor Android werd deze waarschuwing meegegeven, of werd vermeld dat de applicatie per toestel eerst grondig gekalibreerd moest worden. Daarnaast werd ook steeds vermeld dat het berekende volume niet enorm accuraat is.
42
De code van Audalyzer is in principe wel open source, dus wouden we toch nagaan hoe ze hiervoor te werk gingen. Ze maken echter gebruik van de Hermit-bibliotheek, die hiervoor ook geïmplementeerd moet worden. Zoals de ontwikkelaars zelf reeds vermelden, is dit alles behalve eenvoudig, maar is er voorlopig geen andere optie. Wij slaagden er na enkele dagen echter nog steeds niet in om dit te verwezenlijken. Vermits we intussen ook al in de laatste week beland waren die nog voorzien was voor het schrijven van code, leek het ons verstandiger om de analyse van geluid te schrappen uit de planning. Niet alleen de tijdsnood en de vraag of een degelijke uitwerking ervan nog wel zou lukken op enkele dagen speelden mee in deze beslissing, ook de hierboven aangehaalde feiten wogen sterk door. Als er geen garantie is dat de geregistreerde waarden overeenstemmen met deze op een ander toestel, dan kunnen ze ook niet eenduidig geïnterpreteerd worden. Voorbeeld: Een decibelniveau van 85, zoals waargenomen volgens de microfoon van één GSM, kan staan voor een kamer waarin de stemmen van enkele personen weerklinken. Bij de microfoon van een andere GSM kan deze situatie dan weer overeenstemmen met een volume van 50 decibel en wordt 85 decibel geregistreerd wanneer men voorbij een drilboor in werking stapt. Dit zegt uiteindelijk niets zinnigs over de context en dus loont het ook niet de moeite om deze interpretatie uit te werken. Het schrappen van deze klasse zorgt voor een extra beperking voor onze bibliotheek. Niet alleen valt de zelfstandige bijdrage van omgevingslawaai weg, ook kunnen we deze niet langer gebruiken als secundaire informatiebron voor het bepalen van een andere status. Bij onze initiële bespreking van de transportklasse leek het ons een goed idee om omgevingslawaai te gebruiken voor het afleiden van het huidige voertuig. Een luide omgeving en een snelheid van bijvoorbeeld 70 km/u kan bijvoorbeeld een trein voorstellen. Deze gegevens samen gebruiken is dus niet meer mogelijk, waardoor we voor de transportklasse beperkt zijn tot het gebruik van de snelheid.
3. Uiteindelijke implementatie van de interfaces In Hoofdstuk 3 werd beschreven dat wij voorzien hadden om de bibliotheek in andere applicaties te kunnen opnemen door de klassen en interfaces te importeren. Voor het uitwerken van de berekeningen uit dit hoofdstuk hebben wij echter steeds enkel met de klassen gewerkt om deze ook te kunnen testen. Ze zijn dus allemaal opgesteld als activities. Om die reden kunnen onze interfaces ook niet worden aangesproken. Aangezien het proces van code schrijven pas zeer dicht tegen de deadline ten einde kwam, bleef er geen tijd meer over om dit nog volledig te herwerken. Daarom leek het ons het beste om onze goed functionerende klassen te behouden en enkel deze te importeren voor onze applicatie.
43
Hoofdstuk 5: Besluit
Nu we aan het einde gekomen zijn van dit werk, is een algemene beschouwing wel op zijn plaats. Vanaf het begin werd ons duidelijk dat dit een uitzonderlijk project zou worden, verschillend van andere taken uit ons verleden. De grootste uitdaging bestond erin om een voor ons geheel nieuw platform te leren kennen en ons erin te verdiepen, met als grootste moeilijkheid een zeer beperkt tijdskader. Wij hadden beiden vorig jaar reeds een masterproef geschreven, maar deze besloeg een veel langere periode. Terugblikkend zijn wij van mening dat we grotendeels geslaagd zijn in dit opzet. Aanvankelijk was Android een volledig vreemd gegeven voor ons en zelfs de meest eenvoudige taken, zoals het weergeven van tekst op het scherm, vroeg enige gewenning. Tegen het einde van het programmeergedeelte verliep alles al veel vlotter en was van de meeste aspecten duidelijk hoe ze werkten en wat de achterliggende logica ervan was. De verschillende facetten van onze bibliotheek gaven ons de kans om kennis te maken met uiteenlopende elementen van het platform en de verschillende manieren waarop deze aangesproken worden. De uitwerking van het transportgedeelte ging er heel wat anders aan toe dan het bepalen van de positie en zo kwam elk onderdeel met zijn eigen moeilijkheden en uitdagingen. Als we de vergelijking maken met ons initiële opzet voor de bibliotheek en de applicatie, kunnen we concluderen dat we daar grotendeels in geslaagd zijn. We wisten een aantal verschillende informatiebronnen te combineren om hier heel wat contextgegevens uit af te leiden: door ons te baseren op de snelheid die het toestel registreert, zijn we in staat om een goede schatting te maken van welk transportmiddel op dit moment gebruikt wordt; we kunnen nagaan in welke positie het toestel zich bevindt; de lichtsensor laat toe om rudimentaire uitspraken te doen over het licht in de omgeving en door middel van data uit de GPS kunnen we zelf locaties toevoegen en weergeven wanneer we ons hier bevinden. Anderzijds zijn we er niet in geslaagd om al onze vooropgestelde doelstellingen te bereiken. De transportklasse is niet zo precies als we gewild hadden, omwille van de hoogte die niet benut kon worden en de locatiegegevens die we niet konden afleiden. Er kan niet nagegaan worden of het toestel zich bijvoorbeeld in de broekzak bevindt door de te weinig accurate lichtsensor. Ook de informatie over het omgevingslawaai ontbreekt volledig. Op vlak van de applicatie zelf zijn we er ook niet in geslaagd om een handig systeem te voorzien waar elke gebruiker de status van zijn vrienden handig bij elkaar ziet, maar moesten we overschakelen op een minder ideale oplossing in de vorm van Twitter.
44
Deze vermelde tekortkomingen kunnen ook nuttig zijn voor andere ontwikkelaars, om hen mee te delen wat al geprobeerd is, waarom dit niet werkte, of hen net aan te sporen om andere manieren te bedenken die toch tot een oplossing kunnen leiden. Ook onze geslaagde elementen zijn nuttig voor de praktijk, omdat ze anderen het werk besparen van bepaalde zaken te gaan onderzoeken of zelf betekenis te moeten gaan hechten aan de veelheid van onverwerkte informatie. Ook kan het anderen de kans bieden om gebruik te maken van contextgegevens die niet standaard voorzien zijn en hier op creatieve manier mee om te gaan. Dit laatste was uiteindelijk het hoofdopzet van deze thesis en wij denken dat ons werk een positieve bijdrage kan leveren aan de nog jonge gemeenschap van Androidontwikkelaars.
45
Bilbiografie
[1] Smartphone. (2010). Verkregen van http://en.wikipedia.org/wiki/Smartphone. [2] CenceMe. (2009). Verkregen van http://cenceme.org/. [3] Open Handset Alliance. (2010). Verkregen van http://www.openhandsetalliance.com. [4]What is Android. (2010). Verkregen van http://developer.android.com/guide/basics/what-isandroid.html. [5] MURPHY, M.L. (2010). Beginning Android 2. Apress. [6] HASHIMI, S.Y., KOMATINENDI, S., MACLEAN, D. (2010). Pro Android 2. Apress. [7] Sensorsimulator - openintents – Sensor Simulator for simulating sensor data in real time. – Project Hosting on Google Code. (2010, 4 februari). Verkregen van http://code.google.com/p/openintents/wiki/SensorSimulator. [8] Accessing the accelerometer. (2008, 11 januari). Verkregen van http://www.anddev.org/accessing_the_accelerometer-t499.html. [9] JAMISON, J. (2009, 30 maart). Orientation sensor tips in Android. Verkregen van http://www.workingfromhere.com/blog/2009/03/30/orientation-sensor-tips-in-android/. [10] Motion sensors and Orientation in Android | Novoda. (2009, 2 mei). Verkregen van http://novoda.com/2009/05/02/motion-sensors-and-orientation-in-android/. [11] anddev.org – Temperature sensor in Android devices. (2010, 2 april). Verkregen van http://www.anddev.org/temperature_sensor_in_android_devices-t12619.html. [12] PALLER, G. (2010, 14 mei). My life with Android. Verkregen van http://mylifewithandroid.blogspot.com/. [13] Overzicht van alle toestellen | Androidworld. (2010). Verkregen van http://www.androidworld.nl/android-telefoons/overzicht-van-alle-androidtoestellen/. [14] HTC. (2010). Verkregen van http://www.htc.com/nl/. [15] Interfaces. (2010). Verkregen van http://java.sun.com/docs/books/tutorial/java/IandI/createinterface.html. 46
[16] JTwitter. (2008). Verkregen van http://www.winterwell.com/software/jtwitter.php. [17] Assisted GPS. (2010). Verkregen van http://en.wikipedia.org/wiki/Assisted_GPS. [18] ABLESON, F. (2009, 16 juni). Tapping into Android’s sensors. Verkregen van http://www.ibm.com/developerworks/opensource/library/os-android-sensor/index.html. [19] Android Snippets. (2010). Verkregen van http://www.androidsnippets.org/. [20] Location | Android Developers. (2010). Verkregen van http://developer.android.com/reference/android/location/Location.html. [21] LocationListener | Android Developers. (2010). Verkregen van http://developer.android.com/reference/android/location/LocationListener.html. [22] Get speed. (2009, 23 april). Verkregen van http://groups.google.com/group/androidbeginners/browse_thread/thread/0896fb26b159e9c5. [23] VAB. (geen datum). Verkregen van http://www.vab.be/nl/rijschool/content.aspx?pid=144. [24] Sensor | Android Developers. (2010). Verkregen van http://developer.android.com/reference/android/hardware/Sensor.html. [25] Possibility to use the light sensor as a proximity sensor. (2009, 16 november). Verkregen van http://forum.xda-developers.com/archive/index.php/t-584880.html. [26] Burnette, E. (oktober 2009). Hello, Android. Verkregen van http://kronox.org/documentacion/Hello.Android.new.pdf. [27] SensorEvent | Android Developers. (2010). Verkregen van http://developer.android.com/reference/android/hardware/SensorEvent.html. [28] Display current time and date in android application. (2010, 16 februari). Verkregen van http://stackoverflow.com/questions/2271131/display-current-time-and-date-in-androidapplication. [29] SimpleDateFormat | Android Developers. (2010). Verkregen van http://developer.android.com/reference/java/text/SimpleDateFormat.html. [30] How to set a timer in android. (2009, 9 december). Verkregen van http://stackoverflow.com/questions/1877417/how-to-set-a-timer-in-android.
47
[31] SensorManager | Android Developers. (2010). Verkregen van http://developer.android.com/reference/android/hardware/SensorManager.html. [32] MEIER, R. (2007, 19 november). How to Program Google Android. Verkregen van http://blogoscoped.com/archive/2007-11-19-n27.html. [33] HARSH, J. (2008, 2 april). Line Seperator. Verkregen van http://markmail.org/message/i75dt5z27y62rcik. [34] Remove a line from a text file – A Java Code Example. (2010). Verkregen van http://www.javadb.com/remove-a-line-from-a-text-file. [35] AudioManager | Android Developers. (2010). Verkregen van http://developer.android.com/reference/android/media/AudioManager.html. [36] AudioRecord |Android Developers. (2010). Verkregen van http://developer.android.com/reference/android/media/AudioRecord.html. [37] Moonblink – Project Hosting on Google Code. (2010). Verkregen van http://code.google.com/p/moonblink/.
48