-
Alma Mater Studiorum Universita` di Bologna
SCUOLA DI SCIENZE
Corso di Laurea Triennale in Informatica per il management
Un servizio di supporto alla mobilita`just-in-time per trasporti
pubblici
Tesi di Laurea in Laboratorio Applicazioni Mobili
Relatore:Chiar.mo Prof.Luciano Bononi
Presentata da:Andrea Ravalli
Sessione IIIAnno Accademico 2011/2012
-
2
-
Contents
1 Introduzione 5
2 Stato attuale 7
2.1 La navigazione . . . . . . . . . . . . . . . . . . . . . . .
. . . . . 7
2.2 Servizi Vocali . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . 8
2.3 Applicazioni esistenti per la mobilit . . . . . . . . . . .
. . . . . 10
2.3.1 MuoviMi . . . . . . . . . . . . . . . . . . . . . . . . .
. . 10
2.3.2 Autobus Roma . . . . . . . . . . . . . . . . . . . . . . .
. 11
3 Possibilit per il futuro 13
3.1 Utilizzo collaborativo delle tecnologie . . . . . . . . . .
. . . . . . 13
3.1.1 Assistenza ai pendolari . . . . . . . . . . . . . . . . .
. . . 13
3.1.2 Assistenza ai viaggiatori occasionali . . . . . . . . . .
. . 13
3.1.3 Globalizzazione del servizio . . . . . . . . . . . . . . .
. . 14
4 Progetto 15
4.1 Analisi e obiettivi . . . . . . . . . . . . . . . . . . . .
. . . . . . . 15
4.2 Scelte implementative . . . . . . . . . . . . . . . . . . .
. . . . . 16
4.2.1 Android e java . . . . . . . . . . . . . . . . . . . . . .
. . 16
4.2.2 Librerie Utilizzate . . . . . . . . . . . . . . . . . . .
. . . 17
4.2.3 Calcolo del percorso . . . . . . . . . . . . . . . . . . .
. . 17
4.2.4 Utilizzo WebService . . . . . . . . . . . . . . . . . . .
. . 18
4.2.5 Modalit viaggio . . . . . . . . . . . . . . . . . . . . .
. . 18
4.2.6 Avvisi sonori e visivi . . . . . . . . . . . . . . . . . .
. . . 19
4.3 Panoramica applicazione . . . . . . . . . . . . . . . . . .
. . . . . 21
4.3.1 Diagramma dei casi d'uso . . . . . . . . . . . . . . . . .
. 21
4.3.2 Descrizione dell'applicazione . . . . . . . . . . . . . .
. . . 22
4.3.3 Servizi dell'applicazione . . . . . . . . . . . . . . . .
. . . 34
4.3.4 Sperimentazione e test applicazione . . . . . . . . . . .
. 35
4.4 Idee future per l'applicazione . . . . . . . . . . . . . . .
. . . . . 40
4.4.1 Integrazione del lavoro di Iacopo . . . . . . . . . . . .
. . 40
4.4.2 Turismo . . . . . . . . . . . . . . . . . . . . . . . . .
. . . 40
4.4.3 Comunicazione diretta con Tper . . . . . . . . . . . . . .
40
5 Conclusioni 43
3
-
4
-
1 Introduzione
In un mondo in continua evoluzione possedere uno smartphone di
fondamen-
tale importanza. Solo in europa ce ne sono oltre 200 milioni e
2/3 dei dispositivi
mobili fanno parte di questa categoria. Attualmente lo
smartphone ha sostitu-
ito molti strumenti usati nella vita quotidiana: l'agenda,
sostituita e migliorata
dalle versioni digitali con avvisi e ricorrenze automatizzate;
la sveglia che per-
mette di scegliere la nostra suoneria preferita da poter
disattivare e ripetere
a nostro piacimento; la fotocamera sostitutiva della
tradizionale macchina a
rullino e, in alcuni dispositivi, abbiamo risoluzione e qualit
dell'immagine pari
alle fotocamere digitali in commercio e molto altro. In
riferimento all'argomento
trattato ci interessa sapere che lo smartphone, ora come ora, si
pone a noi come
un agente in grado di ricevere ordini ed eseguire azioni, anche
tramite un co-
mando vocale e, soprattutto, ha sostituito in tutto e per tutto
il navigatore GPS,
migliorandolo, permettendoci di scegliere tra i diversi software
con un solo dis-
positivo ma senza rinunciare alla portabilit che lo
contraddistingue. Utilizzare
un navigatore GPS su uno smartphone signica sia collegarlo
all'automobile e
utilizzarlo come un navigatore standard; sia utilizzarlo per i
propri percorsi a
piedi all'interno delle citt e, almeno questo quello che si pone
di fare la ap-
plicazione successivamente trattata, per l'utilizzo dei mezzi
pubblici nella citt
di Bologna.
Nel capitolo 2 si descriver lo stato attuale della situazione
per quanto riguarda
la navigazione su smartphone, l'utilizzo dei servizi vocali e
due applicazioni per
l'utilizzo dei mezzi pubblici nelle citt di Roma e di
Milano.
Nel capitolo 3 si ipotizzeranno diversi scenari per quanto
riguarda il futuro
prossimo nell'utilizzare e nel convogliare le tecnologie per una
migliore espe-
rienza dell'utilizzatore.
Nel capitolo 4 si descriver l'applicazione realizzata
descrivendo l'utilizzo mostrando
le varie sezioni e eettuando un test dell'applicazione, delle
scelte implementa-
tive e delle idee per il futuro.
Nel capitolo 5 verranno trattate le conclusioni riguardo al
lavoro eettuato per
l'applicazione e lo studio della situazione attuale e
futura.
5
-
6
-
2 Stato attuale
2.1 La navigazione
Attualmente ogni sistema operativo per smartphone ha un proprio
software
di navigazione. Questi sono completi e forniscono quasi gli
stessi servizi dei
navigatori standard come Tom Tom e Garmin, per citarne due
famosi. Ora li
analizzeremo in maniera pi approfondita ricordando che, oltre ai
navigatori
preinstallati sul sistema operativo, sugli store sono
disponibili diversi navigatori
gratuiti e non di diverse marche, tra cui la stessa Tom Tom, che
forniscono
servizi simili a quelli gi presenti sul sistema.
Navigatore Google su piattaforma AndroidIl navigatore di Google
permette la ricerca della localit da raggiungere
tramite inserimento, scritto e vocale, della via, nome
dell'attivit commer-
ciale, tipo dell'attivit commerciale proprio come si farebbe su
Google e
Google Maps. Durante il tragitto step by step si possono
visualizzare
diversi livelli sulla mappa: traco aggiornato in tempo reale,
parcheggi,
ristoranti, distributori di benzina e altri ancora. Inoltre
permette di vedere
l'itinerario attraverso l'utilizzo di Google Street e permette
la navigazione
a piedi e, anche se, nell'attuale versione in beta io l'ho
trovata su-
cientemente adabile nonostante si basi soltanto sulle strade
percorribili
dalle automobili e permette all'utente a piedi di percorrerle in
qualsiasi
senso di marcia ignorando l'esistenza o meno di marciapiedi. Per
quanto
riguarda l'utilizzo oine,nell'ultima versione disponibile il
percorso gi
calcolato e la correzione degli errori nel tragitto. Il calcolo
del percorso
necessario farlo con il dispositivo connesso alla rete.
Apple Maps su piattaforma OS6Il navigatore di Apple presente in
OS6 basato sulle mappe di Tom Tom
e ha sostanzialmente le stesse funzioni con gli stessi pregi e
difetti del
software Navigatore di Android. Inoltre esiste la riproduzione
di molte
citt famose in 3D anche se talvolta non molto ecace per la
giovinezza
di queste mappe che vanno ancora perfezionate. I dispositivi
Apple non
aggiornati all'ultima versione hanno il sistema di navigazione
fornito da
Google.
7
-
Here/Nokia drive su piattaforma Windows Mobile e SymbianAccorpo
queste due applicazioni perch, dopo la denitiva morte di Sym-
bian per il cessato supporto dalla ne del 2012, Nokia e tutti i
produttori
che utilizzeranno Windows Mobile si sono adati a Here che
basato, per
alcuni versi su Nokia Drive. Questo navigatore si dierenzia
molto dai
due precedenti in quanto pi simile ad un navigatore tradizionale
che ad
un navigatore da smartphone, in quanto permette di scaricare le
mappe e
navigare completamente oine. Questo aspetto molto utile quando
non
si ha un abbonamento che include traco dati e si viaggia
all'estero, dove
il traco dati in roaming pu avere un prezzo elevato, anche se,
occupa
molto spazio nella memoria del telefono in quanto le mappe
possono pesare
diverse centinaia di megabyte a seconda della dimensione del
Paese. Here
City Lens nell'ultima versione ha una sorta di mappa con realt
aumen-
tata simile a Google Street ma con maggiori informazioni sullo
schermo
che aiutano ad analizzare i luoghi circostanti.
Tutti e 3 gli applicativi analizzati dispongono di un proprio
servizio che gli
permette di calcolare spostamenti attraverso i mezzi pubblici.
Tale servizio
per funziona male o non funziona del tutto in Italia, anche se
va migliorando
con la distribuzione degli open data dei vari fornitori dei
servizi di pubblico
trasporto italiani.
2.2 Servizi Vocali
Da dieci anni, prima i cellulari poi gli smartphone, hanno
sintetizzatori vocali
in grado di riprodurre testo e scrivere testo grazie alla voce;
tuttavia in questo
ambito negli ultimi anni, con l'avvento di dispositivi sempre pi
potenti e con
maggior utilizzo della rete, si arrivati a veri e propri
assistenti vocali che sono
in grado di svolgere molteplici operazioni complesse grazie al
solo comando della
voce.
Google NowGoogle Now il nuovo servizio di Google disponibile
dalla versione 4.1.2
JellyBean. Il suo motto Google Now gets you just the right
information
at just the right time ovvero Google Now ti d le giuste
informazioni
8
-
nel momento giusto ed proprio di questo che si occupa. Si
possono
richiedere diverse informazioni utilizzando la voce: chiedere di
inviare di
un sms ad una persona, attivare o disattivare servizi come la
wi, avviare
la navigazione, chiedere qual' il primo aereo per New York e
comprare il
biglietto, cercare risultati di una partita di calcio no ad
arrivare a cosa pi
complesse come registrare una canzone, ottenere il titolo e
successivamente
acquistarla sul Play Store utilizzando solo la voce. Tutti
questi servizi
sono disponibili in Inglese e nelle lingue pi diuse come lo
Spagnolo e il
Francese ma, per ora, in Italiano le capacit di svolgere azioni
ridotta.
SiriSiri il concorrente di Google Now, molto simile come
struttura e come
utilizzo anche se sembra avere pi comandi disponibili nella
lingua italiana
rispetto all'avversario,ma meno nel complesso. I comandi di Siri
sono
molto improntati sul sociale come, ad esempio, il condividere
uno stato
su Facebook, organizzare appuntamenti, inviare mail o twittare;
indole
naturale considerata la grande interazione di OS con i software
sociali
dedicati.
Questi sono i due servizi nativi implementati in OS e Android,
ma abbiamo ap-
plicazioni proprietarie che svolgono i medesimi servizi come
S-Voice di Samsung.
Questi strumenti sono molto potenti e nel futuro riusciranno a
eseguire un nu-
mero maggiore di comandi e permetteranno,ad esempio, alle
persone alla guida,
o con qualche disabilit l'utilizzo di uno smartphone. Ma di
questo argomento
parleremo pi approfonditamente nel capitolo 3.
9
-
2.3 Applicazioni esistenti per la mobilit
2.3.1 MuoviMi
MuoviMI un applicazione per OS riguardante il trasporto pubblico
di Milano
che fornisce informazioni immediate su orari, linee e tempi di
attesa di oltre 3000
fermate in tutta la citt, di quasi 150 linee urbane e
interurbane di supercie
e di tutta la rete della Metropolitana. Questa applicazione
focalizzata sulle
fermate e non permette il calcolo del percorso ma si limita a
visualizzare gli
orari dei mezzi pubblici.
10
-
2.3.2 Autobus Roma
Autobus Roma un applicazione per Android che permette di
visualizzare, in
tempo reale, gli autobus in arrivo ad una fermata, i percorsi in
formato testuale
e su mappa, le rivendite di biglietti, gli ultimi tweet di
@InfoAtac e @romamo-
bilita, di calcolare il percorso tra due indirizzi e di
visualizzare le disponibilit
in tempo reale per il Bike Sharing. L'applicazione molto simile
a quella real-
izzata e descritta in questa tesi e ore alcuni spunti
interessanti per modiche
future all'applicazione per Tper Bologna.
11
-
12
-
3 Possibilit per il futuro
3.1 Utilizzo collaborativo delle tecnologie
Uno smartphone un dispositivo che ore innite possibilit di
utilizzo.
Convogliando e migliorando le tecnologie attuali si aprono una
serie di scenari
che no a pochi anni fa erano impossibili da pensare. Combinando
i servizi
vocali e la navigazione si potrebbe guidare persino una persona
cieca, sempre se
si sar in grado di avere le informazioni riguardanti i
marciapiedi, i semafori e gli
attraversamenti pedonali. Si potrebbe aiutare un turista a
visitare e spostarsi in
luoghi a lui sconosciuti con il solo ausilio della voce e dei
navigatori incorporati
negli smartphone.
3.1.1 Assistenza ai pendolari
Un pendolare che si trova a percorrere tutti i giorni lo stesso
tragitto con
l'ausilio dei mezzi pubblici ha a che fare con orari,
coincidenze e magari lunghi
viaggi. Come pu essere utile uno smartphone in questi casi? Se
bene integrato
con il sistema dei mezzi pubblici pu assistere l'utente nel
viaggio rendendolo
meno gravoso e abbassando il rischio di perdere coincidenze o
fermate. Dopo
una prima congurazione dell'utente,nella quale verr digitato
l'itinerario, an-
che semplicemente la partenza e l'arrivo con corrispettivi orari
da rispettare, il
sistema avviser l'utente prima che l'autobus o il treno passi
dalla fermata pi
vicina per dare il tempo di recarvici e non perdere la
coincidenza. A bordo il
sistema si occuper di valutare la distanza del mezzo pubblico
alla fermata di
discesa desiderata e lo avviser in prossimit, per evitare che
l'utente impegnato
in qualche altra attivit che lo distrae dal viaggio perda la
discesa dal mezzo.
Con questi due semplici accorgimenti il viaggio di tutti i
giorni verso il lavoro o
la scuola diventerebbe meno stressante e permetterebbe
all'utente di sfruttare
pienamente il tempo prima del viaggio senza inutili attese alla
stazione e senza
l'ansia di dover controllare di continuo la propria
posizione.
3.1.2 Assistenza ai viaggiatori occasionali
Quando si visita una citt in cui non si mai stati la prima
dicolt
muoversi con i mezzi pubblici; i nomi delle fermate, spesso, non
sono d'aiuto al
viaggiatore occasionale che si trover spaesato e non sapr come
spostarsi senza
l'aiuto di un abitante del luogo. Uno smartphone fortemente
integrato con il
sistema dei mezzi pubblici potrebbe aiutare il turista ad
acquistare il ticket
13
-
per il viaggio in citt mostrandogli la posizione delle
biglietterie guidandolo
ad esse e, successivamente, gli potrebbe calcolare il percorso
indicando come
punto di partenza il luogo attuale e come punto di arrivo quello
desiderato
dall'utente. Come punti di arrivo si potrebbero inserire, oltre
agli indirizzi e
alle fermate che sono di poco aiuto al turista, i luoghi di
importanza turistica
e di pubblica utilit, come le stazioni di polizia o gli
ospedali, utili in caso di
bisogno. Inoltre il dispositivo potrebbe fare da Cicerone al
turista spiegando la
storia e l'importanza dei monumenti e dei luoghi che visiter sia
al suo arrivo,
sia durante il tragitto, ma questo argomento si tratter pi
approfonditamente
all'interno del prossimo capitolo.
3.1.3 Globalizzazione del servizio
La sda maggiore per i servizi di assistenza al viaggio con i
mezzi pubblici,
oltre a renderlo facilmente accessibile con la voce per le
persone impossibilitate o
poco pratiche nell'utilizzo dello smartphone, rendere globale il
servizio oerto.
Al momento sono presenti alcune applicazioni dedicate alle
singole citt per la
navigazione e sia Google Now che Siri forniscono informazioni a
livello globale,
ma la quantit di informazioni piuttosto bassa e frammentata.
Attualmente
impossibile essere sicamente a Bologna, inserire il numero del
volo da prendere
a Roma Fiumicino, essere guidati alla stazione dei treni di
Bologna tramite
mezzi pubblici, sapere quale treno prendere e a che ora, sapere
a quale stazione
scendere di Roma, avere le indicazioni riguardo al mezzo
pubblico che ci porter
in aereoporto e, una volta arrivati, avere l'indicazione del
gates in cui prendere il
nostro aereo. Riuscire a organizzare tramite smartphone un
viaggio come quella
sopra descritto ,a mio avviso, una delle sde che in futuro ci si
dovrebbe porre
per migliorare la qualit del viaggio e ridurre lo stress
nell'organizzarlo.
14
-
4 Progetto
4.1 Analisi e obiettivi
Tper, trasporto passeggeri Emilia Romagna, si occupa della
gestione del
servizio di autobus pubblici nella provincia di Bologna, nella
provincia di Fer-
rara e gestisce diverse tratte ferroviarie che estendono
ulteriormente il bacino
di utenza arrivando anche a Parma e Reggio Emilia. Sul sito
dell'azienda
disponibile la consultazione delle linee e agli orari, un
calcola-percorso utiliz-
zando i mezzi pubblici, una mappa che localizza tutte le
biglietterie e altri
servizi. Il servizio pubblico di Bologna non ben inserito
all'interno di Google
Now e del navigatore di Google in quanto sono presenti gli
autobus che pas-
sano dalle fermate con relativo orario per non possibile
calcolare un percorso
utilizzando i mezzi pubblici. L'obiettivo che ci si posti
realizzare questo e
inserire alcuni miglioramenti che aiutino il pendolare o il
viaggiatore occasionale
a muoversi con facilit utilizzando i servizi oerti da Tper. I
dati relativi alle
fermate e alle rivendite sono stati prelevati dagli Open Data
oerti da Tper e
il calcola percorso stato realizzato utilizzando quello gi
disponibile sul sito
nonostante sia stato necessario modicare leggermente le
richieste per adattarle
all'utilizzo all'interno dell'applicazione.
15
-
4.2 Scelte implementative
4.2.1 Android e java
Il linguaggio di programmazione utilizzato nei dispositivi
Android Java.
Esistono diverse versioni di Android, la pi diusa attualmente la
2.3.3 Gin-
gerbread che ancora lo standard in molti dispositivi in vendita,
la seconda
versione pi diusa 4.04 Ice Cream Sandwich a cui buona parte dei
dispos-
itivi gi in commercio sono stati aggiornati da Gingerbread. Dal
23/9/2008,
data dell'uscita della prima versione di Android, Apple Pie, no
ad oggi abbi-
amo avuto ben 31 rilasci di versioni anche se quelle che hanno
portato eettivi
cambiamenti all'utente standard sono principalmente queste:
1.6 utilizzo dei comandi vocali e delle gesture;
2.0 aggiunto il multitouch;
2.2 notevole miglioramento delle prestazioni e della stabilit
grazie ad unadiversa gestione delle risorse hardware,
implementazione di javascript e
ash;
2.3 introdotto NFC,il supporto a schermi con risoluzione pari e
maggiorea WXGA e il supporto nativo a giroscopio e barometro;
3.0 versione dedicata unicamente al nuovo mercato dei
tablet;
4.0 interfaccia completamente riprogettata,prestazioni
migliorate, launcherpersonalizzabile, dettatura in tempo reale,
fotocamera migliorata con modal-
it panorama, Android Beam (scambio di dati tramite NFC) e Wi-Fi
Di-
rect;
4.1 riconoscimento dettatura oine,miglioramenti notevoli nella
uiditgrazie a "Project Butter", nuove funzionalit per la
condivisione di foto
e video tramite NFC, nuovo servizio "Google Now", sintesi vocale
miglio-
rata, riconoscimento vocale avanzato (GSV);
L'applicazione compatibile per tutte le versione di Android a
partire da An-
droid 2.3.3 per mantenere un elevato grado di compatibilit e
aumentare al
massimo il numero di dispositivi in cui possibile utilizzarla
senza limitare
troppo l'utilizzo delle API di sistema. Il progetto stato
realizzato utilizzando
16
-
Eclipse con l'ADT di Android che permette, in pochi semplici
passi, di scaricare
e installare le SDK delle varie versione di Android anche se,
essendo retrocom-
patibili, baster utilizzare la versione minima in cui si vuol
utilzzare la propria
applicazione. L'ADT da anche la possibilit di creare dispositivi
virtuali di
diverso tipo con hardware e versioni dierenti per vericare
l'aspetto e il fun-
zionamento della propria applicazione sul frammentato mercato
Android dotato
di dispositivi molto diversi l'uno dall'altro.
4.2.2 Librerie Utilizzate
Le librerie utilizzate sono state jsoup e ksoap2. La prima
libreria viene
utilizzata nel modulo fornitimi da Iacopo Pazzaglia, conforme
alle speciche
WHATWG Html5, ci ha consentito di inviare la richiesta al sito
di tper relativa
al calcolo del percorso e, dopo aver ricevuto la risposta,
estrarre i dati attraverso
l'utilizzo dei selettori CSS e utilizzarli all'interno
dell'applicazione costruendo
oggetti relativi alle tappe del viaggio. La seconda libreria
viene utilizzata nel
modulo per la richiesta al web service di helloBus, un leggero e
eciente client
SOAP di facile implementazione per Android che ha consentito di
inviare la
richiesta e analizzare la risposta al webService di Tper per
avere gli orari in
tempo reale degli autobus in circolazione.
4.2.3 Calcolo del percorso
Il calcolo del percorso si eettua attraverso l'utilizzo del sito
http://tper.it/percorsi-
orari/il-tuo-percorso-da di Tper. Utilizzando il modulo
fornitomi da Iacopo
Pazzaglia sono in grado di ottenere la risposta dal sito Tper
alla richiesta del
calcolo percorso, che si pu eettuare inserendo come arrivo e
partenza degli
indirizzi, delle fermate o, con la funzione implementata
nell'applicazione, uti-
lizzare la geolocalizzazione partendo o arrivando dal e al luogo
attuale. Tut-
tavia sono intercorsi diversi problemi nel calcolo del percorso.
Il primo che
il calcola-percorso di Tper fornisce il percorso quando il
metodo di inserimento
della richiesta tramite gli indirizzi di partenza o di arrivo
solo all'interno del
comune di Bologna. Per risolvere questo problema si deciso di
utilizzare la
fermata pi vicina alla via ricercata dall'utente. La ricerca
della fermata pi vic-
ina viene eettuata tramite un database remoto, hostato su
altervista, costruito
grazie agli open data forniti da Tper. Un altro problema
relativo alle fermate
con nomi simili in quanto il calcola-percorso gestisce le
fermate con nomi cor-
17
-
relati chiedendo all'utente di scegliere tra le fermate con nomi
simili. Questo
un problema per il modulo di parsing della risposta in quanto
non possi-
bile proseguire con la scelta della fermata indicata, ma si pu
solo riproporre
la query dalla pagina iniziale e non da quella che fornisce le
diverse alternative.
Per ovviare a questo problema si utilizza la fermata pi vicina
con un nome di-
verso da quello che genera l'eccezione, che richiede il dover
scegliere tra diverse
fermate.
4.2.4 Utilizzo WebService
Il servizio helloBus disponibile al pubblico tramite l'invio di
sms al nu-
mero 348 4314314 contenente il numero della fermata, la linea
dell'autobus e
opzionalmente l'orario che, se non inviato in maniera esplicita
tramite sms,
l'orario corrente. Dopo aver inviato l'sms se ne ricever uno di
risposta con-
tente l'orario eettivo dei prossimi due autobus che passeranno
dalla fermata in
base alla linea specicata dall'utente. Come orario eettivo si
intende l'orario
di questi ultimi calcolato con la posizione corrente degli
autobus seguiti dal
satellite. Tper ha reso pubblico da pochi giorni un webservice a
cui inviando i
medesimi dati del servizio sms, ovvero il numero della
fermata,opzionalmente il
numero dell'autobus e l'orario, riceviamo la medesima risposta.
Se non viene
inviato la linea dell'autobus la risposta conterr l'orario dei
due che arriveranno
successivamente all'orario.
4.2.5 Modalit viaggio
La modalit viaggio un modulo multithreading che si occupa della
gestione
e dell'assistenza del viaggio dell'utente. Un primo thread
controlla, in un in-
tervallo di tempo di 5 secondi, la posizione dell'utente e ne
calcola la prossima
tappa. Se la tappa successiva una fermata in cui prendere un
autobus o il
punto di arrivo, il thread si occuper di avviare il navigatore
di Google nella
modalit a piedi e imposter come destinazione la locazione della
tappa. Se la
tappa successiva un percorso a bordo di un mezzo pubblico, il
thread richieder
informazioni al modulo che utilizza il web service HelloBus per
denire l'orario
di partenza dell'autobus e mostrer all'utente queste
informazioni. Una volta
saliti a bordo del mezzo verr avviato il secondo thread che si
occupa di no-
ticare tramite un primo avviso sonoro la vicinanza alla fermata
e tramite un
secondo avviso pi insistente l'arrivo alla fermata
desiderata.Terminato il per-
corso a bordo del mezzo il secondo thread terminer. Una volta
giunti a desti-
nazione nel luogo desiderato il primo thread terminer
concludendo la modalit
18
-
di viaggio.
4.2.6 Avvisi sonori e visivi
L'allarme consiste nell'avvio della suoneria e nell'accensione
dello schermo
per la visualizzazione di un messaggio. All'avvio di
quest'ultimo l'applicazione
si impossessa del wakelock, ovvero acquista massima priorit e
visualizza il
messaggio sullo schermo anche se risultasse bloccato o se fosse
in atto qualsiasi
altra operazione. L'allarme attirer l'attenzione dell'utente che
non perder
l'autobus o la fermata. Questi allarmi possono essere
disattivati dal men o
impostando in modalit silenziosa il telefono.
19
-
20
-
4.3 Panoramica applicazione
4.3.1 Diagramma dei casi d'uso
21
-
4.3.2 Descrizione dell'applicazione
Schermata iniziale
All'interno della schermata iniziale possibile scegliere
tra:
Organizzare un viaggio;
Visualizzare i viaggi salvati;
Richiedere l'orario di un autobus;
Visualizzare le rivendite biglietti;
22
-
All'interno del men possibile settare alcune opzioni riguardanti
il viaggio
23
-
Organizzare un viaggio
La prima cosa da scegliere quando si organizza un viaggio
inserire il tipo
di partenza e di destinazione scegliendo tra la posizione
attuale, il nome di una
fermata o inserendo un indirizzo all'interno del bacino coperto
da Tper.
24
-
Partenza/Arrivo da posizione attuale
L'applicazione sfrutter la geolocalizzazione del dispositivo per
calcolare la
via in cui posizionato l'utilizzatore, che se non fosse
soddisfatto della precisione
oerta pu inserirla manualmente con l'indirizzo. Se il GPS fosse
disattivato la
geolocalizzazione si ottiene tramite l'utilizzo dell'A-GPS e ore
una precisione
di 500 metri con il solo GSM(rete edge e gprs) attivo ma arriva
anche a 40-50
metri di precisione se attivo WCDMA (rete 3G e UMTS).
25
-
Partenza/Arrivo tramite inserimento indirizzo
L'utente pu inserire l'indirizzo nel formato nome
via,Comune,Provincia e
verr aiutato tramite una classe creata appositamente
nell'inserimento di esso
per evitare errori nella digitazione e per ricevere suggerimenti
nel completa-
mento.
26
-
Partenza/Arrivo tramite inserimento fermata
L'utente pu inserire il nome della fermata nel formato nome
fermata,Co-
mune e verr aiutato nella digitazione tramite
l'autocompletamento che con-
sulter un contenitore di stringhe prelevate dagli open data di
Tper.
27
-
Preferenze viaggio
Analogalmente al sito di Tper si possono inserire le preferenze
relative al
viaggio. Le preferenze esprimibili sono:
Orario di partenza/Orario di Arrivo;
Giorno di partenza;
Tempo massimo a piedi espresso in minuti;
Numero massimo di cambi;
28
-
Riepilogo viaggio
Nella schermata di riepilogo del viaggio verranno mostrati
riepilogate con le
informazioni essenziali, ovvero orario di partenza, numero di
cambi e durata del
viaggio, i possibili itinerari per giungere a destinazione.
29
-
Con un singolo tocco sull'itineraio avremo l'espansione della
tendina che
mostrer i vari tratti del viaggio, con un tocco prolungato
avremo l'apertura di
una dialog che ci permetter di scegliere tra tre opzioni:
Guidami che avvier la modalit di guida che spiegher
successivamente;
Memorizza che permette di salvare il viaggio;
Avvisami che ssa una sveglia che avvisa qualche minuto prima
dell'arrivodell'autobus, approfondir questo argomento
successivamente;
30
-
Viaggi Salvati
Nella schermata dei viaggi salvati si visualizza il nome dei
viaggi e un tasto
di azione che permette di scegliere di visualizzare il viaggio e
di ottenere diverse
possibilt:
Guidami che avvier la modalit di guida che spiegher
successivamente;
Orario che restituisce gli orari dei prossimi 2 autobus che
passeranno dallafermata di partenza e che percorrono la tratta del
viaggio;
Cancella viaggio che permette di eliminare il viaggio dal
database;
31
-
Rivendite
Visualizza una mappa in cui sono indicate le rivendite nel
raggio di 10km
dalla posizione dell'utente. Toccando l'icona della rivendit
possibile avere in-
formazioni relative al nome della rivendita, giorno di chiusura,
indirizzo, comune
e possibilit o meno di acquistare ticket parcheggio. Viene data
la possibilit
all'utente di avviare la navigazione a piedi no alla rivendita
utilizzando il nav-
igatore di Google.
32
-
Orario autobus
Questo men permette di avere l'orario di passaggio dei prossimi
autobus in
una specica fermata. Inserendo il numero della fermata,che si
trova sulle pensi-
line Tper, il numero della linea desiderata, questo dato
opzionale in quanto se
l'utente non inserisce nessun autobus il sistema restituir
l'orario dei primi due
che passeranno dalla fermata, e l'orario si avr l'informazione
relativa all'orario
eettivo dei prossimi due autobus. Inoltre possibile essere
avvisati prima del
passaggio dell'autobus grazie ad un allarme sonoro impostabile
ad un tempo
scelto a piacimento come nella modalit di viaggio.
33
-
4.3.3 Servizi dell'applicazione
Avvisi e notiche
A seconda dell'urgenza della notica l'applicazione avverte
l'utente in maniera
diversa. Se abbiamo un avviso meno urgente come l'avvicinarsi
alla fermata
avremo una notica standard e un suono di notica, se invece
avremo un avviso
urgente, come l'arrivo alla fermata, avremo un allarme.
Modalit viaggio
La modalit viaggio guider l'utente in tutto il suo tragitto
informandolo
degli autobus da prendere e come spostarsi nei tragitti a piedi.
All'inizio del
viaggio l'applicazione guider l'utente, tramite Google
navigatore modalit a
piedi, alla fermata di partenza, una volta arrivati informer
l'utente riguardo
all'autobus da utilizzare e all'orario.Saliti a bordo del mezzo
l'utente verr in-
formato all'avvicinarsi della fermata di discesa con un primo
allarme e all'arrivo
della fermata di destinazione con un secondo allarme che gli
ricorder di scen-
dere. Per quanto riguarda l'implementazione troviamo tutti i
dettagli nelle scelte
implementative.
34
-
4.3.4 Sperimentazione e test applicazione
In questo test ho calcolato un percorso che parte da via Fornace
13,Cre-
spellano, BO e arriva nella fermata Irnerio,Bologna. L'orario di
partenza
dell'autobus alle ore 11.06, come si pu vedere nelle seguenti
schermate, e ho
impostato l'allarme perch suoni 30 minuti prima del passsaggio
dell'autobus.
35
-
Alle 10:36 abbiamo avuto l'allarme sonoro desiderato.
36
-
Modalit viaggio In questo test ho calcolato un percorso che
parte da via
Fornace 13,Crespellano, BO e arriva nella fermata
Irnerio,Bologna. All'inizio
verremo guidati alla fermata in cui prendere l'autobus.
37
-
Una volta arrivati alla fermata di partenza ci verr comunicato
l'orario del
prossimo autobus
38
-
Una volta saliti a bordo si avvier il thread percorso che ci
avviser all'avvic-
inarsi della fermata e all'arrivo nella stessa.
39
-
4.4 Idee future per l'applicazione
4.4.1 Integrazione del lavoro di Iacopo
Iacopo Pazzaglia ha costruito moduli riguardanti l'assistenza a
bordo dei
mezzi pubblici per persone con disabilit. Si potrebbero
implementare questi
moduli rendendo il servizio pi completo e ampliando le categorie
di utiliz-
zatori. Il modulo amplierebbe le informazioni disponibili, oltre
a quelle gi
fornite dall'applicazione in se ovvero la vicinanza e l'arrivo
dell'autobus alla fer-
mata, per dare all'utilizzatore dati riguardanti gli orari dei
prossimi autobus,la
prossima fermata in cui il mezzo transiter e il numero di
fermate rimanenti alla
discesa.
4.4.2 Turismo
Bologna ricca di storia, ricca di eventi musicali e
gastronomici, con l'uni-
versit pi antica d'Europa e con uno dei distretti eristici pi
importanti di
Italia meta di turisti da ogni parte del mondo. Turisti che
sempre pi usano
gli smartphone per orientarsi e avere il meglio dei luoghi che
visitano, basti
vedere il successo di applicazioni come TripAdvisor nell'ultimo
periodo. Turisti
che per mancano ancora di vere e proprie guide digitali e
interattive sui propri
smartphone. L'idea di implementare una sorta di guida turistica
in un applica-
tivo che ti guidi, utilizzando i mezzi pubblici, nei luoghi pi
belli e importanti
di Bologna. Proporre intinerari gi preimpostati come ad esempio
Le chiese di
Bologna che porterebbe nelle chiese pi belle, oppure Il medioevo
bolognese
che guiderebbe il turista alle meraviglie dell'era medievale
sparse per Bologna.
Le idee sono molteplici e con la collaborazione dell'ente per il
turismo bolognese
si potrebbe arrivare ad elaborare vari percorsi in cui la guida
elettronica, che
non solo porterebbero il turista nei luoghi turistici in maniera
facile con i mezzi
pubblici e l'utilizzo del navigatore, ma spiegherebbe con la
voce in varie lingue
il luogo che si sta visitando.
4.4.3 Comunicazione diretta con Tper
Sul sito Tper.it sono disponibili gli avvisi in formato RSS,si
potrebbe imple-
mentare un piccolo client di facile consultazione all'interno
dell'applicazione per
permettere all'utente di essere sempre aggiornato. Ritengo
valida la scelta fatta
da molti enti pubblici,anche aziende dei traporti di altre citt
italiane, di aprire
un canale uciale Twitter per fornire le stesse informazioni dei
client RSS e
avere, in pi, un contatto diretto con il cliente che si
sentirebbe pi ascoltato
40
-
dall'azienda e potrebbe avere informazioni in maniera pi rapida
chiedendo di-
rettamente all'operatore che si occupa dei tweet. Inoltre si
potrebbero creare
scorciatoie per chiamare il servizio Clienti Tper, registrarsi
al servizio sms di
avvisi e alla mailing list.
41
-
42
-
5 Conclusioni
L'informatizzazione del sistema pubblico di trasporti, allineato
con lo sviluppo
di applicazioni che rendono disponibile interfacciarsi con esso,
in futuro saranno
sicuramente di grande aiuto ai viaggiatori. La diusione degli
smartphone a
basso prezzo e degli abbonamenti con traco dati incluso
permetteranno sempre
di pi di evitare l'uso di strumenti tradizionali per viaggiare
come le cartine
turistiche o l'utilizzo degli orari nelle pensiline dei servizi
pubblici. L'appli-
cazione analizzata in questa tesi solo una piccola goccia nel
mare per quanto
riguarda il trasporto pubblico a Bologna, c' ancora molto lavoro
da fare sia
nell'implementazione di servizi per garantire un applicazione pi
completa, sia
una maggior informatizzazione di Tper che stata avviata
nell'ultimo periodo
e porter sempre pi informazioni utili all'utente nale. I
responsabili di Tper
si sono dimostrati molto disponibili e interessati al servizio
oerto dall'appli-
cazione trattata e presumo che ci siano le intenzioni di
proseguire con il lavoro
per orire all'utente un'applicazione ancora pi eciente e di
maggior utilit a
tutte le tipologie di utenti che la utilizzeranno.
43
-
44
-
Estratti di codice
In questo capitolo verranno inseriti gli estratti pi signicati
del codice di
cui composta l'applicazione.
Oggetti presenti nell'applicazione
Oggetto fermata package object;
public class fermata {
int codice_linea;
int codice_fermata;
String denominazione;
String ubicazione;
String comune;
double latitudine;
double longitudine;
String zona;
/**
* @param codice_linea
* @param codice_fermata
* @param denominazione
* @param ubicazione
* @param comune
* @param latitudine
* @param longitudine
* @param zona
*/
public fermata(int codice_linea, int codice_fermata, String
denominazione,String
ubicazione, String comune, double latitudine,double longitudine,
String zona) {
this.codice_linea = codice_linea;
this.codice_fermata = codice_fermata;
this.denominazione = denominazione;
this.ubicazione = ubicazione;
this.comune = comune;
this.latitudine = latitudine;
this.longitudine = longitudine;
this.zona = zona;
}
public int getCodice_linea() {
return codice_linea;
}
public void setCodice_linea(int codice_linea) {
this.codice_linea = codice_linea;
}
public int getCodice_fermata() {
return codice_fermata;
45
-
}public void setCodice_fermata(int codice_fermata) {
this.codice_fermata = codice_fermata;
}
public String getDenominazione() {
return denominazione;
}
public void setDenominazione(String denominazione) {
this.denominazione = denominazione;
}
public String getUbicazione() {
return ubicazione;
}
public void setUbicazione(String ubicazione) {
this.ubicazione = ubicazione;
}
public String getComune() {
return comune;
}
public void setComune(String comune) {
this.comune = comune;
}
public double getLatitudine() {
return latitudine;
}
public void setLatitudine(double latitudine) {
this.latitudine = latitudine;
}
public double getLongitudine() {
return longitudine;
}
public void setLongitudine(double longitudine) {
this.longitudine = longitudine;
}
public String getZona() {
return zona;
}
public void setZona(String zona) {
this.zona = zona;
}
}
Oggetto rivendite package object;
public class rivenditeO {
int codice;
46
-
String ragione_sociale;
String giorno_chiusura;
String indirizzo_ubicazione;
String cap_indirizzo_ubicazione;
String comune_indirizzo_ubicazione;
String provincia_indirizzo_ubicazione;
double lat;
double longi;
String codice_zona_stimer;
String rivenditore_titoli_sosta;
public rivenditeO(int codice, String ragione_sociale,
String giorno_chiusura, String indirizzo_ubicazione,
String cap_indirizzo_ubicazione,
String comune_indirizzo_ubicazione,
String provincia_indirizzo_ubicazione, double lat, double
longi,
String codice_zona_stimer, String rivenditore_titoli_sosta)
{
super();
this.codice = codice;
this.ragione_sociale = ragione_sociale;
this.giorno_chiusura = giorno_chiusura;
this.indirizzo_ubicazione = indirizzo_ubicazione;
this.cap_indirizzo_ubicazione = cap_indirizzo_ubicazione;
this.comune_indirizzo_ubicazione =
comune_indirizzo_ubicazione;
this.provincia_indirizzo_ubicazione =
provincia_indirizzo_ubicazione;
this.lat = lat;
this.longi = longi;
this.codice_zona_stimer = codice_zona_stimer;
this.rivenditore_titoli_sosta = rivenditore_titoli_sosta;
}
public int getCodice() {
return codice;
}
public void setCodice(int codice) {
this.codice = codice;
}
public String getRagione_sociale() {
return ragione_sociale;
}
public void setRagione_sociale(String ragione_sociale) {
this.ragione_sociale = ragione_sociale;
}
public String getGiorno_chiusura() {
return giorno_chiusura;
}
public void setGiorno_chiusura(String giorno_chiusura) {
this.giorno_chiusura = giorno_chiusura;
47
-
}public String getIndirizzo_ubicazione() {
return indirizzo_ubicazione;
}
public void setIndirizzo_ubicazione(String indirizzo_ubicazione)
{
this.indirizzo_ubicazione = indirizzo_ubicazione;
}
public String getCap_indirizzo_ubicazione() {
return cap_indirizzo_ubicazione;
}
public void setCap_indirizzo_ubicazione(String
cap_indirizzo_ubicazione)
{
this.cap_indirizzo_ubicazione = cap_indirizzo_ubicazione;
}
public String getComune_indirizzo_ubicazione() {
return comune_indirizzo_ubicazione;
}
public void setComune_indirizzo_ubicazione(String
comune_indirizzo_ubi-
cazione) {
this.comune_indirizzo_ubicazione =
comune_indirizzo_ubicazione;
}
public String getProvincia_indirizzo_ubicazione() {
return provincia_indirizzo_ubicazione;
}
public void setProvincia_indirizzo_ubicazione(
String provincia_indirizzo_ubicazione) {
this.provincia_indirizzo_ubicazione =
provincia_indirizzo_ubicazione;
}
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public double getLongi() {
return longi;
}
public void setLongi(double longi) {
this.longi = longi;
}
public String getCodice_zona_stimer() {
return codice_zona_stimer;
}
public void setCodice_zona_stimer(String codice_zona_stimer)
{
this.codice_zona_stimer = codice_zona_stimer;
}
48
-
public String getRivenditore_titoli_sosta() {
return rivenditore_titoli_sosta;
}
public void setRivenditore_titoli_sosta(String
rivenditore_titoli_sosta) {
this.rivenditore_titoli_sosta = rivenditore_titoli_sosta;
}
}
Oggetto tappa package object;
public class tappa {
private String type;
private double lat;
private double longit;
public tappa(String type, double lat, double longit) {
super();
this.type = type;
this.lat = lat;
this.longit = longit;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public double getLongit() {
return longit;
}
public void setLongit(double longit) {
this.longit = longit;
}
}
Oggetto tappaFermata sottoclasse di tappa package object;
public class tappaFermata extends tappa{
private int codice_fermata;
private String ubicazione;
private String comune;
private String autobus;
49
-
private boolean salita;
public tappaFermata(String type2, double latitude, double
longitude,int codice_fer-
mata, String ubicazione, String comune, String autobus,boolean
salita) {
super(type2, latitude, longitude);
this.codice_fermata = codice_fermata;
this.ubicazione = ubicazione;
this.comune = comune;
this.autobus = autobus;
this.salita = salita;
}
public int getCodice_linea() {
return codice_fermata;
}
public void setCodice_linea(int codice_linea) {
this.codice_fermata = codice_linea;
}
public String getUbicazione() {
return ubicazione;
}
public void setUbicazione(String ubicazione) {
this.ubicazione = ubicazione;
}
public String getComune() {
return comune;
}
public void setComune(String comune) {
this.comune = comune;
}
public String getAutobus() {
return autobus;
}
public void setAutobus(String autobus) {
this.autobus = autobus;
}
public boolean getSalita() {
return salita;
}
public void setSalita(boolean salita) {
this.salita = salita;
}
}
Oggetto viaggio
package object;
import geo.funzioniGeo;
import java.io.IOException;
import java.util.ArrayList;
50
-
import java.util.Collections;
import Android.content.Context;
public class viaggioO {
public int timeMinuti;
public int cambi;
public ArrayList tappe = new ArrayList();
public String oraArrivo;
public String oraPartenza;
public viaggioO(int timeMinuti, int cambi, ArrayList
tappe,String
oraArrivo, String oraPartenza) {
super();
this.timeMinuti = timeMinuti;
this.cambi = cambi;
this.tappe = tappe;
this.oraArrivo = oraArrivo;
this.oraPartenza = oraPartenza;
}
public viaggioO() {
// TODO Auto-generated constructor stub
}
public int getTimeMinuti() {
return timeMinuti;
}
public void setTimeMinuti(int timeMinuti) {
this.timeMinuti = timeMinuti;
}
public int getCambi() {
return cambi;
}
public void setCambi(int cambi) {
this.cambi = cambi;
}
public ArrayList getTappe() {
return tappe;
}
public void setTappe(ArrayList tappe) {
this.tappe = tappe;
}
public void addTappe(tappa tappa){
tappe.add(tappa);
}
public String getOraArrivo() {
return oraArrivo;
}
public void setOraArrivo(String oraArrivo) {
this.oraArrivo = oraArrivo;
51
-
}public String getOraPartenza() {
return oraPartenza;
}
public void setOraPartenza(String oraPartenza) {
this.oraPartenza = oraPartenza;
}
public viaggioO normalizzaViaggio2Address(viaggioO
viaggio,String Partenza,String
Arrivo,Context C){
System.out.println("tappe iniziali" + viaggio.getTappe());
if(viaggio.getTappe().get(0).toString().contains("Fermata"))
{
//swappo tutti di una posizione
for(int i=viaggio.getTappe().size()-1;i>-1;i){
if(i==viaggio.getTappe().size()-1){
viaggio.getTappe().add(viaggio.getTappe().get(i));
}
else{
Collections.swap(viaggio.getTappe(), i, i+1);
}
}
//aggiungo in fondo lo step iniziale
double cords[];
try {
cords = funzioniGeo.getCordsFromAddress(C, Partenza);
//calcolo le cordinate dello step iniziale
tappa tp = new tappa("via", cords[0], cords[1]);
viaggio.getTappe().add(tp);
//lo swappo come primo
Collections.swap(viaggio.getTappe(),
viaggio.getTappe().size()-1, 0);
viaggio.getTappe().remove(viaggio.getTappe().size()-1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(viaggio.getTappe().get(viaggio.getTappe().size()-1).toString().contains("Fer-
mata")){
double cords[];
try {
cords = funzioniGeo.getCordsFromAddress(C, Arrivo);
//calcolo le cordinate dello step iniziale
tappa tp = new tappa("via", cords[0], cords[1]);
viaggio.getTappe().add(tp);
} catch (IOException e) {
// TODO Auto-generated catch block
52
-
e.printStackTrace();
}
}
System.out.println("tappe nali" + viaggio.getTappe());
return viaggio;
}
}
53
-
Utility
Funzioni geograche che utilizzano il geocoder package geo;
import get.funzioni;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import Android.content.Context;
import Android.location.Address;
import Android.location.Geocoder;
public class funzioniGeo {
public static double[] getCordsFromAddress(Context C,String
Address) throws
IOException{
Geocoder geocoder = new Geocoder(C, Locale.getDefault());
List addresses;
addresses = geocoder.getFromLocationName(Address, 1);
Address address = addresses.get(0);
double longitude = address.getLongitude();
double latitude = address.getLatitude();
double[] cords = new double[2];
cords[0]=latitude;
cords[1]=longitude;
return cords;
}
public static boolean iAmArrived (double lat,double longi,double
latCon-
trollo,double longControllo,double Apprx,double dist){
System.out.println("Apprx: "+Apprx);
System.out.println("Lat: "+lat);
System.out.println("Long: "+longi);
System.out.println("LatArrivo: "+latControllo);
System.out.println("LongArrivo: "+longControllo);
double distanza = funzioni.calcolaDist(lat, longi, latControllo,
longControllo);
if (distanza
-
String address = addresses.get(0).getAddressLine(0);
address = address.replace(",","");
String city = addresses.get(0).getAddressLine(1);
String parts[] = city.split(" ");
city = parts[1];
String country = addresses.get(0).getAddressLine(2);
return address + "," + city + ","+country;
}
}
Autocompletamento indirizzi package adapter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import Android.content.Context;
import Android.util.Log;
import Android.widget.ArrayAdapter;
import Android.widget.Filter;
import Android.widget.Filterable;
public class PlacesAutoCompleteAdapter extends ArrayAdapter
implements Filterable {
private static nal String LOG_TAG = "SEACRHPLACES";
private static nal String PLACES_API_BASE =
"https://maps.googleapis.com/maps/api/place";
private static nal String TYPE_AUTOCOMPLETE =
"/autocomplete";
private static nal String OUT_JSON = "/json";
private static nal String API_KEY = "********";
private ArrayList autocomplete(String input) {
ArrayList resultList = null;
HttpURLConnection conn = null;
StringBuilder jsonResults = new StringBuilder();
try {
StringBuilder sb = new StringBuilder(PLACES_API_BASE +
TYPE_AU-
TOCOMPLETE + OUT_JSON);
sb.append("?sensor=false&key=" + API_KEY);
sb.append("&components=country:it");
sb.append("&language=it");
sb.append("&input=" + URLEncoder.encode(input, "utf8"));
URL url = new URL(sb.toString());
55
-
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new
InputStreamReader(conn.getInputStream());
// Load the results into a StringBuilder
int read;
char[] bu = new char[1024];
while ((read = in.read(bu)) != -1) {
jsonResults.append(bu, 0, read);
}
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error processing Places API URL", e);
return resultList;
} catch (IOException e) {
Log.e(LOG_TAG, "Error connecting to Places API", e);
return resultList;
} nally {
if (conn != null) {
conn.disconnect();
}
}
try {
// Create a JSON object hierarchy from the results
JSONObject jsonObj = new JSONObject(jsonResults.toString());
JSONArray predsJsonArray =
jsonObj.getJSONArray("predictions");
// Extract the Place descriptions from the results
resultList = new ArrayList(predsJsonArray.length());
for (int i = 0; i < predsJsonArray.length(); i++) {
resultList.add(predsJsonArray.getJSONObject(i).getString("description"));
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Cannot process JSON results", e);
}
return resultList;
}
private ArrayList resultList;
public PlacesAutoCompleteAdapter(Context context, int
textViewResour-
ceId) {
super(context, textViewResourceId);
}
@Override
public int getCount() {
return resultList.size();
}
@Override
public String getItem(int index) {
return resultList.get(index);
}
56
-
@Override
public Filter getFilter() {
Filter lter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence
constraint) {
FilterResults lterResults = new FilterResults();
if (constraint != null) {
// Retrieve the autocomplete results.
resultList = autocomplete(constraint.toString());
// Assign the data to the FilterResults
lterResults.values = resultList;
lterResults.count = resultList.size();
}
return lterResults;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults re-
sults) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
}
else {
notifyDataSetInvalidated();
}
}};
return lter;
}
}
Allarme package alarm;
import java.io.IOException;
import giga89.tesi.prima.justintimebo.R;
import Android.app.Activity;
import Android.content.Context;
import Android.media.AudioManager;
import Android.media.MediaPlayer;
import Android.media.RingtoneManager;
import Android.net.Uri;
import Android.os.Bundle;
import Android.os.PowerManager;
import Android.os.PowerManager.WakeLock;
import Android.util.Log;
import Android.view.MotionEvent;
import Android.view.View;
import Android.view.View.OnTouchListener;
57
-
import Android.view.Window;
import Android.view.WindowManager;
import Android.widget.Button;
public class AlarmReceiverActivity extends Activity {
private MediaPlayer mMediaPlayer;
private WakeLock wl;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
|
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
setContentView(R.layout.alarm);
Button stopAlarm = (Button) ndViewById(R.id.stopAlarm);
stopAlarm.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
mMediaPlayer.stop();
if(!(wl==null)){
wl.release();
}
nish();
return false;
}
});
playSound(this, getAlarmUri());
}
private void playSound(Context context, Uri alert) {
mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.setDataSource(context, alert);
nal AudioManager audioManager = (AudioManager)
context.getSystem-
Service(Context.AUDIO_SERVICE);
if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM)
!=
0) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mMediaPlayer.prepare();
mMediaPlayer.start();
}
58
-
} catch (IOException e) {
System.out.println("OOPS");
}
}
//Get an alarm sound. Try for an alarm. If none set, try
notication,
//Otherwise, ringtone.
private Uri getAlarmUri() {
Uri alert = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alert == null) {
alert = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if (alert == null) {
alert = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
}
}
return alert;
}
@Override
protected void onResume() {
PowerManager pm = (PowerManager)
getSystemService(Context.POWER_SER-
VICE);
wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "My Tag");
wl.acquire();
super.onResume();
}
@Override
protected void onPause() {
if (wl != null) {
Log.v("wl tag", "Releasing wakelock");
try {
wl.setReferenceCounted(false);
wl.release();
Log.v("wl tag", "Released");
} catch (Throwable th) {
// ignoring this exception, probably wakeLock was already
released
Log.v("wl tag", "Ex in release");
}
} else {
// should never happen during normal workow
Log.e("wl tag", "Wakelock reference is null");
}
super.onPause();
}
}
59
-
HelloBus
Classe che si occupa di inviare la richiesta al web service
package
webService;
import javax.net.ssl.SSLContext;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
public class helloBus {
private static nal String SOAP_ACTION=
"https://solweb.tper.it/tperit/web-
services/hellobus.asmx/QueryHellobus";
private static nal String METHOD_NAME = "QueryHellobus";
private static nal String NAMESPACE=
"https://solweb.tper.it/tperit/web-
services/hellobus.asmx";
private static nal String URL =
"https://solweb.tper.it/tperit/webservices/hel-
lobus.asmx";
private static String resultData;
public static String soap(String fermata, String linea, String
orario){
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//formulo la richiesta
PropertyInfo fermataProp =new PropertyInfo();
fermataProp.setName("fermata");
fermataProp.setValue(fermata);
PropertyInfo lineaProp =new PropertyInfo();
lineaProp.setName("linea");
lineaProp.setValue(linea);
PropertyInfo timeProp =new PropertyInfo();
timeProp.setName("oraHHMM");
timeProp.setValue(orario);
fermataProp.setType(String.class);
lineaProp.setType(String.class);
timeProp.setType(String.class);
request.addProperty(fermataProp);
request.addProperty(lineaProp);
request.addProperty(timeProp);
System.out.println(request.toString());
SoapSerializationEnvelope envelope = new
SoapSerializationEnvelope(SoapEn-
velope.VER11);
envelope.dotNet=true;
envelope.encodingStyle = "utf-8";
envelope.implicitTypes = true;
envelope.setOutputSoapObject(request);
60
-
//invio la richiesta utilizzando hhtps autenticato
HttpTransportSE AndroidHttpTransport = new
HttpTransportSE(URL);
AndroidHttpTransport.debug = true;
AndroidHttpTransport.call(SOAP_ACTION, envelope);
Object result=envelope.getResponse();
if(result != null)
{
System.out.println(result);
}
else
{
System.out.println("Errore");
}
resultData=result.toString();
System.out.println(resultData);
return resultData;
} catch (Exception e) {
System.out.println(e.toString());
}
return resultData;
}
}
61
-
Viaggio
Classe viaggio con relativi Thread package viaggio;
import java.util.ArrayList;
import object.tappa;
import object.tappaFermata;
import webService.helloBus;
import elaborazioneTxtTappe.readWriteTxt;
import geo.funzioniGeo;
import get.funzioni;
import giga89.tesi.prima.justintimebo.MainActivity;
import giga89.tesi.prima.justintimebo.alertActivity;
import accessori.notication;
import accessori.parser;
import Android.app.Activity;
import Android.content.Intent;
import Android.content.SharedPreferences;
import Android.net.Uri;
import Android.os.Bundle;
import Android.preference.PreferenceManager;
public class viaggio extends Activity {
private boolean noticaFermata;
private boolean noticaFermataSonora;
private double distanzaNoticaFermata;
private boolean noticaOraria;
private boolean noticaOrariaSonora;
private double distanzaNoticaOraria;
private String nomeViaggio;
private long update_value_int = 5000;
private boolean controllo;
private boolean controlloTappa;
private double lat;
private double longit;
private boolean controlloAvviso;
public ArrayList viaggio;
public int i;
private SharedPreferences sharedPrefs;
//cordinate di controllo
double latControllo;
double longControllo;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//qui si pescheranno i dati dell'intent (ovvero il nome del
viaggio)
Bundle extras = getIntent().getExtras();
62
-
nomeViaggio = extras.getString("nomeViaggio");
//e si costruira l'array
viaggio = readWriteTxt.startImport(nomeViaggio);
//controllo
controllo = true;
//
sharedPrefs =
PreferenceManager.getDefaultSharedPreferences(getApplica-
tionContext());
noticaFermata = sharedPrefs.getBoolean("Avviso_fermate",
true);
noticaFermataSonora =
sharedPrefs.getBoolean("Avviso_fermate_sonoro",
true);
String SdistanzaNoticaFermata =
sharedPrefs.getString("tempo_avviso_fer-
mata", "500 m");
distanzaNoticaFermata =
parser.getDistanza(SdistanzaNoticaFermata);
noticaOraria = sharedPrefs.getBoolean("Avviso_tempo", true);
noticaOrariaSonora =
sharedPrefs.getBoolean("Avviso_tempo_sonoro", true);
String SdistanzaNoticaOraria =
sharedPrefs.getString("tempo_avviso_tempo",
"500 m");
distanzaNoticaOraria =
parser.getDistanza(SdistanzaNoticaOraria);
//avvio il thread che ci seguira per il viaggio
threadSeguimi.start();
notication.Permanentnotications("Viaggio in corso","Toccare per
inter-
rompere il viaggio",getApplicationContext());
this.nish();
}
//IL THREAD DELLA NOTIFICA FERMATA
Thread threadNoticaFermata = new Thread()
{
@Override
public void run() {
boolean attesaFermata = true;
while(attesaFermata) {
try {
//calcolo la posizione attutale
double latNow = MainActivity.getLat();
double longNow = MainActivity.getLong();
double approx =MainActivity.getApprx();
//calcolo la distanza dalla fermata
double distanza = funzioni.calcolaDist(latNow,longNow,lat,
longit);
if(distanza
-
notication.noticationsFermata("Avviso fermata", "Sei arrivato
alla fer-
mata di arrivo","NOTIFICA VIAGGIO", getApplicationContext(),
noticaFer-
mataSonora,true);
controllo = true;
notication.deletenotications( getApplicationContext());
attesaFermata=false;
}
sleep(update_value_int);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
//IL THREAD CHE TI SEGUE
Thread threadSeguimi = new Thread()
{
private boolean controlloPrimaTappa = true;
@Override
public void run() {
i = 0;
int i2= viaggio.size();
while(i
-
controllo = true;
controlloPrimaTappa=true;
}
else{
controllo = true;
String Lon_des,Lat_des;
Lat_des = String.valueOf(viaggio.get(i).getLat());
Lon_des = String.valueOf(viaggio.get(i).getLongit()); ;
Intent guidamiAllarrivo = (new Intent(Intent.ACTION_VIEW,
Uri.parse("google.nav-
igation:q=" + Lat_des + "," + Lon_des +"&mode=w")));
startActivity(guidamiAllarrivo);
}
}
else if (classeTappa.equals("object.tappaFermata")){
tappaFermata tf = (tappaFermata) viaggio.get(i);
latControllo = viaggio.get(i).getLat();
longControllo = viaggio.get(i).getLongit();
//se e una fermata fai..
if (controlloTappa || i==0){
String Lon_des,Lat_des;
Lat_des = String.valueOf(viaggio.get(i).getLat());
Lon_des = String.valueOf(viaggio.get(i).getLongit()); ;
Intent guidamiAllarrivo = (new Intent(Intent.ACTION_VIEW,
Uri.parse("google.nav-
igation:q=" + Lat_des + "," + Lon_des +"&mode=w")));
startActivity(guidamiAllarrivo);
controllo = true;
}
else{
tappaFermata tf2 = (tappaFermata) viaggio.get(i-1);
latControllo = viaggio.get(i).getLat();
longControllo = viaggio.get(i).getLongit();
//calcolo orario prossimo autobus
String HB = helloBus.soap(String.valueOf(tf2.getCodice_linea()),
tf2.getAu-
tobus(), accessori.time.getNowForHelloBus());
Intent intentProxAutobus = new Intent(getApplicationContext(),
alertAc-
tivity.class);
intentProxAutobus.putExtra("hb", HB);
startActivity(intentProxAutobus);
if(noticaFermata){
if(threadNoticaFermata.isAlive()){
threadNoticaFermata.stop();
}
tf =(tappaFermata) viaggio.get(i);
String autobus = tf.getAutobus();
controlloAvviso = true;
lat = viaggio.get(i).getLat();
65
-
longit = viaggio.get(i).getLongit();
threadNoticaFermata.start();
}
}
controlloTappa = false;
}
i++;
}
sleep(update_value_int);
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
notication.deletenotications(getApplicationContext());
System.out.println("viaggio nito");
}
};
}
66
-
67
-
Bibliograa
jsoup: http://jsoup.org/
ksoap2: https://code.google.com/p/ksoap2-Android/
navigatore google:
http://www.google.it/intl/it_ALL/mobile/navigation/
diusione smartphone:
http://www.techeconomy.it/2012/12/18/ue-cresce-la-penetrazione-
degli-smartphone-litalia-e-penultima/
apple maps: http://www.apple.com/it/ios/maps/
nokia drive here:
http://www.windowsphoneitaly.com/news/software/6393-mwc-
2013-nokia-presenta-here-mappe-here-drive-e-here-city-lens.html
google now: http://www.google.com/landing/now/
siri: http://www.apple.com/it/ios/siri/
open data tper: http://www.tper.it/tper-open-data
wakelock:
http://developer.Android.com/reference/Android/os/PowerManager.Wake-
Lock.html
MuoviMI: http://www.muovimi.it/
68
IntroduzioneStato attualeLa navigazioneServizi
VocaliApplicazioni esistenti per la mobilitMuoviMiAutobus Roma
Possibilit per il futuroUtilizzo collaborativo delle
tecnologieAssistenza ai pendolariAssistenza ai viaggiatori
occasionaliGlobalizzazione del servizio
ProgettoAnalisi e obiettiviScelte implementativeAndroid e java
Librerie UtilizzateCalcolo del percorsoUtilizzo WebServiceModalit
viaggioAvvisi sonori e visivi
Panoramica applicazioneDiagramma dei casi d'usoDescrizione
dell'applicazioneServizi dell'applicazioneSperimentazione e test
applicazione
Idee future per l'applicazioneIntegrazione del lavoro di
IacopoTurismoComunicazione diretta con Tper
Conclusioni