Università degli Studi Mediterranea di Reggio Calabria Dipartimento di Ingegneria dell’Informazione, delle Infrastrutture e dell’Energia Sostenibile Corso di Laurea in Ingegneria dell’Informazione Tesi di Laurea Progettazione e realizzazione della componente di front-end relativa al progetto MediNav, per l’accesso guidato, tramite QRCode, a POI dell’Università Mediterranea Relatore Candidato Prof. Domenico Ursino Dimitri Schiavone Anno Accademico 2015-2016 Indice Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Lo scenario tecnologico di riferimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1 Smartphone e sistemi operativi mobili . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.1 Che cosa è uno smartphone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.2 Storia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.3 Funzionalità . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.4 Caratteristiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.5 Il sistema operativo Android . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.6 Architettura di Android . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Navigazione outdoor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.1 Sistema di posizionamento globale . . . . . . . . . . . . . . . . . . . . . . . . 1.2.2 Il sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.3 Principio di funzionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.4 Sistemi di navigazione e smartphone . . . . . . . . . . . . . . . . . . . . . . 1.3 Navigazione Indoor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.1 QRCode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 7 8 9 9 10 10 12 12 12 13 14 15 17 Descrizione del progetto MediNav . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1 L’idea alla base di MediNav . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 La loro idea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.2 La nostra idea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Evoluzioni tecniche dell’idea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 Localizzazione radio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.2 Google Maps Indoor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 L’idea finale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4 Architettura del sistema MediNav . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.1 Descrizione del front-end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.2 Descrizione del back-end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 19 19 19 22 22 23 25 25 25 29 Analisi dei requisiti della componente di front-end . . . . . . . . . . . . . . . . . . 33 3.1 Obiettivi della componente di front-end . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.1.1 L’interfaccia grafica di Android . . . . . . . . . . . . . . . . . . . . . . . . . . 33 IV Indice 3.2 Requisiti non funzionali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 La piattaforma hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.2 Linguaggio di programmazione adottato . . . . . . . . . . . . . . . . . . . 3.2.3 Approcci alla progettazione dell’interfaccia . . . . . . . . . . . . . . . . 3.3 Requisiti funzionali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 Navigazione guidata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.2 Navigazione libera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.3 Visualizzazione delle schede informative . . . . . . . . . . . . . . . . . . . 34 35 36 38 38 38 39 39 Progettazione della componente di front-end . . . . . . . . . . . . . . . . . . . . . . . . 4.1 Progettazione della componente Java . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 Classe MainActivity.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.2 Classe ChooseFaculty.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.3 Classe ChooseStartingPoint.java . . . . . . . . . . . . . . . . . . . . . . . 4.1.4 Classe ChooseDestination.java . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.5 Classe About.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.6 Classe MarkCard.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.7 Classe MapShow.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Progettazione dei documenti XML a supporto . . . . . . . . . . . . . . . . . . . . 4.2.1 File activity main.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.2 File activity choose faculty.xml . . . . . . . . . . . . . . . . . . . . . . 4.2.3 File activity choose destination.xml . . . . . . . . . . . . . . . . . . 4.2.4 File activity choose starting point.xml . . . . . . . . . . . . . . . 4.2.5 File activity mark card.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.6 File activity about.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.7 File activity map show.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Progettazione della componente applicativa . . . . . . . . . . . . . . . . . . . . . . 4.3.1 Mockup di livello 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.2 Process Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 41 41 43 43 44 44 46 46 47 47 47 48 48 48 48 49 50 50 50 Implementazione della componente di front-end . . . . . . . . . . . . . . . . . . . . 5.1 Implementazione della componente Java . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 Implementazione della classe MainActivity.java . . . . . . . . . . 5.1.2 Implementazione della classe ChooseFaculty.java . . . . . . . . . 5.1.3 Implementazione della classe ChooseDestination.java . . . . . 5.1.4 Implementazione della classe MarkCard.java . . . . . . . . . . . . . . 5.1.5 Implementazione della classe MapShow.java . . . . . . . . . . . . . . . 5.2 Implementazione della componente XML . . . . . . . . . . . . . . . . . . . . . . . . 5.2.1 Implementazione del file activity main.xml . . . . . . . . . . . . . . . . . 5.2.2 Implementazione del file activity choose faculty.xml . . . . . . . . . 5.3 Manuale utente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 59 59 62 64 65 66 67 67 69 71 Discussione critica in merito al sistema realizzato . . . . . . . . . . . . . . . . . . . 6.1 Analisi SWOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.1 Punti di forza . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.2 Punti di debolezza . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.3 Opportunità . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.4 Minacce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 77 77 78 78 79 Indice V 6.2 Soluzioni alternative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 6.2.1 Wescape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 6.3 Lesson learned . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 Conclusioni e uno sguardo al futuro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 Ringraziamenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 Elenco delle figure 1.1 1.2 1.3 1.4 1.5 1.6 IBM Simon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Architettura di Android . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Un satellite GPS in orbita . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Un comune ricevitore GPS nautico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Google Maps ed Apple Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Esempio di QRCode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 11 12 13 14 17 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 2.15 Un primo esempio di disposizione dei QRCode sulla mappa . . . . . . . . . Un secondo esempio di disposizione dei QRCode sulla mappa . . . . . . . Un primo concept dell’app per come era stata inizialmente pensata . . Un secondo concept dell’app per come era stata inizialmente pensata Un terzo concept dell’app per come era stata inizialmente pensata . . . Google Maps Indoor: visuale della mappa via smartphone . . . . . . . . . . Google Maps Indoor: visuale della mappa via web . . . . . . . . . . . . . . . . . Map Layer di MapView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bitmap Layer di MapView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Location Layer di MapView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mark Layer di MapView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Route Layer di MapView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tipi di layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Esempio di ConstraintLayout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Activity principale di MediNav . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 20 21 21 22 23 24 26 27 28 29 30 31 31 32 3.1 3.2 3.3 3.4 3.5 3.6 L’interfaccia utente nell’ambito dell’architettura di un sistema . . . . . . Vari tipi di UI Android a confronto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Esempio di dispositivo Nexus Google con la tipica UI stock . . . . . . . . . Il logo di Xamarin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Il logo di Ionic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Apache Cordova . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 35 35 37 37 37 4.1 4.2 4.3 Diagramma della classe MainActivity.java . . . . . . . . . . . . . . . . . . . . . . 42 Diagramma della classe ChooseFaculty.java . . . . . . . . . . . . . . . . . . . . . 43 Diagramma della classe ChooseStartingPoint.java . . . . . . . . . . . . . . 44 VIII Elenco delle figure 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12 4.13 4.14 4.15 4.16 4.17 4.18 4.19 4.20 4.21 4.22 4.23 4.24 4.25 4.26 Diagramma della classe ChooseDestination.java . . . . . . . . . . . . . . . . . Diagramma della classe About.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Diagramma della classe MarkCard.java . . . . . . . . . . . . . . . . . . . . . . . . . . Diagramma della classe MapShow.java . . . . . . . . . . . . . . . . . . . . . . . . . . . Struttura del file activity main.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . Struttura del file activity choose faculty.xml . . . . . . . . . . . . . . . . . . Struttura del file activity choose destination.xml . . . . . . . . . . . . . . Struttura del file activity choose starting point.xml . . . . . . . . . . . Struttura del file activity mark card.xml . . . . . . . . . . . . . . . . . . . . . . . Struttura del file activity about.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . Struttura del file activity map show.xml . . . . . . . . . . . . . . . . . . . . . . . . Mockup relativo all’activity principale dell’applicazione . . . . . . . . . . . . Mockup relativo alla scelta di un’area . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mockup relativo alla scelta di una destinazione in modalità “Navigate” Mockup relativo alla scelta di una destinazione in modalità “Explore” Mockup relativo alla visualizzazione di una scheda informativa . . . . . . Mockup relativo alla navigazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Process flow relativo a MainActivity.java . . . . . . . . . . . . . . . . . . . . . . . Process flow relativo a ChooseFaculty.java in modalità “Navigate” . Process flow relativo a ChooseFaculty.java in modalità “Explore” . . Process flow relativo a ChooseDestination.java . . . . . . . . . . . . . . . . . . Process flow relativo a ChooseStartingPoint.java . . . . . . . . . . . . . . . Process flow relativo a MapShow.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 45 46 47 48 49 49 50 51 51 52 52 53 54 54 55 55 56 56 57 57 58 58 Ciclo di vita di un’activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Esempio di progettazione visiva di activity main.xml . . . . . . . . . . . . . Esempio di progettazione visiva di activity choose faculty.xml . . Schermata di primo avvio dell’applicazione . . . . . . . . . . . . . . . . . . . . . . . Messaggio che viene mostrato all’utente che nega il permesso di usare la fotocamera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6 Schermata principale dell’applicazione . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.7 Schermata relativa alla scelta di un’area in modalità “Explore” . . . . . . 5.8 Schermata relativa alla scelta di una destinazione in modalità “Explore” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.9 Schermata relativa alla navigazione in modalità “Explore” . . . . . . . . . . 5.10 Schermata relativa ad una scheda informativa . . . . . . . . . . . . . . . . . . . . . 5.11 Schermata relativa alla navigazione in modalità “Navigate” . . . . . . . . . 60 69 72 73 5.1 5.2 5.3 5.4 5.5 6.1 6.2 6.3 73 74 74 75 75 76 76 Analisi SWOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 Il logo di Wescape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Navigazione tramite Wescape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Elenco dei listati 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 5.11 5.12 5.13 5.14 5.15 5.16 5.17 5.18 5.19 Definizione del metodo onCreate della classe MainActivity.java . . . Definizione del metodo onCreateOptionsMenu della classe MainActivity.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Definizione del metodo onOptionsItemSelected della classe MainActivity.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Definizione del metodo onNavigate della classe MainActivity.java . Definizione del metodo onExplore della classe MainActivity.java . . Definizione del metodo checkPermissions della classe MainActivity.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Definizione del metodo onRequestPermissionsResult della classe MainActivity.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Definizione del metodo onCreate della classe ChooseFaculty.java . . Definizione del metodo onActivityResult della classe ChooseFaculty.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Definizione del metodo onCreate della classe ChooseDestination.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Definizione del metodo onActivityResult della classe ChooseDestination.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Definizione del metodo onCreate della classe MarkCard.java . . . . . . . Definizione del metodo setDescription della classe MarkCard.java . Definizione del metodo setImage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Definizione del metodo onCreate della classe MapShow.java . . . . . . . . Definizione del metodo initMapView della classe MapShow.java . . . . . Struttura del file activity main.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . File activity choose faculty.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . File row.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 61 61 61 61 62 62 63 63 64 65 65 65 65 66 67 68 70 71 Introduzione Al giorno d’oggi si sente parlare sempre più spesso di “mobile”, “smartphone”, “app”, “wireless”, “3G”, termini che, ormai, sono diventati parte del vocabolario di tutti i giorni, e questo grazie alla rapida evoluzione delle tecnologie mobili. Gli smartphone o i tablet sono ormai in grado di compiere operazioni complesse che, fino a qualche anno fa, erano ritenute impossibili; i dispositivi sono diventati sempre più potenti, efficienti, innovativi ed alla portata di tutti. Il mondo delle applicazioni mobili ha, quindi, subito un’espansione esponenziale e continuerà a crescere in quanto il mercato è in continua evoluzione. Non si parla soltanto di applicazioni ludiche, ma di software applicabili a diversi ambiti, quali la vita privata, la sanità, la pubblica amministrazione, le aziende, etc. I primi smartphone integravano un semplice web browser, tramite cui era possibile usufruire quasi degli stessi servizi web di un comune PC. Il mondo web ha fornito (e continua a fornire) innumerevoli servizi e vantaggi ai vari utenti; da un semplice PC connesso alla rete è possibile svolgere moltissime operazioni tra cui: navigare su Internet per la ricerca di informazioni (news, mappe, meteo, etc.), accedere a servizi social (Facebook, Twitter, Linkedin, Myspace, etc.), consultare il proprio conto corrente ed effettuare pagamenti, consultare forum, blog e condividere proprie esperienze, inviare messaggi di posta elettronica e “chattare” o videocomunicare con utenti sparsi in tutto il mondo. L’immissione sul mercato del primi telefoni cellulari che avevano la possibilità di gestire e-mail (blackberry) o navigare tramite wap ha fatto si che il processo di integrazione tra mondo web e mondo mobile iniziasse ad avere luogo. Molti pensano che il mondo mobile sia nato in corrispondenza dell’arrivo dell’iPhone, ma non è cosı̀. I dispositivi mobili erano già disponibili da qualche anno (i primi smarphone arrivano intorno al 2003) e avevano già delle ottime caratteristiche; gli schermi iniziavano ad avere una qualità più alta, la multimedialità veniva già tenuta in gran considerazione (player mp3, radio FM, video streaming, etc.), i programmi per la gestione delle e-mail erano già presenti ed evolvevano sempre di più. Nel 2006, poi, si assiste ad un ulteriore passo avanti con i terminali che si connettevano al segnale 3G, con schede Wi-Fi integrate, GPS, sensori di luminosità e movimento, riconoscimento vocale, brower web (non solo wap). Nel 2007 l’immissione sul mercato del telefono di Cupertino ha segnato una svolta nel mondo mobile non tanto grazie alla tecnologia innovativa (gli altri smarphone 4 Introduzione facevano già le stesse cose), quanto a: • Innovazione del marketing: grazie all’Apple Store e iTunes la modalità di rilascio di un software era molto semplice, veloce e a prezzi molto competitivi; • Usabilità: grazie allo schermo multitouch, le gesture e l’assenza di tastiera fisica, il dispositivo risultava molto facile da utilizzare; • Sicurezza e chiusura: all’epoca l’iPhone molto più stabile e sicuro dei diretti concorrenti. Da quel momento, grazie al successo ottenuto, i vari competitor si sono adeguati e hanno iniziato a produrre strumenti sempre più simili al dispositivo di riferimento, cercando di migliorare sempre più le varie funzionalità. Ad oggi il maggior concorrente di Apple è Google che, con il sistema operativo open source Android e la sua presenza su terminali di brand diversi, ha superato Apple nelle vendite dei dispositivi mobili. Ovviamente, l’utente finale è colui il quale trae più giovamento da questa situazione, in quanto ha a disposizione una notevole quantità di dispositivi con diverse caratteristiche e diversi prezzi, che gli permettono di effettuare una molteplicità di operazioni tra le quali, naturalmente, essere sempre connesso alla rete. Dal 2007 ad oggi lo sviluppo dei dispositivi mobili è proseguito in maniera esponenziale; i più comuni smartphone possono annoverare, tra le proprie caratteristiche, la telefonia, il bluetooth, il microfono, la fotocamera, la multimedialità, la grafica 3D, il touchscreen, notifiche ed allarmi, il networking, la realtà virtuale, presenza di svariati sensori (accelerometro, giroscopio, bussola, GPS, etc.), la realtà aumentata, etc. La motivazione che ci ha spinti a progettare e implementare questo sistema è stata, quindi, quella di metterci alla prova, come ingegneri, con questa nuova ed emergente realtà. Grazie al crescente uso di smartphone e tablet, il settore dello sviluppo di applicazioni mobili sta registrando un’enorme crescita e costituisce un segmento industriale particolarmente promettente, in cui non sono richiesti grandi capitali, ma grandi competenze e buone idee. La domanda di ingegneri nel campo dell’ICT da parte delle aziende è, perciò, in crescente aumento. Tutto questo ci fa comprendere come la preparazione nel campo della programmazione “mobile” sia utile, o addirittura indispensabile, per un aspirante ingegnere informatico. Il lavoro effettuato nella tesi è stato motivato anche dal fatto che i sistemi di navigazione indoor sono anch’essi un fenomeno piuttosto recente, fonte di continue ricerche e studi, che ci hanno permesso di valutare, fra tante opportunità ed idee, quella più adeguata per la realizzazione del nostro sistema. La scelta, nel nostro caso, è ricaduta sull’utilizzo di QRCode. Un codice QR (Quick Response Code) è un codice a barre bidimensionale, ossia a matrice, composto da moduli neri disposti all’interno di uno schema di forma quadrata; esso viene impiegato per memorizzare informazioni generalmente destinate a essere lette tramite smartphone. La scelta di utilizzare i QRCode come infrastruttura di supporto alla navigazione è motivata dal fatto che essi rappresentano sia la soluzione più semplice (di facile generazione), sia quella più economica, essendo praticamente a costo nullo. Introduzione 5 Il progetto vuole offrire una modalità di orientamento alternativa all’interno degli edifici dell’Università Mediterranea, garantendo, cosı̀, un’autonomia totale nella ricerca di un luogo specifico, con conseguente risparmio di tempo. La tesi intende unire elementi di analisi e progettazione di un sistema ad elementi di implementazione e testing dello stesso, coinvolgendo gli aspetti alla base del lavoro di un ingegnere informatico. L’applicazione è studiata in modo tale che sia fruibile da chiunque sia in possesso di uno smartphone con sistema operativo Android dotato di fotocamera. Tale utente potrà, tramite la scansione di appositi QRCode, orientarsi all’interno dei vari edifici. Il software permette di avere due modalità di navigazione, una che prevede, tramite scansione di QRCode e scelta di una destinazione, di visualizzare mappe guidate; l’altra consente di esplorare liberamente le planimetrie delle varie aree. La tesi è strutturata come di seguito specificato: • • • • • • • Nel primo capitolo verrà proposto un breve excursus sulla nascita ed evoluzione degli smartphone e dei principali sistemi operativi che li affiancano; inoltre vengono analizzate le tecniche di navigazione outdoor, e soprattutto indoor, che questi dispositivi offrono. Nel secondo capitolo viene proposta un’analisi del progetto MediNav, illustrando le sue principali caratteristiche e l’idea da cui ha avuto sviluppo. Il terzo capitolo si concentrerà sull’analisi dei requisiti della componente di frontend del sistema e descriverà nei dettagli la sua architettura. Nel quarto capitolo verrà introdotta la progettazione del nostro sistema, facendo riferimento a dei mock-up, per la pianificazione del layout, e ad un workflow grafico, per analizzare l’interazione dell’utente con esso. Sarà, inoltre, descritta la progettazione della componente dati dell’applicazione mediante l’utilizzo dei diagrammi di classe e dei relativi file di layout XML. Nel quinto capitolo verrà descritta l’implementazione del nostro sistema, suddivisa in più parti, concentrate sulle singole classi analizzate in fase di progettazione. Nel sesto capitolo verrà proposta un’analisi SWOT del progetto realizzato, valutandone gli aspetti positivi e negativi. Infine, verranno tratte le conclusioni e verranno delineati alcuni possibili sviluppi futuri. 1 Lo scenario tecnologico di riferimento L’enorme avanzamento, nell’ultimo decennio, delle tecnologie legate ai telefoni cellulari ha, indubbiamente, cambiato le nostre abitudini. Il cellulare, da semplice strumento adibito alla sola comunicazione telefonica e all’invio e ricezione dei messaggi di testo, si è evoluto in un vero e proprio microcomputer mobile. Lo tesimonia la rapida diffusione degli smartphone, telefoni cellulari caratterizzati dalla presenza di un sistema operativo e dalla possibilità di installare ed eseguire applicazioni. Basandosi su quanto detto, in questo capitolo, verranno descritti brevemente i più diffusi sistemi operativi mobili; particolare attenzione sarà data ai sistemi di navigazione outdoor ed indoor che questi dispositivi offrono. 1.1 Smartphone e sistemi operativi mobili 1.1.1 Che cosa è uno smartphone Lo smartphone, o telefono intelligente, è un telefono cellulare con capacità di calcolo, di memoria e di connessione dati molto più avanzate rispetto ai normali telefoni cellulari, basato su un sistema operativo per dispositivi mobili. I primi smartphone combinavano le funzioni caratteristiche di un palmare a quelle di un telefono cellulare. I modelli più moderni, successivamente, si sono arricchiti delle funzionalità tipiche dei dispositivi multimediali, permettendo di girare e riprodurre video, scattare e visualizzare foto ed ascoltare musica. Col passare del tempo le capacità di questi dispositivi si sono evolute sempre di più fino a renderli dei micro-computer tascabili che permettono di navigare in internet mediante browser web alla pari di un computer fisso, leggere la posta elettronica, scaricare e modificare documenti pdf, e cosı̀ via. Una peculiarità importante di tali dispositivi è, inoltre, quella di poter estendere ulteriormente le funzionalità di base tramite l’installazione delle cosiddette app (applicazioni dedicate ai dispositivi mobili, cosı̀ come i programmi lo sono per i computer fissi), scaricabili dai rispettivi market di vendita. 8 1.1.2 1 Lo scenario tecnologico di riferimento Storia L’idea di unire funzionalità tipiche di un telefono a quelle di un computer risale al 1973. Il termine smartphone fu usato per la prima volta nel 1997, quando la Ericsson produsse Penelope, un dispostivo a cui la società attribuı̀ il termine smartphone. Il primo smartphone, chiamato Simon (Figura 1.1), fu progettato dalla IBM nel 1992 e messo in commercio dalla BellSouth a partire dal 1993. Questo nuovo dispositivo possedeva tutte le comuni funzionalità di un telefono, alle quali affiancava la presenza di calendario, rubrica, orologio, block notes, funzioni per la lettura di e-mail e giochi. I BlackBerry sono considerati i primi dispositivi ad essersi affermati su scala internazionale come smartphone. Inizialmente questi dispositivi permettevano di aprire e consultare allegati, oltre a poter navigare in internet con un browser mobile, caratteristica che all’epoca era considerata unica. Dai primi anni 2000 l’evoluzione degli smartphone è andata di pari passo con lo sviluppo degli standard di telefonia mobile cellulare, in particolare dall’UMTS fino all’HSPA e all’LTE con capacità di banda superiori ai precedenti standard GSM/GPRS. La crescita della capacita in banda ha consentito a questi dispositivi che sono costantemente connessi alla rete, di poter ricevere ed inviare grandi quantità di informazioni quasi istantaneamente. Figura 1.1. IBM Simon Gli smartphone, per come sono conosciuti oggi, hanno avuto inizio a partire dal 2007 quando Apple ha introdotto sul mercato un nuovo tipo di cellulare, dotato di multitouch e pinch to zoom: l’iPhone (col termine “pinch to zoom” si intende il movimento a pinza delle dita per ingrandire o rimpicciolire elementi sullo schermo del dispositivo). Questo nuovo dispositivo ha conferito una grande spinta al mercato 1.1 Smartphone e sistemi operativi mobili 9 degli smartphone ed ha favorito la nascita della concorrenza. Nel 2008, infatti, HTC ha introdotto il T-Mobile G1, meglio noto come HTC Dream, il primo smartphone Android, sistema operativo sviluppato da Google che, grazie alla sua natura open source, è stato adottato da numerosi produttori, tra cui Samsung, LG, HTC e Huawei. La sezione mobile di Nokia, restia ad adottare il sistema operativo di Google, è stata acquisita da Microsoft nel 2013, dando vita alla serie di smartphone Lumia con sistema operativo Windows Phone. Col passare degli anni sono questi i sistemi operativi che ancora oggi dominano il mercato mobile. Android, grazie alla sua natura open source, risulta il sistema operativo più diffuso, seguito da iOS, il sistema operativo proprietario di Apple, e per ultimo da Windows Phone, la versione mobile del celebre sistema operativo Windows per server e desktop. 1.1.3 Funzionalità Le funzionalità comuni alla maggior parte degli smartphone includono la connessione dati, ovvero l’accesso a Internet, le e-mail, la pianificazione delle attività (agenda o scheduler), la fotocamera, la rubrica e i contatti personali, il registratore audio, il riproduttore audio-musicale. Nella maggioranza dei modelli è disponibile la navigazione satellitare con GPS e la compatibilità con i formati di file più comuni, come PDF e quelli della suite Microsoft Office. Esistono smartphone con vari tipi di connettività, come GSM, GPRS, EDGE, UMTS, HSDPA, HSUPA, LTE, che integrano tecnologie Bluetooth, Wi-Fi ed NFC per la comunicazione con altri dispositivi. Molte di queste funzionalità sono possibili grazie alla presenza nel dispositivo mobile di svariati sensori tra i quali l’accelerometro, il magnetometro, il sensore di prossimità, il sensore di pressioni atmosferica, etc. Modelli più recenti consentono l’uso dello smartphone come modem-router, tramite una tecnologia chiamata tethering, mediante la quale la connessione del dispositivo host viene condivisa attraverso Bluetooth, Wi-Fi o tramite un cavo USB. La caratteristica principale di uno smartphone è quella di poter estenderne le funzionalità installando applicazioni di terze parti. Un’altra caratteristica tra le tante di uno smartphone è quella di poter inserire direttamente dal cellulare un numero fisso o mobile in una blacklist, per bloccare tutte le comunicazioni, come la ricezione di SMS, MMS e chiamate vocali sul proprio terminale. Questa ed altre funzionalità si possono ottenere anche mediante l’installazione di app specifiche per il call-blocking o l’sms-blocking. Esistono, anche, app che permettono di effettuare call-recording, ovvero registrare le chiamate effettuate e ricevute. 1.1.4 Caratteristiche A rendere gli smartphone cosı̀ performanti e funzionali rispetto ai comuni terminali vocali sono stati l’aumento delle prestazioni in termini di potenza di calcolo del processore e il costante aumento della capacità e della velocità in lettura/scrittura delle memorie. Tutto ciò è stato possibile grazie ai progressi fatti nel campo dell’elettronica dei circuiti integrati, che hanno permesso di ridurre sempre di più 10 1 Lo scenario tecnologico di riferimento le dimensioni dei microprocessori, aumentandone, allo stesso tempo, la potenza di calcolo e diminuendone i consumi elettrici. Oltre ai progressi a livello hardware, per questi dispositivi sono stati sviluppati sistemi operativi ad hoc. I principali sono Android, sviluppato da Google, iOS, sistema operativo proprietario di Apple, Windows Mobile, sistema operativo sviluppato da Microsoft per i dispositivi Lumia, ed altri di minore rilevanza, come Symbian, MeeGo, Firefox Os, Blackberry 10 etc. Tipicamente l’interazione con questi dispositivi avviene mediante interfacce utente sempre più facili da utilizzare, come lo schermo tattile, che ha permesso di eliminare l’esigenza di avere tastiere e tasti fisici. 1.1.5 Il sistema operativo Android Android, insieme ad iOS e Windows Mobile, fa parte della categoria dei sistemi operativi per dispositivi mobili. Sviluppato da Google, e basato sul kernel Linux, non è propriamente un sistema GNU/Linux dal momento che la maggior parte delle utilità GNU è sostituita da software scritto in linguaggio Java. Lo sviluppo di Android prosegue attraverso l’Android Open Source Project, il quale è software libero, ad esclusione di diversi firmware non-liberi inclusi per i produttori di dispositivi, e delle cosiddette Google Apps come, ad esempio, Google Play. Android è distribuito sotto i termini della licenza libera Apache 2.0 che si riserva di non includere software coperto da licenze copyleft. 1.1.6 Architettura di Android La piattaforma Android è ben strutturata e stratificata (Figura 1.2) a tal punto che ha poco da invidiare a quelle dei comuni sistemi desktop. Il cuore del sistema è basato sul kernel di Linux (Versione 2.6), che costituisce il livello di astrazione di tutto l’hardware sottostante; quest’ultimo include il Wi-Fi, il Bluetooth, il GPS, la fotocamera, il touchscreen, etc. I produttori hardware possono, quindi, intervenire già a questo livello per personalizzare i driver che consentono la comunicazione con i propri dispositivi. Grazie all’astrazione dell’hardware, infatti, i livelli soprastanti non si accorgono dei cambiamenti hardware, permettendo una programmazione ad alto livello omogenea ed una user experience indipendente dal dispositivo. Il livello superiore riguarda l’equipaggiamento software costitutio dalle librerie fondamentali che gestiscono, ad esempio, la grafica 2D e 3D (OpenGL ES), dal browser con engine WebKit, dal supporto per i database (SQLite) o, ancora, dal supporto alla crittografia (SSL). L’ambiente di runtime, o esecuzione, è costituito da una libreria core e da una macchina virtuale (VM). Insieme esse rappresentano la piattaforma di sviluppo per Android. La virtual machine di Android è una versione personalizzata della Java Virtual Machine (Chiamata Dalvik per versioni di Android inferiori alla 5.0 e ART per versioni superiori), progettata ed ottimizzata appositamente per essere eseguita su hardware meno “performanti”, come quello degli smartphone, che fanno parte della categoria dei sistemi embedded, ovvero sistemi dotati di risorse hardware (quantità di RAM, risorse energetiche, potenza di calcolo) limitate. In realtà i più 1.1 Smartphone e sistemi operativi mobili 11 Figura 1.2. Architettura di Android moderni smartphone possono vantare processori quad-core con quantitativi di RAM dell’ordgine dei 4 Gb, per cui questa affermazione comincia già ad essere obsoleta. Il kernel Linux di Android è un sistema multi-utente nel quale ogni applicazione rappresenta un utente differente. Il sistema, infatti, crea un unico User ID per ogni applicazione (sconosciuto ad essa) e imposta i permessi dei file dell’applicazione stessa in modo che solo quel determinato ID possa averne l’accesso. Inoltre, ogni applicazione sullo smartphone viene lanciata in un processo Linux a se stante all’interno di una propria istanza della virtual machine (Dalvik o ART). Questa architettura a sandbox garantisce la stabilità del sistema nel caso in cui qualche applicazione crei problemi. La comunicazione tra applicazioni diverse è permessa tramite la condivisione dello stesso User ID e della stessa macchina virtuale in modo da preservare la coerenza delle risorse di sistema. Al penultimo livello è possibile rintracciare i gestori e le applicazioni di base del sistema. Ci sono gestori per le risorse, per le applicazioni installate (package manager), per le telefonate, per il file system etc. All’ultimo e più alto livello risiedono le applicazioni utente. Le funzionalità di base del sistema, come, ad esempio, il telefono, non sono altro che applicazioni utente scritte in codice Java e che vengono eseguite ciascuna nella propria istanza della macchina virtuale. Da notare che non è la distribuzione Java ME che viene eseguita, ma una versione appositamente creata per la Dalvik Virtual Machine. Il codice Java, infatti, viene compilato e tradotto in bytecode; dopodichè, rispetto a Java, subisce un’ulteriore trasformazione in un formato chiamato dex file. Quest’ultimo passaggio ha consentito, da un lato, a Google di svincolarsi da possibili problemi legali con Oracle, nuova proprietaria di Java, e dall’altro di poter ottimizzare il codice per la sua JVM. 12 1 Lo scenario tecnologico di riferimento 1.2 Navigazione outdoor 1.2.1 Sistema di posizionamento globale Il sistema di posizionamento globale, o GPS, è un sistema di posizionamento e navigazione satellitare civile, che, mediante una rete dedicata di satelliti (Figura 1.3) artificiali in orbita, fornisce ad un ricevitore GPS (Figura 1.4), o ad un terminale mobile, come uno smartphone, informazioni sulle sue coordinate geografiche ed orario, in qualunque condizione meteorologica, ovunque sulla Terra vi sia un contatto privo di ostacoli con almeno quattro satelliti del sistema. La localizzazione è resa possibile tramite la trasmissione di un segnale radio da parte di ciascun satellite e la successiva elaborazione dei segnali ricevuti da parte del ricevitore. Figura 1.3. Un satellite GPS in orbita 1.2.2 Il sistema Il segmento spaziale comprende da 24 a 32 satelliti. Il segmento di controllo si compone di una stazione di controllo principale, una stazione di controllo alternativa, varie antenne dedicate e condivise e stazioni di monitoraggio. Il segmento utente, infine, è composto dai ricevitori GPS. Attualmente sono in orbita 31 satelliti attivi nella costellazione GPS (più alcuni satelliti dismessi, alcuni dei quali riattivabili in caso di necessità). I satelliti supplementari migliorano la precisione del sistema permettendo misurazioni ridondanti. Al crescere del numero di satelliti, la costellazione è stata modificata secondo uno schema non uniforme che si è dimostrato maggiormente affidabile in caso di guasti contemporanei di più satelliti. 1.2 Navigazione outdoor 13 Figura 1.4. Un comune ricevitore GPS nautico 1.2.3 Principio di funzionamento Il principio di funzionamento si basa su un metodo di posizionamento sferico detto trilaterazione, che parte dalla misura del tempo impiegato da un segnale radio a percorrere la distanza satellite-ricevitore. Poiché il ricevitore non conosce quando è stato trasmesso il segnale dal satellite, per il calcolo della differenza dei tempi il segnale inviato dal satellite è di tipo orario, grazie all’orologio atomico presente sul satellite; il ricevitore calcola l’esatta distanza di propagazione dal satellite a partire dalla differenza (dell’ordine dei microsecondi) tra l’orario pervenuto e quello del proprio orologio, sincronizzato con quello a bordo del satellite, tenendo conto della velocità di propagazione del segnale. L’orologio a bordo dei ricevitori GPS è, però, molto meno sofisticato di quello a bordo dei satelliti e deve essere corretto frequentemente, non essendo altrettanto accurato sul lungo periodo. In particolare, la sincronizzazione di tale orologio avviene all’accensione del dispositivo ricevente, utilizzando l’informazione che arriva dal quarto satellite, venendo, cosı̀, continuamente aggiornata. Se il ricevitore avesse anch’esso un orologio atomico al cesio perfettamente sincronizzato con quello dei satelliti, sarebbero sufficienti le informazioni fornite da 3 satelliti; nella realtà non è cosı̀, e, dunque, il ricevitore deve risolvere un sistema di 4 incognite (latitudine, longitudine, altitudine e tempo) e, per riuscirci, necessita, dunque, di 4 equazioni. Ciascun satellite opera su due frequenze, una per uso civile ed una per uso militare, anche se i più recenti ricevitori GPS in campo ingegneristico hanno la possibilità di usufruire del canale dedicato all’uso militare, che permette di ottenere una precisione di localizzazione superiore rispetto a quella ottenibile usando il solo canale civile (dell’ordine dei centimetri invece che dei metri). Ogni messaggio inviato da ciascun satellite contiene le seguenti informazioni: • • • • tempo della trasmissione del satellite (satellite time-of-transmission); effemeridi satellite (satellite ephemeris); grado di funzionalità del satellite (satellite (SIS) health); correzione relativistica dell’orologio satellitare (satellite clock correction); 14 1 Lo scenario tecnologico di riferimento • effetti di ritardo del segnale dovuti alla ionosfera (ionospheric delay effects); • correlazione con il tempo coordinato universale (UTC), come specificato dallo United States Naval Observatory (USNO); • stato della costellazione (constellation status). La funzione del ricevitore di bordo è, prima di tutto, quella di identificare il satellite attraverso la banca dati di codici che quest’ultimo ha in suo possesso; infatti, ogni satellite ha un codice e il ricevitore lo identifica grazie a quest’ultimo. L’altra funzione importante del ricevitore è quella di calcolare il “delta t”, ovvero il tempo impiegato dal segnale per arrivare dal satellite al ricevitore. Ogni satellite trasmette l’almanacco (parametri orbitali approssimati) dell’intera costellazione, ma esclusivamente le effemeridi relative a se stesso. La parte relativa alle effemeridi dura 18 secondi e viene ripetuta ogni 30 secondi. Per scaricare completamente l’almanacco dell’intera costellazione sono necessari, invece, 12,5 minuti. In tal modo il ricevitore GPS, mentre effettua il conteggio Doppler, riceve i parametri dell’orbita da cui deriva la posizione del satellite; viene, cosı̀, a disporre di tutti gli elementi necessari a definire nello spazio la superficie di posizione. 1.2.4 Sistemi di navigazione e smartphone La presenza di ricevitori GPS integrati nei moderni smartphone ha portato allo sviluppo di sistemi di navigazione assistita sia online (Google Maps, Apple Maps Figura 1.5) che offline (TomTom Go). Figura 1.5. Google Maps ed Apple Maps Tra i tanti servizi offerti da queste piattaforme il più comune è quello della navigazione assistita verso una destinazione prefissata. Oltre alla localizzazione semplice, mediante gli smartphone, i servizi GPS sono stati integrati anche nei social network, 1.3 Navigazione Indoor 15 con la possibilità di condividere in ogni istante la propria posizione. Altri usi del GPS permettono di catalogare le foto effettuate con il cellulare in base alla posizione. Google Maps integra nella propria piattaforma la possibilità di effettuare ricerche di ristoranti, negozi, località, etc. I servizi GPS, benchè comodi, hanno le loro limitazioni, come visto nella sezione 1.2.3. Per riuscire ad ottenere la posizione in un determinato punto sulla superficie terrestre è necessario che il ricevitore GPS sia in grado di agganciare almeno 4 satelliti. Questa condizione, spesso, non viene rispettata, specialmente nelle zone cosiddette indoor. All’interno degli edifici, nelle gallerie, nei sottopassaggi, o in qualunque altro ambiente che non sia a cielo aperto, il segnale GPS diventa troppo debole e la sua ricezione può essere pessima, o addirittura nulla. Altra importante limitazione è la mancanza di informazioni altimetriche. Viste le forti limitazioni del sistema GPS in ambienti a bassa o nulla ricezione, si è cercato di sviluppare tecnologie ausiliarie che permettessero la navigazione anche in ambienti isolati dal segnale GPS. Queste nuove tecnologie sfruttano il segnale GPS in combinazione con le informazioni ricavate dai vari sensori dello smartphone (come l’accellerometro, il magnetometro, il sensore di prossimità) le informazioni relative alle caratteristiche delle infrastrutture già presenti nell’ambiente urbano (tra cui intensità del segnale di rete mobile, la presenza e l’intensità di reti Wi-Fi, dispositivi Bluetooth etc). Queste informazioni, in combinazione con quelle relative al segnale GPS, permettono una precisione di localizzazione dell’ordine dei centimetri. Inoltre, in assenza di segnale GPS, mediante il rilevamento di reti Wi-Fi, dispositivi bluetooth e reti mobili, è possibile risalire alla posizione del dispositivo, anche se, spesso, con una precisione molto inferiore. 1.3 Navigazione Indoor L’esigenza di avere sistemi di localizzazione anche in assenza del segnale GPS ha dato il via allo sviluppo di tecnologie alternative, che fossero in grado di fornire gli stessi risultati dei servizi a cielo aperto in zone indoor. Gli utilizzi della navigazione indoor permetterebbero la nascita di sistemi di navigazione all’interno dei supermercati, la possibilità di conoscere l’esatta locazione di ciascun prodotto all’interno di un magazzino o, più semplicemente, una navigazione stile GPS in ambienti dove quest’ultimo non sia disponibile (parcheggi sotterranei). La navigazione indoor è, per sua natura, più complessa e variegata di quella outdoor, e comunque non riconducibile ad un’unica tecnologia, come quella GPS per l’outdoor. Questo, nel corso degli anni, si è rivelato un interessante problema di studio e ricerca scientifica, allo scopo di trovare una soluzione efficiente e definitiva. Gli studi proposti negli ultimi anni hanno individuato varie tipologie di soluzioni, che possiamo raggruppare nelle seguenti categorie: • • • radio localization (Wi-Fi, Bluetooth, ZigBee) dead reckoning pattern recognition ed analisi ambientale 16 1 Lo scenario tecnologico di riferimento Radio Localization È un metodo di posizionamento basato su un’infrastruttura, esterna o interna, costituita da antenne radio, solitamente installate in delle posizioni ben precise conosciute a priori e geolocalizzate. È una sorta di emulazione di quello che avviene con la triangolazione tramite i satelliti del sistema GPS. Questa metodologia di posizionamento, in alcuni, casi prende anche il nome di GPS-like pseudolites. Lo Pseudolite, o pseudo satellite, è un trasmettitore del segnale GPS, installato in modo stabile a terra, utilizzato per incrementare la diffusione del segnale su ambienti a copertura scarsa o su ambienti indoor. Gli pseudoliti possono essere definiti, quindi, come dei piccoli satelliti GPS che permettono una precisa localizzazione ma richiedono alti costi di installazione e di calibrazione. Molti di questi sistemi di navigazione permettono il tracking indoor a tre dimensioni e si basano su reti radio UWB (Ultra Wide Band), Bluetooth, ZigBee, o Wi-Fi. La navigazione indoor via radio, già disponibile da alcuni anni, presenta l’inconveniente di essere eccessivamente costosa. Essa necessita, infatti, dell’installazione di un’infrastruttura di rete e, tuttavia, non è esente da errori di misurazioni: il segnale radio (UWB, Bluetooth o Wi-Fi), da solo, non è sufficiente per una perfetta localizzazione continua e costante a causa di interferenze o cadute di segnale. Dead reckoning Una tecnica alternativa deriva dal dead reckoning, o navigazione stimata. Nella maggior parte dei casi questo metodo prevede la conoscenza a priori delle mappe degli edifici. Il dead reckoning ha come principali vantaggi il basso costo e la richiesta di un’infrastruttura minimale rispetto alle altre tecniche. Il dead reckoning si basa sul calcolo della posizione corrente di un oggetto mediante l’utilizzo di una posizione precedentemente nota, ed avanza tale posizione basandosi sulla conoscenza o stima della velocità di spostamento nel tempo. Mediante gli smartphone è possibile stimare la posizione di un utente conteggiando i passi da una posizione nota mediante l’utilizzo dell’accellerometro e del giroscopio. Lo svantaggio principale è che la posizione è sempre approssimata e l’errore di misurazione si accumula di posizione in posizione. Pattern recognition Si tratta di un metodo di posizionamento che sfrutta le informazioni, visive e non, relative all’ambiente circostante. Un esempio a basso costo di posizionamento indoor che usa la tecnica del pattern recognition è quello che prevede l’utilizzo della fotocamera di un cellulare per determinare la posizione dell’utente attraverso dei piccoli codici a barre bidimensionali. La fotocamera esegue la scansione dell’ambiente alla ricerca di questi codici, posizionati in punti strategici, in modo da ottenere la localizzazione dell’utente. Il lavoro svolto in questa tesi prevede l’implementazione di un sistema di questo genere, mediante l’ausilio di appositi QRCode posizionati nei punti di interesse che, una volta scansionati con la fotocamera, visualizzano sullo schermo la posizione dell’utente sulla mappa. 1.3 Navigazione Indoor 1.3.1 17 QRCode I codici QR (Figura 1.6) o, in inglese, QRCode, sono codici a barre bidimensionali, generalmente composti da moduli neri disposti all’interno di uno schema di forma quadrata. Il termine “QRCode” sta per Quick Response Code; tali codici sono, infatti, studiati per permettere una rapida decodifica del contenuto informativo. Figura 1.6. Esempio di QRCode Sviluppati nel 1994 da parte di una società Giapponese, la Deuso Wave, per tracciare i pezzi delle automobili nelle fabbriche Toyota, nel 1999 sono stati rilasciati sotto licenza libera, definiti e pubblicati come standard ISO. I QRCode sono utilizzati per memorizzare informazioni destinate alla lettura ottica tramite lettori ottici o fotocamere, in particolare di smartphone o tablet; essi si prestano bene, quindi, come marcatori da utilizzare per la localizzazione indoor basata sul pattern recognition. 2 Descrizione del progetto MediNav In questo capitolo daremo uno sguardo generale al progetto MediNav, illustrando sia l’idea da cui è nato che le sue principali caratteristiche. 2.1 L’idea alla base di MediNav MediNav nasce dalla collaborazione tra gli studenti del DArTe (Dipartimento di Architettura e Territorio) e quelli del DIIES (Dipartimento di ingegneria dell’informazione, delle infrastrutture e dell’energia sostenibile). Gli studenti Mario Ciardullo, Giuseppe Genovese, Vittoria Triestino, nell’ambito del corso di “accessibilità, fruibilità e sicurezza degli spazi” a cura del Prof. Arch. Francesco Bagnato, hanno progettato “MEDITERRANEA WAYFINDING”, un’app per orientarsi all’interno dell’università Mediterranea. 2.1.1 La loro idea L’idea di base prevedeva la realizzazione di un’app per smartphone per fornire l’accesso guidato all’interno dell’ateneo. Attraverso l’applicazione, che interagisce con la fotocamera del proprio dispositivo, è possibile visualizzare un QRCode che rimanda a informazioni necessarie non solo per gli spostamenti, ma anche per tutte le possibili attività che si svolgono all’interno dell’Università Mediterranea: orari, lezioni, appelli, convegni, riunioni ed attività. I codici QR posti agli ingressi (Figura 2.1) indirizzeranno gli utenti alle rispettive destinazioni tramite schermate guida. Quelli posti all’ingresso dei luoghi (Figura 2.2) conterranno, invece, informazioni relative ad orari, agli eventi, etc. Nelle Figure 2.3, 2.4 e 2.5 vengono illustrate alcune immagini rappresentative del concept dell’app secondo gli studenti del DArTe. 2.1.2 La nostra idea Grazie ad un incontro avvenuto tra gli studenti dei due dipartimenti, è stato possibile evidenziare le mancanze e le debolezze dell’idea iniziale. L’app, per come era stata 20 2 Descrizione del progetto MediNav Figura 2.1. Un primo esempio di disposizione dei QRCode sulla mappa Figura 2.2. Un secondo esempio di disposizione dei QRCode sulla mappa pensata dai ragazzi del DArTe, offriva una “falsa” navigazione, ovvero, mediante la scansione di un codice QR, l’applicazione avrebbe dovuto mostrare una sequenza di immagini statiche con indicazioni (frecce segnaletiche) su come raggiungere i punti stabiliti. Questo approccio, troppo semplicistico, avrebbe reso poco utile l’utilizzo dei codici QR, in quanto l’applicazione avrebbe potuto salvare tutte le immagini relative ai principali punti di interesse e mostrarle in sequenza in seguito alla scelta di una destinazione da un apposito menù. L’idea di utilizzare i QRCode, è stata mantenuta ma, al contempo, ampliata 2.1 L’idea alla base di MediNav 21 Figura 2.3. Un primo concept dell’app per come era stata inizialmente pensata Figura 2.4. Un secondo concept dell’app per come era stata inizialmente pensata in modo tale da offrire una navigazione più dinamica rispetto alla semplice visualizzazione di sequenze di immagini segnaletiche. Posizionando QRCode per tutta l’Università Mediterranea è possibile utilizzare gli stessi come marcatori associati a delle planimetrie, da usare come mappe. Ad ogni scansione di un QRCode, viene visualizzata la posizione dell’utente sulla mappa. 22 2 Descrizione del progetto MediNav Figura 2.5. Un terzo concept dell’app per come era stata inizialmente pensata 2.2 Evoluzioni tecniche dell’idea A partire dall’idea di base, sono state prese in considerazione varie opzioni per la realizzazione del sistema. 2.2.1 Localizzazione radio Analizzando l’infrastruttura di rete presente all’interno dei vari edifici dell’Università Mediterranea, ci si è accorti della presenza di un gran numero di access point Wi-Fi. Questa infrastruttura garantisce l’accesso ad Internet agli studenti ed ai docenti; tramite essa è, teoricamente, possibile realizzare un sistema di localizzazione basato su onde radio (Sezione 1.3). Il sistema in questione avrebbe un vantaggio rispetto all’uso dei QRCode, poichè garantirebbe una navigazione real-time, ovvero il cursore che indica la posizione sulla mappa seguirebbe lo spostamento effettivo dell’utente, aggiornandosi costantemente e facilitando, cosı̀, l’orientamento. Benche il metodo in questione garantisca una navigabilità più affidabile, esso è, nella pratica, irrealizzabile, poichè richiede la copertura da parte di 3 access point in ogni punto, per poter utilizzare la tecnica della triangolazione. Purtroppo nei vari edifici dell’Università Mediterranea sono pochi i punti in cui è possibile ricevere i segnali radio di 3 access point contemporaneamente. Oltretutto, un malfunzionamento di più access point renderebbe inutilizzabile la localizzazione in aree specifiche. Altri problemi di questo metodo derivano direttamente dai problemi relativi alla radiopropagazione: attenuazione, fading o evanescenza, disturbo. Alla luce di tutto ciò, la localizzazione tramite onde radio è stata abbandonata. 2.2 Evoluzioni tecniche dell’idea 2.2.2 23 Google Maps Indoor Abbandonata l’idea della localizzazione radio, dopo varie ricerche, anche su suggerimento dei Dott. Vincenzo Periti e Francesco Paviglianiti dell’ufficio Comunicazione di Ateneo, si è optato per l’utilizzo di Google Maps Indoor, un servizio offerto da Google, integrato in Google Maps. Il servizio permette di caricare le planimetrie dei singoli piani di un edificio, consentendo, cosı̀, ai visitatori di esplorare e visualizzare i corrispettivi punti di interesse come se fosse una normale mappa esterna di Google Maps (Figure 2.6 e 2.7). Figura 2.6. Google Maps Indoor: visuale della mappa via smartphone Per usufruire del servizio è necessario, innanzitutto, eseguire l’upload delle planimetrie relative all’edificio di un’attività, mediante un apposito form reperibile dal sito di Google Maps Indoor (per attività di una certa dimensione è, invece, necessario accordarsi con il team dedicato di Google). Lo step successivo (dopo aver ottenuto l’approvazione da parte di Google) consiste nel sovrapporre, tramite l’interfaccia web di Google Maps, le planimetrie caricate nell’edificio. L’ultimo step consiste nel determinare i punti di interesse sulla mappa, tramite un’apposita applicazione di- 24 2 Descrizione del progetto MediNav Figura 2.7. Google Maps Indoor: visuale della mappa via web rettamente dallo smartphone (“Floor Maker”). L’app in questione usa tecniche di navigazione passive, come rilevamento di segnali di rete, Wi-Fi, Bluetooth, etc. La soluzione mediante Google Maps Indoor è, sicuramente, la più vantaggiosa, poichè, un qualunque sviluppatore, dopo aver caricato con successo le planimetrie ed effettuato tutti gli step necessari, può appoggiarsi tranquillamente alla piattaforma Maps di Google, per la quale esistono specifiche API. Questo è un enorme vantaggio, perchè lo sviluppatore, sfruttando le API preconfezionate di Google, è in grado di integrare nella propria applicazione un servizio di navigazione indoor senza dover progettare un’app dedicata. Visti gli evidenti vantaggi offerti dalla suddetta piattaforma, si è pensato, quindi, ad una implementazione che sfruttasse Google Maps Indoor per la visualizzazione della mappe e dei relativi punti di interesse; mappe su cui, poi, sarebbero stati tracciati i marcatori dei punti contenenti i QRCode ed i relativi percorsi a livello applicativo, sfruttando le interfacce fornite dal componente MapView di Android e le API del servizio per la localizzazione. Recentemente, però, tale servizio ha avuto un “cambio di target”, focalizzandosi principalmente sulle zone a densità elevata, come aeroporti, centri commerciali, stadi sportivi, stazioni. Dal servizio sono state esplicitamente escluse le università. Ciò, purtroppo, ha reso impraticabile l’utilizzo di questa piattaforma per lo sviluppo di MediNav. Nonostante ciò, abbiamo provato a contattare Google, la quale ci ha offerto la possibilità di caricare le planimetrie relative all’Università Mediterranea tramite lo strumento di upload online, senza, però, alcuna garanzia riguardo al loro effettivo inserimento nel servizio. L’alternativa sarebbe stata quella di diventare partner di Google Maps a pagamento, il che era una cosa che ricadeva fuori dai nostri obiettivi iniziali. 2.4 Architettura del sistema MediNav 25 2.3 L’idea finale La soluzione finale per MediNav, presa nota dell’impossibilità di appoggiarsi a soluzioni già esistenti, è ricaduta sulla progettazione di un’applicazione “ex novo”. La soluzione proposta si appoggia su di una libreria chiamata “MapView”, open source e rilasciata sotto licenza MIT su github dall’utente “onlylemi”. La libreria in questione è caratterizzata dalla presenza di un componente che permette la visualizzazione di mappe su Android. Esso, è, a sua volta, suddiviso in vari livelli chiamati “layer”. Ciascun livello si occupa di mostrare informazioni specifiche sul video; la sovrapposizione di tutti i livelli, infine, costituisce l’immagine finale che verrà presentata all’utente. I layer principali sono i seguenti: • • • • • Map Layer (Figura 2.8): è il livello base del componente; visualizza l’immagine della mappa, consentendo di effettuare lo scroll, il pinch to zoom e la rotazione della stessa. Bitmap Layer (Figura 2.9): è un livello che consente di mostrare un’immagine personalizzata. (Come, ad esempio, un’icona) come overlay sulla mappa con coordinate impostabili dall’utente. Location Layer (Figura 2.10): è il livello che si occupa della rappresentazione della posizione dell’utente sulla mappa. Mark Layer (Figura 2.11): questo livello, data una lista di punti di interesse, permette la loro rappresentazione sulla mappa e la gestione delle azioni associate ad essa, come, ad esempio, il “tap”. Route Layer (Figura 2.12): è il livello del routing. Basandosi su di un grafo tracciato sulla mappa, è in grado di indirizzare l’utente tra due o più punti (nodi) di esso, sfruttando algoritmi genetici per determinare il percorso migliore e tracciando i risultati direttamente sulla mappa come un percorso da seguire. 2.4 Architettura del sistema MediNav 2.4.1 Descrizione del front-end Che cosa è il front-end In un sistema informatico, i termini “front-end” e “back-end” denotano, rispettivamente, la parte visibile all’utente, e con la quale egli può interagire (interfaccia utente), e la parte che permette l’effettivo funzionamento di queste interazioni. Il front-end, più comunemente, è responsabile dell’acquisizione dei dati in ingresso e della loro elaborazione con modalità conformi a specifiche predefinite ed invarianti, tali da renderli utilizzabili dal back-end. Il collegamento tra front-end e back-end avviene mediante l’utilizzo di interfacce (punto di incontro o collegamento, spesso standardizzato, tra sistemi diversi e/o modalità per permettere la loro interazione sotto forma di scambio di informazioni). 26 2 Descrizione del progetto MediNav Figura 2.8. Map Layer di MapView Descrizione del front-end Analizzando un’applicazione Android, si possono individuare quattro componenti fondamentali: le activity, i service, i content provider ed i broadcast receiver. Per quanto riguarda il front-end, l’unico componente che analizzeremo è l’activity. Che cosa è un’activity? È un’interfaccia utente. Quando si usa un’app, generalmente, si interagisce con una o più “pagine” mediante le quali si consultano dati o si immettono input. Queste pagine rappresentano il componente con cui l’utente ha il contatto più diretto. Un’Activity ha bisogno di un volto, di un suo aspetto grafico. Sempre. Anche nei casi più semplici, come quando si limita a stampare la stringa “Hello World!”. La struttura grafica di un’Activity prende il nome di Layout. Le interfacce utente in Android possono essere create in modo procedurale o dichiarativo. Nel primo caso si intende l’implementazione dell’interfaccia grafica direttamente nel codice; ad esempio, in un’applicazione Swing (un framework per Java orientato allo sviluppo di interfacce grafiche), scriviamo il codice Java per creare e manipolare tutti gli oggetti dell’interfaccia utente, come JButton, JFrame, e cosı̀ via. La creazione dichiarativa non richiede la scrittura di codice: l’esempio tipico del metodo dichiarativo è rappresentato dalla creazione di una pagina web statica, in 2.4 Architettura del sistema MediNav 27 Figura 2.9. Bitmap Layer di MapView cui utilizziamo l’HTML per descrivere cosa vogliamo vedere nella pagina. L’HTML è, dunque, dichiarativo. Android permette la creazione di interfacce sia procedurali sia dichiarative; possiamo creare un’interfaccia utente completamente in codice Java (metodo procedurale) oppure attraverso un descrittore XML (metodo dichiarativo). Android, inoltre, permette un approccio ibrido, in cui si crea un’interfaccia in modo dichiarativo e la si controlla e specifica in modo procedurale (si richiama il descrittore XML da codice e si continua a lavorare da lı̀). Dando un’occhiata alla documentazione di Android, si intuisce che, per i componenti delle interfacce utente, gli attributi presenti nelle API Java e quelli utilizzabili negli XML dichiarativi sono gli stessi; ciò dimostra che, in entrambi i casi, abbiamo a disposizione le medesime possibilità. Nel framework Android sono stati definiti vari tipi di layout; tuttavia ce ne sono tre di utilizzo molto comune che permettono di affrontare ogni situazione: • LinearLayout: contiene un insieme di elementi che distribuisce in maniera sequenziale dall’alto verso il basso (se definito con orientamento verticale) o da sinistra a destra (se ha orientamento orizzontale, il caso di default). È un layout molto semplice e piuttosto naturale per i display di smartphone e tablet. 28 2 Descrizione del progetto MediNav Figura 2.10. Location Layer di MapView • TableLayout: altro layout piuttosto semplice; inquadra gli elementi in una tabella e, quindi, è particolarmente adatto a mostrare strutture regolari suddivise in righe e colonne, come form o griglie. È piuttosto semplice da usare e ricorda molto le tabelle HTML nelle pagine web con i ben noti tag ⟨table⟩ ⟨tr⟩ ⟨td⟩. • RelativeLayout: sicuramente il più flessibile e moderno. Adatto a disporre in maniera meno strutturata gli elementi, ricorda un pò il modo di posizionare ⟨div⟩ flottanti nelle pagine web. Essendo “relativi”, gli elementi si posizionano in relazione l’uno all’altro, o rispetto al loro contenitore, permettendo un layout fluido che si adatta bene a display diversi. Rispetto agli altri due layout, questo è ricco di attributi XML che servono ad allineare e posizionare gli elementi tra loro. I vari elementi che compaiono all’interno delle interfacce utente, disposti secondo i vari tipi di layout, prendono il nome di view. Con questo termine intendiamo un qualunque elemento che appare in un’interfaccia utente e che svolge due funzionalità: mostra un aspetto grafico e gestisce eventi relativi all’interazione con l’utente. Esiste, anche, un ulteriore tipo di layout, denominato “ConstraintLayout” (Figura 2.14), introdotto con l’ultima versione di Android Studio (IDE per Android); esso rende possibile progettare ed implementare le interfacce utente in maniera del tutto grafica (“drag and drop”), permettendo di stabilire i vincoli (constraint) tra 2.4 Architettura del sistema MediNav 29 Figura 2.11. Mark Layer di MapView i diversi elementi presenti nell’interfaccia. Questo tipo di layout è quello che verrà usato nell’app MediNav (Figura 2.15 e ne verrà ampliamente approfondita la descrizione nei capitoli a seguire, insieme al resto della progettazione front-end di MediNav. 2.4.2 Descrizione del back-end La componente di back-end si occupa dell’elaborazione dei dati ricevuti dal frontend, attraverso l’interfaccia utente che l’applicazione offre (form, pulsanti, liste, etc). Il back-end è, quindi, quella parte di un’applicazione che, ricevendo i dati, li elabora e restituisce l’output desiderato. Nell’applicazione MediNav il back-end è costituito dalla libreria “MapView” (Sezione 2.3) e da “ZXing” (“zebra crossing”), una libreria open source di Google che permette la scansione e la generazione di QRCode. Di cosa si occupa il back-end di MediNav? Fondamentalmente, tutto ciò che l’applicazione fa è visualizzare le informazioni richieste all’utente tramite appositi menù, pulsanti, punti sulla mappa, scansioni di QRCode. Le planimetrie delle varie aree dell’università Mediterranea sono integrate nell’applicazione come immagini in formato .png e caricate “on demand” ove necessario. Per ogni planimetria è necessario specificare informazioni aggiuntive come l’area a cui essa si riferisce, l’edificio del dipartimento a cui essa si riferisce, piano dell’edificio a cui si riferisce, e tutti i punti di interesse presenti su quella planimetria 30 2 Descrizione del progetto MediNav Figura 2.12. Route Layer di MapView (aule, bagni, uscite di emergenza, etc). Tutte queste informazioni sono salvate come informazioni statiche (in formato “JSON”) e note a priori all’interno del pacchetto dell’applicazione. In informatica, nell’ambito della programmazione web, JSON (acronimo di “JavaScript Object Notation”) è un formato adatto all’interscambio di dati fra applicazioni client-server. È basato sul linguaggio JavaScript Standard ECMA-262 3a edizione dicembre 1999, ma ne è indipendente. Viene usato in AJAX come alternativa a XML/XSLT. Per rappresentare le entità “università”, “edificio” e “piano” sono state create le rispettive classi: University.java, Building.java, Floor.java. Queste entità sono vincolate dall’appartenenza ad una determinata planimetria, e ciò viene rappresentato tramite una classe aggiuntiva denominata Location.java. Le activity principali di MediNav sono MainActivity.java e MapShow.java. La prima fornisce la schermata iniziale all’apertura dell’applicazione; la seconda è quella che si occupa di mostrare sul video le mappe dei luoghi con i punti ed i percorsi. Entrambe le activity hanno una base comune, ovvero CommonActivity.java, che si occupa di inizializzare i dati dal file JSON. La MainActivity (Figura 2.15) presenta due pulsanti, ovvero “explore” e “navigate”, che forniscono due modalità di utilizzo del servizio di navigazione offerto 2.4 Architettura del sistema MediNav 31 Figura 2.13. Tipi di layout Figura 2.14. Esempio di ConstraintLayout dall’app. Cliccando su “explore” è possibile usufruire di una navigazione libera; l’utente viene reindirizzato ad una schermata dove gli viene chiesto di scegliere l’area di interesse ed un eventuale punto di partenza (necessario per caricare una specifica planimetria); eventualmente il punto di partenza può essere ottenuto anche tramite la scansione di un QRCode vicino. La seconda modalità, ovvero quella che avviene tramite il pulsante “navigate”, 32 2 Descrizione del progetto MediNav Figura 2.15. Activity principale di MediNav reindirizza l’utente ad una schermata dove egli deve scegliere l’area di destinazione e, successivamente, il punto di interesse nella suddetta area (segreteria, caffetteria, etc.); infine, viene richiesta la scansione del QRCode più vicino per determinare la posizione iniziale. Fatto ciò, l’applicazione genererà automaticamente il percorso migliore dal punto di partenza al punto di destinazione e lo visualizzerà tracciandolo sulla planimetria. Il percoso migliore viene calcolato tramite l’ausilio del“Floyd Algorithm” integrato nella libreria “MapView”. In questa sezione è stata presentata una breve descrizione di come funziona a grandi linee la componente di back-end di MediNav, senza addentrarsi fino all’analisi del codice Java, in quanto la descrizione dettagliata è oggetto di un’altra tesi, e quindi esula dai nostri obiettivi. Ciò che verrà analizzato nel dettaglio nei successivi capitoli è la componente di front-end e la sua reale implementazione mediante codice. 3 Analisi dei requisiti della componente di front-end In questo capitolo verranno analizzati i requisiti complessivi del sistema da realizzare; tali requisiti sono suddivisi in due categorie differenti, ma allo stesso tempo complementari, ovvero i requisiti funzionali e quelli non funzionali. 3.1 Obiettivi della componente di front-end Lo scopo del front-end (Sezione 2.4.1) è quello di permettere la comunicazione tra l’utente ed il sistema informatico. La comunicazione può avvenire in vari modi, dei quali il più comune e standardizzato è un’interfaccia grafica. Lo sviluppo delle tecnologie mobili, e l’ingresso sul mercato di dispositivi come gli smartphone, hanno permesso di estendere le comuni interfacce grafiche, comprensive di pulsanti, form, menù, etc, con funzionalità avanzate, come, ad esempio, i comandi vocali. Per quanto concerne MediNav, l’approccio alla componente di front-end farà uso di comuni interfacce grafiche, i cui obiettivi sono l’usabilità e la semplicità. L’obiettivo finale che si vuole ottenere con l’usabilità è quello di rendere la tecnologia sottostante invisibile, trasparente all’utilizzatore. L’utente deve potersi concentrare esclusivamente sul compito. L’interfaccia grafica deve essere tale da permettere all’utente di raggiungere i propri scopi nel modo più facile e veloce possibile. 3.1.1 L’interfaccia grafica di Android Riproponendo lo schema di un OS (operating system), si può notare come l’interfaccia utente è formata da interprete dei comandi e interfaccia grafica e comunica con il kernel 1 e con i programmi utente (Figura 3.1), anche questi ultimi posseggono un’interfaccia. In sostanza la UI (user interface) è tutto ciò che vediamo sul display; con essa interagiamo tramite “click”, “tap” e “swipe”. L’interprete dei comandi è, invece, la parte che si occupa di ricevere le richieste e di comunicarle al kernel, aspettando una 1 in informatica, il kernel costituisce il nucleo di un sistema operativo, ovvero il software avente il compito di fornire ai processi in esecuzione sull’elaboratore, un accesso sicuro e controllato all’hardware 34 3 Analisi dei requisiti della componente di front-end Figura 3.1. L’interfaccia utente nell’ambito dell’architettura di un sistema risposta che sarà visualizzata sul display (o su qualsiasi sistema di output) tramite l’interfaccia utente. La UI di Android si basa sui gesti, come i “tap”, gli “swipe”, i “pinch”; ovviamente, tutto questo richiede la presenza di un touchscreen 2 . Per questi motivi si dice che l’interfaccia utente di Android (ma anche degli altri sistemi operativi mobili) si impernia sul concetto di “direct manipulation”, ovvero manipolazione diretta degli oggetti. In Android l’interfaccia utente ha subito numerosi mutamenti, sia per funzionalità che per design. In genere l’OS di Google ha sempre avuto una “Home”, formata da alcune pagine, al cui interno si possono aggiungere icone di applicazioni e “widget”, un “drawer” delle applicazioni, ossia un grande cassetto che contiene tutte le applicazioni installate nel dispositivo, una barra di stato con orologio, simboli di notifica e altri per le reti wireless, una tendina delle notifiche, nonchè altre parti che possono essere diverse in base alla personalizzazione del produttore. Proprio la personalizzazione è un punto forte della UI di Android (Figura 3.2). Attorno a questo OS ci sono numerose interfacce personalizzate dai produttori e da amanti del modding (pratica che consiste nel modificare le funzionalità originali di software e/o dell’hardware per rispecchiare le proprie preferenze), che rendono l’esperienza d’uso più completa e funzionale. Quasi tutti i principali produttori personalizzano in modo più o meno pesante la UI di Android Stock (Figura 3.3) 3 . 3.2 Requisiti non funzionali Preliminare al vero e proprio sviluppo del software, l’analisi dei requisiti definisce le funzionalità che quest’ultimo deve rispettare; il prodotto che ne scaturisce 2 3 in elettronica lo schermo tattile o touch screen è un particolare dispositivo frutto dell’unione di un display/schermo ed un digitalizzatore, che permette all’utente di interagire con una interfaccia grafica mediante le dita o particolari oggetti; uno schermo tattile è allo stesso tempo un dispositivo di ingresso e di uscita per UI stock o di fabbrica si intende quella che si può vedere nei dispositivi rilasciati da Google, come la famiglia dei dispositivi “Nexus” 3.2 Requisiti non funzionali 35 Figura 3.2. Vari tipi di UI Android a confronto Figura 3.3. Esempio di dispositivo Nexus Google con la tipica UI stock è la specifica dei requisiti, documento che fa da guida, organizzata e di immediata comprensione, per le successive fasi di progettazione e implementazione del programma. Il lavoro di analisi può essere suddiviso in due fasi, ovvero l’analisi dei requisiti funzionali e quella dei requisiti non funzionali. Più precisamente, un requisito funzionale specifica cosa farà il sistema, mentre un requisito non funzionale è un vincolo imposto dal sistema (relativo, ad esempio, all’hardware). 3.2.1 La piattaforma hardware Tra i requisiti non funzionali, un aspetto sicuramente molto importante da valutare è la scelta della piattaforma hardware su cui sviluppare il software. Per quanto 36 3 Analisi dei requisiti della componente di front-end riguarda il progetto MediNav, la scelta è ricaduta su Android. Perchè Android? Uno dei principali motivi per cui la scelta è ricaduta sul sistema operativo di Google è la sua diffusione; infatti ,quest’ultimo risulta essere il sistema operativo dominante (al 2015, Android risultava il sistema operativo per dispositivi mobili più diffuso al mondo, con una fetta di mercato attestatasi a quota 82% sul totale, seguito da iOS con il 13,9%). Il vantaggio di scrivere un programma per Android è, quindi, quello di riuscire a catturare il maggior numero possibile di utenti. Un ulteriore vantaggio di Android sta nel fatto che esso è in grado di girare su hardware variegato (di fascia sia alta che bassa) che copre una vasta gamma di prezzi. È più probabile quindi, che l’utente medio possieda un dispositivo Android che, per esempio, un dispositivo Apple. 3.2.2 Linguaggio di programmazione adottato Tra i requisiti tecnici non funzionali, il linguaggio di programmazione ricopre, sicuramente, un ruolo fondamentale, poichè è il mezzo attraverso il quale l’applicazione stessa prende vita. Android offre la possibilità di sviluppare app sia in linguaggio “nativo”, ovvero Java, che in altri linguaggi, attaverso l’utilizzo di un framework 4 . Il vantaggio di usare il linguaggio “nativo” Java sta nella sua grande diffusione;esso è, infatti, un linguaggio multipiattaforma che permette lo sviluppo di software su hardware totalmente diversi attraverso lo stesso linguaggio di programmazione, grazie alla JVM (Java Virtual Machine). Infatti, per supportare un nuovo hardware è necessario semplicemente fornire un’implementazione della JVM per esso e il gioco è fatto. Un programmatore che conosce Java parte già avvantaggiato nello sviluppo di software per Android anche senza avere nessuna esperienza precedente nella programmazione mobile. Tra le alternative a Java, ci sono vari framework, che permettono di sviluppare applicazioni non in linguaggio nativo; tra essi citiamo “Xamarin”, “Ionic” e “Apache Cordova”. Esistono tre categorie fondamentali di applicazioni mobili, ovvero “app native”, “webapp” ed “app ibride”. La differenza principale tra le tre sta nel linguaggio di programmazione adottato. Le app native sono applicazioni scritte e compilate per una specifica piattaforma utilizzando i linguaggi di programmazione e le librerie supportati dal particolare sistema operativo mobile (ad esempio Java per Android). Tra le webapp ricadono le pagine web ottimizzate per dispositivi mobili; esse sfruttano le tecnologie web, in particolare HTML5, JavaScript e CSS3. Le app ibride, invece, sono applicazioni che cercano di sfruttare il meglio delle due categorie precedenti; sono scritte mediante tecnologie web, ma vengono eseguite localmente all’interno di un’applicazione nativa e possono interagire con il dispositivo. 4 in informatica e specificatamente nello sviluppo software, è un’architettura logica di supporto (spesso un’implementazione logica di un particolare design pattern) su cui un software può essere progettato e realizzato, spesso facilitandone lo sviluppo da parte del programmatore 3.2 Requisiti non funzionali 37 Figura 3.4. Il logo di Xamarin Xamarin (Figura 3.4) è una piattaforma basata sul linguaggio C#, pensata per consentire principalmente lo sviluppo di applicazioni per iOS, Android e Windows, che possono essere compilate in modo distinto durante il deploy. Si tratta di un framework abbastanza avanzato, che consente agli sviluppatori l’utilizzo trasparente delle API native nell’app prodotta. Tramite Xamarin.Forms, gli sviluppatori hanno inoltre a disposizione un vasto numero di componenti per la realizzazione dell’interfaccia, in grado di adattarsi facilmente ai sistemi operativi mobili supportati. Xamarin offre la possibilità di eseguire il codice su un framework .NET, potendo simulare l’esecuzione dell’app sia su iOS che su Android. Risulta versatile soprattutto per grandi team, in cui molte persone partecipano allo stesso progetto. L’intera piattaforma può essere utilizzata tramite l’IDE Microsoft Visual Studio, le cui funzionalità sono ben note anche a chi non si occupa di sviluppo mobile. Figura 3.5. Il logo di Ionic Ionic (Figura 3.5) è un framework che consente di sfruttare al meglio le tecnologie web per creare applicazioni mobili con “look and feel” simile a quelle native; in questo ambito esso si rivela tra le soluzioni di maggior successo. Figura 3.6. Apache Cordova Apache Cordova (Figura 3.6) permette ai programmatori di creare applicazioni mobili usando CSS3, HTML5 e Javscript, invece di affidarsi ad API specifiche delle piattaforme Android, iOS o Windows Phone. Il framework incapsula, poi, il codice 38 3 Analisi dei requisiti della componente di front-end CSS, HTML e JavaScript generato all’interno delle predette piattaforme. Le applicazioni generate dal framework non possono nè considerarsi puramente native (il rendering della struttura grafica viene effettuato con visualizzazioni web) nè basate completamente sul web (il programma viene impacchettato come un’applicazione per la distribuzione e ha accesso alle API native dei dispositivi mobili). Per quanto riguarda il progetto MediNav, la scelta è ricaduta su Java, sia per i motivi precedentemente discussi, sia per la necessità di utlizzare, all’interno del progetto, la libreria “MapView” scritta in Java. 3.2.3 Approcci alla progettazione dell’interfaccia Come discusso in precedenza (Sezione 2.4.1), in Android è possibile costruire interfacce grafiche sia tramite codice Java che tramite XML. Scrivere interfacce tramite XML è più semplice ed ha alcuni vantaggi, come la possibilità di definire layout per schermi a risoluzioni diverse, definire layout su base dell’orientamento dello schermo (verticale o orizzontale), nonchè definire layout per lingue differenti lasciando che Android carichi automaticamente ciò che corrisponde alla lingua di sistema impostata dall’utente. Infine, scrivere layout in XML permette su molti IDE di vedere un’anteprima del proprio lavoro. Scrivere interfacce in codice Java, dall’altro lato, ha il vantaggio di avere performance leggermente migliori, permette di gestire gli eventi associati all’interfaccia (ad esempio la pressione di un pulsante da parte di un utente), consente di rendere l’interfaccia dinamica (mostrando, ad esempio, parti dell’interfaccia sulla base di determinate condizioni). Nel progetto MediNav si è utilizzato l’approccio ibrido, ovvero la struttura delle activity è stata fatta in XML e gli eventi associati sono stati gestiti in Java. 3.3 Requisiti funzionali I requisiti funzionali specificano le funzionalità che il sistema dovrà implementare. Per quanto riguarda la componente di front-end di MediNav, i requisiti funzionali sono illustrati nelle prossime sottosezioni. 3.3.1 Navigazione guidata Scopo dell’applicazione è fornire una navigazione guidata all’interno degli edifici dell’Università Mediterranea. Risulta chiaro che il primo requisito funzionale dell’app sarà , proprio, la gestione della navigazione guidata. MediNav dovrà permettere all’utente di impostare una destinazione tramite un menù (facoltà, edificio, punto di interesse), e, tramite la scansione di un QRCode che ne stabilirà la posizione iniziale, dovrà visualizzare un percorso guidato che verrà disegnato sulla mappa. In ogni momento della navigazione, l’utente, qualora non riesca ad orientarsi, ha la possibilità di scansionare il primo QRCode che incontra e l’app mostrerà la sua posizione sulla mappa. 3.3 Requisiti funzionali 3.3.2 39 Navigazione libera Complementarmente alla navigazione guidata, il sistema dovrà offrire la possibilità di esplorare le mappe degli edifici dell’Università Mediterranea. Questa funzionalità dovrà permettere all’utente di selezionare una determinata area e, successivamente, una destinazione (necessaria per caricare la planimetria adeguata). Il sistema dovrà fornire la possibilità di scegliere la destinazione anche mediante scansione di un QRCode. Selezionata l’area e la destinazione, il sistema caricherà la planimetria corrispondente senza, però, disegnare alcun percorso, consentendo, cosı̀, di esplorare la planimetria stessa. 3.3.3 Visualizzazione delle schede informative Ultimo requisito del sistema è quello di poter visualizzare informazioni relative ai punti di interesse. Ogni volta che viene caricata una planimetria, l’utente dovrà essere in grado, mediante “tap” sul punto di interesse, di visualizzare una scheda contente informazioni su di esso. Ciascuna scheda dovrà avere associate un’immagine ed una breve descrizione. 4 Progettazione della componente di front-end In questo capitolo si modellerà la realtà del sistema, iniziando a progettare la componente dati di supporto al front-end dell’applicazione. Ciò avverrà attraverso la presentazione dei diagrammi delle classi e dei file XML a supporto delle activity. Successivamente, attraverso l’uso di mockup, verrà progettato il layout ed, infine, attraverso i workflow verranno descritte le modalità mediante cui è possibile usufruire delle funzionalittà dell’applicativo. 4.1 Progettazione della componente Java In questa sezione verranno presentati i diagrammi delle classi delle activity di MediNav. 4.1.1 Classe MainActivity.java La classe MainActivity.java (Figura 4.1) fa riferimento alla schermata principale dell’applicazione, quella che si presenta alla prima apertura tramite il “tap” sull’icona nel launcher di Android. La funzione onCreate() è una funzione standard di Android di cui è necessario effettuare “l’override” in ogni activity. All’interno di questa funzione è possibile richiamare altre funzioni e svolgere attività che è necessario eseguire al momento in cui l’activity viene creata; inoltre, in essa viene impostato anche il layout relativo all’activity che viene definito nel relativo file XML. La funzione onCreateOptionsMenu() si occupa di impostare un “overflow menù”. Questo menù si presenta in alto a destra nella schermata dell’activity principale e permette di scegliere di visualizzare la pagina relativa all’about. La funzione onOptionsItemSelected() si occupa di gestire gli eventi relativi all’overflow menù (“tap” su una delle opzioni del menù). La funzione onNavigate() gestisce l’evento relativo alla pressione del pulsante “Navigate” che rimanda all’activity gestita dalla classe ChooseFaculty.java. La funzione onExplore() gestisce l’evento relativo alla pressione del pulsante “Explore” che rimanda all’activity ChooseFaculty.java. La differenza rispetto 42 4 Progettazione della componente di front-end Figura 4.1. Diagramma della classe MainActivity.java alla funzione precedente è che, in questo caso, mediante “Intent” (metodo che Android mette a disposizione per scambiare dati tra activity differenti) viene inviata a ChooseFaculty.java una variabile booleana che permette alla suddetta activity di capire se l’utente ha premuto il pulsante “Navigate” o “Explore”. La funzione checkPermissions(), che viene richiamata al lancio dell’activity, serve per richiedere i permessi per utilizzare la fotocamera del dispositivo (dalla Versione 6.0 di Android la gestione dei permessi è stata modificata ed è necessario effettuare all’utente le richieste in modo esplicito). La funzione visualizza sul video un popup che richiede tutti i permessi che lo sviluppatore dell’applicazione necessita per far funzionare l’app. La funzione onRequestPermissionsResult() si occupa di gestire l’evento associato alla funzione checkPermissions(). Essa visualizza sul display un messaggio che informa l’utente che, per far funzionare l’app, è necessario consentire l’uso della fotocamera del dispositivo, qualora l’utente stesso ne abbia negato il consenso. Ogni activity estende la classe CommonActivity.java che presenta al suo interno alcune funzioni comuni da essa richiamate. La funzione initMapManager() effettua operazioni inerenti all’inizializzazione di componenti relative al back-end. La funzione launchMarkCardActivity si occupa di mostrare sul video le informazioni relative ai punti di interesse (segreteria, aula magna, etc) e viene richiamata all’interno dall’activity Mapshow.java alla pressione sull’immagine della planimetria del punto di interesse. La funzione initToolbar() inizializza la “toolbar” di Android. La funzione initiateQRScan() inizializza componenti di back-end che permettono l’utilizzo della funzionalità di scansione dei codici QR. 4.1 Progettazione della componente Java 43 La funzione scanQR() sfrutta la funzione initiateQRScan() per effettuare una scansione di QRCode tramite la fotocamera del dispositivo; essa viene richiamata nell’activity chooseFaculty.java nella modalità “Explore”, e nell’activity ChooseDestination.java. 4.1.2 Classe ChooseFaculty.java La classe ChooseFaculty.java (Figura 4.2) è la classe che si riferisce alla schermata di selezione dell’ateneo di riferimento (Ingegneria, Agraria, etc.); il suo unico scopo è quello di visualizzare una lista di facoltà e dare la possibilità all’utente di sceglierne una. L’activity, in base a quale pulsante (tra “Explore” o “Navigate”) dell’activity principale viene premuto, rimanda, rispettivamente all’activity ChooseStartingPoint.java o ChooseDestination.java. Figura 4.2. Diagramma della classe ChooseFaculty.java La funzione onActivityResult() gestisce l’evento relativo alla pressione dell’icona pulsante che permette di scansionare un QRCode. Il pulsante viene visualizzato all’interno dell’activity solo se si è giunti a ChooseFaculty.java mediante la pressione del pulsante “Explore” dell’activity principale. Alla scansione del QRCode viene avvitata l’activity Mapshow.java che carica la planimetria relativa e posiziona il cursore in corrispondenza del QRCode scansionato. 4.1.3 Classe ChooseStartingPoint.java La classe ChooseStartingPoint.java (Figura 4.3) si occupa di visualizzare sullo schermo una lista di destinazioni possibili per la facoltà che si è scelto preceden- 44 4 Progettazione della componente di front-end temente nell’activity ChooseFaculty.java. Una volta scelto il punto di partenza dalla lista, l’utente viene reindirizzato all’activity MapShow.java ed il cursore viene posizionato in corrispondenza del punto iniziale selezionato. Queste funzionalità sono realizzate nell’ambito del metodo onCreate(). Figura 4.3. Diagramma della classe ChooseStartingPoint.java Il metodo onActivityResult() è del tutto analogo all’omonimo metodo presente nell’acitivty ChooseFaculty.java. 4.1.4 Classe ChooseDestination.java La classe ChooseDestination.java (Figura 4.4) visualizza sullo schermo una lista di destinazioni possibili per l’area prescelta nell’activity ChooseFaculty.java. Alla scelta della destinazione viene chiamata la funzione initiateQRScan() che la classe eredita dalla CommonActivity; tale funzione avvia una scansione di QRCode tramite la quale il sistema ricava la posizione dell’utente. Successivamente viene avviata l’activity MapShow.java che mostrerà sul video una mappa con un percorso che parte dalla posizione iniziale dell’utente e che giunge alla destinazione scelta. L’intera funzionalità viene implementata nell’unico metodo onCreate. 4.1.5 Classe About.java La classe About.java (Figura 4.5) visualizza sullo schermo alcune informazioni relative agli autori del progetto MediNav. Questa activity è chiamata alla selezione, dal menù principale dell’applicazione, dell’opzione “about”. La funzone onCreate() 4.1 Progettazione della componente Java 45 Figura 4.4. Diagramma della classe ChooseDestination.java di questa classe richiama, semplicemente, il relativo file XML che visualizza sul video una “TextView”. Figura 4.5. Diagramma della classe About.java 46 4.1.6 4 Progettazione della componente di front-end Classe MarkCard.java La classe Markcard.java (Figura 4.6) visualizza sullo schermo una scheda informativa relativa ad un punto di interesse. L’activity è composta da un’immagine ed un’area di testo. Figura 4.6. Diagramma della classe MarkCard.java La funzione onCreate() riceve i dati da MapShow.java e li elabora per caricare le informazioni necessarie a visualizzare la scheda informativa. La funzione setDescription() imposta il testo visualizzato nella TextView. Il testo viene impostato da codice Java, anzichè dal file XML, perchè non è statico e l’applicazione, di volta in volta, deve caricare il testo relativo al punto di interesse selezionato. La funzione setImage() imposta l’immagine visualizzata; anche qui si è preferito l’utilizzo di codice Java, anzichè file XML, poichè l’immagine appropriata deve essere caricata di volta in volta in base a punto di interesse di cui si vuole visualizzare la scheda informativa. 4.1.7 Classe MapShow.java La classe Mapshow.java (Figura 4.7) implementa l’activity più importante dell’intera applicazione, ovvero la visualizzazione su video delle planimetrie con i relativi percorsi, se si è in modalità “Navigate”, o le planimetrie senza il layer dei percorsi, se si è in modalità “Explore”. La funzione onCreate() inizializza alcuni parametri necessari per il back-end ed elabora eventuali dati pervenuti dalle activity precedenti, come la posizione attuale e la destinazione desiderata. Se tali dati fossero nulli, l’activity sarebbe in modalità “Explore”; tale modalità permette di visionare le planimetrie liberamente. 4.2 Progettazione dei documenti XML a supporto 47 Figura 4.7. Diagramma della classe MapShow.java La funzione initMapView() inizializza i vari layer dell’immagine della planimetria. Inoltre, in essa viene implementato l’handler degli eventi relativi al “tap” sui punti di interesse, che rimanda alle relative schede informative MarkCard.java. Le rimanenti funzioni gestiscono eventi come il cambio dei piani, l’aggiornamento della posizione sulla mappa, il cambio degli edifici ed il cambio delle facoltà. 4.2 Progettazione dei documenti XML a supporto Come visto nella Sezione 2.4.1, il layout delle varie activity è definibile attraverso dei file XML. 4.2.1 File activity main.xml Il file in questione definisce il layout dell’activity principale. Al suo interno vengono definite una “Toolbar” al cui interno è presente una “TextView”. Sotto alla toolbar vengono definiti una “ImageView”, due “Button” ed un’altra “TextView”. 4.2.2 File activity choose faculty.xml Questo file è relativo al layout dell’activity ChooseFaculty.java. La sua struttura comprende una “Toolbar” con all’interno una “TextView”. Al di sotto è definita un’altra “TextView” ed una “ListView”. Viene definito, inoltre, un “FloatingActionButton”, che rappresenta il pulsante per la scansione del QRCode (visualizzato solo in modalità “Explore”). 48 4 Progettazione della componente di front-end Figura 4.8. Struttura del file activity main.xml 4.2.3 File activity choose destination.xml Il file è relativo al layout dell’activity ChooseDestination.java. Esso definisce una “Toolbar” al cui interno è definita una “TextView”. Sotto la “Toolbar” è definita una “TextView” al di sotto della quale è definita una “ListView”. 4.2.4 File activity choose starting point.xml Questo file XML è relativo al layout dell’activity ChooseStartingPoint.java ed ha una struttura identica a quella di activity choose destination.xml rispetto alla quale definisce anche un “FloatingActionButton”. 4.2.5 File activity mark card.xml Il file è relativo al layout dell’activity MarkCard.java. La sua struttura definisce una “Toolbar” al cui interno è definita una “TextView”. Al di sotto della toolbar è definita una “ImageView” al di sotto della quale è definita, a sua volta, una “ScrollView” con all’interno una “TextView”. 4.2.6 File activity about.xml Questo file definisce il layout relativo ad About.java. La sua struttura è costituita da una “Toolbar” con all’interno una “TextView”. Al di sotto della toolbar è definita una semplice “TextView”. 4.2 Progettazione dei documenti XML a supporto 49 Figura 4.9. Struttura del file activity choose faculty.xml Figura 4.10. Struttura del file activity choose destination.xml 4.2.7 File activity map show.xml Questo file è relativo all’activity MapShow.java e definisce una “Toolbar” al cui interno è definita una “TextView”. Sotto la toolbar è definita una “Mapview” che fa riferimento alla libreria “onlylemi” e visualizza l’immagine costituita dai vari layer (Sezione 2.3). Infine, è definito un “FloatingActionButton” relativo al pulsante che permette di effettuare una scansione dei QRCode. 50 4 Progettazione della componente di front-end Figura 4.11. Struttura del file activity choose starting point.xml 4.3 Progettazione della componente applicativa 4.3.1 Mockup di livello 0 I mockup di livello 0 relativi alle principali activity dell’applicazione vengono mostrati nelle Figura 4.15 - 4.20. In particolare: • nella Figura 4.15 viene mostrato il mockup relativo all’activity principale dell’applicazione, dove è possibile selezionare la modalità di navigazione desiderata. • nella Figura 4.16 viene mostrato il mockup relativo alla scelta di un’area. • nella Figura 4.17 viene presentato il mockup relativo alla scelta di una destinazione in modalità “Navigate”. • nella Figura 4.18 viene presentato il mockup relativo alla scelta di una destinazione in modalità “Explore”. • nella Figura 4.19 viene mostrato il mockup relativo alla visualizzazione di una scheda informativa. • nella Figura 4.20 viene presentato il mockup relativo alla navigazione. 4.3.2 Process Flow In Figura 4.21 viene presentato il process flow relativo all’activity principale. Come si evince dalla figura il flusso ha inizio quando l’utente avvia l’applicazione dal launcher di Android che carica l’activity principale. A questo punto, se l’utente preme il pulsante “Navigate”, viene reindirizzato all’activity “ChooseFaculty” in modalità navigazione. Se invece l’utente preme il pulsante “Explore” viene rimandato alla 4.3 Progettazione della componente applicativa 51 Figura 4.12. Struttura del file activity mark card.xml Figura 4.13. Struttura del file activity about.xml medesima activity di prima in modalità esplorazione. Se l’utente fa “tap” sul menù in altro a destra, viene mostrata l’opzione “About” che, se selezionata, rimanda all’activity “About”. In Figura 4.22 viene mostrato il process flow relativo all’activity che permette la selezione di un’area in modalità navigazione. Il flusso parte quando Android carica la relativa activity; all’utente viene presentato un elenco di aree possibili tra cui scegliere. Alla scelta di una specifica area esso viene reindirizzato all’activity che 52 4 Progettazione della componente di front-end Figura 4.14. Struttura del file activity map show.xml Figura 4.15. Mockup relativo all’activity principale dell’applicazione permette di scegliere una destinazione. In Figura 4.23 viene mostrato il process flow relativo all’activity che permette la scelta di un’area in modalità esplorazione. La differenza rispetto al flusso precedente sta nella presenza di un pulsante che alla pressione reindirizza l’utente all’activity che visualizza la planimetria con punto iniziale ricavato dai dati della scansione del QRCode. In Figura 4.24 viene mostrato il process flow relativo all’activity che permette di 4.3 Progettazione della componente applicativa 53 Figura 4.16. Mockup relativo alla scelta di un’area scegliere una destinazione in modalità navigazione. Il flusso ha inizio quando sullo schermo viene mostrata l’activity; all’utente viene presentata una lista di possibili destinazioni da selezionare. Alla scelta di una destinazione, esso, viene rimandato all’activity che visualizza la planimetria. In Figura 4.25 viene mostrato il process flow relativo all’activity che permette di scegliere una destinazione in modalità esplorazione. Il flusso è uguale a quello precedente, dal quale si differenzia per la presenza di un pulsante per la scansione di QRCode. Alla pressione del pulsante in questione, l’utente viene reindirizzato all’activity di navigazione con punto iniziale ricavato dai dati della scansione del QRCode. In Figura 4.26 viene mostrato il process flow relativo all’activity che visualizza le planimetrie e che permette la navigazione. Il flusso inizia quando l’activity in questione viene visualizzata sul video. Se l’activity è lanciata e nessuna destinazione è stata impostata, la navigazione viene impostata in modalità esplorazione. Se la destinazione è stata impostata la navigazione sarà in modalità navigazione; a questo punto l’applicazione verifica se la destinazione si trova nello stesso edificio o nello stesso piano o nella stessa area. Se l’esito è negativo esso viene invitato a cambiare edifico, piano, area. 54 4 Progettazione della componente di front-end Figura 4.17. Mockup relativo alla scelta di una destinazione in modalità “Navigate” Figura 4.18. Mockup relativo alla scelta di una destinazione in modalità “Explore” 4.3 Progettazione della componente applicativa Figura 4.19. Mockup relativo alla visualizzazione di una scheda informativa Figura 4.20. Mockup relativo alla navigazione 55 56 4 Progettazione della componente di front-end Figura 4.21. Process flow relativo a MainActivity.java Figura 4.22. Process flow relativo a ChooseFaculty.java in modalità “Navigate” 4.3 Progettazione della componente applicativa Figura 4.23. Process flow relativo a ChooseFaculty.java in modalità “Explore” Figura 4.24. Process flow relativo a ChooseDestination.java 57 58 4 Progettazione della componente di front-end Figura 4.25. Process flow relativo a ChooseStartingPoint.java Figura 4.26. Process flow relativo a MapShow.java 5 Implementazione della componente di front-end In questo capitolo verrà fatta un’analisi dettagliata delle classi e di alcuni file XML che sono stati trattati in fase di progettazione. A fine analisi, mediante immagini, verrà stilato un piccolo manuale utente che illustrerà le funzionalità principali dell’applicazione. 5.1 Implementazione della componente Java In questa sezione verranno analizzati in dettaglio le implementazioni delle classi che realizzano le activity più complesse dell’applicazione. 5.1.1 Implementazione della classe MainActivity.java In questa sezione illustriamo i principali metodi della classe MainActivity.java. Il metodo onCreate (Listato 5.1), comune ad ogni activity di Android, viene chiamato dal sistema allorquando una determinata activity viene visualizzata sullo schermo per la prima volta. Questo metodo fa parte di una serie di metodi definiti nella superclasse Activity della libreria Android che gestiscono il ciclo di vita (Figura 5.1) di ogni activity generata dal sistema. La prima funzione del metodo è quella di impostare il layout della View (Sezione 2.4.1) corrente. Ciò viene fatto invocando il metodo setContentView che riceve in ingresso un parametro (R.layout.activity main) che indica il file di layout associato all’activity. Per capire come il sistema faccia il mapping delle risorse nei file Java, presentiamo una breve descrizione della struttura dei file in un tipico progetto Android. • • • • La cartella src contiene i file sorgente (.java o di altri linguaggi). La cartella gen contiene i sorgenti generati automaticamente. In particolare, R.java serve per poter richiamare nel codice Java tutte le risorse memorizzate nella cartella res. La cartella assets raggruppa file arbitrari, aggiunti al file .apk (pacchetto generato dalla compilazione di un progetto Android). La cartella bin contiene il risultato della compilazione (risorse, .dex, .apk, etc.). 60 5 Implementazione della componente di front-end Figura 5.1. Ciclo di vita di un’activity • La cartella res contiene i dati esterni all’applicazione Android; essa è suddivisa in ulteriori sotto cartelle ovvero: – anim per le animazioni. – color per i colori. – drawable per le immagini utilizzate dal programma. – layout per i layout usati dell’app. – menù per i menù usati dall’applicazione. – raw per qualsiasi tipo di file e rappresenta un’alternativa ad assets. – values per i dati (stringhe, interi, array, etc.) che saranno utilizzati nel programma. • XML per i file XML arbitrari (incluse le configurazioni). • la cartella libs contiene le librerie native custom. • il file AndroidManifest.xml contiene i metadati sull’applicazione. Il metodo initToolbar, definito nella classe CommonActivity.java (in questo progetto ogni activity eredita da questa classe), inizializza la toolbar dell’applicazione, richiamando il relativo layout allo stesso modo del metodo setContentView. 1 2 3 4 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initToolbar(); 5.1 Implementazione della componente Java 5 6 7 61 checkPermissions(); initMapManager(); } Listato 5.1. Definizione del metodo onCreate della classe MainActivity.java Il metodo onCreateOptionsMenu (Listato 5.2) crea un “overflow menu”. Si tratta di un menù predefinito di Android che posiziona, in alto a destra, un’icona costituita da 3 puntini alla cui pressione viene visualizzato un menù a tendina. Il metodo richiama il file di layout XML con id over flow menu. 1 2 3 4 public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.over_flow_menu, menu); return true; } Listato 5.2. Definizione MainActivity.java del metodo onCreateOptionsMenu della classe Il metodo onOptionsItemSelected (Listato 5.3) definisce il gestore degli eventi associato all’overflow menu. Tramite questo metodo è possibile stabilire cosa deve fare l’applicazione alla selezione di un determinato item del menù. Il metodo definisce un unico caso, ovvero, la selezione dell’opzione “About” che fa partire l’activity relativa ad esso. 1 2 3 4 5 6 7 8 9 public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_about: Intent intent = new Intent(this, About.class); startActivity(intent); default: return super.onOptionsItemSelected(item); } } Listato 5.3. Definizione MainActivity.java del metodo onOptionsItemSelected della classe Il metodo onNavigate (Listato 5.4) definisce cosa succede alla pressione del pulsante “Navigate”, ovvero apre l’activity ChooseFaculty. 1 2 3 4 public void onNavigate(View view) { Intent intent = new Intent(this, ChooseFaculty.class); startActivity(intent); } Listato 5.4. Definizione del metodo onNavigate della classe MainActivity.java Analogamente al metodo precedente, il metodo onExplore (Listato 5.5) definisce cosa farà l’applicazione alla pressione del pulsante “Explore”. Rispetto a prima il metodo lancia l’activity ChooseFaculty passando un parametro booleano MODE. 1 2 3 4 5 public void onExplore(View view) { Intent intent = new Intent(this, ChooseFaculty.class); intent.putExtra("MODE",true); startActivity(intent); } Listato 5.5. Definizione del metodo onExplore della classe MainActivity.java 62 5 Implementazione della componente di front-end Il metodo checkPermissions (Listato 5.6), richiamato nel metodo onCreate, fa si che l’applicazione richieda il permesso di utilizzare la fotocamera del dispositivo. 1 2 3 4 5 6 7 8 public void checkPermissions(){ if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1); } } Listato 5.6. Definizione del metodo checkPermissions della classe MainActivity.java L’ultimo metodo della classe, onRequestPermissionsResult (Listato 5.7) gestisce i due possibili eventi associati alla richiesta del permesso di utilizzare la fotocamera del dispositivo. Come si è visto in precedenza, sono possibili due casi. Nel primo caso l’utente acconsente alla richiesta del permesso e l’applicazione procede correttamente. Nel secondo caso viene mostrato un popup che informa l’utente che l’applicativo necessita del permesso per poter funzionare. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case 1: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { return; } else { AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(this); dlgBuilder.setTitle(R.string.permission_error_title); dlgBuilder.setMessage(R.string.permission_error); dlgBuilder.setCancelable(false); dlgBuilder.setPositiveButton(R.string.ok,new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog,int id) { System.exit(0); } }); AlertDialog alertDialog = dlgBuilder.create(); alertDialog.show(); } return; } } } Listato 5.7. Definizione del metodo onRequestPermissionsResult della classe MainActivity.java 5.1.2 Implementazione della classe ChooseFaculty.java In questa sezione illustreremo i principali metodi della classe ChooseFaculty.java. Il metodo onCreate(Listato 5.8) inizializza la toolbar e carica il file di layout relativo activity choose faculty dalla cartella layout presente dentro la cartella res. Successivamente viene effettuato il controllo sulla variabile booleana isExplore, che permette di stabilire se l’utente nell’activity precedente ha premuto il pulsante di navigazione o di esplorazione. Se la varibile risulta false e l’utente, quindi, ha premuto il pulsante “Navigate”, il pulsante di scansione dei QRCode viene reso invisibile; altrimenti, esso resta visibile. La funzione principale del metodo è quella di stampare una lista di aree che l’utente può selezionare sullo schermo. La scelta è ricaduta sull’utilizzo di una “ListView”. Le facoltà da stampare sul video vengono ricavate dalla funzione getUniList, definita nella classe MapManager ed inizializzata nella classe 5.1 Implementazione della componente Java 63 CommonActivity, inerente al back-end. Essa ricava i dati dal database, costituito da un file in formato JSON, e restituisce in output una lista di University. Dalla List vengono ricavati i nomi di ogni facoltà e vengono salvati in un array di tipo String. Questo perchè, per visualizzare una “ListView”, è necessario usare un ArrayAdapter in questo caso di tipo String. Il costruttore della classe ArrayAdapter, si aspetta in ingresso l’id del layout relativo alla definizione della lista “ListView” (list view list), il file relativo al layout dei singoli item che verranno stampati all’interno della lista (row) e l’array di String da stampare. Successivamente, alla ListView viene associato un “handler”, che gestisce l’evento legato alla pressione di un’opzione della lista. L’handler è implementato mediante il metodo onItemClick che non fa altro che reindirizzare l’utente all’activity successiva passando l’area selezionata. Se la variabile booleana isExplore è impostata a true l’activity avviata sarà ChooseStartingPoint, altrimenti, verrà avviata l’activityChooseDestination. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_choose_faculty); initToolbar(); isExplore = false; isExplore = getIntent().getBooleanExtra("MODE",isExplore); if(!isExplore) { Log.d("Mode","Explore mode not active!"); //Hide FAB android.support.design.widget.FloatingActionButton fab = (android.support.design.widget.FloatingActionButton) findViewById(R.id.qrScanFAB); fab.setVisibility(View.GONE); } final ListView listView = (ListView) findViewById(R.id.facultyList); List<University> uniList = mm.getUniList(); String[] uniArray = new String[uniList.size()]; for (int i = 0; i < uniList.size(); i++) { uniArray[i] = uniList.get(i).getName(); } ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.row, R.id.listview_list, uniArray); listView.setAdapter(arrayAdapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, final int position, long id) { Intent universityChosenIntent = new Intent(ChooseFaculty.this, (isExplore) ? ChooseStartingPoint.class : ChooseDestination.class); universityChosenIntent.putExtra("idUniversityChosen", position); startActivity(universityChosenIntent); } }); } Listato 5.8. Definizione del metodo onCreate della classe ChooseFaculty.java Il secondo ed ultimo metodo della classe, denominato onActivityResult, gestisce l’evento associato all’avvenuta scansione di un QRCode. Infatti, se l’utente si trova in questa activity in modalità “Explore”, ed è attivo il pulsante di scansione dei QRCode e, infine, è stata portata a termine con successo un’eventuale scansione, viene lanciata l’activity MapShow a cui verrà passato il parametro CURRENT POSITION che stabilisce univocamente la posizione del QRCode, e, di conseguenza, la posizione dell’utente all’interno dell’Università Mediterranea. 1 2 3 4 5 public void onActivityResult(int requestCode, int resultCode, Intent intent) { IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); if (scanResult != null) { String re = scanResult.getContents(); 64 5 Implementazione della componente di front-end 6 7 8 9 10 11 12 13 14 15 16 if(re != null) { Log.d("Scanned code:", re); Intent intent2 = new Intent(this, MapShow.class); intent2.putExtra("CURRENT_POSITION", re); startActivity(intent2); } } else { //Show error Log.d("Error scanning code!",""); } } Listato 5.9. Definizione del metodo onActivityResult della classe ChooseFaculty.java 5.1.3 Implementazione della classe ChooseDestination.java Questa sezione è dedicata ai principali metodi della classe ChooseDestination.java. Il metodo onCreate di questa classe (Listato 5.10) svolge un lavoro analogo a quello della classe precedente, con la differenza che, adesso, viene stampata una “ListView” contenente le destinazioni possibili per l’area precedentemente scelta nell’activity ChooseFaculty. I dati vengono ricavati alla stessa maniera della classe ChooseFaculty tramite la classe MapManager che si interfaccia al database in formato JSON. Le possibili destinazioni sono stampate sullo schermo mediante una “ListView” alla quale è associato un gestore di eventi che chiama la funzione initiateQRScan, per iniziare una scansione di QRCode. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_choose_destination); initToolbar(); final ListView listView = (ListView) findViewById(R.id.destinationList); Intent universityChosenIntent = getIntent(); int idUniversityChosen = universityChosenIntent.getIntExtra("idUniversityChosen", 0); final List<Location> locationList = mm.getLocations(idUniversityChosen); String[] destArray = new String[locationList.size()]; for(int i = 0; i<locationList.size(); i++){ Location location = locationList.get(i); destArray[i] = location.getName(); } ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.row, R.id.listview_list_2, destArray); listView.setAdapter(arrayAdapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, final int position, long id) { locationChosen = locationList.get(position).jsonSerialize(); initiateQRScan(); } }); } Listato 5.10. Definizione del metodo onCreate della classe ChooseDestination.java Il metodo onActivityResult (Listato 5.11), analogo all’omonimo metodo della classe precedente, gestisce l’evento associato all’avvenuta scansione di un QRCode. Dalla scansione viene ricavato il parametro CURRENT POSITION. Successivamente viene avviata l’activity MapShow a cui vengono passati i parametri CURRENT POSITION e TARGET POSITION (quest’ultimo ricavato mediante il gestore degli eventi della “ListView”). 5.1 Implementazione della componente Java 65 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public void onActivityResult(int requestCode, int resultCode, Intent intent) { IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); if (scanResult != null) { String re = scanResult.getContents(); if(re != null) { Log.d("Scanned code:", re); Intent intent2 = new Intent(this, MapShow.class); intent2.putExtra("CURRENT_POSITION", re); intent2.putExtra("TARGET_POSITION", locationChosen); startActivity(intent2); } } else { //Show error Log.d("Error scanning code!",""); } } } Listato 5.11. Definizione ChooseDestination.java 5.1.4 del metodo onActivityResult della classe Implementazione della classe MarkCard.java In questa sezione illustreremo i principali metodi della classe MarkCard.java. Il metodo onCreate di questa classe (Listato 5.12) imposta il file di layout relativo e controlla se i due parametri CARD IMAGE e CARD DESC, che vengono ricavati tramite Intent dall’activity MapShow, sono nulli o meno. Qualora i due parametri non fossero nulli vengono chiamate le due funzioni setImage e setDescription. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mark_card); initToolbar(); Intent callerIntent = getIntent(); String imagePath = callerIntent.getStringExtra("CARD_IMAGE"); String desc = callerIntent.getStringExtra("CARD_DESC"); if(imagePath != null) { Log.d("MarkCard","Setting image path "+imagePath); setImage(imagePath); } if(desc != null) { Log.d("MarkCard","Setting description "+desc); setDescription(desc); } } Listato 5.12. Definizione del metodo onCreate della classe MarkCard.java Il metodo setDescription (Listato 5.13) imposta il testo visualizzato all’interno della “TextView”. 1 2 3 4 private void setDescription(String desc){ TextView descText = (TextView)findViewById(R.id.cardDesc); descText.setText(desc); } Listato 5.13. Definizione del metodo setDescription della classe MarkCard.java Analogamente il metodo setImage (Listato 5.14) imposta l’immagine visualizzata all’interno della “ImageView”. 1 2 3 4 private void setImage(String path){ try{ Drawable d = Drawable.createFromStream(getAssets().open(path), null); ImageView image = (ImageView)findViewById(R.id.cardImage); 66 5 Implementazione della componente di front-end 5 6 7 8 9 10 image.setImageDrawable(d); } catch(IOException ex){ Log.e("Load image","Failed to load image!"); ex.printStackTrace(); } } Listato 5.14. Definizione del metodo setImage 5.1.5 Implementazione della classe MapShow.java In questa sezione illustreremo i principali metodi della classe MapShow.java. Il metodo onCreate (Listato 5.15) inizializza alcune componenti della libreria onlylemi chiamando initMapView. Successivamente viene effettuata la verifica della presenza dei parametri TARGET POSITION e CURRENT POSITION. Se i due parametri dovessero essere nulli, l’activity sarà in modalità “Explore”. Ricavati i parametri necessari, vengono chiamate le funzioni LoadFloor, che carica la planimetria relativa alla posizione dell’utente (in modalità “esplorazione” la posizione viene ricavata tramite selezione dalla lista o scansione di QRCode, mentre in modalità “navigazione” la posizione iniziale è sempre ricavata tramite scansione di QRCode). Una volta fatto ciò, viene chiamato il metodo UpdatePosition, che aggiorna la posizione sulla mappa visualizzata (se si è in modalità “navigazione” controlla anche che l’utente sia nell’edificio, nel piano o nell’area corretta). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map_show); initToolbar(); curPoint = new PointF(0,0);//Current position in floor is initialized to 0,0 InitMapView();//Initialize position - independent attributes //Grab user-choosen destination from caller intent String destTarget = getIntent().getStringExtra("TARGET_POSITION"); if(destTarget != null){ Log.d("Received Destination",destTarget); curDestination = new Location(destTarget); } //Grab starting point from caller intent (User has to scan a QRCode before navigation starts) String qrData = getIntent().getStringExtra("CURRENT_POSITION"); if(qrData != null){ Log.d("Received Position",qrData); curPosition = new Location(qrData); //Load current floor map LoadFloor(curPosition); UpdatePosition(curPosition); } } Listato 5.15. Definizione del metodo onCreate della classe MapShow.java Il metodo initMapView (Listato 5.16) effettua operazioni di inizializzazione della libreria “MapView” impostando i vari layer che andranno costituiranno l’immagine finale della mappa. Inoltre, per quanto riguarda il layer dei “mark” (icone associate alle destinazioni sulla mappa), viene definito un gestore di eventi di click, denominato setMarkIsClickListener, all’interno del quale viene definito il metodo markIsClick, che gestisce il click su un punto di destinazione. Il metodo controlla dapprima se il “mark” che l’utente ha premuto è di tipo “EndPoint” (per realizzare la navigazione si è sfruttato un algoritmo basato su grafi che richiede la presenza di punti ausiliari che non corrispondono a punti di interesse sulla mappa); in caso affermativo, alla pressione del mark, viene invocata l’activity MarkCard, mediante il metodo LauncMarkCard definito nella classe 5.2 Implementazione della componente XML 67 CommonActivity. Al metodo viene passato un oggetto di tipo Mark dal quale esso è in grado di estrarre la “TextView” e la “ImageView” da visualizzare nell’activity corrispondente. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public void initMapView(){ mapView = (MapView) findViewById(R.id.mapview); mapView.setScaleAndRotateTogether(true);//Allow pinch-and-rotate gestures //Create Location Layer locationLayer = new LocationLayer(mapView); locationLayer.setOpenCompass(false); mapView.addLayer(locationLayer); //Create Route Layer routeLayer = new RouteLayer(mapView); mapView.addLayer(routeLayer); //Create Mark Layer markLayer = new CustomMarkLayer(mapView); //Set Mark click handler, this is called whenever the user taps on a mark. //We are not using this feature for now. markLayer.setMarkIsClickListener(new MarkLayer.MarkIsClickListener() { @Override public void markIsClick(int num) { //num is the Mark ID IN CURRENT FLOOR! Mark clickedMark = curFloor.getMark(num); Log.d("Mark clicked",String.format("Clicked mark with id %d name %s type %s", num,clickedMark.name, clickedMark.type.toString())); if(clickedMark.type == Mark.Types.Endpoint) LaunchMarkCard(clickedMark); return; } }); mapView.addLayer(markLayer); } Listato 5.16. Definizione del metodo initMapView della classe MapShow.java Gli altri metodi di questa classe contengono metodi che fanno uso estensivo delle funzionalità della libreria “MapView” e non sono di interesse nell’ambito della presente tesi. 5.2 Implementazione della componente XML In questa sezione verranno analizzati alcuni file di layout di supporto alle activity principali dell’applicazione; inoltre, verrà mostrato, attraverso l’uso di immagini, come Android offre la possibilità, attravero l’IDE “Android Studio”, di costruire i layout per via grafica. 5.2.1 Implementazione del file activity main.xml In questa sezione illustreremo le principali caratteristiche del file di layout relativo alla principale activity dell’applicazione. Il file in questione, denominato activity main.xml (Listato 5.17), è responsabile del layout della MainActivity. Il primo tag XML definisce il tipo di layout che verrà utilizzato nell’activity (Sezione 2.4.1). Ogni elemento del file corrisponde ad un determinato oggetto grafico che verrà visualizzato sullo schermo. L’IDE “Android Studio” permette di progettare il tutto interamente mediante due modi: “Text” e “Design”. Il primo modo prevede la scrittura dei tag XML completamente a mano, mentre il secondo usa una tecnica grafica di tipo “drag and drop”. La progettazione del file è stata effettuata per la maggior parte col metodo visivo. L’unico lavoro svolto manualmente ha riguardato l’impostazione degli “id” univoci degli elementi e la definizione dei metodi che gestiscono gli eventi. Per i due Button, 68 5 Implementazione della componente di front-end infatti, sono state definite due funzioni onClick; per il pulsante “Navigate” è stato definito onNavigate() e per il pulsante “Explore” è stato definito onExplore(). onClick() stabilisce quale sarà il metodo del corrispettivo file Java che gestirà l’evento associato al determinato elemento. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:fitsSystemWindows="true" tools:context="it.unirc.barbiana20.medinav.MainActivity"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="64dp" android:background="@color/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintRight_toRightOf="parent"> <TextView android:text="@string/app_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/toolbar_title" android:gravity="start" android:textSize="24sp" android:textStyle="normal|bold" android:textColor="#fff" /> </android.support.v7.widget.Toolbar> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/logo_unirc" android:scaleType="centerInside" android:id="@+id/imageView" android:cropToPadding="false" app:layout_constraintBottom_toTopOf="@+id/welcome_text" android:layout_marginBottom="8dp" android:layout_marginTop="8dp" app:layout_constraintTop_toBottomOf="@+id/toolbar" android:layout_marginStart="16dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" /> <Button android:backgroundTint="@color/colorPrimary" android:text="@string/button_explore" android:textColor="#ffffff" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/explore_btn" android:onClick="onExplore" app:layout_constraintRight_toLeftOf="@+id/navigate_btn" android:layout_marginEnd="8dp" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="16dp" /> <Button android:backgroundTint="@color/colorPrimary" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/navigate_btn" android:text="@string/button_navigate" android:textColor="#ffffff" android:onClick="onNavigate" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="16dp" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" /> <TextView android:text="@string/welcome_line" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/welcome_text" 5.2 Implementazione della componente XML 85 86 87 88 89 90 91 92 69 app:layout_constraintBottom_toTopOf="@+id/explore_btn" android:layout_marginBottom="8dp" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginStart="16dp" app:layout_constraintLeft_toLeftOf="parent" /> </android.support.constraint.ConstraintLayout> Listato 5.17. Struttura del file activity main.xml Figura 5.2. Esempio di progettazione visiva di activity main.xml Nell’immagine in Figura 5.2 è possibile vedere un esempio di progettazione visiva dell’activity. Dall’immagine risulta che ogni elemento è ancorato ad un altro o all’elemento che lo contiene. Questo metodo, chiamato “ConstraintLayout” permette di ancorare i bordi di ogni elemento ai bordi di altri elementi presenti nella “View”. Questo processo può essere effettuato a mano, definendo i parametri app:layout constraintRight toRightOf, o per via grafica, trascinando le ancore rispetto a ciascun elemento. 5.2.2 Implementazione del file activity choose faculty.xml In questa sezione illustreremo le principali caratteristiche del file di layout relativo alla scelta di un’area. 70 5 Implementazione della componente di front-end Il file activity choose faculty (Listato 5.18) è relativo al layout dell’activity ChooseFaculty. Il layout è composto dalla “Toolbar” con all’interno una “TextView” che visualizza il nome dell’applicazione. Le stringhe visualizzate all’interno delle “TextView” sono indicizzabili mediante @string/nome stringa. Il codice fa riferimento al file strings.xml contenuto nella cartella values all’interno della cartella dei file di risorse. È possibile definire più file di questo tipo che contengono stringhe pensate per lingue differenti, permettendo, cosı̀, allo sviluppatore di supportare lingue diverse, richiamando nei file XML le stringhe una volta sola. Al di sotto del titolo dell’applicazione troviamo un’ulteriore “TextView” che fa da titolo dell’activity. Sotto è definita una “ListView” che mostrerà sullo schermo un “item” per ogni area generata dal corrispettivo file Java. La struttura dei file delle risorse di Android impone di gestire a parte il file di layout (row.xml) delle singole righe della “ListView”. Nel file activity choose faculty.xml è definito anche un “FloatingActionButton” che altro non è che un pulsante fluttuante. Ad esso è associata un’icona tramite android:src=@drawable/qrcode scan, un comando XML che richiama un file da usare come icona, contenuto nella cartella drawable della cartella dei file delle risorse dell’applicazione. Al pulsante è associato un gestore dell’evento di pressione su di esso android:onClick=scanQR. Nel relativo file Java la funzione che gestirà tale evento sarà ScanQR(). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_choose_position" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="it.unirc.barbiana20.medinav.ChooseFaculty" android:fitsSystemWindows="true"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="56dp" android:background="@color/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintRight_toRightOf="parent"> <TextView android:text="@string/app_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/toolbar_title" android:gravity="start" android:textSize="24sp" android:textStyle="normal|bold" android:textColor="#fff" /> </android.support.v7.widget.Toolbar> <TextView android:text="@string/choose_faculty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/chooseFacultyText" android:layout_marginTop="16dp" app:layout_constraintTop_toBottomOf="@+id/toolbar" android:layout_marginStart="16dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" /> 5.3 Manuale utente 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 71 <android.support.design.widget.FloatingActionButton android:src="@drawable/qrcode_scan" app:fabSize="normal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:elevation="2dp" app:backgroundTint="@color/colorPrimary" android:tint="@color/darkAccent" android:onClick="scanQR" android:id="@+id/qrScanFAB" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginEnd="16dp" /> <ListView android:id="@+id/facultyList" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginTop="8dp" app:layout_constraintTop_toBottomOf="@+id/chooseFacultyText" android:layout_marginStart="16dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="16dp" android:divider="@android:drawable/divider_horizontal_bright" /> </android.support.constraint.ConstraintLayout> Listato 5.18. File activity choose faculty.xml All’interno del file row.xml (Listato 5.19) sono definite due “TextView”. La prima specifica lo stile degli item della lista a cui fa riferimento il file ChooseFaculty.java, mentre la seconda gestisce gli item delle liste dei file ChooseDestination.java e ChooseStartingPoint.java. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:weightSum="1"> <TextView android:id="@+id/listview_list" android:layout_width="match_parent" android:layout_height="match_parent" android:text="" android:padding="10dip" android:textSize="22dip" android:layout_weight="0.10" /> <TextView android:id="@+id/listview_list_2" android:layout_width="match_parent" android:layout_height="match_parent" android:text="" android:padding="10dip" android:textSize="22dip" android:layout_weight="0.10" /> </LinearLayout> Listato 5.19. File row.xml Nella Figura 5.3 è possibile vedere un esempio di progettazione visiva del layout dell’activty activity choose faculty.xml. 5.3 Manuale utente L’utente che vuole orientarsi all’interno dell’Università Mediterranea, una volta scaricata, installata e mandata in esecuzione l’applicazione, si ritrova nella schermata principale. Qualora l’applicazione venga avviata per la prima volta, essa richiederà i permessi per l’utlizzo della fotocamera (Figura 5.4). 72 5 Implementazione della componente di front-end Figura 5.3. Esempio di progettazione visiva di activity choose faculty.xml Nel caso il permesso fosse negato, l’applicazione visualizza un messaggio che informa l’utente che, per funzionare, necessita di tale permesso; in tale evenienza l’app viene chiusa (Figura 5.5). Se l’utente acconsente all’utilizzo della fotocamera, viene portato all’activity principale (Figura 5.6). Qui può premere i due pulsanti per scegliere il tipo di navigazione desiderato ed eventualmente, cliccare sul menù in alto a destra per visionare la schermata “About”, che contiene varie informazioni circa gli autori del progetto, le licenze di terze parti, i collaboratori e i ringraziamenti. Premendo il pulsante “Explore”, l’utente viene reindirizzato alla schermata di scelta di un’area (Figura 5.7). A seguito di ciò viene visualizzata sullo schermo una lista di aree. Cliccando sull’icona con l’immagine del QRCode è possibile scansionarne uno ed essere reindirizzati immediatamente all’activity che mostra la planimetria corrispondente alla posizione del QRCode scansionato. Se l’utente ha scelto manualmente un’area dalla schermata precedente, egli viene reindirizzato ad una schermata che stampa una lista di destinazioni possibili per quella determinata area (Figura 5.8). Qualora l’utente prema il pulsante di scansione del QRCode, viene avviata l’activity che mostra la planimetria corrispondente alla posizione del QRCode scansionato. Se l’utente, nella schermata precedente, ha selezionato manualmente una destinazione dalla lista, viene caricata la planimetria che contiene la destinazione selezionata (Figura 5.9). A questo punto egli può esplorare liberamente la mappa 5.3 Manuale utente 73 Figura 5.4. Schermata di primo avvio dell’applicazione Figura 5.5. Messaggio che viene mostrato all’utente che nega il permesso di usare la fotocamera cliccando sui punti per vederne la corrispondente descrizione. L’utente che, ad esempio, clicca su “Laboratorio Barbiana 2.0” viene reindirizzato alla schermata della scheda informativa corrispondente (Figura 5.10). Se, nella schermata principale, l’utente dovesse premere il pulsante “Navigate” sarebbe reindirizzato alle stesse schermate di scelta di un’area e scelta di una destinazione. La differenza è nell’assenza del pulsante di scansione del QRCode. Nella schermata di scelta della destinazione, a scelta avvenuta viene automaticamente 74 5 Implementazione della componente di front-end Figura 5.6. Schermata principale dell’applicazione Figura 5.7. Schermata relativa alla scelta di un’area in modalità “Explore” richiesta la scansione di un QRCode. Successivamente viene caricata la planimetria corrispondente e, su di essa, viene tracciato un percorso che va dalla posizione iniziale dell’utente, ottenuta tramite scansione del QRCode, fino alla destinazione, scelta nella schermata apposita (Figura 5.11). 5.3 Manuale utente 75 Figura 5.8. Schermata relativa alla scelta di una destinazione in modalità “Explore” Figura 5.9. Schermata relativa alla navigazione in modalità “Explore” 76 5 Implementazione della componente di front-end Figura 5.10. Schermata relativa ad una scheda informativa Figura 5.11. Schermata relativa alla navigazione in modalità “Navigate” 6 Discussione critica in merito al sistema realizzato In questo capitolo verranno analizzati i punti di forza e di debolezza del sistema. Verranno valutate le soluzioni offerte dai competitor che verranno, successivamente, confrontate con le scelte adottate in questo progetto. 6.1 Analisi SWOT L’analisi SWOT (Figura 6.1) è uno strumento di pianificazione strategica molto diffuso che permette di valutare i punti di forza e di debolezza e le eventuali opportunità e minacce di un sistema. Figura 6.1. Analisi SWOT 6.1.1 Punti di forza In questa parte dell’analisi prendiamo in considerazione tutto ciò che costituisce un reale vantaggio per la nostra applicazione. 78 6 Discussione critica in merito al sistema realizzato Uno dei principali punti di forza di cui il il nostro sistema dispone è la semplicità di utilizzo. L’interfaccia, minimale, consente l’utilizzo dell’applicazione anche da parte di utenza con scarsa dimestichezza del software, riducendo al minimo il rischio di errore. L’applicazione, realizzata per Android, è stata implementata in linguaggio Java, che consente un alto livello di riusabilità del codice. Inoltre, Android permette di implementare le interfacce grafiche mediante file XML, consentendo, cosı̀, di separare la progettazione del back-end da quella del front-end. Il vantaggio di questa configurazione è la possibilità di poter ridisegnare totalmente l’intera interfaccia grafica, senza alterare le funzionalità di back-end, e viceversa. Il sistema di navigazione, basato sui QRCode, permette facilmente di aggiungere nuove aree senza sforzi aggiuntivi. Per aggiungere nuove zone basta, infatti, caricare le immagini relative alle nuove planimetrie e generare i relativi QRCode. Ciò permette di usare lo stesso sistema anche in atenei diversi dall’Università Mediterranea. Rispetto ad altre applicazioni di navigazione indoor, questo sistema non necessita di infrastrutture esterne, abbattendo, cosı̀, del tutto le spese per l’adozione dello stesso. 6.1.2 Punti di debolezza Nella parte in cui si analizzano i punti di debolezza prenderemo in considerazione tutto ciò che costituisce un problema al conseguimento di un determinato risultato, considerando, anche, i possibili freni ad un eventuale evoluzione del progetto. L’utilizzo dei QRCode come infrastruttura di supporto alla navigazione del sistema ha costitutito un vantaggio dal punto di vista delle spese e della complessità. Allo stesso tempo, ciò risulta essere un punto di debolezza del sistema, poichè, in questo modo, la navigazione non è in tempo reale. Il sistema, infatti, riconosce le posizioni dell’utente basandosi unicamente sulle scansioni di questi codici. Qualora l’utente che stia cercando di orientarsi non scansioni continuamente i QRCode, o peggio, non riesca ad individuarli, non riuscirebbe ad orientarsi correttamente. La scelta di svluppare il sistema in codice nativo per Android, ovvero Java, pone alcune limitazioni. Il codice nativo, infatti, si appoggia alle librerie proprie del sistema operativo Android, rendendo difficile un eventuale porting su altre piattaforme senza un refactoring completo del codice. 6.1.3 Opportunità L’analisi SWOT si rivolge, adesso, verso l’esterno. È necessario considerare tutti i fattori esterni al prodotto, quali l’ambiente, la concorrenza, i clienti, etc. Con il termine “opportunità” si intendono tutti quegli elementi esterni che vanno a vantaggio dell’oggetto in analisi. Una prima opportunità viene fornita dalla scelta di sviluppare l’applicazione per Android. Questo sistema operativo infatti, permette di avere un gran numero di dispositivi pronti ad implementare il software in esame, consentendo di scegliere quello al momento più conveniente, e di sostituire, nel tempo, i modelli antiquati o difettosi con delle versioni più moderne senza dover apportare modifiche al sistema. 6.2 Soluzioni alternative 79 Il software è stato progettato come sistema di navigazione indoor per l’Università Mediterranea, ma la sua semplice implementazione ne consente facilmente l’utilizzo in qualsiasi altro ateneo o luogo che richieda una navigazione interna. 6.1.4 Minacce Le minacce sono i rischi generati da particolari condizioni del contesto in cui si opera, sempre in riferimento ad ambiente, concorrenza, clienti, etc. Per quanto riguarda il sistema in esame, una minaccia è costituita dall’uso dei QRCode. Essi vengono generati, stampati, e posizionati nei punti di interesse e sono facilmente suscettibili al deterioramento nel tempo. Inoltre, essendo posizionati in luoghi pubblici, sono a rischio di eventuali atti vandalici. 6.2 Soluzioni alternative In questa sezione si procede prendendo in considerazione alcune soluzioni alternative al sistema da noi realizzato, valutando vantaggi e svantaggi di queste soluzioni rispetto al nostro sistema. 6.2.1 Wescape Wescape (Figura 6.2) è un’applicazione di navigazione indoor (Figura 6.3) che permette di navigare all’interno degli edifici, sia in condizioni normali che in condizioni di emergenza. Figura 6.2. Il logo di Wescape Wescape è il risultato di un progetto svolto durante il corso di ingegneria del software presso UnivPM (Università politecnica delle marche). Il progetto è nato 80 6 Discussione critica in merito al sistema realizzato Figura 6.3. Navigazione tramite Wescape da una idea di alcuni ricercatori di UnivPM: Gabriele Bernardini, Marco D’Orazio, Enrico Quagliarini, Silvia Santarelli, Luca Spalazzi. Tra le feature che questo sistema offre possiamo elencare: • • • • • utilizzo del navigatore per capire come arrivare in una zona di un edificio; guida verso l’uscita di emergenza più vicina in caso di pericolo; scelta tra più percorsi alternativi. scansione dei QRCode per capire la propria posizione all’interno dell’edificio; scelta dei percorsi più veloci e sicuri grazie alla comunicazione con i sensori di sicurezza presenti nell’edificio. Il sistema in questione è ibrido rispetto al sistema MediNav, poichè si basa sia sull’utilizzo dei QRCode, sia sull’utilizzo di alcuni sensori di sicurezza presenti all’interno degli edifici. L’infrastruttura ausiliaria dei sensori permette al sistema in questione di calcolare i percorsi in modo più preciso. Una caratteristica sicuramente interessante è il sistema di guida automatico verso un’uscita di emergenza in caso di pericolo. Inoltre, questo sistema offre la possibilità di scegliere tra più percorsi alternativi per giungere ad una determinata destinazione. Facendo un confronto fra la soluzione offerta dal competitor e quella proposta in questo progetto è possibile affermare che la navigazione mediante sensori ausiliari è più precisa ed efficiente, ma, allo stesso tempo, più costosa. In ultima analisi, il sistema MediNav offre una navigazione meno precisa, ma, al tempo stesso, poichè svincolato da infrastrutture esterne, si presta bene all’immediato utilizzo in ambienti diversi. La soluzione del competitor richiederebbe il 6.3 Lesson learned 81 deploy di vari sensori, qualora si volesse coprire una zona nuova, con costi e tempi aggiuntivi. 6.3 Lesson learned Il percorso che ha portato allo sviluppo del progetto MediNav, nato come concept puramente astratto, dalla collaborazione tra i ragazzi del DIIES ed i ragazzi del DArTe, arrivato ad essere un sistema completamente funzionante, è stato un’opportunità per ampliare le proprie conoscenze e confrontarsi con realtà differenti. Tra le esperienze più significative vanno annoverate il confronto con l’ufficio stampa di ateneo, grazie al quale è stato possibile giungere all’idea di usare Google Maps Indoor, Google stessa, mediante i contatti con il team a supporto di Google Maps Indoor, rivelatisi, sfortunatamente inconcludenti. Lo sviluppo del sistema ha evidenziato sfide sia a livello progettuale sia a livello implementativo, permettendo di andare alla ricerca di soluzioni poco esplorate, come i QRCode, arricchendo, cosı̀, il proprio bagaglio tecnico e culturale in merito ai sistemi di navigazione indoor. Inoltre lo sviluppo per la piattaforma Android è stato un punto di partenza per apprendere l’architettura di questo sistema ed esplorare le librerie messe a disposizione da Google; il risultato di tutte queste esperienze ha portato alla realizzazione di questo progetto. 7 Conclusioni e uno sguardo al futuro In questa tesi è stata progettata e implementata la componente di front-end di un’applicazione Android, di supporto alla navigazione guidata verso un insieme di POI dell’Università Mediterranea di Reggio Calabria. Il primo passo è stato quello di effettuare una ricerca, sia nell’ambito delle tecnologie degli smartphone, sia in quello delle tecniche di navigazione indoor esistenti, in modo da ottenere le informazioni necessarie per una corretta progettazione del lavoro. Il passo successivo è consistito in uno studio di fattibilità, dove sono stati raccolti ed analizzati i requisiti tecnici del sistema, con particolare attenzione a quelli relativi alla componente di front-end. Successivamente sono stati realizzati alcuni mock-up grafici, per studiare una semplice ed intuitiva realizzazione del layout dell’applicazione. In seguito si è passati alla progettazione delle classi del sistema, dei suoi file di interfaccia e delle sue activity. Infine, si è passati alla fase di implementazione, dove la struttura delle classi precedentemente progettata è stata implementata mediante codice Java e file XML. È stato, quindi, stilato un manuale utente, facendo uso di screenshot rappresentativi del prodotto finale. Il lavoro di tesi si è concluso con una discussione critica sulle attività realizzate e sul sistema che è stato ottenuto. Per quanto riguarda i possibili sviluppi futuri di questo progetto, si può pensare di rendere la navigazione tramite QRCode “real-time”, attraverso l’implementazione del “dead reckoning” (Sezione 1.3. Mediante l’utilizzo dei sensori presenti negli smartphone (contapassi, giroscopio, bussola, accellerometro, etc.) sarebbe possibile visualizzare gli spostamenti dell’utente da un codice QR a quello successivo, migliorando, cosı̀, la capacità di orientamento dell’utente nei vari edifici dell’Ateneo. Dal lato del front-end l’obiettivo che ci si prefigge è quello di estendere i layout per supportare tutte le più comuni risoluzioni dei dispositivi Android e per supportare lingue alternative all’italiano ed all’inglese. Ringraziamenti Desidero ringraziare tutti coloro che mi hanno aiutato nella stesura di questa tesi di laurea; ringrazio, innanzitutto, il Professor Domenico Ursino, mio Relatore, che mi ha guidato in questo percorso con la sua disponibilità e la sua professionalità. Proseguo ringraziando tutti i colleghi e gli amici che mi hanno incoraggiato in questi anni di università. Un ringraziamento speciale va ai miei amici più cari, Marco Colica e David Toscano, che hanno condiviso con me sia momenti lieti che momenti difficili. In particolar modo vorrei ringraziare David Toscano per avermi fatto capire l’importanza dello studio e della conoscenza, incoraggiandomi a credere in me stesso. Vorrei ringraziare Giuseppe D’Agostino, collega ed amico, con il quale ho condiviso sia gli aspetti positivi che negativi di questo percorso di studi. Ringrazio i miei zii, Domenico Schiavone e Vincenzo Schiavone, che, a loro modo, si sono sempre mostrati interessati allo stato dei miei studi. Il grazie più grande va a mio zio Giuseppe, che mi ha sostenuto durante il mio percorso di studi che è venuto a mancare. Il suo affetto ed il suo amore sono energia che mi accompagna nel raggiungimento del mio traguardo. Vorrei, infine, ringraziare le persone a me più care, mia madre Romana e mio padre Umberto, che non hanno mai smesso di credere in me, incoraggiandomi sempre a continuare gli studi. Grazie al loro affetto ed al loro sostegno in qualunque mia scelta, è stato possibile giungere a questo traguardo. Riferimenti bibliografici 1. Android. https://it.wikipedia.org/wiki/Android, 2014. 2. Introduction to Android. https://developer.android.com/guide/index.html, 2016. 3. A.Como. L’Architettura di Android. http://android.devapp.it/larchitetturadi-android, 2011. 4. M. Canducci. XML. Conoscere il linguaggio XML significa poter comunicare veramente con tutti. Apogeo, 2009. 5. M. Carli. Android 6. Guida per lo sviluppatore. Apogeo, 2016. 6. C. De Sio Cesari. Manuale di Java 8: Programmazione orientata agli oggetti con Java standard edition 8. Hoepli, 2014. 7. E. Cisotti and M. Giannino. Android. Guida completa. Edizioni LSWR, 2015. 8. I.G. Clifton. Android User Interface Design: Implementing Material Design for Developers (Usability). Addison-Wesley Professional, 2015. 9. F. Collini, M. Bonifazi, A. Martellucci, and S. Sanna. Android: Programmazione avanzata. Edizioni LSWR, 2015. 10. J. Gosling, B. Joy, G. Steele, G. Bracha, and A. Buckley. The Java Language Specification, Java SE 8 Edition (Java Series). Addison-Wesley Professional, 2014. 11. C. Horstmann. Concetti di Informatica e fondamenti di Java (IV Edizione). Apogeo S.R.L., 2007. 12. J. Joseph. QR Code Based Indoor Navigation with Voice Response. http://www. ijsr.net/archive/v3i11/T0NUMTQxMDkz.pdf, 2014. 13. G. Maggi. Creare GUI per App Android, la guida. http://www.html.it/guide/ progettare-interfacce-per-android-la-guida/, 2016. 14. G. Nudelman. Android Design Patterns: Interaction Design Solutions for Developers. Wiley, 2013. 15. A. Serban. Indoor Navigation Apps: The Best for Android and iOS. http://techpp. com/2014/03/26/indoor-navigation-apps/, 2014. 16. A. Serra. Un sistema di posizionamento indoor basato su smartphone. http://www. dsf.unica.it/~andrea/tesils/tAlbertoSerra.pdf, 2016. 17. B. Cruz Zapata. Android Studio Application Development. PACKT PUBLISHING, 2013.