Tesi about android application

68
Alma Mater Studiorum · Universit ` a di Bologna 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

description

Year 2013

Transcript of Tesi about android application

  • 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