Anda di halaman 1dari 68

` di Bologna Alma Mater Studiorum Universita

SCUOLA DI SCIENZE Corso di Laurea Triennale in Informatica per il management

Un servizio di supporto alla mobilit` a just-in-time per trasporti pubblici

Tesi di Laurea in Laboratorio Applicazioni Mobili

Relatore: Chiar.mo Prof. Luciano Bononi

Presentata da: Andrea Ravalli

Sessione III Anno Accademico 2011/2012

Contents
1 2 Introduzione Stato attuale
2.1 2.2 2.3 La navigazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . Servizi Vocali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Applicazioni esistenti per la mobilit . . . . . . . . . . . . . . . . 2.3.1 2.3.2 MuoviMi . . . . . . . . . . . . . . . . . . . . . . . . . . . Autobus Roma . . . . . . . . . . . . . . . . . . . . . . . .

5 7
7 8 10 10 11

Possibilit per il futuro


3.1 Utilizzo collaborativo delle tecnologie . . . . . . . . . . . . . . . . 3.1.1 3.1.2 3.1.3 Assistenza ai pendolari . . . . . . . . . . . . . . . . . . . . Assistenza ai viaggiatori occasionali Globalizzazione del servizio . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

13
13 13 13 14

Progetto
4.1 4.2 Analisi e obiettivi . . . . . . . . . . . . . . . . . . . . . . . . . . . Scelte implementative 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.3 4.3.1 4.3.2 4.3.3 4.3.4 4.4 4.4.1 4.4.2 4.4.3 Android e java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15
15 16 16 17 17 18 18 19 21 21 22 34 35 40 40 40 40

Librerie Utilizzate Utilizzo WebService Modalit viaggio

Calcolo del percorso

. . . . . . . . . . . . . . . . . . . . . . .

Avvisi sonori e visivi . . . . . . . . . . . . . . . . . . . . . Diagramma dei casi d'uso . . . . . . . . . . . . . . . . . . Descrizione dell'applicazione . . . . . . . . . . . . . . . . . Servizi dell'applicazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sperimentazione e test applicazione Integrazione del lavoro di Iacopo Comunicazione diretta con Tper

Panoramica applicazione . . . . . . . . . . . . . . . . . . . . . . .

Idee future per l'applicazione

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Turismo . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Conclusioni

43

1 Introduzione
In un mondo in continua evoluzione possedere uno smartphone di fondamentale 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 sostituito molti strumenti usati nella vita quotidiana: l'agenda, sostituita e migliorata dalle versioni digitali con avvisi e ricorrenze automatizzate; la sveglia che permette 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 comando vocale e, soprattutto, ha sostituito in tutto e per tutto il navigatore GPS, migliorandolo, permettendoci di scegliere tra i diversi software con un solo dispositivo 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 applicazione 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 esperienza 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 implementative 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.

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 Android Il navigatore di Google permette la ricerca della localit da raggiungere tramite inserimento, scritto e vocale, della via, nome dell'attivit commerciale, 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 sucientemente 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 OS6 Il 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.

Here/Nokia drive su piattaforma Windows Mobile e Symbian Accorpo queste due applicazioni perch, dopo la denitiva morte di Symbian 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 aumentata 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 Now Google 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

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.

Siri Siri 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 applicazioni proprietarie che svolgono i medesimi servizi come S-Voice di Samsung. Questi strumenti sono molto potenti e nel futuro riusciranno a eseguire un numero 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.

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 @romamobilita, 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 realizzata 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, anche 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 Ferrara 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 utilizzando 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 passano 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 Gingerbread che ancora lo standard in molti dispositivi in vendita, la seconda versione pi diusa 4.04 Ice Cream Sandwich a cui buona parte dei dispositivi 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 abbiamo 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 una diversa gestione delle risorse hardware, implementazione di javascript e ash;

2.3 introdotto NFC,il supporto a schermi con risoluzione pari e maggiore a 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, launcher personalizzabile, dettatura in tempo reale, fotocamera migliorata con modalit panorama, Android Beam (scambio di dati tramite NFC) e Wi-Fi Direct;

4.1 riconoscimento dettatura oine,miglioramenti notevoli nella uidit grazie a "Project Butter", nuove funzionalit per la condivisione di foto e video tramite NFC, nuovo servizio "Google Now", sintesi vocale migliorata, riconoscimento vocale avanzato (GSV);

L'applicazione compatibile per tutte le versione di Android a partire da Android 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 retrocompatibili, 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 funzionamento della propria applicazione sul frammentato mercato Android dotato di dispositivi molto diversi l'uno dall'altro.

4.2.2

Librerie Utilizzate
La prima libreria viene

Le librerie utilizzate sono state jsoup e ksoap2.

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/percorsiorari/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, utilizzare la geolocalizzazione partendo o arrivando dal e al luogo attuale. tavia sono intercorsi diversi problemi nel calcolo del percorso. Tut-

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 vicina 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 possibile 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 diverso 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 numero 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 noticare tramite un primo avviso sonoro la vicinanza alla fermata e tramite un secondo avviso pi insistente l'arrivo alla fermata desiderata.Terminato il percorso a bordo del mezzo il secondo thread terminer. Una volta giunti a destinazione 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 Questi allarmi possono essere disattivati dal men o

l'autobus o la fermata.

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 completamento.

26

Partenza/Arrivo tramite inserimento fermata


L'utente pu inserire il nome della fermata nel formato nome fermata,Comune e verr aiutato nella digitazione tramite l'autocompletamento che consulter 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'arrivo dell'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 dalla fermata 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 informazioni 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 navigatore 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 pensiline 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 informato 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 scendere. 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,Crespellano, 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'avvicinarsi 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 utilizzatori. Il modulo amplierebbe le informazioni disponibili, oltre a quelle gi

fornite dall'applicazione in se ovvero la vicinanza e l'arrivo dell'autobus alla fermata, 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'universit 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 applicativo 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 implementare 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 direttamente 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'applicazione 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


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; package object;

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
int codice;

package object;

public class rivenditeO {

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_ubicazione) { 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


public class tappaFermata extends tappa{ private int codice_fermata; private String ubicazione; private String comune; private String autobus;

package object;

49

private boolean salita; public tappaFermata(String type2, double latitude, double longitude,int codice_fermata, 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<tappa> tappe = new ArrayList<tappa>(); public String oraArrivo; public String oraPartenza; public viaggioO(int timeMinuti, int cambi, ArrayList<tappa> 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<tappa> getTappe() { return tappe; } public void setTappe(ArrayList<tappa> 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("Fermata")){ 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


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<Address> 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 latControllo,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<Apprx || distanza<dist){ return true; } else{ return false; } } public static String getAddressFromLatLng(Context C,double latitude,double longitude) throws IOException{ Geocoder geocoder; List<Address> addresses; geocoder = new Geocoder(C, Locale.getDefault()); addresses = geocoder.getFromLocation(latitude, longitude, 1); package geo;

54

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
import java.io.IOException; import java.io.InputStreamReader;

package adapter;

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<String> 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<String> autocomplete(String input) { ArrayList<String> resultList = null; HttpURLConnection conn = null; StringBuilder jsonResults = new StringBuilder(); try { StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + 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<String>(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<String> resultList; public PlacesAutoCompleteAdapter(Context context, int textViewResourceId) { 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 results) { 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.getSystemService(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_SERVICE); 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


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/webservices/hellobus.asmx/QueryHellobus"; private static nal String METHOD_NAME = "QueryHellobus"; private static nal String NAMESPACE = "https://solweb.tper.it/tperit/webservices/hellobus.asmx"; private static nal String URL = "https://solweb.tper.it/tperit/webservices/hellobus.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(SoapEnvelope.VER11); envelope.dotNet=true; envelope.encodingStyle = "utf-8"; envelope.implicitTypes = true; envelope.setOutputSoapObject(request); package

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


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<tappa> 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(); package viaggio;

62

nomeViaggio = extras.getString("nomeViaggio"); //e si costruira l'array viaggio = readWriteTxt.startImport(nomeViaggio); //controllo controllo = true; // sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); noticaFermata = sharedPrefs.getBoolean("Avviso_fermate", true); noticaFermataSonora = sharedPrefs.getBoolean("Avviso_fermate_sonoro", true); String SdistanzaNoticaFermata = sharedPrefs.getString("tempo_avviso_fermata", "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 interrompere 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<distanzaNoticaFermata&&controlloAvviso){ controlloAvviso=false; notication.noticationsFermata("Avviso fermata", "Mancano "+distanzaNoticaFermata+" m alla fermata di arrivo","NOTIFICA VIAGGIO", getApplicationContext(), noticaFermataSonora,false); } if(distanza<approx || distanza <20){

63

notication.noticationsFermata("Avviso fermata", "Sei arrivato alla fermata di arrivo","NOTIFICA VIAGGIO", getApplicationContext(), noticaFermataSonora,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<viaggio.size()) { //PERIODO DI RIPOSO TRA UNA SCANSIONE E L'ALTRA try { //scorri l'arraylist while (i<viaggio.size()&&controllo){ //controllo se sono arrivato boolean sonoArrivato = funzioniGeo.iAmArrived(MainActivity.getLat(), MainActivity.getLong(), latControllo, longControllo, MainActivity.getApprx(), 20); //se la prima destinazione e una fermata.. String classeTapp = viaggio.get(0).getClass().getName(); if (controlloPrimaTappa){sonoArrivato=true;} if(sonoArrivato){ controlloPrimaTappa=false; sonoArrivato=false; String classeTappa = viaggio.get(i).getClass().getName(); if (classeTappa.equals("object.tappa")){ latControllo = viaggio.get(i).getLat(); longControllo = viaggio.get(i).getLongit(); //per ricordare che la tappa precedente euna tappa senza fermata controlloTappa = true; //se e il primo elemento dell'array vuol dire che e il punto di partenza quindi non ci interessa guidarci li if (i==0){

64

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.navigation: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.navigation: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.getAutobus(), accessori.time.getNowForHelloBus()); Intent intentProxAutobus = new Intent(getApplicationContext(), alertActivity.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-penetrazionedegli-smartphone-litalia-e-penultima/ apple maps: http://www.apple.com/it/ios/maps/ nokia drive here: http://www.windowsphoneitaly.com/news/software/6393-mwc2013-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.WakeLock.html MuoviMI: http://www.muovimi.it/

68

Anda mungkin juga menyukai