Download - Tesi Android Maggioni Magni

Transcript

POLITECNICO DI MILANOFacolt di Ingegneria

Corso di laurea in Ingegneria Informatica Dipartimento di Elettronica e Informazione Anno Accademico 2007/2008

Elaborato di tesi

Progettazione e implementazione di un'applicazione per la navigazione in ambito urbano per la piattaforma Android

Autori:

Marcello Maggioni matricola: 678703 Alberto Magni matricola: 676355

Relatore: Correlatore:

prof. Antonio Capone ing. Luca Dell'Anna

1

Indice1Introduzione........................................................................................................................................4 1.1Descrizione del problema...........................................................................................................4 1.2Obiettivi prefissi.........................................................................................................................5 1.3Scelte Tecnologiche....................................................................................................................6 1.4Soluzioni preesistenti..................................................................................................................8 1.5Organizzazione del Documento..................................................................................................9 2Android: il sistema operativo...........................................................................................................10 2.1La struttura del sistema operativo [14].....................................................................................10 2.2Lo sviluppo di un'applicazione per Android.............................................................................13 2.2.1Il plugin per Eclipse e l'emulatore.....................................................................................13 2.2.2Un progetto Android per Eclipse......................................................................................16 2.2.3Programmare in Android [16]...........................................................................................18 2.2.4Altri elementi utilizzati nel progetto.................................................................................23 3L'applicazione...................................................................................................................................26 3.1L'architettura dell'applicazione.................................................................................................26 3.2Il modello della rete dei servizi pubblici..................................................................................27 3.2.1OpenStreetMap [23]..........................................................................................................27 3.2.2Il Database.........................................................................................................................29 3.2.3La struttura del modello....................................................................................................34 3.2.4La comunicazione con il Database....................................................................................36 3.3L'algoritmo di calcolo del percorso consigliato........................................................................40 3.3.1Introduzione......................................................................................................................40 3.3.2La modellizzazione delle stazioni.....................................................................................40 3.3.3La scelta del mezzo e del percorso....................................................................................42 3.3.4L'individuazione dei malfunzionamenti............................................................................45 3.4Interfaccia grafica ed Esempio di utilizzo................................................................................47 3.4.1L'inserimento dei dati........................................................................................................47 3.4.2La presentazione del percorso...........................................................................................50 3.4.3Conclusioni e possibili sviluppi........................................................................................53 4Note..................................................................................................................................................55 4.1Bibliografia...............................................................................................................................55

2

Indice delle Figure1: Struttura del sistema Operativo Android........................................................................................11 2: La perspective DDMS....................................................................................................................14 3: L'emulatore del sistema operativo Android....................................................................................15 4: La struttura di un progetto Android in Eclipse...............................................................................16 5: Il ciclo di vita di un'Activity...........................................................................................................19 6: La struttura del Modello.................................................................................................................35 7: La comunicazione con il DataBase................................................................................................38 8: Sequence diagram della costruzione del modello .........................................................................39 9: La classe Node e le sue sottoclassi.................................................................................................41 10: Esempio di percorso.....................................................................................................................43 11: La schermata di Input...................................................................................................................47 12: La scelta fra diverse opzioni.........................................................................................................48 13: L'utilizzo del dispositivo GPS......................................................................................................49 14: Esempio di Elenco Scambi...........................................................................................................50 15: Partenza e Destinazione di Esempio............................................................................................50 16: La mappa e le stazioni..................................................................................................................52

3

1 IntroduzioneIn questo capitolo introduttivo viene esposto l'ambito all'interno del quale il progetto si inserisce. Si descrivono quindi i problemi che il lavoro svolto intende risolvere o semplificare. Verranno discusse e motivate le scelte implementative effettuate descrivendo le possibilit tra le quali ci si mossi. Si confronteranno quindi gli obiettivi fissati con altri progetti in sviluppo o gi in circolazione mettendone in evidenza limiti e pregi

1.1 Descrizione del problemaI centri ad alta densit abitativa sono particolarmente interessati da problemi legati all'elevato numero di mezzi di trasporto privati in circolazione. In alcune fasce orarie la velocit media delle automobili nel traffico cittadino decisamente bassa. Una tale situazione comporta costi, non solo economici, e disagi molto elevati per la collettivit: alti valori degli inquinanti, cattiva qualit di vita, sprechi di risorse energetiche, dispendio di tempo e denaro. I problemi esposti sono cos gravi che le molte amministrazioni comunali delle citt pi grandi d'Europa (Milano, Londra, Stoccolma) hanno deciso di introdurre una tassa per accedere al centro cittadino con i mezzi di trasporto privati. Per disincentivare l'utilizzo dell'automobile il pedaggio stato stato fissato a valori decisamente elevati (a Londra si raggiungono 25 per singolo accesso per mezzi particolarmente inquinanti)[1]. Purtroppo soluzioni di questo tipo non sono radicali n definitive. In particolare la citt di Milano non ha risolto i suoi gravi problemi di inquinamento in quanto l'area a traffico limitato ha una superficie ridotta, il che rende in pratica impossibile conseguire gli obiettivi prefissati in fase di studio. Una soluzione definitiva e duratura ai problemi del traffico pu invece giungere da un utilizzo pi intenso ed esteso dei mezzi pubblici, da incentivare verso tutti i possibili fruitori. Ai frequentatori saltuari di una grande citt spesso risulta difficile orientarsi nella rete del trasporto urbano, e ci un freno a ricorrervi. Ancora pi difficolt incontra un turista che intende visitare una citt del tutto ignota. Pu anche presentarsi il caso di cittadini che devono recarsi in quartieri che conoscono poco. Le mappe cartacee, quando sono disponibili, non sempre sono efficaci in quanto non riportano la completa e aggiornata rappresentazione n delle linee n degli orari. Questi ultimi sono difficili da reperire se non ci si trova gi alla stazione o fermata di partenza. Gravi disagi per i viaggiatori derivano dal blocco totale di una linea dei mezzi pubblici in seguito a scioperi improvvisi (particolarmente frequenti in Italia) o a malfunzionamenti dei mezzi.4

Inconvenienti di questo tipo sono decisamente fastidiosi in quanto costringono il viaggiatore a riconsiderare per intero il proprio itinerario. L'obiettivo quindi quello di rendere il ricorso ai mezzi pubblici pi amichevole proponendo semplici soluzioni a problemi quali la determinazione del percorso pi veloce fra localit tenendo conto degli orari e degli eventuali scioperi o malfunzionamenti.

1.2 Obiettivi prefissiLo scopo quindi quello di realizzare un software che permetta di rendere pi semplice l'utilizzo dei mezzi pubblici. Si vuole aiutare l'utente che non conosce in modo approfondito la rete delle linee urbane di una citt a raggiungere una determinata destinazione. Verr quindi elaborato un percorso da seguire tenendo conto degli orari dei mezzi che si intendono utilizzare e di eventuali problemi riguardo a guasti o a scioperi. Alla luce dei problemi descritti, per essere realmente utile e innovativa l'applicazione che si vuole realizzare deve presentare determinate caratteristiche.

Deve poter essere consultabile in qualsiasi momento; in particolare quando si in viaggio o in movimento, permettendo, in questo modo, di orientarsi in una citt che non si conosce. Deve contenere informazioni riguardo la completa struttura delle linee dei diversi mezzi pubblici di cui una citt dotata. In particolare devono essere note le posizioni di tutte le fermate. Questo un problema non semplice da risolvere in quanto spesso le linee di superficie subiscono modifiche non solo negli orari ma anche nella posizione delle fermate. L'ideale sarebbe quindi quello di possedere una fonte di informazioni sempre aggiornata. Questi dati sono di vitale importanza per realizzare sistema in grado di elaborare un percorso per raggiungere una localit prestabilita. Per differenziarsi realmente da una semplice guida stradale, devono inoltre essere disponibili orari e segnalazioni di guasti o scioperi in tempo reale. necessario anche tenere conto di quale orario consultare: festivo o feriale, estivo o invernale. L'affidabilit di questo tipo di informazioni di fondamentale importanza in quanto su di esse si basa l'elaborazione del percorso. Ovviamente essi devono essere tenute costantemente aggiornatei in relazione a eventuali cambiamenti. La presentazione di una mappa interattiva molto utile per poter determinare e visualizzare in modo preciso e veloce le localit di partenza, arrivo e gli eventuali5

scambi da effettuare tra le differenti linee.

1.3 Scelte TecnologicheDall'esposizione degli obiettivi che il progetto si propone di raggiungere risulta evidente che il miglior supporto per l'applicazione in sviluppo uno smart-phone, ovvero un telefono portatile che possiede un proprio sistema operativo con funzionalit quali la navigazione in rete e la semplice gestione di file e contatti. Spesso dispositivi di questo tipo sono dotati di tastiera e di touch-screen che permettono una fruizione davvero immediata delle sue potenzialit. Grazie all'evoluzione tecnologica dell'hardware sono oggi disponibili modelli dotati di sistemi operativi con prestazioni tali da far considerare questi dispositivi assimilabili a computer invece che a semplici telefonini. L'accessibilit di questo tipo di prodotti aumentata di molto nel corso degli anni, portando a un grande aumento delle vendite negli ultimi anni [2],[3] e permettendo una diffusione capillare del prodotto e delle loro applicazioni. Un dispositivo hardware che ha trovato grande diffusione fra gli smartphone il rilevatore di coordinate geografiche GPS. Esso stato introdotto per ottenere la posizione del telefono sulla superficie terreste. Questa integrazione, e la possibilit di accedere in modo veloce alla rete, ha permesso la nascita di un nuovo tipo di applicazioni software: i servizi Location-Based [4]. Essi si prefiggono l'obiettivo di fornire servizi rispondendo a tre semplici domande: Dove mi trovo?, A che cosa sono vicino? e Dove posso andare da qui?. Il mercato dei sistemi operativi per dispositivi mobili molto variegato e scenario di grande concorrenza. a oggi1 quelli esposti di seguito sono i software pi diffusi [5]:

Il sistema operativo Symbian possiede la maggioranza relativa del mercato con il 46% delle vendite. Esso controllato per intero dalla multinazionale finlandese Nokia, la quale ha acquistato la propriet della Symbian Ltd nel giugno del 2008 con l'obiettivo di fondare una societ di software open-source [6]. Symbian stato uno dei primi sistemi operativi per smart-phone e nel corso degli anni sono state rilasciate numerose versioni, il che ha permesso una larga diffusione su differenti modelli di dispositivi. Dato il suo grande successo e la sua diffusione Symbian stato pi volte oggetto di attacco da parte di virus informatici; questo problema pu essere risolto permettendo l'installazione solo di software autenticato e protetto. Il linguaggio di

1 Ci si riferisce al terzo quadrimestre del 2008.

6

programmazione utilizzato per lo sviluppo di software in Symbian il C++. Creare applicazioni su questo sistema operativo per piuttosto complicato. Sono difficile realizzazione anche compiti banali. Questo dovuto all'architettura di vecchia concezione sulla quale il software si basa.

IPhone OS il sistema rilasciato da Apple per supportare prodotti quali IPhone e Ipod Touch. Esso stato progettato in layer, come un normale sistema operativo, e con l'obiettivo di essere molto leggero; adatto a essere eseguito su un dispositivo mobile [7]. La principale limitazione del software riguarda la portabilit, esso infatti stato studiato appositamente per l'hardware Apple. L'azienda ha rilasciato nel marzo del 2008 un tool di sviluppo per applicazioni chiamato iPhone SDK2, che permette la programmazione di software per sfruttare le potenzialit del sistema operativo. La distribuzione del prodotto sviluppato non pu per avvenire in modo libero: infatti necessario far approvare il proprio lavoro da Apple e ottenere l'autorizzazione a distribuirlo. L'azienda canadese RIM ha concentrato le proprie ricerche nello sviluppo di un sistema operativo per il dispositivo BlackBerry. Gli sforzi si sono stati diretti allo sviluppo di soluzioni wireless (per rendere semplice e funzionale il collegamento alla rete) e applicazioni per le attivit di lavoro. Windows Mobile il sistema operativo per cellulari rilasciato da Microsoft. Esso una derivazione del sistema Windows 32 per PC. Una delle caratteristiche fondamentali del prodotto la sua portabilit: esso infatti disponibile per innumerevoli hardware, sia smart-phone che computer palmari. Anche Microsoft ha rilasciato un tool di sviluppo che permette la realizzazione da parte di terzi. Questo disponibile in abbinamento all'editor di Windows Visual Studio. Di recente introduzione il sistema operativo Android. Esso sviluppato da una societ chiamata Open Handset Alliance che guidata dal leader dei motori di ricerca Google. La distribuzione del software sul mercato non ancora avvenuta a livello mondiale ma da tempo disponibile in rete un SDK (Software Development Kit) che permette lo sviluppo di applicazioni per l'architettura. Le funzionalit che vengono messe a disposizione sono davvero notevoli: possibilit di usufruire di mappe;

2 http://developer.apple.com/iphone/

7

sensore GPS, fotocamera e di database integrato. Molto interessante il fatto che il progetto ha come obiettivo rendere semplice e intuitiva la scrittura di codice. A questo si aggiunge la possibilit di accedere al codice sorgente sia del sistema operativo che di quello di ogni altra applicazione distribuita. Queste premesse fanno pensare che in futuro Android si assicurer una fetta considerevole del mercato. Riteniamo quindi questa la soluzione migliore per lo sviluppo del software cercato.

1.4 Soluzioni preesistentiI navigatori satellitari per automobili che aiutano gli automobilisti nella guida fornendo informazioni riguardo la posizione del veicolo e il tragitto da seguire sono molto diffusi. Questo non vale per dispositivi che facilitano l'utilizzo dei mezzi pubblici indicando le linee ideali per raggiungere una localit. Lo stato dell'arte in questo campo rappresentato dal prodotto Discover Cities [8] della societ statunitense NAVTEQ. Si tratta di un'applicazione software che fornisce informazioni riguardo la struttura urbanistica delle principali citt americane ed europee. Essa si propone come un supporto ai programmatori che intendono sviluppare applicazioni location-based in ambito cittadino. Discover Cities permette di elaborare percorsi molto dettagliati accompagnando l'utente curva dopo curva anche sui mezzi pubblici e fornendogli orari e informazioni. A questo si aggiunge la disponibilit ottenere dati e indicazioni su come raggiungere i principali luoghi di interesse e le attrazioni di un citt, funzionalit molto utile per i turisti. All'interno del progetto GoogleMap l'azienda californiana ha promosso, dal dicembre 2005, il progetto Transit [9]. Esso un'applicazione web che permette di pianificare i propri spostamenti in ambito urbano in modo estremamente semplice. Il progetto stato realizzato in associazione con le aziende di trasporto pubblico locale, disponendo cos di informazioni dettagliate e sempre aggiornate sulle stazioni e sugli orari. Oltre che nella versione web, disponibile anche su smart-phone e molti sono i sistemi operativi supportati. Anche per la piattaforma Android, quella scelta per lo sviluppo del progetto, stata sviluppata un'applicazione simile a quella descritta. Essa prende il nome di Metroid [10] e ha come obiettivo quello di pianificare viaggi urbani sfruttando le linee pubbliche. Il suoi sviluppatori hanno anche partecipato al concorso indetto da Google denominato Android Challenge. A nostro giudizio Metroid, ancora in fase di sviluppo, ha notevoli margini di8

miglioramento. Infatti nella base di dati utilizzata non sono mantenute informazioni sulla posizione delle fermate dei mezzi. quindi reso difficile capire quale fermata la pi comoda per giungere in una determinata localit. Oltre al semplice elenco degli scambi da effettuare, sarebbe stata molto utile l'integrazione di una mappa della citt, in modo da visualizzare chiaramente destinazione e partenza. D'altro canto la semplicit con la quale sono mantenuti i dati utilizzati permette una facile estensione del progetto a nuove citt.

1.5 Organizzazione del DocumentoLa presente relazione stata suddivisa in tre capitoli principali. 2.Android: il sistema operativo Il capitolo espone in modo dettagliato le caratteristiche principali del sistema operativo sul quale l'applicazione viene sviluppata. Viene qui messo in luce il carattere fortemente innovativo di Android, appositamente studiato per lo sviluppo di software in modo semplice e veloce. Viene poi descritta la modalit con la quale pu essere realizzato un progetto Android utilizzando un apposito plugin per l'editor Eclipse. Infine sono evidenziate le componenti principali dell'SDK distribuito da Google. 3.L'applicazione Viene qui presentato il software realizzato nel corso del progetto. La trattazione inizia descrivendo l'architettura globale dell'applicazione e addentrandosi poi nei particolari. Sono esposte e giustificare le scelte implementative effettuate considerando i problemi incontrati nello sviluppo. Una volta descritta la modalit di recupero dei dati necessari all'esecuzione presentato l'utilizzo che ne fatto nella costruzione del modello della rete dei mezzi pubblici. Segue quindi l'algoritmo per il calcolo del percorso per il raggiungimento della destinazione prefissata. Sono qui esposte le semplificazioni introdotte e i criteri utilizzati per elaborare un algoritmo semplice ma che fornisca risultati affidabili e realistici. Infine descritta l'interfaccia grafica con cui l'utente viene in contatto. Il capitolo si conclude con un esempio di utilizzo del software prodotto descrivendo nei particolari ogni fase dell'utilizzo. 4.Conclusioni e possibili sviluppi In questo capitolo sono esposte considerazioni circa il raggiungimento degli obiettivi prefissati, la qualit del percorso proposto e la funzionalit del software. Infine sono presentate eventuali soluzioni per ampliare il progetto rimuovendo alcune semplificazioni introdotte.9

2 Android: il sistema operativoAndroid un sistema operativo progettato per dispositivi mobili sviluppato inizialmente da Google e successivamente da Open Handset Alliance (OHA). Questa un'alleanza di aziende composta fra le altre da: Google, Intel, HTC, Motorola, Samsung, LG, Nvidia, Qualcomm e T-Mobile, che ha il fine di sviluppare applicazioni e hardware per smartphone. Il sistema operativo stata annunciato il 5 novembre 2007 e rilasciato il 12 novembre. La prima versione commerciale di un cellulare fornito del sistema operativo Android stata rilasciata il 22 ottobre del 2008 negli Stati Uniti, sotto il nome di T-Mobile G13. L'hardware del telefono stato realizzato dalla compagnia di Taiwan High Tech Computer (HTC). La caratteristica che rende particolarmente interessante Android il fatto che stato rilasciato sotto licenze open-source [11] : Apache 2.0 [12] e GPLv2 [13]. quindi disponibile in rete anche il codice sorgente del sistema operativo4, il quale pu essere modificato e redistribuito a piacere. Questa scelta stata presa in quanto Android pensato per rendere facile lo sviluppo libero di applicazioni che sfruttino appieno le funzionalit.

2.1 La struttura del sistema operativo [14]Come i sistemi operativi per calcolatori fissi, anche Android organizzato secondo il paradigma a pila. Uno schema della sua struttura rappresentato nella figura seguente.

3 http://t-mobileg1.com/ 4 http://source.android.com/download

10

1: Struttura del sistema Operativo Android

Applications: la versione base di Android non presenta solamente il sistema operativo ma anche applicazioni base di frequente utilizzo come un browser, un client di posta elettronica, un'agenda per la gestione dei contatti eccetera. a esse possono essere aggiunti altri programmi non appartenenti alla distribuzione ufficiale. La filosofia della OHA riguardo lo sviluppo di nuove applicazioni pu essere riassunto con la frase: All applications are created equal. Ovvero: non c' differenza fra i prodotti ufficiali e quelli da sviluppare in modo indipendente. Tutti si basano sulle stesse librerie e hanno pari privilegi nell'accesso alle risorse messe a disposizione dal sistema operativo. Application Framework: questo livello dello stack necessario per rendere disponibili i servizi del sistema operativo alle applicazioni al livello superiore. Come detto in precedenza queste API (Application Programming Interface) sono comuni sia alle applicazioni ufficiali che a quelle sviluppate in modo indipendente. L'obiettivo fondamentale che si cercato di raggiungere nella progettazione di questo livello il riuso del codice. Ovvero ogni applicazione pu rendere disponibile alle altre servizi11

specifici permettendo cos la progettazione in modo semplice di servizi nuovi basati su quelli preesistenti. Gli elementi pi importanti del framework sono:

View System: ovvero l'insieme di oggetti grafici che permettono la costruzione dell'interfaccia con l'utente5. Content Providers: un content provider un elemento che permette la condivisione di dati fra applicazioni. La gestione dei dati memorizzati lasciata all'implementazione del singolo provider mentre tutti devono implementare interfacce comuni per permettere l'esecuzione di query e l'inserimento di dati a ogni applicazione. Resource Managers: permettono l'accesso a tutti gli oggetti non costituiti da codice sorgente, quali immagini, file di configurazione dell'interfaccia, stringhe eccetera. Notification Managers: permettono alle applicazioni di presentare all'utente notifiche di eventi asincroni che avvengono in background. Activity Managers: gestiscono il life-cycle delle activity, le quali sono oggetti che rappresentano una singola operazione che l'utente pu eseguire. Le activity, essendo la base di ogni programma sviluppato in Android, verranno descritte in modo approfondito in seguito.

Libraries: le funzionalit messe a disposizione dall'application framework sono implementate da una serie di librerie scritte in C/C++; le pi importanti sono:

Un'implementazione della libreria standard C (libc) specificatamente implementata per i sistemi Linux di tipo embedded. Librerie per la gestione di materiale multimediale basate su PacketVideo's OpenCORE. WebKit: libreria per web browsing. SQLite: libreria di piccole dimensioni per la gestione di un database relazionale. Gestione della grafica 2D e 3D attraverso la libreria OpenGL. Android Runtime: oltre a ulteriori librerie presente in questo sottoinsieme la Dalvik Virtual Machine, ovvero una macchina virtuale all'interno della quale sono eseguite le applicazioni. Essa esegue classi java che sono state compilate in uno specifico bytecode chiamato dex.

Linux Kernel: Android stato sviluppato a partire dalla versione 2.6 del kernel Linux.

5 Per una collezione di esempi di view consultare l'indirizzo: http://code.google.com/android/reference/viewgallery.html

12

Esso ha la funzione di astrarre dal livello hardware e fornire i servizi base di qualsiasi calcolatore, ovvero gestione della memoria, dei processi e del collegamento alla rete.

2.2 Lo sviluppo di un'applicazione per AndroidIl linguaggio di programmazione scelto dagli sviluppatori della OHA per la realizzazione di applicazioni in Android Java. Questa scelta particolarmente significativa in quanto Java il linguaggio pi diffuso al mondo [15]. L'obiettivo della Open Handset Alliance quindi quello di rendere accessibile al maggior numero di programmatori la possibilit di realizzare software per Android. da leggere in quest'ottica la scelta di Google di indire nel maggio del 2008 un concorso (Android Developer Challenge) volto a premiare le applicazioni pi innovative. Le semplificazioni introdotte permettono al programmatore di concentrarsi sulla sua applicazione tralasciando le problematiche riguardanti l'interazione con l'hardware, gestite dal sistema operativo.

2.2.1 Il plugin per Eclipse e l'emulatoreLa realizzazione di applicazioni per Android possibile attraverso il Software Development Kit (SDK), ovvero l'insieme di tutte le classi Java necessarie allo sviluppo. La ricerca da parte della OHA della massima semplicit nella realizzazione di nuove applicazioni ha portato alla realizzazione di una IDE (Integrated Development Environment) apposita per Android. Essa consiste in un'estensione della IDE preesistente Eclipse attraverso un plugin. Anche la scelta di Eclipse non casuale in quanto esso uno degli ambienti di sviluppo gratuiti pi diffusi per la programmazione in java. Il plugin ADT (Android Developement Tools) non parte integrante dell'SDK ma estremamente utile in fase di sviluppo. Esso, ad esempio, aggiunge a Eclipse la perspective chiamata DDMS (Dalvik Debug Monitor Service) che permette di lanciare l'emulatore in modalit di debug e avere una visione di insieme sui processi attivi, l'occupazione della memoria e le prestazioni della CPU. Vi sono anche view per il controllo dei dati sul file-system dell'emulatore, dello heap e dei singoli thread di ogni processo. Di grande importanza per la rilevazione degli errori la view chiamata LogCat la quale presenta allo sviluppatore messaggi di log inviati dall'emulatore. Attraverso la classe Log possibile programmare l'invio di messaggi con il fine di verificare lo stato dell'applicazione e quindi determinare eventuali errori.

13

2: La perspective DDMS

Le applicazioni sviluppate con il plugin possono essere testate in modo realistico attraverso un emulatore: un telefonino virtuale eseguito sul computer. L'emulatore, come si vede nella figura nella pagina seguente, presenta la riproduzione di un telefonino a fianco di una di una tastiera con la quale possibile interagire con l'emulatore. Tutti i bottoni visibili sono funzionanti e hanno un effetto sull'emulatore. L'unico limite dell'emulatore consiste nel fatto che non pu effettuare vere telefonate. Si possono anche simulare eventi esterni come l'arrivo di un SMS, di una chiamata o il cambiamento della posizione nel mondo del telefono. La presenza del dispositivo GPS molto importante per applicazioni di tipo location-based. Se non si usa il plugin di Eclipse possibile comandare l'emulatore attraverso comandi telnet inviati alla porta sulla quale in esecuzione l'emulatore Nel caso in figura il comando per connettersi il seguente: telnetlocalhost5554.

14

3: L'emulatore del sistema operativo Android

15

2.2.2 Un progetto Android per EclipseLa struttura di un progetto Android sviluppato con il plugin di Eclipse qui riportata nell'immagine a fianco. Nella cartella src sono contenute tutte le classi java utilizzate per lo sviluppo del progetto. Molto interessante la cartella chiamata res. In essa sono contenute tutte le risorse non costituite da codice4: La struttura di un progetto Android in Eclipse

sorgente

utilizzate

dall'applicazione.

Esse

sono

suddivise in cartelle:

Drawable raccoglie tutti gli elementi che possono essere utilizzati come icone o in generale disegnati sullo schermo.

Sono accettati tre tipi di oggetti: immagini (di solito in formato png o jpg), definizioni di colori attraverso file xml e immagini di tipo NinePatch (file png a cui associato un xml che ne definisce propriet riguardanti la deformazione che pu subire).

Layout contiene tutti i file per la definizione delle interfacce utente delle differenti activity specificate in formato xml. Ogni file contiene la definizione di una schermata o di una parte di essa. Essi sono associati alla corrispondente activity attraverso l'invocazione del metodo Activity.setContentView() il quale prende come parametro un riferimento all'xml desiderato. Attraverso l'utilizzo dei tag propri di xml possibile creare una struttura ad albero che rappresenta l'interfaccia grafica. a ogni elemento proprio di un'interfaccia corrisponde un tag. Ad esempio esistono i tag e ma anche elementi che ne raggruppano di altri al loro interno come , ordinandoli secondo un criterio prestabilito. Per l'elenco completo degli elementi che possono essere utilizzati nella definizione di un layout e dei corrispondenti tag xml consultare l'indirizzo: http://code.google.com/android/devel/ui/layout.html.

Values raccoglie valori semplici che sono utilizzati da molti elementi all'interno dell'applicazione. Si possono inserire tre tipi di oggetti: stringhe definizioni di colori e di misure di lunghezza. Se si usa il plugin di Eclipse tutte le classi sviluppate e tutte le risorse saranno

16

automaticamente raccolte in un singolo file di estensione .apk (Android PacKage). Esso sar l'unico file necessario per l'installazione dell'applicazione su un emulatore come quello descritto in precedenza. Questa soluzione rende estremamente semplice la condivisione di programmi. Prima di essere inseriti nel file .apk tutte le risorse utilizzate dall'utente e inserite nella cartella rsc verranno prima compilate dal compilatore aapt (Android Asset Packaging Tool) in file binari. Ancora una volta ADT si rivela estremamente comodo in quanto invoca in modo automatico il tool in fase di deploy dell'applicazione. L'ultimo file rimasto da descrivere quello chiamato AndroidManifest.xml. Esso deve essere specificato in ogni programma e fornisce informazioni di carattere generale. Per esempio devono qui essere dichiarati le Activity e i Service utilizzati, i permessi che devono essere garantiti all'applicazione per l'esecuzione dei suoi compiti, oppure riferimenti a librerie necessarie per specifiche funzionalit. Sono qui definiti anche gli IntentFilter spiegati nello specifico nei paragrafi successivi.

17

2.2.3 Programmare in Android [16]Si presentano ora i concetti e i tipi di dato astratto fondamentali per lo sviluppo di un'applicazione Android.

Activity [17] Ogni singola operazione che l'utente pu svolgere rappresentata da una Activity. La creazione di una nuova azione prevede la definizione di una nuova classe, la quale estende la classe Activity che si trova nel package android.app dell'SDK. La maggior parte delle Activity prevede un'interazione con l'utente. Si rende quindi necessaria la creazione di una interfaccia grafica e la sua associazione alla corrispondente Activity. La definizione della struttura dell'interfaccia stata spiegata nel capitolo precedente. La Dalvik Virtual Machine mantiene in memoria una pila delle attivit invocate dall'utente durante l'utilizzo dell'applicazione. Ogni volta che l'utente invoca una nuova schermata (ovvero un'attivit) essa viene inserita sulla cima della pila. Sul fondo si troveranno invece le attivit meno recenti, che non sono visualizzate attualmente sullo schermo. Questo meccanismo rende molto facile e veloce il browsing fra le differenti schermate. quindi molto importante comprendere a fondo il cosiddetto life-cycle delle activity, ovvero la gestione degli stati nei quali esse si possono trovare. Tre sono le modalit principali nelle quali un'Activity si pu trovare:

Running: l'activity visualizzata sullo schermo e l'utente interagisce con essa. Paused: l'utente non pu pi interagire con l'attivit ma il suo layout ancora visibile (ad esempio sopra di esso appare una finestra di dialogo). Le activity in questo stato mantengono tutte le informazioni riguardanti il loro stato e possono essere terminate dalla DVM nel caso di scarsit di risorse. Stopped: quando l'utente passa da un'Activity a un'altra, la prima posta in stato di stop. Ci significa che una nuova activity verr posta sulla cima della pila. Le attivit in stop sono le prime a essere terminate in caso di necessit di ulteriori risorse.

La figura seguente mostra i passaggi di stato di activity. I rettangoli rappresentano le chiamate ai metodi di callback, ognuno dei quali svolge una funzione specifica nell'ambito del ciclo di vita dell'applicazione.18

5: Il ciclo di vita di un'Activity

19

Tutti i seguenti metodi possono essere oggetto di override da parte del programmatore, che pu quindi adattarli alle proprie esigenze.

onCreate(Bundle): questo metodo invocato dalla DVM quando l'Activity viene creata per la prima volta ed necessario alla sua inizializzazione. Le operazioni fondamentali che vengono svolte in questo metodo riguardano la definizione dell'interfaccia grafica attraverso un file .xml, l'associazione di ogni elemento dell'interfaccia alla corrispondente azione desiderata e l'inizializzazione delle strutture dati utilizzate quali liste e basi di dati. L'oggetto di tipo Bundle passato come parametro necessario al passaggio di informazioni riguardanti lo stato dell'applicazione. onPause(): ogni volta che l'utente lascia un'Activity la DVM invoca questo metodo nel quale il programmatore dovr aver specificato operazioni riguardanti il salvataggio dello stato raggiunto dall'applicazione. onStart(): quando l'activity visualizzata sullo schermo del telefono viene invocato questo metodo. onRestart(): metodo chiamato ogni volta che l'activity diventa visibile all'utente dopo che stata posta nello stato paused. Subito dopo la terminazione del metodo viene invocato onStart(). onResume(): il metodo chiamato subito prima che l'activity sia posta sulla cima della pila e che quindi si possibile per l'utente un'interazione. onStop(): quando un'Activity viene oscurata da un'altra viene invocato questo metodo. onDestroy(): il metodo lanciato subito prima della distruzione finale dell'Activity.

Nello schema si possono qui individuare 3 cicli:

ciclo di vita: ricadono in questo insieme tutte le operazioni comprese fra le chiamate ai metodi onCreate(), nel quale si allocano tutte le risorse necessarie, e onDestroy(), nel quale le risorse sono rilasciate. ciclo di visibilit: compreso fra i metodi onStart() e onStop(). In questo periodo di tempo l'interfaccia dell'actitvity s visibile all'utente ma pu non essere possibile l'interazione con essa a causa della presenza di altre activity in20

primo piano.

ciclo di vita in primo piano: in questo insieme sono comprese tutte le operazioni fra i metodi onResume() ed onPause(). L'Activity qui completamente disponibile all'utente il quale pu interagire con essa, ad esempio riempiendo dei form di input.

Esistono due modi per lanciare un'Activity. Essi si identificano nei due metodi startActivity(Intent) e startActivityOnResult(Intent,int). Il primo permette il semplice lancio di un'Activity identificata dall'oggetto di tipo Intent (spiegato nel paragrafo successivo). Il secondo metodo invece prevede che la classe invocata ritorni un risultato; esso sar disponibile facendo override, nel chiamante, del metodo onActivityResult(int,int,Result) che verr invocato alla terminazione dell'attivit chiamata.

Intent [18] Questo tipo di dato rappresenta la descrizione astratta di un'operazione che pu essere compiuta. Esso pu essere utilizzato per lanciare nuove Activity o nuovi Service. In ogni istanza di un Intent necessario specificare almeno due parametri:

l'azione che si intende compiere ad esempio: ACTION_VIEW o ACTION_EDIT. I dati necessari all'esecuzione dell'azione identificati da un URI (Uniform Resource Identifier). La definizione di un Intent pu avvenire quindi nel seguente modo: Intent intent = new Intent (Intent.ACTION_VIEW, content://contacts/1); Questo intent permetter di visualizzare le informazioni caratteristiche del contatto identificato dal numero 1. Una volta creato l'oggetto necessario avviare l'Activity che possa effettivamente visualizzare queste informazioni. Questa operazione possibile attraverso: startActivity(intent); L'associazione fra intent e activity avviene grazie alla definizione di un IntentFilter. Esso consiste in una dichiarazione di essere in grado di gestire una determinata richiesta e deve essere specificato nel file AndroidManifest.xml associato a ogni applicazione. L'utilizzo degli21

IntentFilters particolarmente utile in quanto permette di riutilizzare codice gi scritto in precedenza per assolvere dei compiti semplici come ottenere informazioni riguardo un contatto dalla rubrica. importante anche notare che il chiamante ignora completamente come il compito sia assolto, in quanto conosce solo l'interfaccia pubblicata dall'IntentFilter.

Service [19] Un Service un componente dell'applicazione che viene eseguito in background per un periodo di tempo indefinito, e che non ha quindi interazione diretta con l'utente. importante notare che il codice contenuto in una classe che estende Service eseguito nel thread principale dell'applicazione. Nel caso in cui siano eseguite operazioni che utilizzano molto la CPU o la connessione a una rete quindi consigliabile la creazione di un nuovo thread. Come per le activity anche nei Service sono presenti metodi di callback eseguiti in momenti specifici dell'esecuzione. Essi sono ad esempio onCreate(), onDestroy(), dal significato affine a quello specificato per la classe Activity. Vi sono due modi per avviare un service:

All'invocazione del metodo Context.startService() una nuova istanza di un service creata (con il metodo onCreate()) e lanciata ( con il metodo onStart(Intent,int)). L'esecuzione prosegue fino alla chiamata del metodo Context.stopService(). Se il metodo Context.onBind() invocato viene instaurata una connessione persistente a un o specifico servizio il quale, se non esiste gi, pu venir creato. In questo caso il metodo onStart() non chiamato. Il chiamante otterr cos un identificativo del Service, cosa che gli permetter di effettuare richieste. Un Service pu essere al tempo stesso avviato con il metodo onStart() e oggetto di connessioni. Esso potr essere terminato solo quando non ci saranno pi connessioni attive e il metodo Context.stopService() non verr chiamato.

Content Provider [20] Gli oggetti di tipo ContentProvider hanno la funzione di garantire l'accesso a dati condivisi da pi applicazioni. L'effettiva implementazione del salvataggio dei dati in memoria di massa non specificato ed lasciata al programmatore. Tutti i content22

provider per devono implementare interfacce predefinite che specificano il modo col quale le query possono essere effettuate e la modalit di presentazione del risultato. I tipi di dati salvati possono essere di vario tipo6: contatti telefonici, file audio e video. Ogni ContentProvider fornisce un URI ai client che vogliono utilizzare i suoi dati; attraverso questa stringa che possibile effettuare richieste o inserire dati. Esempio: L'URI content://contacts/people/ permette di ottenere tutti gli elementi della tabella people; invece l'URL content://contacts/people/10 ritorna la singola persona identificata dal codice 10. L'inserimento di dati invece avviene specificando oltre a un URI anche una mappa che fa corrispondere alle colonne della tabella relazionale i campi della riga da inserire.

2.2.4 Altri elementi utilizzati nel progetto

Le Mappe Nel tipo di applicazione sviluppata in questo progetto di fondamentale importanza la visualizzazione di una mappa per permettere all'utente di orientarsi all'interno della citt. L'SDK di Android rende possibile l'integrazione di una mappa all'interno dell'applicazione. Per questo scopo fornita una particolare sottoclasse di Activity chiamata MapActivity. Come per la sua superclasse sar necessario specificarne il layout attraverso un file xml. Esso, oltre ai normali elementi grafici, conterr un tag di nome che corrisponde a un oggetto della classe MapView, la quale rappresenta la mappa vera e propria. MapView fornisce accesso ai dati di Google Maps, per questo per utilizzarla necessario possedere una chiave chiamata Maps API Key7 propria per ogni sviluppatore, che la pu usare in tutte le sue applicazioni. Attraverso il metodo ereditato dalla classe Activity findViewById() il programmatore pu istanziare un oggetto MapView e lavorare su di esso. Molto utile un classe di supporto chiamata MapController che permette di impostare alcuni parametri della mappa

6 Per consultare l'elenco dei tipi di dato astratti che rappresentano i dati memorizzati in un ContentProvider si veda: http://code.google.com/android/reference/android/provider/package-summary.html 7 http://code.google.com/android/toolbox/apis/mapkey.html

23

quali le coordinate del centro e il livello di ingrandimento. Un oggetto di questo tipo si pu ottenere a partire da MapView attraverso il metodo getController().

Il GPS L'SDK di Android mette a disposizione alcune classi per permettere al programmatore di ottenere informazioni riguardanti la posizione attuale del telefono (e quindi del suo proprietario) nel mondo. Lo strumento a disposizione il rilevatore GPS (Global Positioning System). Esso permette di ottenere le coordinate geografiche del luogo dove si trova il telefono sotto forma di latitudine e longitudine. Realizzare programmi che sfruttino questa potente funzionalit molto facile nell'ambiente Android. La classe che permette di ottenere le due coordinate chiamata LocationManager8 ed istanziabile nel seguente modo: LocationManagerlm= (LocationManager)getSystemService(Context.LOCATION_SERVIC E); Per poter utilizzare questa funzionalit necessario garantire un permesso particolare all'applicazione specificando nel file AndroidManifest.xml il seguente tag. Una volta ottenuto l'oggetto lm da esso possibile ottenere un'istanza della classe Location. Locationloc=lm.getLastKnownLocation (LocationManager.GPS_PROVIDER); Location rappresenta un preciso luogo geografico in un determinato momento. Attraverso i due metodi getLatitude() e getLongitude() possibile ottenere le coordinate del luogo rappresentato. Questa funzionalit pu essere testata sull'emulatore anche se non possiede una connessione alla rete GPS. Sar necessario simulare il funzionamento di un LocationProvier. Ci possibile in molti modi:

Sotto la voce Location Controls nella finestra Emulator Control della perspective DDMS fornita dal plugin ADT di Eclipse si specificano direttamente le coordinate del luogo desiderato, oppure si fa l'upload di file di formato KML o

8 http://code.google.com/android/toolbox/apis/mapkey.html

24

GPX contenenti anche molte coordinate.

Inviando attraverso un comando telenet direttamente le coordinate all'emulatore. Una volta stabilita la connessione eseguire il seguente comando: geofixlongitudelatitude

Il DataBase SQLite [21], [22] Un database SQLite un DBMS relazionale di piccole dimensioni perfetto per essere utilizzato da un'applicazione per smart-phone. Esso non un processo indipendente che si basa sul paradigma client-server come i normali DBMS quali MySQL (utilizzato in un altro ambito del progetto), ma una libreria parte integrante del programma realizzato. quindi possibile accedere ai dati memorizzati attraverso semplici chiamate a metodi, molto pi veloci rispetto alla comunicazione fra processi. Il database vero e proprio memorizzato in un file il quale viene messo in lock ogni qualvolta una query viene eseguita. La classe dell'SDK che rappresenta un database SQLite si chiama: SQLiteDatabase. Essa mette a disposizione metodi quali query, delete e update che permettono una completa gestione del database. Di grande utilit il tipo di dato astratto SQLiteOpenHelper. Esso gestisce le operazioni elementari da eseguire sul database. La classe si occupa ad esempio di aprire il database, o di crearlo se esso non esiste, e di organizzare le transizioni a seguito di upgrade (ad esempio un'aggiunta o una rimozione di una tabella). Due database SQLite sono utilizzati nell'applicazione sviluppata per gestire la memorizzazione delle localit frequentate e per permettere il passaggio di parametri riguardanti il percorso generato da un'Activity a un'altra.

25

3 L'applicazioneQuesto capitolo ha il fine di descrivere in modo approfondito le caratteristiche fondamentali dell'applicazione sviluppata in questo progetto. Verranno quindi presi in considerazione elementi quali la costruzione del modello della rete dei mezzi pubblici cittadini; l'elaborazione dell'algoritmo di calcolo del percorso pi veloce e la presentazione del risultato all'utente. Insieme alle soluzioni implementate verranno presentati anche le problematiche affrontate durante lo sviluppo e come queste sono state superate giungendo alla soluzione realizzata.

3.1 L'architettura dell'applicazioneL'applicazione stata strutturata a livelli. Ognuno di essi raggruppa tipi di dato astratto che hanno funzionalit e scopi simili. Una classe appartenente a un dato livello pu comunicare solamente con quelle appartenenti ai livelli contigui. Questa architettura ha diversi vantaggi, apprezzabili soprattutto in fase di sviluppo e testing. Infatti possibile cambiare l'effettiva implementazione delle classi di un dato livello se si mantiene l'interfaccia che esse presentano agli altri. Questo evidente per la comunicazione con il database remoto. L'applicazione non infatti legata al particolare tipo di database usato ma pu essere estesa in modo semplice come descritto nel capitolo dedicato. Per quanto riguarda il debugging esso pu essere condotto in modo pi semplice analizzando un livello per volta. La seguente tabella presenta la struttura dell'architettura. Livello Presentazione Modello della rete dei mezzi pubblici e Algoritmo Rappresentazione del database Elaborazione delle query e Connessione con il Database Classi Principali LocationsInsertion, StopList, Map, Error, RowEntry, EntryView, PlacesOverlays, StopsOverlays, LocalDataBase MetroLines,TramLines,Station,Node,MetroNode, TramNode, Problem, Path, PathCreator DBInterface; RemoteDB SQLQueryUtil, ToSql

Le classi in corsivo nel livello Presentazione estendono un'Activity.

26

3.2 Il modello della rete dei servizi pubbliciPer realizzare un algoritmo che computa un percorso fra due luoghi di una citt necessario possedere una struttura completa della rete dei mezzi pubblici. Dovranno quindi essere note le posizioni geografiche di tutte le fermate e il loro numero d'ordine nelle linee che le utilizzano. Uno dei problemi maggiori incontrati durante la progettazione e lo sviluppo stato proprio ottenere queste informazioni. Con riferimento a Milano, la citt utilizzata come esempio, parte di questi dati sono disponibili sul sito dell'azienda locale dei trasporti pubblici: http://www.atm-mi.it/ATM/. Nel sito contenuto l'intero elenco delle linee dei mezzi pubblici, le corrispondenti fermate e gli orari. stato per deciso di non utilizzare questa fonte per molti motivi:

L'ATM non mette a disposizione le coordinate geografiche in latitudine e longitudine delle stazioni. Questi dati sono per fondamentali per la determinazione delle distanze. Ovviamente l'accesso al database di back-end dell'applicazione web precluso ai normali utenti. Recuperare le informazioni di cui si ha bisogno da un sito internet attraverso il parsing di una risposta HTML non un modo corretto di procedere. La controindicazione pi grave riguarda eventuali modifiche che il sito pu subire in fase di manutenzione. Queste comporterebbero a una completa riprogettazione del parser.

L'ipotesi di utilizzare il sito ATM stata per questi motivi scartata. Si quindi cercata un'altra fonte per recuperare i dati necessari, in particolare le coordinate delle stazioni e delle fermate. Si quindi rivolta l'attenzione a un progetto open-source: OpenStreetMap.

3.2.1 OpenStreetMap [23]Il progetto OpenStreetMap ha lo scopo di realizzare mappe del mondo attraverso la libera collaborazione di volontari. Per quanto riguarda il recupero di informazioni sulle fermate dei mezzi, quello che interessa non sono le mappe in s ma piuttosto gli elementi topologici che le compongono. Tutte le cartine di OpenStreetMap sono costruite a partire dai dati contenuti in un database chiamato OSM Database. possibile interrogare la base di dati effettuando una richiesta HTTP e ottenendo una risposta in formato testuale. I parametri della query da

27

inoltrare al database devono essere tutti inseriti nell'URL. Un esempio di indirizzo che permette di ottenere informazioni riguardo le stazioni della metropolitana in una zona centrale di Milano il seguente: http://www.informationfreeway.org/api/0.5/node[railway=subway] [bbox=9.19064,45.478228,9.22201,45.4957] Nell'URL si possono individuare due elementi fondamentali:

node: questa parola chiave permette di specificare l'elemento topologico che si intende ricercare nel database. In questo caso vengo cercate stazioni della metropolitana: verr quindi inserita la parola chiave subway. L'elenco completo degli elementi che possono essere recuperati dal database consultabile all'indirizzo: http://wiki.openstreetmap.org/wiki/Mapfeatures. bbox: questo predicato necessario a definire un rettangolo di superficie terrestre nel quale effettuare la ricerca. Esso dovr essere specificato nella forma: [bbox=left,bottom,right,top], dove i left e right sono gli estremi della latitudine, mentre bottom e top sono gli estremi della longitudine.

La risposta dal server in formato xml; in cui il tag identifica un singolo elemento topografico. Quello riportato di seguito un passaggio della risposta fornita alla richiesta descritta in precedenza. Come si nota contiene molte informazioni riguardo la stazione come le coordinate, il nome, la linea e l'identificativo dell'utente di OpenStreetMap che ha inserito il dato. Questa struttura del file xml presenta per molti problemi a essere analizzata da un parser.

Non specificata la linea alla quale la stazione appartiene. Nel caso di esempio essa stata inserita nel nome, ma questa non una convenzione: stata semplicemente la scelta dell'utente. Non esiste infatti un tag xml che identifica la linea. Pur avendo specificato nell'URL la variabile subway vengono incluse nella risposta28

stazioni diverse da quelle della metropolitana.

Non possibile stabilire un ordinamento delle stazioni; non vi presente infatti nessuna informazione riguardo la posizione della fermata all'interno della linea.

In definitiva l'insieme dei tag messi a disposizione per la specifica dei luoghi rilevanti a nostro giudizio insufficiente per effettuare un'analisi programmatica dei file xml forniti. Per questa ragione stata scartata l'ipotesi di utilizzare OpenStreetMap come database. Per risolvere il problema del reperimento di informazioni stato deciso di creare un database costruito appositamente per le nostre esigenze. Esso non conterr l'insieme di tutte le linee di tram o metropolitana ma solo una piccola parte. Le tratte coperte saranno per complete, ovvero da esso sar possibile costruire il modello. Oltre alle informazioni topologiche su fermate e stazioni esso conterr dati riguardo gli orari dei mezzi e eventuali interruzioni sulle linee.

3.2.2 Il DatabaseIl database di tipo relazionale ed stato realizzato utilizzando la tecnologia MySql. La base di dati composta di molte tabelle, ognuna delle quali rappresenta un particolare insieme elementi per la costruzione del modello. Qui di seguito riportato il codice SQL che definisce la strutture delle tabelle.

Metro Stops e Tram Stops Queste due tabelle sono simili fra loro in quanto rappresentano e mantengono in memoria le informazioni riguardanti rispettivamente le stazioni della metropolitana e le fermate del tram. createtablemetro_stops( stop_namevarchar(28)notnull, linetinyintnotnull, stop_numbersmallintnotnull, latituderealnotnull, longituderealnotnull, terminalbooleannotnull, branchbooleannotnull, primarykey(stop_name,line));29

createtabletram_stops( stop_namevarchar(28)notnull, linetinyintnotnull, stop_numbersmallintnotnull, latituderealnotnull, longituderealnotnull, terminalbooleannotnull, primarykey(stop_name,line)); Oltre al nome e alla linea a cui appartiene la fermata sono memorizzati il numero della fermata all'interno della linea, le coordinate geografiche in latitudine longitudine, un flag per segnalare se la fermata un capolinea e uno per indicare la presenza in quella stazione di diramazioni della linea. La chiave composta dai due campi stop_name e line. Due aspetti sono da evidenziare riguardo questa scelta di salvataggio dei dati. Il primo riguarda le stazioni comuni a pi linee. Per ognuna di essa saranno presenti nel database tante entry quante sono le linee che usano quella fermata. Ognuna di queste si distinguer dalle altre solo per il campo line. Il secondo aspetto riguarda la numerazione delle fermate in corrispondenza di biforcazioni di una linea (cosa che a Milano avviene per due tratte della metropolitana). In questi casi la numerazione continua in modo progressivo aggiungendo al numero computato nella maniera normale una cifra in pi. Essa sar 0 per la prima biforcazione (la quale scelta in modo arbitrario), 1 per la seconda, 2 per la terza e cos via. Questa scelta permette di mantenere un ordine crescente nella numerazione delle fermate.

30

Time Table La tabella Time Table memorizza per ogni fermata del tram gli orari dei passaggi. Il database non rispecchia il reale orario dei tram in quanto esso stato realizzato a puro scopo dimostrativo. createtabletime_table( stop_namevarchar(28)notnull, linetinyintnotnull, summerbooleannotnull, working_daybooleannotnull, hour_of_daytinyintnotnull, minutesvarchar(50)notnull, primarykey(stop_name,line,summer,working_day), foreign cascade); I due campi stop_name e line sono necessari per individuare in modo univoco la fermata alla quale ci si riferisce. I due flag summer e working_day servono a discriminare fra orario estivo ed invernale e fra giorno festivo e feriale. hour_of_day identifica l'ora all'interno della quale si intende prendere il tram. In corrispondenza di ogni ora salvata una stringa al cui interno sono salvati i minuti dei passaggi sotto forma di interi separati da virgole. Effettuando una query a questa tabella si otterranno quindi i minuti dei passaggi del tram per l'ora desiderata. key (stop_name,line) references tram_stops(stop_name,line) on update cascade on delete

31

Metro Problem e Tram Problem Queste due tabelle della base di dati memorizzano le informazioni riguardanti eventuali problemi sulle linee di tram e metro. createtablemetro_problem( first_stop_namevarchar(28)notnull, last_stop_namevarchar(28)notnull, linetinyintnotnull, start_datedatenotnull, end_datedatenotnull, start_timetimenotnull, end_timetimenotnull, descriptionvarchar(100), primarykey (line,start_date,first_stop_name,last_stop_name), foreignkey(first_stop_name,line)references metro_stops(stop_name,line)onupdatecascadeondelete cascade, foreignkey(last_stop_name,line)references metro_stops(stop_name,line)onupdatecascadeondelete cascade) Per poter individuare in modo preciso i differenti problemi che possono verificarsi sono qui memorizzate la prima e l'ultima stazione in cui l'inconveniente si verifica (in caso di uno sciopero saranno i due capolinea). Vi sono poi i riferimenti alle date e agli orari di inizio di fine presunta del malfunzionamento o dello sciopero.

32

Per simulare in modo realistico la presenza di un sito remoto dal quale tutte le informazioni sopra riportate sono recuperate stata creata un'applicazione web che funge da interfaccia al database. Non quindi possibile effettuare delle query direttamente alla base di dati; esse verranno inoltrate dall'applicazione sullo smart-phone alla web-application la quale le interpreter e le inoltrer al server MySql fornendo poi il risultato. Questo stato realizzato utilizzando la tecnologia Servlet di Java [24]. Una servlet un oggetto eseguibile da un application-server che svolge una specifica funzione a seguito di una richiesta. Nell'applicazione server qui sviluppata la classe QuerySrv, estendendo HTTPServlet, avr il compito di interpretare le richieste del client e interrogare il database. La richiesta HTTP proveniente dal client dovr contente i parametri per poter effettuare la richiesta SQL. Essi sono 4 e corrispondono ai campi di una query SQL: select, from, wheree orderby. La classe di supporto DBUtil avr il compito di effettuare la richiesta vera e propria. Il collegamento fra la business-logic e i dati permesso dalle classi dell'API JDBC (Java DataBase Connectivity) [25]. Viene ora presentata la procedura utilizzata per accedere e interrogare il server MySql. La classe JDBC che permette l'accesso al database chiamata Connection. Per ottenerne un'istanza necessario possedere un account sul server MySql (ovvero un username ed una password) e conoscere la porta sulla quale esso in ascolto. Il tipo di dato astratto Statement rappresenta un'istruzione in codice Sql che viene inoltrata al database a cui si connessi. possibile ottenere un oggetto di questo tipo invocando il metodo connection.createStatement() una volta avvenuto il collegamento con il server. L'istruzione da eseguire verr specificata attraverso il metodo statement.execute() o statement.executeQuery() sotto forma di String a partire dai dati forniti in input dall'utente attraverso l'oggetto request. Il risultato delle query effettuate sar del tipo ResultSet. Esso verr quindi scansionato per ottenerne una String. Per identificare i campi delle differenti colonne in fase di lettura essi sono divisi fra di loro da un simbolo separatore convenzionale. La stringa testuale cos elaborata sar quindi la risposta alla richiesta effettuata. La risposta arriver quindi al client in formato testuale in modo che se ne possa effettuare il parsing in modo semplice.

33

3.2.3 La struttura del modelloLa classe fondamentale per la costruzione del modello si chiama Station. Essa eredita dalla classe dell'SDK Location contenuta nel package android.locationdescritta in precedenza. Questo permette di riutilizzare attributi e metodi della superclasse senza re implementarne di nuovi. In particolare verranno utilizzati i metodi set e get degli attributi doublelatitude e longitude; e il metodo float distanceTo(Location dest). Esso ritorna la distanza in metri fra la localit che lo implementa e quella passata come parametro. Si riveler molto utile nella elaborazione del percorso pi breve. La classe Station aggiunge quindi a questi attributi variabili per la memorizzazione dei dati ricavati dalla lettura del database. Essi sono: privateStringname; privateintline; privateintnumber; privatebooleanterminal; privatebooleanbranch; Una volta rappresentate le stazioni necessario costruire un modello per le linee dei diversi tipi di mezzi pubblici. A questo scopo sono state introdotte le due classi MetroLines e TramLines. Esse possiedono gli attributi tram_stops e metro_stops i quali sono del tipo ArrayList. Queste due liste conterranno quindi tutte le istanze della classe Station utili per la determinazione del percorso da compiere. da notare che le due liste contengono tutte le stazioni (o della metropolitana o dei tram), non vi quindi distinzione fra le differenti linee. Inoltre l'ordine con il quale le stazioni sono raccolte non rispecchia la successione delle fermate su una linea; ma l'ordinamento alfabetico. La struttura sopra descritta riassunta nel seguente schema UML.

34

6: La struttura del Modello

35

3.2.4 La comunicazione con il DatabaseLa classe che mette a disposizione i metodi per la comunicazione con il database chiamata ToSql. Essa implementa l'interfaccia DBInterface la quale contiene tutti i metodi pubblici indispensabili per il recupero delle informazioni necessarie. I metodi della classe ToSql non possono essere chiamati direttamente dalle classi di livello pi alto. Al loro posto devono essere invocati quelli di RemoteDB, che implementa anch'esso l'interfaccia DBInterface. Questo stato fatto in quanto non si voluto legare il funzionamento dei livelli superiori dell'applicazione a una specifica implementazione del collegamento con il database. Infatti se si decidesse di sostituire la classe ToSql si dovrebbe cambiare solo una riga di codice nella classe RemoteDB mentre le classi ai livelli superiori rimarrebbero invariate. Nel costruttore delle classi che compongono il modello quali TramLines e MetroLines vi sar quindi un'invocazione di un metodo di RemoteDB che chiamer a sua volta ToSql per ottenere le informazioni richieste. In ogni metodo di RemoteDB presente un'invocazione del corrispondente in ToSql. Per evitare la creazione di oggetti di tipo RemoteDB che risulterebbero inutili ai fini pratici questa classe implementa il pattern architetturale chiamato Singleton [26]. Il quale prevede di nascondere il costruttore di una classe e rendere pubblico solo il metodo getInstance() che ritorna un nuovo oggetto o fornire un riferimento a quello gi esistente. Viene qui di seguito descritta la procedura, implementata dalla classe ToSql, con la quale possibile effettuare richieste a un server attraverso il protocollo HTTP. Ci garantito dalle classi del package dell'SDK org.apache.http. La classe DefaultHttpClient identifica un generico client HTTP. attraverso di essa che possono quindi essere inoltrate le richieste ed ottenere le risposte. Il tipo HttpPost identifica una request inoltrata al metodo POST del protocollo, mentre HttpResponse rappresenta ovviamente la risposta ritornata. Una volta inizializzati gli oggetti di tipo DefaultHttpCliente HttpPost necessario inserire nella richiesta i dati di input, ovvero i parametri della query. A questo scopo si utilizza la classe NameValuePair, una mappa che fa corrispondere due stringhe fra loro: ovvero il nome ed il valore di un parametro. possibile ora inoltrare la richiesta che verr elaborata dalla servlet descritta in precedenza. Il metodo per fare ci : http_client.execute(request). L'oggetto36

HttpResponse ritornato quindi trasformato in una String ed pronto per essere analizzato.

37

7: La comunicazione con il DataBase

38

Per meglio visualizzare il procedimento di costruzione del modello della rete dei mezzi pubblici e mettere in evidenza la suddivisione in livelli viene presentato il seguente sequence diagam.

8: Sequence diagram della costruzione del modello

39

3.3 L'algoritmo di calcolo del percorso consigliato3.3.1 IntroduzioneL'algoritmo di calcolo del percorso la parte del programma che genera l'itinerario attraverso le linee di metro e tram per raggiungere punto prestabilito dall'utente. L'algoritmo contenuto nella classe PathCreator e il percorso viene generato attraverso il metodo: PathCreator.generatePath(double from_x, double from_y, double to_x,doubleto_y). generatePath() prende in input le coordinate x (longitudine) e y (latitudine) rispettivamente di origine e destinazione e ritorna una lista delle stazioni di snodo che l'utente deve attraversare per raggiungere una destinazione. Vengono qui definite stazioni snodo quelle in cui si incrociano pi linee di mezzi pubblici. Esse permettono quindi di cambiare linea in modo da utilizzare la migliore per raggiungere il punto desiderato.

3.3.2 La modellizzazione delle stazioniPer rappresentare nel modo migliore una stazione di snodo l'algoritmo utilizza la classe Node. Essa permette di gestire la relazione tra le differenti linee che attraversano una stazione di scambio. In particolare sono mantenuti riferimenti, sotto forma di array, ai numeri delle linee che si incrociano e al numero d'ordine della stazione all'interno della linea. La classe Node estesa da MetroNode e TramNode; le quali identificano rispettivamente uno snodo per la metropolitana e per il tram. Questa struttura introdotta semplifica il calcolo dei percorsi racchiudendo l'interconnessione tra le varie linee dei mezzi in un'unica classe. Si rende cos semplice ottenere informazioni riguardanti la presenza o meno di una linea in una determinata stazione, il fatto che che ci sia una deviazione e il numero d'ordine.

40

9: La classe Node e le sue sottoclassi

Ecco una generale spiegazione su ogni metodo delle classi:

getStations() ritorna un ArrayList contenente una Station per ogni linea presente in quel nodo. getStation(intline) ritorna l'oggetto Station relativo alla linea passata come parametro. getStationNumber(intline) ritorna il numero della stazione rappresentata dall'oggetto Node sulla linea line. addStation(Station st) aggiunge una linea a un nodo. Come parametro viene fornito un oggetto di tipo Station che rappresenta la stazione sulla linea. Questo metodo oggetto di override nella classe MetroNode in quando le linee della metropolitana possiedono delle biforcazioni e si deve quindi gestire in modo corretto il numero d'ordine. hasLine(intline) ritorna un boolean che identifica la presenza o meno di una linea sul nodo sulla quale chiamato.

La classe MetroNode inoltre ha due metodi in pi:

isDeviation(intline) ritorna un boolean indicante se il MetroNode o meno una biforcazione di linea sulla linea passata come parametro. Per esempio, con41

riferimento a Milano, la citt presa in considerazione, Cascina Gobba una biforcazione sulla linea della metro 2 e una chiamata a gobba_node.isDeviation(2) ritornerebbe true.

getBranch(intline) ritorna un intero: il numero del ramo in cui la stazione si trova sulla linea passata come parametro. Se la stazione non si trova su alcun ramo verr ritornato il valore 0. Come esempio la stazione di Cologno Nord si trova sul ramo 1 della linea 2, quindi una ipotetica chiamata a cologno_node.getBranch(2) ritornerebbe 1.

Entrambe le sottoclassi MetroNode e TramNode hanno poi un attributo public, chiamato LINES_NUMBER di tipo int, che specifica il numero di linee totali rispettivamente sul sistema delle metro e sul sistema dei tram considerato.

3.3.3 La scelta del mezzo e del percorsoI mezzi a disposizione dell'utente sono due: Metropolitana e Tram. L'algoritmo tende sempre e comunque di preferire il mezzo che riduce al minimo il percorso a piedi dell'utente. Esso calcolato in base alla distanza che separa il viaggiatore dalla fermata pi vicina l'ultima fermata dalla destinazione. L'algoritmo supporta anche la generazione di percorsi misti, ossia con cambio di mezzo da tram a metro o viceversa. Si introduce qui una semplificazione che prevede che sia possibile effettuare un solo cambio di mezzo, in quanto cambiare pi volte pu essere oneroso per l'utente. Il criterio che l'algoritmo segue per la generazione dei percorsi misti il medesimo seguito per i percorsi semplici, ossia la riduzione al minimo del percorso a piedi dell'utente. Per esempio, se la destinazione si trova vicino a una stazione della metropolitana e l'utente vicino a una fermata del tram allora verr generato un percorso misto che preveder il tram come primo mezzo e terminer con la metro. Questo sempre che la differenza di distanza tra la stazione terminale di tram e metro sia sufficientemente ampia, altrimenti viene scelto un percorso semplice. Come gi indicato, il percorso viene calcolato dal metodo generatePath(double from_x, double from_y, double to_x, double to_y), che ritorna al chiamante un ArrayList contenente tutti i punti di scambio da effettuare sulla rete di trasporto.42

Ad esempio, se il percorso comporta la partenza dalla stazione di San Babila linea 1 e l'arrivo a Centrale FS linea 3 sulla rete metropolitana l'ArrayList ritornato conterr gli oggetti Station rappresentanti le stazioni di partenza e arrivo (San Babila L1 e Centrale FS L3) rispettivamente come primo e ultimo elemento della lista, e poi tutte le stazioni di scambio tra una linea e l'altra che, nel caso descritto sarebbe semplicemente Duomo.

10: Esempio di percorso

Nell'ArrayList vengono anche specificati i passaggi attraverso determinate diramazioni (come ad esempio Cascina Gobba) che, anche se non sono stazioni di partenza, arrivo o di scambio, vengono comunque inserite all'interno del percorso per rendere chiari eventuali scambi da effettuare. La metodo generatePath() non il principale attore del calcolo del percorso. Esso si occupa principalmente di trovare le stazioni pi vicine e di decidere quale mezzo adottare per raggiungere la destinazione in base al criterio del percorso a piedi pi breve. Il calcolo vero e proprio viene delegato a due metodi privati: getNearestMetro(Locationl) egetNearestTram(Locationl). Essi prendono in input la posizione di partenza o destinazione dell'utente e ritornano un oggetto di tipo Node che rappresenta la fermata del tram o della metropolitana pi vicina. In mancanza di informazioni riguardanti il tragitto che possibile effettuare a piedi per determinare la distanza viene utilizzato il metodo di Location distanceTo(Location l) ereditato dalle classi Metro e TramStation e descritto in precedenza (3.2.3). Il lavoro di generazione del percorso vero e proprio lasciato quindi a due metodi privati :43

metroPathCalculation(MetroNode metro_end) e

metro_start,

MetroNode

tramPathCalculation(TramNode tram_start, TramNode tram_end) i quali ritornano un oggetto del tipo Path. Esso semplicemente un contenitore per il percorso generato da PathCreator e viene usato solo internamente alla classe stessa. La classe Path contiene al suo interno tre attributi di tipo public:

ArrayListpath: una lista contenente le stazioni del percorso. E' ci che, a fine computazione, viene ritornato al chiamante di generatePath(); intcost: il costo del percorso in numero di stazioni; int original_line: questo valore indica, nel caso di percorso ancora incompleto, la linea da cui viene raggiunta la prima stazione del percorso. Se il percorso completo allora questo valore 0.

I metodi metroPathCalculation() e tramPathCalculation() generano il percorso in maniera ricorsiva richiamandosi continuamente fino al raggiungimento della destinazione. A ogni chiamata il metodo controlla se la stazione di destinazione sta sulla stessa linea di quella di partenza. Questo il caso base e il percorso generato comprende, banalmente, la stazione di partenza ed arrivo. Quando ci non avviene vengono raccolte tutte le stazioni di snodo (stazioni in cui sono presenti pi di una linea di metro, come Centrale FS o Duomo) e, per ognuna di esse viene richiamato il metodo di calcolo del percorso, impostando come punto di arrivo sempre la destinazione e come punto di partenza la stazione di snodo che si sta considerando. A questo punto il metodo si ripete fino a che non viene trovata una stazione di snodo che ha la stessa linea della stazione di arrivo. Visto che il metodo viene chiamato pi volte (una volta per ogni stazione di snodo nel caso in cui il percorso non sia banale) i percorsi generati saranno pi d'uno. In base al costo (il criterio adottato il pi semplice, ovvero il numero di stazioni percorse) viene selezionato il percorso pi breve e ritornato. Per quanto riguarda i percorsi misti vengono di fatto calcolati due percorsi differenti chiamando quindi una volta la metroPathCalculation() e una volta tramPathCalculation(). Le due funzioni vengono chiamate per creare due percorsi, uno di metro e uno di tram, per44

raggiungere prima, dalla stazione di partenza, un punto di raccordo e poi, dal punto di raccordo, la destinazione . Il punto di raccordo tra le due tipologie di mezzi differenti viene calcolato attraverso la ricerca di due nodi vicini dai quali possibile passare facilmente da un mezzo all'altro. Ovviamente viene considerato che la distanza in pi che il passaggio da un mezzo all'altro pu comportare pu rendere sconveniente l'utilizzo di un percorso misto, per questa ragione viene considerato un percorso misto solo se ci sono due nodi di passaggio tra tram e metro sufficientemente vicini. Nel calcolo del punto di raccordo viene usato il metodo privato findNearest(Collection, Collection) che prende in input due liste di nodi, rispettivamente di tram e metro e ritorna la coppia di nodi pi vicini nelle due liste. Le liste passate alla funzione sono rispettivamente la lista composta da tutte le stazioni della metro e delle stazioni del tram presenti sulle linee della stazione dalla quale il tram parte o arriva (a seconda che il percorso misto preveda la partenza o l'arrivo col tram).

3.3.4 L'individuazione dei malfunzionamentiLe reti pubbliche possono essere soggette a malfunzionamenti di varia natura. L'applicazione si assume il compito di individuare eventuali problemi sulle linee. Essi sono recuperati dalla base di dati remota come e sono organizzati nel modo descritto nel capitolo 3.2.2. Nel caso in cui il percorso migliore non si disponibile il software si fa carico di elaborare un percorso alternativo. L'individuazione di guasti o scioperi delegata al metodo privatehasProblem(Path path). La funzione viene chiamato ogni volta che generato un percorso dai metodi di generazione precedentemente presentati. Il percorso elaborato ricevuto in ingresso quindi suddiviso in tratti in relazione al mezzo e alla linea utilizzati. Su ognuno di essi invocato il metodo del livello sottostante di comunicazione con il database getProblem(). Esso riceve in ingresso la prima e l'ultima fermata del tratto che si intende percorrere su una determinata linea e l'ora attuale. La query effettuata al database tiene conto di questi elementi per valutare la presenza o meno di inconvenienti. In particolare si verifica che non ci siano problemi su tutte le stazioni del percorso nell'orario indicato. Nel caso si riscontrino malfunzionamenti o scioperi viene ritornato un oggetto del tipo Problem. Esso conterr il

45

tratto bloccato e una descrizione del problema. Se, al contrario, tutto funzionante getProblem() ritorna null. L'informazione sul problema cos ottenuta viene poi usata per scegliere il percorso alternativo fra quelli disponibili. Al verificarsi di un inconveniente molto grave, e su pi linee, che impedisce il raggiungimento della destinazione In questo viene caso l'utente generata viene una informato ProblemOnEveryPathException.

dell'impossibilit di utilizzare i mezzi attraverso una finestra di pop-up.

46

3.4 Interfaccia grafica ed Esempio di utilizzo3.4.1 L'inserimento dei datiLa prima parte schermata dell'interfaccia grafica, implementata dall'Activity LocationsInsertion, necessaria all'inserimento dei dati utili per il calcolo del percorso: ovvero la localit di partenza e di destinazione. L'interfaccia riportata nella figura seguente.

11: La schermata di Input

Per l'inserimento della partenza sono a disposizione dell'utente due modalit di input: la specifica delle via dalla quale intende partire oppure l'utilizzo del dispositivo GSP. Con la prima possibilit l'utente deve inserire il nome della via e della citt dalla quale intende partire. L'SDK di Android mette a disposizione nel package android.location la classe GeoCoder[27] che possiede metodi utili per la gestione degli indirizzi. In questo conteso con il verbo GeoCoding si intende il processo di ottenere le coordinare geografiche latitudine e longitudine a partire da un identificativo di una localit. Mentre Reverse Goecoding il procedimento opposto il quale parte dalle coordinate per ottenere un indirizzo. In questa Activity sono utilizzati entrambi. Ecco come: l'indirizzo fornito in input

47

dall'utente convertito attraverso il metodo getFromLocationName(String,int). Esso, dati in input il nome della strada e il numero massimo di risultati che si intende ottenere, fornisce un ArrayList di Address. Questa classe identifica un indirizzo e contiene, oltre alle coordinate geografiche, il nome della via, citt, provincia e nazione. Il metodo descritto pu lavorare anche se riceve in ingresso una parte di un indirizzo; ovviamente non potr ritornare un'unica localit ma fornir l'insieme che pi si avvicina alla descrizione fornita. In questi casi, quando vi un'incertezza sull'effettiva localit, mostrata all'utente una lista delle possibili scelte. Star quindi a lui il compito di selezionare la desiderata. Se l'indirizzo dal quale si intende partire non presente nemmeno nell'elenco sar necessario aumentare la precisione della descrizione fornita. Un esempio dell'elenco fornito all'utente riportato nella figura seguente:

12: La scelta fra diverse opzioni

Per rendere pi semplice e veloce l'input da parte dell'utente vengono mantenute in memoria e presentate in fase di inserimento le localit richieste in precedenza. Questo stato fatto utilizzando il database SQLite messo a disposizione dall'SDK di Android9. Se invece ci si trova gi nel luogo dal quale si vuole partire possibile utilizzare il GPS9 Esso descritto nel capitolo: 2.2.4.Altri elementi utilizzati nel progetto

48

(2.2.4). Il rilevatore calcoler la posizione geografica fornendo le coordinate latitudine e longitudine. Con il processo di Reverse GeoCoding messo a disposizione dal metodo getFromLocation(double,double,int) possibile ottenere un'istanza della classe Address che rappresenta il luogo nel quale ci si trova. Per notificare all'utente il successo dell'operazione mostrato in output una finestra di pop-up con l'indirizzo ottenuto.

13: L'utilizzo del dispositivo GPS

Una volta terminata con successo la fase di inserimento dell'indirizzo della partenza ora necessario specificare la destinazione. Questo possibile nella parte inferiore della schermata; dove necessario inserire l'indirizzo. Nel caso di incertezza il comportamento identico a quello del primo inserimento. Solo una volta completata la fase di input possibile proseguire con l'utilizzo dell'applicazione.

49

3.4.2 La presentazione del percorsoLa pressione sul bottone Ok provoca la l'avvio del processo di elaborazione del percorso attraverso l'invocazione del metodo generatePath. Esso richiede una quantit di tempo significativa in quanto necessario il recupero di tutte le informazioni dal database attraverso una connessione HTTP. Una volta ultimato il calcolo viene presentato all'utente un elenco con tutte le informazioni riguardanti gli scambi che deve effettuare per giungere a destinazione. Le figure seguenti illustrano un esempio di inserimento di dati e il risultato ottenuto.

15: Partenza e Destinazione di Esempio

14: Esempio di Elenco Scambi

Come si nota, nella lista sono riportati i differenti tratti del tragitto consigliato. Per poter visualizzare gli scambi da effettuare necessario condividere l'oggetto ritornato dall'algoritmo fra le differenti Activity che compongono l'interfaccia. Questo per non di semplice soluzione. La condivisione di oggetti fra activity permessa principalmente in due modi:

con l'aggiunta di parametri alla creazione dell'oggetto di tipo Intent utilizzato per l'invocazione dell'Activity. Ci permesso dal metodo putExtra(), che prende in

50

ingresso la variabile da inviare e una String identificativa del parametro passato.

attraverso la creazione di oggetti del tipo SharedPreferences. Essi sono infatti recuperabili da differenti Activity all'interno della stessa applicazione. L'aggiunta di parametri avviene attraverso l'utilizzo della classe Editor che possiede metodi quali putString() o putInt().

I due metodi sono per insufficienti in questo caso. Infatti essi non permettono la condivisione di oggetti di tipo complesso come ArrayList. stato quindi necessario elaborare un altra modalit. Essa prevede l'utilizzo della base di dati locale SQLite. Sono qui utilizzate due tabelle distinte. Una, chiamata locations_table, mantiene informazioni riguardo le stazioni di partenza, scambio e destinazione. Essa sar utilizzata nella MapActivity Map per la visualizzazione delle icone sulle mappe. La seconda, di nome stops_table, invece permette di costruire l'insieme dei tratti di percorso visualizzati nell'elenco. Ognuno di essi rappresentato da una classe apposita chiamata RowEntry. Nella tabella, e anche nella classe che la rappresenta, sono quindi mantenute informazioni quali: la prima e l'ultima fermata per ogni linea, il tipo di mezzo e, nel caso dei tram, anche gli orari dei prossimi passaggi. L'elenco in figura stato realizzato, nella classe StopList, attraverso un'implementazione specifica di un particolare tipo di Activity: ListActivity [28]. La classe BaseAdapter stata utilizzata per personalizzare la lista presentata. A ogni elemento visualizzato associato quindi un oggetto del tipo RowEntry ottenuto dalla lettura del database. In una ListActivity anche possibile attribuire un'azione a un click dell'utente su un elemento della lista. Il metodo onListItemClick di ListActivity stato pensato a questo scopo. Come parametro esso riceve il numero d'ordine della riga selezionata permettendo cos al programmatore di definire il comportamento desiderato. In questo caso selezionando un elemento possibile visualizzare una mappa di Milano che mette in evidenza i luoghi pi importanti ai fini del viaggio. Essi, come detto, sono ottenuti da un'interrogazione alla tabella locations_table del database SQLite. Un segnalino verde evidenzia la partenza, uno giallo l'arrivo e i simboli dei diversi mezzi le fermate di scambio. Questi elementi sono stati realizzati attraverso Overlay, ovvero oggetti che vengono disegnati sopra una mappa. In particolare stata ridefinita la classe

51

ItemizedOverlay. Essa rappresenta un insieme di overlay accomunati dalla stessa icona. Al suo interno definito un oggetto del tipo ArrayList che mantiene l'elenco completo degli oggetti. a ogni OverlayItem associata una breve descrizione ed un oggetto GeoPoint che salva la posizione dell'overlay sulla superficie terrestre permettendone la visualizzazione in un punto preciso di una mappa. Una volta costruiti gli oggetti del tipo PlacesOverlays e StopsOverlays essi possono essere aggiunti alla mappa e presentati attraverso il metodo getOverlays().add della classe MapView. Per poter visualizzare in modo pi chiaro le vie da percorrere possibile effettuare zoom sulla mappa.

16: La mappa e le stazioni

52

3.4.3 Conclusioni e possibili sviluppiLo sviluppo del progetto qui presentato stato fortemente influenzato dall'evoluzione della piattaforma stessa sulla quale esso stato elaborato. L'SDK di Android infatti durante il periodo di elaborazione dell'applicazione ha subito molte modifiche. In particolare stata rimossa la libreria chiamata googlenav. Essa conteneva classi particolarmente utili per un progetto come quello realizzato in quanto queste fornivano il supporto per elaborare e visualizzare su mappe percorsi pedonali o automobilistici per il raggiungimento di una destinazione prefissa. Caduta l'opzione googlenav, si tentato di recuperare informazioni di routing spostando l'attenzione su un progetto dell'universit di Bonn: OpenRouteService [29]. Esso si appoggia sui dati di OpenStreetMap (3.2.1) per elaborare percorsi dati la partenza e la destinazione. Il progetto molto interessante soprattutto se si tiene in considerazione che tutti i dati sono open-source e possono essere ottenuti gratuitamente. OpenRouteService per a oggi ancora in fase di sviluppo. Esso presenta infatti un'interfaccia grafica per poter effettuare richieste e visualizzare i risultati via web. Dal web anche possibile ottenere un file in formato xml che contiene tutte le informazioni riguardo al viaggio pianificato curva per curva. Al momento possibile ottenere questo file solo attraverso l'interfaccia e non con una connessione HTTP in modo programmatico. In una nota sul sito gli sviluppatori affermano di voler introdurre questa funzionalit nelle versioni future10. La possibilit di ottenere informazioni di routing avrebbe permesso di offrire un miglior supporto all'utente permettendogli di orientarsi in modo ancora pi semplice e accompagnandolo a ogni svolta. OpenRouteService sarebbe stato anche utile nel rimuovere una semplificazione introdotta nel calcolo del percorso. Avremmo potuto tenere in considerazione l'effettiva lunghezza dei tratti da percorrere a piedi e non la distanza in linea d'aria. Come ampiamente spiegato nel capitolo 3.2 difficolt si sono incontrare nel reperimento dei dati necessari alla costruzione di un modello completo per la rete dei mezzi pubblici. La soluzione adottata, la costruzione di un database apposito, pu sembrare semplicistica ma se opportunamente mantenuto e aggiornato, questo rappresenta di sicuro la soluzione pi efficiente per il recupero di tutte le informazioni desiderate.10 http://data.giub.uni-bonn.de/openrouteservice/contact.php#Intro

53

Un'estensione molto interessante quella di fornire indicazioni sul tempo richiesto dal tragitto. Sarebbe stato possibile quindi aggiungere un metro di giudizio nell'elaborazione del percorso. Non si sarebbe tenuto conto solo del numero di fermate ma anche del tempo impiegato; considerando anche l'attesa per un mezzo quale il tram. Questa funzionalit richiede per una base di dati molto pi fornita e completa rispetto a quella da noi costruita. Informazioni di questo tipo sono disponibili solo accedendo alle basi di dati dei gestori dei mezzi pubblici di una citt. Vengono di seguito presentate considerazioni sulla qualit dell'algoritmo elaborato. Il metodo costruito particolarmente efficace nel trovare percorsi fra due fermate dei tram o della metropolitana; in questi casi esso ritorna il percorso pi veloce in termini di fermate effettuate. Problemi nascono quando l'utente indica come partenza un luogo vicino a pi fermate di mezzi differenti. Mantenendo il criterio prescelto, ovvero quello di minimizzare il percorso effettuato a piedi, l'algoritmo opta per la fermata pi vicina. Questa non sempre la scelta migliore in quanto costringe l'utente a tragitti spesso pi complicati pur di risparmiare pochi metri a piedi. Riteniamo per che elaborare innumerevoli percorsi considerando le possibili fermate dei mezz