Sei sulla pagina 1di 336

POLITECNICO DI TORINO

Collegio di Ingegneria Gestionale

Corso di Laurea Magistrale in Ingegneria Gestionale

Tesi di Laurea Magistrale

PROGETTAZIONE E REALIZZAZIONE DI
UNA PIATTAFORMA INTEGRATA
PER LA CONSEGNA DI FARMACI A DOMICILIO
MEDIANTE DRONI QUADRIMOTORE

Relatori Candidati

Prof. Fabrizio LAMBERTI Alberto LISANTI


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

Prof. Claudio DEMARTINI Giorgio VENEZIA


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

Sessione di laurea di Novembre 2014


Indice generale
Indice generale ..................................................................................................................................... 2
Ringraziamenti ...................................................................................................................................... 8
Introduzione ......................................................................................................................................... 9
Cos’è PharmaCopter? ...................................................................................................................... 9
Presentazione del progetto.............................................................................................................. 9
Obiettivi e motivazioni........................................................................................................................ 10
Perché PharmaCopter? .................................................................................................................. 10
Identificazione del target progettuale ........................................................................................... 10
Stato dell’arte e benchmarking........................................................................................................... 12
Ambiti applicativi attuali e potenziali ............................................................................................ 12
Perché un’applicazione android? ................................................................................................... 15
Portabilità....................................................................................................................................... 15
Tecnologie utilizzate ........................................................................................................................... 16
Applicazione android ..................................................................................................................... 16
Server e database online ............................................................................................................... 16
Drone ............................................................................................................................................. 17
Elettronica: ................................................................................................................................ 17
Hardware:.................................................................................................................................. 17
Componenti utilizzate in fase di testing:................................................................................... 17
Descrizione sintetica dei componenti meccanici ed elettronici .................................................... 17
Controllore di volo (APM) ......................................................................................................... 18
GPS ............................................................................................................................................ 18
Ricevitore radio e Telemetry kit ................................................................................................ 19
Arduino UNO ............................................................................................................................. 19
SONAR SR04 .............................................................................................................................. 20
PIR (SR501) ................................................................................................................................ 20
Micro-Servomotore (Hitec HS-53)............................................................................................. 20
Cooking Hacks 3G+GPS Shield: ................................................................................................. 21
Raspberry PI .............................................................................................................................. 22
Frame (Turnigy Talon)................................................................................................................ 22
Motori (Turnigy Multistar) ........................................................................................................ 22
ESC (AfroESC)............................................................................................................................. 23

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 2
Integrazioni complementari ........................................................................................................... 24
Obstacle detection and warning ............................................................................................... 24
Accurate release system............................................................................................................ 25
Live streaming video ................................................................................................................. 26
Progettazione...................................................................................................................................... 29
Logical Framework Analysis ........................................................................................................... 30
Individuazione degli stakeholder .............................................................................................. 30
Description Matrix..................................................................................................................... 31
Diagramma di Venn ................................................................................................................... 34
Swot Analysis ................................................................................................................................. 35
Quality function development (QFD) ............................................................................................ 38
Bisogni del farmacista e loro importanza relativa..................................................................... 40
Peso dei bisogni e pianificazione della qualità.......................................................................... 41
Caratteristiche del prodotto...................................................................................................... 42
Correlazione tra le caratteristiche............................................................................................. 43
Spider Diagram.......................................................................................................................... 45
Dissemination plan.................................................................................................................... 48
Dissemination plan.................................................................................................................... 49
Analisi dei problemi ....................................................................................................................... 51
Albero dei problemi .................................................................................................................. 51
Analisi delle soluzioni..................................................................................................................... 54
Albero delle soluzioni ................................................................................................................ 54
Realizzazione e funzionamento .......................................................................................................... 57
Diagramma IDEF0 .......................................................................................................................... 57
Livello 0 ..................................................................................................................................... 58
Livello 1 ..................................................................................................................................... 59
Livello 2 ..................................................................................................................................... 60
Diagrammi UML ............................................................................................................................. 61
Use Case Diagram...................................................................................................................... 61
Activity Diagram ........................................................................................................................ 64
Sequence Diagram .................................................................................................................... 64
Class Diagram ............................................................................................................................ 65
State Chart Diagram .................................................................................................................. 66
Risultati ............................................................................................................................................... 67
Utilizzo del sistema da parte del cliente ........................................................................................ 67

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 3
Download dell’applicazione ...................................................................................................... 67
Registrazione ............................................................................................................................. 67
Login .......................................................................................................................................... 67
Login con Facebook ................................................................................................................... 67
Scelta della farmacia ................................................................................................................. 68
Visualizzazione del catalogo...................................................................................................... 68
Dettagli del prodotto................................................................................................................. 68
Visualizzazione del carrello ....................................................................................................... 69
Ciclo di evasione dell’ordine e sistema di notifiche .................................................................. 69
Visualizzazione elenco ordini .................................................................................................... 70
Barcode Scanner ....................................................................................................................... 70
Utilizzo del sistema da parte del farmacista .................................................................................. 70
Registrazione ............................................................................................................................. 70
Login .......................................................................................................................................... 70
Pannello clima ........................................................................................................................... 70
Visualizzazione delle condizioni di volo .................................................................................... 71
Ciclo di evasione dell’ordine e sistema di notifiche .................................................................. 71
Visualizzazione dell'elenco ordini ............................................................................................. 71
Barcode Scanner ....................................................................................................................... 71
Live streaming video ................................................................................................................. 71
Prototipo del drone realizzato ....................................................................................................... 72
Configurazione della componentistica...................................................................................... 72
Drone pronto per l’uso .............................................................................................................. 74
Conclusioni ......................................................................................................................................... 76
Appendice ........................................................................................................................................... 77
Activity Diagram............................................................................................................................. 77
Sequence Diagram ......................................................................................................................... 84
Class Diagram................................................................................................................................. 95
State Chart Diagram....................................................................................................................... 96
Codice sorgente ................................................................................................................................ 100
Codice android: it.sii.android.pharmacopter............................................................................... 100
About.java ............................................................................................................................... 100
CalcolaDistanze.java ................................................................................................................ 100
CarrelloView.java .................................................................................................................... 101
CatalogoView.java ................................................................................................................... 105

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 4
Config.java............................................................................................................................... 107
DettagliOrdine.java ................................................................................................................. 107
DettagliProdotto.java .............................................................................................................. 128
GCMBroadcastReceiver.java.................................................................................................... 132
GCMNotificationIntentService.java......................................................................................... 132
GoogleGraph.java.................................................................................................................... 134
GPSTracker.java ....................................................................................................................... 137
Login.java ................................................................................................................................ 141
MainActivity.java ..................................................................................................................... 153
MappaConMarker.java ............................................................................................................ 153
OrdiniView.java ....................................................................................................................... 159
PannelloFarmacista.java.......................................................................................................... 165
PannelloUtente.java ................................................................................................................ 168
Register.java ............................................................................................................................ 175
RegisterUser.java ..................................................................................................................... 177
RiceProd.java ........................................................................................................................... 183
RiceProdLoader.java ................................................................................................................ 188
ShareExternalServer.java......................................................................................................... 191
Codice android: it.sii.android.pharmacopter.classes ................................................................... 193
CatalogoFill.java ...................................................................................................................... 193
Farmacia.java .......................................................................................................................... 196
ItemCarrello.java ..................................................................................................................... 196
ItemCatalogo.java ................................................................................................................... 197
ItemListaOrdini.java ................................................................................................................ 199
JSONObjectUtils.java............................................................................................................... 202
Ordine.java .............................................................................................................................. 203
Prodotto.java........................................................................................................................... 205
SocketService.java ................................................................................................................... 206
Utente.java .............................................................................................................................. 209
Codice android: it.sii.android.pharmacopter.db.......................................................................... 211
DbAltitude.java........................................................................................................................ 211
DbCarrello.java ........................................................................................................................ 213
DbCoordinate.java................................................................................................................... 214
DbCredenziali.java................................................................................................................... 215
DbFarmaciaSelezionata.java ................................................................................................... 215

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 5
Codice android: it.sii.android.pharmacopter.task ....................................................................... 216
CambiaStatoTask.java.............................................................................................................. 216
GetElencoOrdiniFBTask.java .................................................................................................... 220
GetElencoOrdiniTask.java........................................................................................................ 224
GetListaFarmacieLocationTask.java......................................................................................... 227
GetWeatherClienteTask.java ................................................................................................... 231
GetWeatherFarmacistaTask.java ............................................................................................. 234
HTTPConnectTask.java ............................................................................................................ 237
LoginTask.java.......................................................................................................................... 240
OttieniDettagliOrdineTask.java ............................................................................................... 248
PutNewOrderTask.java ............................................................................................................ 251
RegisterTask.java ..................................................................................................................... 256
Codice android: it.sii.android.loginserver2.classi ........................................................................ 260
ElencoFarmacie.java................................................................................................................ 260
ElencoOrdini.java .................................................................................................................... 260
Farmacia.java .......................................................................................................................... 261
Ordine.java .............................................................................................................................. 262
Utente.java .............................................................................................................................. 264
Codice android: it.sii.android.loginserver2.dao .......................................................................... 266
DBConnect.java ....................................................................................................................... 266
ElencoFarmacieDAO.java ........................................................................................................ 268
ElencoOrdiniDAO.java ............................................................................................................. 270
OrdineDAO.java ....................................................................................................................... 272
UtenteDAO.java....................................................................................................................... 278
Codice android: it.sii.android.loginserver2.servlets .................................................................... 284
LoginServlet.java ..................................................................................................................... 284
OrdineModificaStatoServlet.java ............................................................................................ 286
OrdineNuovoServlet.java ........................................................................................................ 289
OttieniCoordinateArrivoServlet.java ....................................................................................... 292
OttieniDettagliOrdineServlet.java ........................................................................................... 295
OttieniElencoFarmacieServlet.java ......................................................................................... 297
OttieniElencoOrdiniFBServlet.java .......................................................................................... 300
OttieniElencoOrdiniServlet.java .............................................................................................. 303
RegisterServlet.java................................................................................................................. 308
sd.java ..................................................................................................................................... 309

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 6
Codice android: com.google.android.gcm.demo.server ............................................................. 310
ApiKeyInitializer.java................................................................................................................ 310
BaseServlet.java ...................................................................................................................... 312
Datastore.java ......................................................................................................................... 313
HomeServlet.java .................................................................................................................... 314
RegisterServlet.java................................................................................................................. 316
SendAllMessagesServlet.java .................................................................................................. 316
UnregisterServlet.java ............................................................................................................. 319
Codice android: com.javapapers.java.gcm .................................................................................. 320
GCMNotification.java .............................................................................................................. 320
Codice Arduino............................................................................................................................. 322
Sistema detect and warning:................................................................................................... 322
Richiesta coordinate gps (coordinate di arrivo per sgancio pacco) ....................................... 326
GPS ............................................................................................................................................... 330
Allegati .............................................................................................................................................. 333
Sitografia ........................................................................................................................................... 334
Bibliografia ........................................................................................................................................ 336

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 7
Ringraziamenti

Gli scriventi ringraziano:

 I proff. C. Demartini e F. Lamberti, per aver senza riserve creduto nel progetto,
fornendoci una preziosa collaborazione, nonché le fondamenta metodologiche
del lavoro stesso, tramite i corsi di Gestione Innovazione Sviluppo Prodotto ICT e
Sistemi ICT innovativi;

 L'Istituto superiore Mario Boella, nella persona dell’ing. E. Calia, per aver
sponsorizzato il progetto e non aver mai negato la propria disponibilità per
discutere piacevolmente sulla sua realizzazione;

 La società Farmaconsult SRL, per la squisita disponibilità che ci ha riservato, il


prezioso supporto tecnico e la consulenza riguardo ai possibili sviluppi del
progetto, ed infine per la gentile messa a disposizione di un server reale su cui
effettuare la ricerca dei prodotti;

 Il Politecnico di Torino, e in modo particolare il LADISPE, per aver fornito agli


scriventi le conoscenze iniziali, fondamentali per affacciarsi sul mondo della
modellistica e della programmazione su Arduino IDE;

 Il prof. F. Canavero, per aver espresso entusiasmo ed averci dischiuso la fervente


realtà dei team del Politecnico, consentendoci, così, di conoscere e reclutare
validi studenti e ricercatori interessati ad un futuro sviluppo ed espansione del
progetto;

 I Team Fused e Isaac, per averci permesso il confronto con menti ed ambiti di
applicazione diversi, basati su droni e non;

 I lettori di questo report, con l'auspicio che la lettura sia stata per loro di qualche
utilità, poichè la curiosità talvolta può indurre all’approfondimento di nozioni,
concetti e metodologie importanti, utili per superare quell’impreparazione che
spesso determina l’insuccesso di progetti pur validi ed innovativi, e per creare
invece quella cultura tecnica di cui la nostra società avanzata ha un bisogno
vitale.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 8
Introduzione

Cos’è PharmaCopter?
PharmaCopter è una piattaforma integrata hardware e software, atta alla consegna di farmaci tramite
quadricotteri, presso il domicilio dell'interessato oppure sul luogo di un incidente.

Pensato originariamente come un servizio destinato alle zone rurali o di alta montagna, in cui la
possibilità di raggiungere una farmacia non è agevole, né immediata, la portata dell’applicazione è
stata estesa al supporto tempestivo per un’unità ambulanza, nell’eventualità che quest’ultima
necessiti di farmaci od altra dotazione di cui non è munita.

 Qualsiasi cittadino in possesso di uno smartphone potrà ricevere le medicine che desidera nel
cortile di casa, tramite un quadricottero.

 Qualsiasi unità ambulanza potrà richiedere ed ottenere prontamente, in caso di emergenza, la


dotazione sanitaria necessaria ad un soccorso specifico, guadagnando tempo prezioso.

Dopo aver scaricato una semplice app, fornendo i propri dati personali e le coordinate GPS del proprio
domicilio, l'utente potrà prenotare un PharmaCopter presso i punti farmaceutici abilitati.

Con PharmaCopter, chiunque "ha un'intera farmacia a portata di tap".

Presentazione del progetto


Il core di PharmaCopter si divide in tre grossi sottoprogetti:
 il primo è relativo all’applicazione android, che permette al privato cittadino di registrare
un’utenza cliente e, effettuato il login, di fornire le proprie coordinate GPS, scegliere una
farmacia convenzionata presso la quale effettuare la ricerca di uno o più prodotti, comporre
un ordine, evaderlo e, una volta che il farmacista l’ha approvato, pagarlo, ricevendo, così un
PharmaCopter con i medicinali che ha richesto;
 il secondo consiste nel drone vero e proprio, assemblato partendo dalle singole componenti e
dotato di microcontrollori APM 2.6 e Arduino One/Raspberry PI, di due moduli GPS – uBlox
GPS, atto al viaggio principale e Cooking Hacks Shield GPS, assegnato alle sole operazioni
critiche, quali consegna del carico e atterraggio dopo il viaggio di ritorno alla base;
 per risolvere alcuni problemi critici connessi alla tecnologia utilizzata, sono state infine
necessarie alcune integrazioni, pensate, progettate e codificate da zero, al fine di migliorare
l’efficienza e la precisione del servizio.

Nel corso dei capitoli successivi, i diversi ambiti che riguardano il progetto vengono presentati
secondo lo schema logico appena proposto; viene, inoltre, illustrato il funzionamento del servizio sia
per il farmacista, utilizzatore principale cui il servizio è commercialmente rivolto, sia per il cliente, che
rappresenta l’utente finale che ne trae beneficio, sia per le unità ambulanza, che utilizzano
l’applicazione con modalità leggermente diversa da quella del cliente.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 9
Obiettivi e motivazioni

Perché PharmaCopter?
L’utopistico movimento del paradismo sogna un mondo in cui l'innovazione liberi l'umanità dalla
schiavitù del denaro e del lavoro, in cui la tecnologia sia al servizio dell’uomo e non sua concorrente,
dove la realizzazione e gestione di prodotti e servizi avviene senza l’intervento umano.
PharmaCopter si propone in qualche modo di rendere disponibile una “tecnologia che sia al servizio
dell’uomo”, realizzando un servizio d’utilità sociale. In particolare, si cerca l a soluzione all’esigenza di
disporre di un facile accesso alla cura, e più specificamente ai farmaci ed ai presidi sanitari di primo
soccorso. Il servizio di rende prezioso nei casi in cui sia necessario sopperire alla inadeguatezza delle
infrastrutture di trasporto o alla presenza di barriere architettoniche.
Si offre, dunque, un servizio di consegna destinato prevalentemente, ma non solo, a cittadini che per
qualche motivo non riescono ad effettuare con facilità ed in tempo utile gli spostamenti. necessa ri per
raggiungere la farmacia più vicina. Questa difficoltà può essere determinata dalla scarsa accessibilità
dell'area geografica in cui il cittadino vive, oppure può dipendere dalle non perfette capacità psico-
fisiche del cittadino medesimo.
Partendo da questo presupposto, la l'efficacia del progetto è maggiore quanto maggiore è la
tempestività ed effettività del servizio offerto all'utente finale. In altri termini, si rende opportuno
raggiungere nei tempi più rapidi e nel modo più preciso possibile la postazione in cui il cliente si trova.

Identificazione del target progettuale


Preliminarmente, sono stati stabiliti alcuni vincoli fondamentali che caratterizzano l'intero progetto.
In primis, si è voluto garantire il maggior numero possibile di potenziali sviluppi commerciali. Perché
così fosse, si è scelto di configurare un sistema modulare, facilmente modificabile e customizzabile, in
modo da poter , all’occorrenza, espandere il bacino d’utenza a tipologie e a volumi diversi di
utilizzatori, rivolgendosi anche ad altri possibili ambiti applicativi.
Ci si è premurati, poi, di utilizzare tecnologie e servizi open source e in particolare, laddove possibile,
open software o open hardware, per ridurre tempi e costi di progetto e soprattutto per aumentare la
modularità e l'interfacciabilità con le tecnologie elettroniche più aggiornate, presenti e future, in
considerazione della costante evoluzione prestazionale della componentistica.
In tal modo, si è automaticamente conseguito l'obiettivo già esposto di realizzare un prodotto basato
su una tecnologia facilmente esportabile in altri ambiti applicativi: all'occorrenza, PharmaCopter si
presta infatti ad essere reimpiegato con semplici adattamenti in settori commerciali molto diversi da
quello sanitario.
La ricchezza di PharmaCopter risiede, oltre che nell'idea originale di soddisfare una concreta esigenza
di mercato in ambito farmaceutico, nella sua peculiare formula realizzativa e metodologica: le
componenti software, elettroniche ed elettromeccaniche, prima di es sere sviluppate ed interfacciate
tra loro, sono state accuratamente prescelte tra una gamma di molteplici possibili alternative. La
selezione è stata fatta in modo da ottimizzare i punti di forza che lo stato dell'arte delle tre tecnologie
può offrire, tenendo in conto le finalità non solo attuali ma anche future del progetto. Si è privilegiata

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 10
cioè la strategia di mantenere un'apertura al miglioramento, in termini di costi e di efficienza,
mettendo a frutto il continuo progresso tecnologico (si pensi, ad esempio, al fatto che la precisione di
posizionamento dell’intero sistema PharmaCopter dipende dalla qualità dei dispositivi GPS installati e
delle reti satellitari di georeferenziazione, e che sia per i primi che per le seconde sono attesi nel
futuro prossimo importanti miglioramenti prestazionali, a costi invariati o addirittura decrescenti).

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 11
Stato dell’arte e benchmarking
Il primo tentativo noto di costruire e utilizzare un velivolo senza pilota risale al 1849, quando gli
Austriaci attaccarono la città di Venezia utilizzando dei palloni caricati di esplosivo: alcuni di questi
ordigni vennero lanciati dalla nave austriaca Vulcano. Sebbene alcuni dei palloni liberati avessero
raggiunto l'obiettivo, altri, a causa del vento, finirono per colpire le linee di attacco austriache.

Soltanto dieci anni fa, i droni erano tecnologie militari costosissime e spesso progettate, sviluppate e
collaudate in segreto. Oggi sono alla portata di tutti.

Dieci anni fa nessuno avrebbe immaginato come sarebbe cambiata la vita di tutti i giorni, con la
diffusione, ormai capillare, di dispositivi come gli smartphone. Venti anni fa nessuno avrebbe
immaginato che si sarebbe arrivati a portare in tasca un apparecchio telefonico più piccolo di un
pacchetto di sigarette; trent’anni fa, che le potenzialità di calcolo di macchine calcolatrici grandi come
una stanza, divoratrici di pacchi di schede perforate, potessero essere concentrate in un personal
computer, poi in un laptop o in un tablet.

Ambiti applicativi attuali e potenziali


I droni prefigurano una vera e propria rivoluzione tecnologica, tanto da suggerire una ridefinizione del
concetto stesso di utility.

Non è sempre facile riconoscere un evento straordinario durante il suo esordio, ma la reale portata di
una nuova tecnologia si può valutare in base alla quantità di applicazioni in cui essa può essere
utilizzata.
Al momento attuale, tralasciando di enumerare i possibili impieghi in ambito militare, i droni sono
utilizzabili nelle più disparate applicazioni civili, tra cui, a titolo d’esempio:

1. Tutela dell'ambiente e della salute

• Nell'ambito della lotta all’inquinamento, il Ministero dell’Ambiente ha ricevuto i primi droni


per l’analisi in volo degli inquinanti presenti nei pressi di impianti industriali o di ciminiere.

• In Africa i droni vengono utilizzati per il monitoraggio ed il controllo numerico degli animali
selvatici, soprattutto quelli a rischio di estinzione, o anche per contrastare il bracconaggio
delle specie animali protette.

• In fotogrammetria, sono ormai molte le applicazioni informatiche che permettono di mappare


un’area in 2d o in 3d per ricreare modelli digitali del territorio. Ad esempio, in Italia sono stati
impiegati droni per l’elaborazione del nuovo piano regolatore comunale del paese di
Compiano in provincia di Parma.

• Grazie alle riprese aeree effettuate con droni in aree difficilmente accessibili, gli organismi di
tutela della salute negli ambienti di vita e di lavoro hanno potuto scoprire sostanze dannose
per la salute (come ad esempio nel caso dei pannelli di eternit, contenenti amianto, usati
come coperture di edifici, o di serbatoi in cemento-amianto).

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 12
• In un programma di ricerca microbiologica, l’università del Texas utilizza un drone
equipaggiato con capsule di Petri per raccogliere e analizzare i microorganismi presenti a varie
altezze nell’atmosfera.

2. Protezione civile

• Nell'attività di prevenzione delle frane, i droni vengono usati per rilevare e mappare le aree
soggette a frane e per valutare gli insediamenti circostanti dal punto di vista del rischio
idrogeologico.

• In caso di calamità naturali quali terremoti, incendi e inondazioni, i droni vengono anche
utilizzati per la ricerca di sopravvissuti e per la mappatura dei danni, in maniera da individuare
correttamente le priorità e predisporre adeguatamente gli interventi.

• I droni possono effettuare in tutta sicurezza accessi nelle zone pericolose, quali immobili
pericolanti, zone a rischio d'esplosione, aree contaminate.

• La Nasa ha varato un programma di ricerca consistente nel mandare all’interno degli uragani
degli speciali droni muniti di sensori in grado di rilevare i principali parametri atmosferici, allo
scopo di monitorare le variabili in gioco e comprendere la dinamica dei fenomeni estremi.

• Per la prevenzione degli incendi, diverse città degli Stati Uniti hanno dotato i Vigili del Fuoco di
droni capaci di ispezionare i luoghi ad elevato rischio d'incendio, oltre che per fornire
supporto nello spegnimento, nell'analisi dei danni, nella ricerca dei sopravvissuti.

3. Pubblica sicurezza e repressione dei reati

• Si impiegano droni nella lotta alla criminalità, come ad esempio nel contrasto al
contrabbando, nell'inseguimento e cattura di ricercati, nel monitoraggio e controllo del
territorio. Parallelamente, sono da mettere in conto usi illegali dei droni da parte dei
malviventi: negli Stati Uniti alcune persone sono state arrestate per aver tentato di introdurre
clandestinamente tabacco in una prigione impiegando un drone.

• Per la tutela delle frontiere, gli USA hanno in corso un progetto di monitoraggio del confine
con il Messico, tramite droni in volo 24 ore su 24 lungo tutto il confine. Attraverso camere a
infrarossi sono in grado di scoprire attività clandestine anche di notte. Il governo italiano
progetta altresì di pattugliare il mare con droni per l’avvistamento precoce delle barche di
migranti che tentano di arrivare in Italia, mentre all'estero questa nuova tecnologia viene già
usata in ambito marittimo per il controllo delle coste.

• Nella lotta all’abusivismo edilizio, sono in corso diversi i progetti per monitorare dall’alto lo
stato di un territorio e verificare l’esistenza di abusi edilizi, immobili non dichiarati, lavori e
cantieri non autorizzati.

• La Polizia stradale di Pesaro ha utilizzato un drone per scattare le foto dettagliate dell’area di
un incidente che ha determinato la morte di un giovane motocilista, nell'ambito della propria
attività istituzionale di esecuzione dei rilievi negli incidenti stradali.

• Nel contrasto alle attività illegali di smaltimento dei rifiuti, vengono ispezionati con i droni i
territori in cui si sospetta che si celino discariche abusive.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 13
4. Agricoltura e allevamenti

• Con la tecnica della fotografia aerea ad infrarossi, i droni consentono la valutazione dello stato
di salute delle coltivazioni, dell'efficacia o della necessità dell'irrigazione. Nel controllo della
vegetazione, possono essere anche impiegati per combattere la deforestazione illegale e per
garantire la protezione delle aree verdi (esempi a tal riguardo si registrano in svariati paesi nel
mondo quali Indonesia, Nepal, Tanzania). In Italia sono stati utilizzati per monitorare
l’estensione effettiva dei boschi e lo stato delle foreste (in Trentino e nella Tuscia, Lazio).

• In Canada, alcuni droni-pastore vengono utilizzati come ausiliari nel governo di greggi di
pecore ed oche.

• In Florida i droni sono utilizzati nella lotta alle zanzare, per scoprire l'ubicazione di pozze e
acquitrini, in maniera da rendere più mirate le azioni di bonifica.

5. Cultura e tempo libero

• In archeologia, si eseguono riprese fotografiche aeree dei siti d'interesse per scoprire
manufatti sotterranei, ricercando regolarità geometriche nelle anomalie vegetative di
superficie.
• Elaborando ed analizzando rilievi video e fotografici ad alta risoluzione di chiese e monumenti,
si possono individuare con precisione i danni causati dagli agenti atmosferici e le aeree in cui è
necessario intervenire selettivamente con l'attività di restauro. Oltre, ovviamente, a
valorizzare con riprese ad alto impatto visivo il patrimonio artistico e archeologico,
particolarmente significativo nel nostro Paese.
• Al MIT stanno studiando l'impiego di un piccolo drone che viene contattato come guida
urbana da chi ha bisogno di istruzioni per raggiungere una certa destinazione. Il drone arriva
presso l'utente e lo accompagna attraverso il campus fino alla meta desiderata.

• Nella promozione turistica, le riprese aeree permettono di valorizzare ancor più un territorio
di pregio, offrendo la possibilità di visualizzare punti di vista spettacolari e suggestivi.

• Nello sport e nei grandi spettacoli all'aperto molti eventi si prestano ad essere
spettacolarizzati attraverso le riprese aeree. La squadra di calcio del Barcellona utilizza invece i
droni per riprendere dall’alto il campo di gioco durante gli allenamenti e studiare così da una
prospettiva privilegiata la disposizione ottimale dei giocatori sul campo.

• Grazie alla flessibilità e stabilità di manovra dei droni, si possono scattare fotografie artistiche
da diverse altezze ed angolazioni, ottenendo immagini di grande impatto visivo ed emozionale.

6. Altri ambiti

• In ambito missilistico, un drone è stato utilizzato per riprendere da vicino il lancio di prova di
un missile.

• In diversi paesi ove il diritto alla privacy è poco tutelato, i droni vengono utilizzati nel
giornalismo, oltre che per riprendere fatti di cronaca, anche per “paparazzare” personaggi
famosi.
• In particolari settori della logistica, sono attualmente in fase di studio reti di trasporto basate
su droni, capaci di portare carichi di qualche chilogrammo nelle zone meno accessibili o in
territori ad alta pericolosità.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 14
Una tecnologia spendibile in ambiti così diversificati, sebbene ancora allo stato embrionale, è
sembrata agli scriventi una scelta ideale per chi voglia cimentarsi in un progetto che guardi al futuro,
proponendosi di ottenere inoltre un output riutilizzabile, con qualche minore adattamento, in uno
spettro di applicazioni potenzialmente molto ampio.

Perché un’applicazione android?


L’idea stessa di PharmaCopter include in sé il concetto di trasportabilità.
Pensare allo smartphone come supporto hardware per l’applicazione significa dare all’utente la
possibilità di prenotare la consegna con un drone anche quando è lontano da casa, come durante un
soggiorno in vacanza o durante un viaggio in un posto poco accessibile.
Dal punto di vista del progettista, poi, Android è il sistema operativo ideale se si desidera avvalersi di
tecnologie open-source. La sua facilità di reperimento e scalabilità fanno la differenza: creare una web
application a partire da quanto già realizzato può essere immediato.
Sono, poi, evidenti i vantaggi di una tecnologia "tascabile" per l’utente finale: questi può ricercare uno
specifico medicinale, magari di difficile reperibilità, nel database di tutte le farmacie poste nelle
vicinanze e disporre poi di farsi recapitare l’ordine in un qualunque posto coperto da segnale GPS.
Perché, però, preferire un supporto smartphone anche per il farmacista?
La maggior parte dei farmacisti si occupa del servizio al banco, come siamo abituati a pensare. Ne
esiste, però, un numero non trascurabile che opera in un magazzino o nel retrobottega, operando più
spesso “dietro le quinte” piuttosto che a contatto col cliente.
Alcuni, inoltre, fanno un lavoro a cavallo tra quello del grossista e quello del farmacista, trovandosi ad
operare in diverse sedi (talvolta dotate di software e sistemi di catalogazione diversi) spostandosi
spesso tra l’una e l’altra, nonché all’interno di una stessa sede. Avere a disposizione in un dispositivo
tascabile di immediata consultazione l'elenco dei prodotti aggiornato in tempo reale (grazie ad un
servizio erogato direttamente dalla società fornitrice), con la possibilità di tenere sotto controllo gli
ordini di più punti vendita, o di servirne alcuni da postazioni normalmente non atte alla vendita, è
certamente un valore aggiunto particolarmente apprezzato.

Portabilità
Coniugando tecnologie all’avanguardia, basate sull’open source e facili da portare con sé, si è
automaticamente conseguito l'obiettivo prima esposto di realizzare una tecnologia facilmente
portabile ad altri ambiti applicativi: all'occorrenza, PharmaCopter si presta essere reimpiegato con
semplici adattamenti in ambiti molto diversi.
Ad esempio, il team Fused del Politecnico di Torino (tra i ringraziamenti di questa tesi) si occupa di un
sistema di ricognizione di alta montagna e individuazione di persone sommerse da valanghe e slavine,
utilizzando buona parte della componentistica presente su un drone PharmaCopter.
Ultimamente, inoltre, sono in fase di sviluppo preziose applicazioni nell’ambito della sanità stessa.
Basti pensare al drone-defribillatore “capace di trasportare in tempi record un defibrillatore di circa 4
kg sul luogo della chiamata, localizzata con il GPS”, presentato soltanto qualche settimana fa in Olanda
all'università tecnica di Delft.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 15
Tecnologie utilizzate
Come illustrato nella presentazione iniziale, all’interno del lavoro svolto è conveniente operare una
distinzione tra due diversi sottoprogetti; sebbene entrambi trovino applicazione soltanto se
considerati in maniera congiunta, saranno trattati in sezioni differenti, che afferiscono rispettivamente
una alla parte applicativa e l'altra a quella fisica/logica.
Stabilita tale importante differenziazione espositiva, si elencano nel seguito le caratteristiche delle
componenti software dell’applicazione Android e delle componenti fisiche del drone.

Applicazione android
 Server Tomcat v7.054 (uso di certificati SSL, servlet java);

 Database MySQL;

 AsyncTask;

 Stream WebSocket (comunicazione con i server di Farmaconsult SRL);

 Integrazioni di API (Google Elevation / Graph, Google Maps v2 con inserimento dinamico dei
marker, World Weather Online, Facebook API, Paypal API);

 Sistema di riconoscimento ottico Zxing Barcode Scanner;

 Sistema di notifiche push Google Cloud Messaging;

 Ground Control System (ad oggi, Copter-GPS).

Per consentire il funzionamento dell’applicazione in qualsiasi punto del mondo, è stato necessario
definire un’infrastruttura cloud atta ad ospitare tutti i flussi informativi ad essa relativi.

Server e database online


Il deployment del server e del database è stato effettuato mediante la sottoscrizione e la
configurazione di un account Amazon Web Service.
Nella fattispecie, i servizi utilizzati sono:

 EC2: definisce un cloud e consente la creazione di server virtuali al suo interno;

 VPC: gestisce isolatamente le risorse del cloud;

 Cloudwatch: consente il monitoraggio delle risorse e dell’applicazione;

 RDS: riconosce vari tipi di database, tra cui quello MySQL;

 Elastic Beanstalk: funge da contenitore di applicazioni AWS;

 Route 53: fornisce un la registrazione di un dominio e un DNS scalabile.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 16
Drone
Si è stabilito di separare ulteriormente le componenti in base alla loro natura, in modo da poter
analizzare in maniera distinta i dispositivi elettronici dall’hardware puramente elettro-meccanico.

Elettronica:
 APM 2.6;

 GPS uBlox;

 Arduino One / Raspberry PI;

 Cooking Hacks 3G+GPS shield;

 Sonar HC-SR04 x3;

 HC-SR501 infra-red PIR x3.

Hardware:
 Turnigy Talon Carbon Fiber Frame;

 Turnigy Multistar 2814-700Kv Motors x4;

 Afro ESC 30Amp x4;

 Turnigy 5000mAh 4S 25C Battery;

 HITec Micro-servomotor HS53.

Componenti utilizzate in fase di testing:


 Spektrum DX6i;

 OrangeRx R620 6Ch 2.4Ghz.

I datasheet relativi alle singole componenti finora illustrate sono riportati nell’Appendice in allegato a
questo documento.
Si è ritenuto di omettere alcune delle parti della componentistica (ad esempio le eliche) considerate
trascurabili dal punto di vista della rilevanza tecnica, o in quanto perfettamente intercambiabili con
altri prodotti similari, aventi analoghe caratteristiche tecniche. Il medesimo criterio è stato adottato
nella descrizione di cui al capitolo seguente.

Descrizione sintetica dei componenti meccanici ed elettronici


Si ritiene che i componenti funzionali costituenti un drone quadricottero possano non essere
immediatamente noti a tutti, per cui vengono dedicate alcune pagine per offrire al lettore un quadro
descrittivo della componentistica hardware ed elettronica presente nel Pharmacopter.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 17
Sebbene la scelta degli specifici componenti del drone PharmaCopter sia stata molto accurata e
meditata, la descrizione che segue si propone di illustrare per grandi linee le caratteristiche funzionali,
piuttosto che le specifiche tecniche dettagliate del modello effettivamente adottato.

Controllore di volo (APM)


Il controller di volo o autopilota è un dispositivo
elettromeccanico che può guidare un veicolo senza
assistenza da parte di un essere umano. Se invece è
abbinato a un ricevitore di onde radio, il controller può
essere radiocomandato da terra tramite un
radiotrasmettitore (nel caso di PharmaCopter sono
possibili entrambe le casistiche).
La maggior parte delle persone associa l'autopilota
specificatamente agli aeroplani, ma gli autopiloti per
barche e navi sono denominati allo stesso modo e
hanno stesso scopo e analogo funzionamento.
L’APM è dotato, pertanto, di porte di connessione per la telemetria radio, di un doppio
microcontrollore interno ATMEGA2560/ATMEGA32U-2, che interpreta e gestisce i vari input
incrociandoli con le informazioni ottenute da alcuni sensori integrati.
Nella fattispecie, si tratta di:
 3-axis giroscopio;
 accelerometro;
 magnetometro;
 barometro ad alta precisione.
Questo controllore di volo è dotato di ingressi per GPS e numerose altre porte digitali, analogiche e
pwm, assolutamente fondamentali per l’applicazione prevista da PharmaCopter.

GPS
Il sistema GPS (Global Positioning System) è un
sistema di navigazione satellitare sviluppato e gestito
dal dipartimento della difesa statunitense.
Esso fornisce a utenti che si spostano via terra, mare
o aria, informazioni relative a posizione, velocità e
orario, 24 ore su 24, e contemporaneamente per un
numero illimitato di utenti.
Ogni satellite GPS, in orbita geostazionaria, trasmette
una serie di segnali ad apparecchiature collocate a
terra, i ricevitori GPS, che si limitano a ricevere
passivamente i segnali satellitari, senza trasmettere
nulla. Per rilevare i segnali, i ricevitori GPS devono
avere una visuale libera della parte di cielo ove
orbitano i satelliti, e pertanto vengono utilizzati esclusivamente all'aperto. Possono perciò presentare
problemi di ricezione in prossimità di alberi o edifici alti. Il funzionamento del sistema GPS dipende da

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 18
riferimenti orari estremamente precisi, forniti da orologi atomici di cui ogni satellite GPS è dotato.
Un drone PharmaCopter è dotato di due ricevitori GPS: il primo viene utlizzato per indirizzare il
controller di volo verso determinate coordinate (si tratta del più preciso e rapido tra i due); Il secondo,
montato sullo shield Cooking Hacks, serve per gestire lo sgancio del pacco e di conseguenza la
reattività nell’agganciare il segnale non influisce sul risultato, dato che i tempi di consegna sono
ragionevolmente più lunghi rispetto a ogni pessimistica previsione di ritardo nel rilevamento di un
segnale di georeferenziazione.

Ricevitore radio e Telemetry kit


Utilizzato sinergicamente con il controller di volo, questo
sistema permette di pilotare un drone da terra. Poiché esso si
basa su onde radio, è necessario che i dispositivi atti alla
trasmissione e quelli atti alla ricezione siano sotto copertura
radio.
Si tratta, in particolare, di:
 un ricevitore radio, capace di captare le onde radio
trasmesse dal radiocomando (dev’essere in ascolto
sulla stessa frequenza del trasmettitore e deve constare
di tanti canali di ricezione quanti quelli di trasmissione
di quest’ultimo);
 un telemetry kit, utilizzato affinché la Ground Control Station (ovvero la stazione di controllo a
terra, situata nel punto di partenza del drone) sia in grado di trasmettere informazioni riguardo
la destinazione (in coordinate x, y, z) di ogni way
point che il volo deve raggiungere, nonché di
raccogliere dati di volo che vengono trasmessi a
terra dal drone (feedback).
Queste due componenti sono state di
fondamentale importanza durante la fase di
testing del drone PharmaCopter, in cui si è reso
necessario configurare i PID (parametri che
consentono il mantenimento dell’assetto del
velivolo), testare i livelli di tolleranza allo sforzo, al
carico e così via, nonché i tempi di reazione del
drone a un comando dato da terra.

Arduino UNO
Arduino è una scheda elettronica di piccole
dimensioni con un microcontrollore ed una
circuiteria di contorno, utile per creare
rapidamente protipi, per scopi hobbistici e
didattici.
La scheda possiede 14 pin digitali programmabili
come ingressi o uscite (i quali hanno anche la
capacità di essere utilizzati per funzioni dedicate
come la generazione di segnale PWM o la

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 19
comunicazione UART ) e 6 ingressi per l’acquisizione ed elaborazione di segnali analogici.
Il microcontrollore di cui la scheda è corredata è AT mega 328, prodotto da Atmel, ha una velocità di
16MHz, una memoria flash da 32KB, una sram da 2KB e una memoria EEPROM da 1KB.
L’alimentazione della scheda avviene tramite porta usb o tramite l’apposito connettore. Nel caso in cui
siano collegati sia il cavo usb sia il connettore di alimentazione, la scheda è capace di scegliere
automaticamente la fonte di alimentazione esterna.
Con Arduino si possono realizzare in maniera relativamente rapida e semplice piccoli dispositivi come
controllori di luci, di velocità per motori, sensori di luce, temperatura e umidità e molti altri progetti
che utilizzano sensori, attuatori e comunicazione con altri dispositivi.
Esso è fornito di un semplice ambiente di sviluppo integrato per la programmazione.
Tutto il software a corredo è libero, e gli schemi circuitali sono distribuiti come hardware libero.

SONAR SR04
L’SR04 è il più minimale sonar compatibile con Arduino, ma ha tutte le caratteristiche di un
normalissimo sensore ad ultrasuoni.
Si tratta di un dispositivo elettronico
che, sfruttando la riflessione delle onde radio
che colpiscono un oggetto, è in grado di
misurare la distanza, la forma e la velocità
dell’oggetto stesso.

Può essere utile per la misurazione di prossimità


di un corpo in movimento, oppure per il
rilevamento di un ostacolo durante un percorso.
Basti pensare che il sonar è la versione primitiva
dei moderni radar, utilizzati su aeroplani
moderni di grossa stazza, per sondare il cielo e la
presenza di altri velivoli.

PIR (SR501)
In pratica, un sensore PIR non rileva autonomamente un movimento; tuttavia, è possibile che esso si
attivi in seguito brusche variazioni di temperatura che modificano lo
stato che il PIR aveva precedentemente memorizzato come
“normale".
Quando un corpo in movimento passa di fronte a uno sfondo, ad
esempio un muro, "fotografato" in precedenza dal PIR come stato
normale, la temperatura in quel punto si innalza bruscamente,
passando da quella della stanza a quella del corpo. Questo rapido
cambiamento attiva il rilevamento. Lo spostamento di oggetti di
temperatura identica, com'è prevedibile, non innesca alcuna
rilevazione.

Micro-Servomotore (Hitec HS-53)


I micro-servomotori sono apparecchi molto utilizzati nella robotica per gli azionamenti. Di solito, si

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 20
presentano come piccoli componenti assemblati in un contenitore in materiale plastico, da cui
fuoriesce un alberino in grado di ruotare (nel caso specifico, di un angolo compreso tra 0 e 180°)
mantenendo stabilmente la posizione raggiunta. Per ottenere la rotazione dell’albero in uscita,
vengono utilizzati un motore a corrente continua e un meccanismo di demoltiplica che consente di
aumentare la coppia in uscita.
La rotazione del motore è effettuata tramite un circuito di controllo interno, in grado di rilevare
l'angolo di rotazione raggiunto dall’asse in uscita tramite un potenziometro resistivo e bloccare così il
motore nel punto desiderato.

Cooking Hacks 3G+GPS Shield:


Il Cooking Hacks Shield abilita l’uso della connessione ad alta velocità WCDMA e HSPA.
Tale modulo consta anche di un GPS interno, che rende possibile la geolocalizzazione del dispositivo,
sia in location outdoor, sia in location indoor, grazie all’incrocio tra gli stard NMEA frame e la
triangolazione dell’ID del
cellulare, utilizzando sia l’ A-
GPS (assisted-mobile) sia l’S-
GPS (mobile-baseed).
Vi è inoltre la possibilità di
aggiungere una fotocamera di
risoluzione fino a 2MP, un
microfono, uno speaker e delle
cuffie. Ciò permette la
creazione eventuale di video
salvabili in un secondo mo-
mento sulla scheda micro SD
presente sempre sullo shield.
Tale shield, infine, può essere
utilizzato, come nel caso di
PharmaCopter, come un
normale 3G modem.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 21
Raspberry PI
Il Raspberry PI è un single-board
computer (un calcolatore implemen-
tato su una sola scheda elettronica)
sviluppato nel Regno Unito dalla
Raspberry PI Foundation).

L'idea che sta alla sua base è la


realizzazione di un dispositivo econo-
mico, concepito per stimolare l'inse-
gnamento di base dell'informatica e
della programmazione nelle scuole.

Il progetto ruota attorno a un System-


on-a-chip (SoC) Broadcom BCM2835, che incorpora un processore ARM1176JZF-S a 700 MHz, una
GPU VideoCore IV, e 256 o 512 Megabyte di memoria. Il progetto non prevede né hard disk né una
unità a stato solido, affidandosi invece a una scheda SD per il boot e per la memoria non volatile.

La scheda è stata progettata per ospitare sistemi operativi basati su un kernel Linux o RI SC OS. È
assemblata fisicamente in Galles, nel Sony UK Technology Centre.

Frame (Turnigy Talon)


Il frame costituisce lo scheletro, ovvero l’ossatura
dell’hardware, nonché la base di supporto di varie schede
elettroniche e cablaggi annessi.
Realizzato, nel caso in esame, in fibra di carbonio, il Turnigy
Talon riesce ad essere ultra-leggero sebbene abbia una
dimensione abbastanza notevole (55 cm); esso, inoltre, è
in grado di sopportare tutto ciò che si rende necessario per
il volo pilotato e autonomo del drone (motori, esc, fly-
controller, radio ricevitore, batteria e power distribution
board).

Motori (Turnigy Multistar)


Il motore di un drone è alimentato direttamente da un
power module, gestito dal controllore di volo.
Sul modello PharmaCopter sono presenti quattro
motori, collegati ad un unico fly-controller, che calcola
e stabilisce la quantità di potenza da erogare su
ognuno, in base alla condizione di assetto del velivolo.
Questo genere di turbina ha la necessità di ricevere la
corrente in modo corretto da sbalzi e sovraccarichi.
Perché sia così, è necessario che ci siano degli ESC a
fare da ponte tra l’alimentazione e ognuno dei quattro
motori.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 22
ESC (AfroESC)
In base al tipo di motore, alla sua potenza,
all’utilizzo che si intende farne ed al diametro delle
eliche calettate su di essi, bisogna scegliere il giusto
regolatore (o Electronic Speed Controller).
Questo componente svolge due funzioni:
 convertire i comandi per variare la rotazione
del motore;
 alimentare il resto dell'elettronica (radio e
servo in primis).

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 23
Integrazioni complementari
La fase progettuale del lavoro ha fatto emergere alcuni problemi di grave impatto sulla riuscita
complessiva di PharmaCopter (si faccia riferimento all’Analisi dei problemi, più avanti). Si è resa,
quindi, necessaria la creazione di alcune strutture addizionali, atte a migliorare le lacune che il sistema
nativo presentava.
E’ doveroso, perciò, considerare in modo a sé stante tre integrazioni, create da zero:

 Obstacle detection and warning: un impianto atto al rilevamento e alla segnalazione degli
ostacoli individuati in fase di volo;

 Accurate release system: un sistema di miglioramento del processo di sgancio del pacco,
effettuato all’arrivo del drone presso il domicilio del cliente.

 Live streaming video: un’utility integrata nell’applicazione, che permette di visualizzare su


dispositivo mobile ciò che si para davanti al drone in volo;

 Accurate landing system: un sistema di miglioramento del processo di atterraggio, effettuato


al termine del viaggio di ritorno del drone presso la farmacia.

Obstacle detection and warning


Dall’analisi dei bisogni degli stakeholders è emerso che la necessità principale dei potenziali clienti di
PharmaCopter (in particolare dei farmacisti) è avere la percezione di utilizzare un prodotto sicuro.
Le coordinate del punto di
consegna per ogni viaggio di
droni PharmaCopter vengono
fornite dall’utente. Prima della
partenza, tramite integrazione
con l’API di Google Altitude,
sono calcolate puntualmente
le altimetrie del percorso,
stabilendo il punto di
altitudine massima del
terreno.
Normalmente i quadricotteri,
come illustrato
precedentemente, volano 10-
20 metri più in alto della
costruzione più alta presente sul percorso. In questo modo, si riesce a garantire l’assenza di collisioni
con edifici e grosse costruzioni (tralicci dell’alta tensione, pale eoliche, ecc.). Tuttavia, esiste la
possibilità di trovare durante il percorso degli ostacoli mobili, oppure di altra natura non prevista.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 24
Al fine di garantire la massima sicurezza percepita, è stato realizzato questo sistema, utilizzando tre
coppie di sensori (una coppia per ogni verso di percorrenza), ognuna composta da un sensore sonar
HC-SR04 e da un sensore PIR a raggi infrarossi HC-SR501.
Nel momento in cui ciascuno dei sensori di una coppia percepiscano per più di 10 misure (5 secondi)
rispettivamente la presenza di un ostacolo fisico e di un movimento, il sistema invia un avviso di
ostacolo rilevato.
In una futura versione commerciale, al momento di una rilevazione, verrà richiesto al farmacista un
intervento da remoto, coniugando questa estensione con il live streaming video, presentato più
avanti.
Si riporta ora lo schema di mappatura dei circuiti.

Accurate release system


La tecnologia GPS normalmente garantisce la localizzazione all’interno di un cerchio del diametro di
dieci metri, per cui si conosce con certezza il punto in cui il drone si trova con un errore di ±5m.
Come accennato nell’introduzione, PharmaCopter è pensato per effettuare consegne in zone poco
accessibili, o quantomeno è destinato a ricoprire aree rurali o montane, in cui non è importante che il

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 25
pacco raggiunga il punto previsto con una massima precisione. Inoltre, essendo il pacco dotato di un
mini-paracadute, è possibile che, deviato dal vento, questo non atterri comunque dove ci si
aspetterebbe.
Tale operazione è gestita tramite la coppia Cooking Hacks – Arduino, con l’ausilio di un servomotore,
collegato come nella figura alla pagina precedente.
In primis, la scheda Arduino fa effettuare al Cooking Hacks una richiesta HTTP GET, diretta al server
dell’applicazione Android; in risposta, questo riceve le coordinate del domicilio del cliente (fornite da
quest’ultimo al momento dell’evasione dell’ordine).
Il Cooking Hacks è dotato di fabbrica di un’antenna GPS. La scheda Arduino confronta in continuazione
i valori ricevuti dal server con quelli che riceve dallo shield. Quando sia la latitudine che la longitudine
assumono un valore pari a quello nella memoria nel server (tenuto conto di 10 metri di tolleranza
dell’errore della localizzazione dei GPS), la scheda attiva un servomotore, la cui rotazione fa sì che il
pacco si sganci e cada verso il suolo.

Live streaming video


Un altro modo di migliorare il livello di sicurezza è quello di fornire il drone di un “occhio”.
Tramite l’integrazione di una scheda Raspberry PI, si riesce a gestire flussi di dati e di calcolo molto più
consistenti, rispetto a quelli che riesce a sopportare una scheda Arduino.
In particolare, si riesce ad elaborare lo streaming video fornito da una webcam.
Il sistema è costituito da tre
schede, collegate a costituire
un circolo: Arduino one, Coo-
king Hacks Shield e Raspberry
PI.
Quest’ultima è l’unica compo-
nente attiva, alimentata trami-
te una comune power bank.
Sulla scheda Raspberry è stato
installato un sistema Linux ba-
sed (al momento, Ubuntu
14.04). Esso viene, quindi, uti-
lizzato in qualità di calcolatore
centrale. Al fine di garantire la
copertura, si utilizza la connes-
sione 3G fornita da una SIM card prepagata inserita all’interno del Cooking Hacks. Esso ed è
alimentato dalla scheda Arduino. Quest’ultima, invece, è alimentata dal Raspberry PI.
In realtà, in questo schema, la scheda Arduino ha l’unico compito di alimentare il Cooking Hacks, ma
la configurazione trova semantiche diverse nella realizzazione congiunta delle altre integrazioni

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 26
complementari.
Il Cooking Hacks è provvisto di una piccola webcam VGA, che punta in avanti (visibile in figura, sotto la
dicitura webcam frontale). Si intende far viaggiare il flusso video di questa webcam tramite rete 3G.
La configurazione non è complicata, per cui viene sinteticamente riportata di seguito.
Utilizzando il Raspberry PI come un computer, prima di tutto, è necessario avere tutti i driver dei
dispositivi correttamente installati. Una volta che il Cooking Hacks ha riconosciuto il modulo SIM5218,
il driver che consente la funzione 3G della SIM card, si riesce a stabilire la connessione alla rete
tramite i comandi AT.
Tramite il Raspberry PI, poi, viene effettuato un port forwarding al Cooking Hacks (da intendersi
sempre come modem), in modo tale che le richieste effettuate dal web all’indirizzo IP di quest’ultimo
vengano reindirizzate al Raspberry. In questo modo, all’accensione del sistema, quest’ultimo,
trasmette sulla porta 8081 il flusso video della webcam frontale.
Sebbene questo tipo di flusso video non garantisca qualità e fluidità ben lontane da quelle che
necessarie per effettuare delle riprese, questa integrazione regala notevoli vantaggi.
Ad esempio, di fronte alla segnalazione di un ostacolo, il farmacista può immediatamente controllare
la situazione e rendersi conto se si tratta di un reale pericolo, oppure di un falso allarme e decidere
così se proseguire il volo o meno.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 27
Accurate landing system
Il momento in cui, al contrario, è necessario avere una buona precisione di localizzazione nello spazio,
si ha alla fine del viaggio di ritorno, nel momento in cui il drone deve atterrare alla base, che
presumibilmente si trova all’ingresso della farmacia (in un piazzale, su un marciapiede, …) oppure nel
suo cortile.
A fronte di questa situazione, l’errore massimo che ci si può permettere è di 1-2 metri.
Fortunatamente, il GPS UBlox è dotato di controlli incrociati con dispositivi di trasmissione a terra,
che, in zone di copertura normale, massimizzano la precisione della georeferenziazione.
Al fine di rendere ancora più efficiente il processo di atterraggio, è stato sviluppato un sistema di
riconoscimento ottico di una bandiera a scacchi, collocata nel punto in cui si desidera che il drone si
posi.
Il codice atto al riconoscimento (disponibile nell’Appendice di questa tesi) viene fatto girare sulla
scheda Raspberry PI: utilizzando una seconda webcam (visibile in figura sotto la dicitura webcam
inferiore), la scheda elabora il flusso video e controlla la presenza della bandiera a scacchi.
Nel caso in cui la bandiera non venga riconosciuta, il drone atterra normalmente, con la precisione del
GPS di bordo, nel momento in cui perviene la prima segnalazione di basso livello di carica della
batteria.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 28
Progettazione
Lo studio di fattibilità di un prodotto viene effettuato durante la fase di progettazione, strutturata per
punti.

In primo luogo, si effettua la Logical Framework Analysis (LFA), utilizzata per sintetizzare in modo
razionale e sistematico tutta la struttura dell'iniziativa che si intende realizzare.

Si individua, quindi, il target del servizio offerto, suddividendo il bacino d’utenza commerciale e
intellettuale in gruppi di stakeholder e analizzandone i punti di interesse, le prospettive di adozione e
le possibili azioni atte ad aumentare l’interesse.

A fronte di tali stakeholder, si effettua la SWOT analysis, atta ad individuare, per ognuno di essi, i
punti di forza, quelli di debolezza, le opportunità e le minacce, in seguito all’adozione del servizio.

Si realizza, poi, il Quality Function Deployment, per verificare che i bisogni del cliente principale cui
PharmaCopter si rivolge siano stati correttamente individuati e per analizzarne la correlazione con le
caratteristiche tecniche del prodotto.

In relazione ai bisogni del cliente evidenziati nel QFD, si tracciano degli Spider Diagram, da cui si possa
evincere il livello di importanza di ognuno di essi per ognuno dei diversi stakeholder.

Si stila, dunque, un dissemination plan, per identificare i modi in cui i risultati e i deliverable del
progetto sono o saranno messi a disposizione delle parti interessate e del grande pubblico.
Si conclude la fase di progettazione con l’analisi dei potenziali problemi dell’applicazione, dei rischi
che essi possono comportare e delle soluzioni adottate in risposta, evidenziando le migliorie che esse
apporterebbero o apportano già e gli effetti previsti sul mercato riguardo la riuscita e la percezione
del progetto agli occhi dei suoi utilizzatori, con particolare attenzione all’utente finale.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 29
Logical Framework Analysis
Come già detto, gli ambiti di applicazione della tecnologia dei droni sono innumerevoli. Persino la
stessa struttura meccanica/elettronica del drone presentato in questo progetto sarebbe facil mente
adattabile ad impieghi estremamente diversi da quello preso in considerazione dagli scriventi, tra cui
molte delle utilizzazioni illustrate in precedenza.

Per ragioni di sintesi e di uniformità di lavoro, tutte le analisi qui di seguito riportate sa ranno
comunque riferite essenzialmente a quanto esposto all’inizio del presente elaborato, mentre le
possibili applicazioni alternative verranno discusse in separata sede.

Individuazione degli stakeholder


Con il termine stakeholder (o portatore di interesse) si indica un soggetto (o gruppo di soggetti)
influente nei confronti di un'iniziativa economica, sia essa un'azienda o un progetto.

Per quanto riguarda quello in analisi, sono stati individuati:

 Farmacisti: possessori o amministratori di una o più farmacie;

 Venditori di farmaci all’ingrosso: riforniscono le farmacie, almeno una volta al giorno (ma talvolta
anche 5 volte)

 Società farmaceutiche: aziende (normalmente SRL) che gestiscono i flussi informativi delle
farmacie e dei venditori di farmaci all’ingrosso;

 Case farmaceutiche: aziende dell'industria farmaceutica che si occupano della ricerca, della
produzione e della commercializzazione dei farmaci;

 Unità ambulanza del 118: gestite dal servizio sanitario di urgenza ed emergenza delle aziende
sanitarie locali, sono suddivise in:

- MSB - Mezzi di Soccorso di Base, con a bordo solo soccorritori (minimo 2), sono dotate dei presidi
necessari per il soccorso di base.

- MSI - Mezzi di Soccorso Intermedio, con a bordo, oltre ai soccorritori (di cui uno in funzione di autista)
anche un infermiere, solitamente in possesso di formazione "di area critica";

- MSA - Mezzi di Soccorso Avanzato, con a bordo soccorritori (di cui uno in funzione di autista), un
medico (solitamente anestesista-rianimatore) e generalmente anche un infermiere d'area critica; sono
spesso attrezzate con presidi sanitari di pertinenza medica, come, ad esempio, un defibrillatore
manuale o il necessario per l'intubazione.

Nella categoria delle ambulanze del servizio 118, si devono intendere incluse anche quelle delle
tante associazioni ed enti che gestiscono il primo soccorso e il pronto intervento (Croce Rossa,
Croce Verde, Misericordia, ecc.).

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 30
Description Matrix
Possibili azioni aumento
Stakeholder Punti d’interesse Prospettive di adozione
interesse

Farmacisti Costituiscono il target principale del I farmacisti sono da tempo abituati Nessuna: essendo il target prin-
progetto. a stipulare contratti d’acquisto per cipale, il prodotto è ottimizzato
prodotti o servizi estranei al nucleo per questo target.
La tecnologia PharmaCopter per-
metterebbe loro di raggiungere principale della farmacia (ad es.:
aree prima non servite e di fide- bilance pesapersone, analisi
lizzare la clientela sporadica. cliniche, consulenze nutrizionali,
ecc.), per cui l’acquisto di unità
PharmaCopter rientrerebbe
nell’ordinaria amministrazione.

Venditori di farmaci all’ingrosso Vista l’alta frequenza di ordini da I grossisti hanno un bacino d’utenza Aumentare la capacità di carico
parte dei farmacisti, una parte (se molto esteso, per cui sono già dotati (payload) dei PharmaCopter
non la maggior parte) delle di una rete di trasporti convenzio- permetterebbe di soddisfare
consegne presso le singole farmacie nale adatta a soddisfare la domanda richieste numericamente e
potrebbe essere effettuata tramite esistente. Con l’adozione di Pharma- ponderalmente più consistenti.
PharmaCopter. Copter, però, la domanda si innal-
zerebbe per soddisfare nuove
esigenze; in ogni caso, la consegna
tramite quadricottero rappresente-
rebbe un enorme risparmio in
termini di consumi, di mezzi e di
personale impiegato.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 31
Possibili azioni aumento
Stakeholder Punti d’interesse Prospettive di adozione
interesse

Società farmaceutiche Il valore tecnologico e innovativo Come nel caso della società Fornire il codice sorgente
del progetto potrebbe determinare "Farmaconsult SRL", partner del dell’applicazione, in modo che
un importante incremento del presente progetto, quasi tutte le sia più facilmente adattabile
numero di clienti. società farmaceutiche hanno alle esigenze specifiche di una
sviluppato specifici software, atti singola società, oppure stabilire
all’acquisto online di medicinali. un numero determinato di
L’app di PharmaCopter coniuga ad società farmaceutiche che
una prospettiva “brick-and-click” acquistino l’esclusiva del
(ordina e ritira) la possibilità di progetto garan-tirebbe un
ricevere la consegna a domicilio. incremento ed una
fidelizzazione della propria
clientela.

Case farmaceutiche Il mercato dei farmaci crescerebbe Alcune case farmaceutiche potreb- Troppa variabilità in base al tipo
modestamente, se la possibilità di bero decidere di sponsorizzare il di consensi che il progetto
consegna fosse estesa ad utenze progetto, dal momento che otter- potrà raccogliere una volta
che oggi hanno difficoltà a rebbero un discreto guadagno lanciato sul mercato.
procacciarsi i farmaci. indiretto dalla sua buona riuscita,
inoltre il settore farmaceutico nel
suo complesso registrerebbe una
crescita di mercato.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 32
Possibili azioni aumento
Stakeholder Punti d’interesse Prospettive di adozione
interesse

Unità ambulanza 118 La possibilità di salvare una vita Se nei paraggi di un incidente non Attivare l’utenza di tipo “Unità
umana costituisce sempre una sono presenti unità ambulanza, Ambulanza”, che garantisce la
priorità. Normalmente, le unità oppure vi sono MSB o MSI consegna di quadricotteri a
ambulanza del servizio sanitario sprovviste del necessario per un prescindere dal tipo di farmaci e
nazionale sono dotate del intervento d’urgenza, se (come di dal fatto che la carica della
necessario per effettuare un solito capita) c’è un medico in zona, batteria sia sufficiente per
intervento d’urgenza. Ma gli l’occorrente per l’assistenza può effettuare il viaggio di ritorno o
imprevisti? essere velocemente recapitato meno.
tramite PharmaCopter.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 33
Diagramma di Venn
Di seguito, viene riassunto graficamente il rapporto di interesse / clientela / correlazione con
PharmaCopter.
Al centro degli assi viene raffigurato l’insieme al quale il progetto principalmente si rivolge.
All’allontanarsi dal centro, invece, diminuisce il rapporto di stretta clientela, quindi l’interesse
diretto che ogni insieme nutre nei confronti del progetto.

Case farmaceutiche

Società

Venditori di farmaci farmaceutiche

all’ingrosso
Farmacisti

Unità
ambulanza

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 34
Swot Analysis
La Swot Analysis è uno strumento di pianificazione strategica usato per valutare i punti di forza
(Strengths), i punti di debolezza (Weaknesses), le opportunità (Opportunities) e le minacce
(Threats) di un progetto o in un'impresa o in ogni altra situazione in cui un'organizzazione o un
individuo debba assumere una decisione per il raggiungimento di un obiettivo. L'analisi può
riguardare l'ambiente interno (punti di forza e debolezza) o esterno di un'organizzazione (minacce
ed opportunità).
E’ importante specificare che IN NESSUN MODO la vendita di PharmaCopter è destinata al pubblico
(che infatti non compare tra gli stakeholders), in quanto non presenta in generale le stesse garanzie
di affidabilità e professionalità riscontrabili tra i farmacisti, nell’uso di un prodotto che può anche
risultare pericoloso.

Farmacisti:

PUNTI DI FORZA DEBOLEZZE

- Ne esiste un numero molto grande; - E’ necessaria una pubblicità efficace, per con-
- Sono abituati ad acquistare prodotti e servizi vincere un imprenditore che già conduce
dall’esterno; un’attività redditizia, ad intraprenderne una
nuova ed innovativa.
- Hanno un bacino d’utenza già definito e
consistente; - Il farmacista tendenzialmente non è un grande
esperto in tecnologia.
- E’ possibile vendere loro anche il servizio di
assistenza e di consulenza per tutto il ciclo-vita
del drone.

OPPORTUNITA’ MINACCE

- I farmacisti costituiscono il target principale del - Le normative vigenti che regolamentano il volo
drone, per cui il progetto è ottimizzato per loro; con controllo da remoto potrebbero scorag-
- Non esistono prodotti simili, tantomeno a giarne l’utilizzo;
basso prezzo; - La decisione di effettuare o meno l’acquisto
- I farmacisti “pionieri” otterrebbero un’esclusiva dipende fortemente dalle attitudini personali
importante: un’ottima occasione di differen- dello specifico farmacista.
ziazione rispetto ai competitors. - Nel caso in cui ci fossero incidenti dovuti alla
scarsa affidabilità del prodotto, i farmacisti ne
sarebbero direttamente responsabili.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 35
Venditori di farmaci all’ingrosso:

PUNTI DI FORZA DEBOLEZZE

- I grossisti devono comunque evadere un - L’introduzione della nuova tecnologia compor-


numero elevato di ordini; terebbe costi di formazione per gli operatori
- Ognuno di essi è alla ricerca di nuove strategie addetti ai droni.
per incrementare la propria fetta di mercato;
- Esiste già un ottimo rapporto fiduciario tra i
farmacisti ed i grossisti.

OPPORTUNITA’ MINACCE

- L’applicazione porterebbe un aumento notevo- - Nel caso in cui ci fossero incidenti o percezione
le dell’efficienza complessiva; di scarsa affidabilità del prodotto, la cattiva
- I costi di consegna calerebbero drasticamente. pubblicità si diffonderebbe nel modo più
veloce.

Società farmaceutiche:

PUNTI DI FORZA DEBOLEZZE

- Hanno già in casa la tecnologia di prodotti soft- - Esistono delle intersezioni tra il lavoro di una
ware destinati ai farmacisti; società farmaceutica e quello della società
- Normalmente ognuna di esse si occupa dei erogante il servizio di PHarmaCopter;
flussi informativi di un gran numero di - Le società farmaceutiche tendono ad esternaliz-
farmacie, per cui l’adozione da parte di una zare molto poco.
società promuoverebbe la medesima adozione
da parte di un buon numero di farmacie.

OPPORTUNITA’ MINACCE

- Una farmacia normalmente si affida ad una - Buona parte del lavoro delle società si basa su
sola società farmaceutica. L’offerta di un servizi di consulenza, per cui potrebbe crearsi
servizio come questo renderebbe il nome della un conflitto d’interessi;
società molto più vendibile. - Normalmente ognuna delle società si occupa
dei flussi informativi di un gran numero di
farmacie, per cui il peso del feedback di una
società è molto alto.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 36
Case farmaceutiche:

PUNTI DI FORZA DEBOLEZZE

Sono dei giganti del mercato, quindi: - Storicamente promotori di campagne


- Eserciterebbero pressioni importanti per il pubblicitarie non proprio “pulite”, a tutti i livelli,
cambiamento della normativa vigente sulla le case farmaceutiche potrebbero essere restie
regolamentazione dei voli con controllo da a un cambiamento di mission aziendale.
remoto;
- Potrebbero portare a una vera rivoluzione nel
modo di gestire i servizi farmaceutici.

OPPORTUNITA’ MINACCE

- Le case farmaceutiche sono alla costante ricer- - Anche se non si tratterebbe di clienti diretti,
ca di soluzioni per incrementare gli introiti. avere una cattiva reputazione agli occhi delle
case farmaceutiche significherebbe il fallimento
- Il cambio di scope delle case farmaceutiche
totale del progetto.
potrebbe spostare l’utenza che acquista
farmaci verso un pubblico più “tecnologico”.
- Alcuni presidi farmaceutici “particolari”
potrebbero essere reintrodotti con un concept
completamente diverso (preservativi, viagra,
ecc.)

Unità ambulanza del 118:

PUNTI DI FORZA DEBOLEZZE

- Clienti quasi obbligati: qualsiasi innovazione in - La tecnologia dei droni, al momento attuale, è
grado di risparmiare vite è moralmente ancora un po’ acerba per garantire un
irrinunciabile, oltre che auspicabile; supporto efficace ed efficiente per le unità
- Riduzione significativa dei costi sanitari ambulanza. Una soluzione potrebbe consistere
complessivi, dipendente dalla miglior efficacia nel dotare le ambulanze di un trasmettitore
dell'intervento di primo soccorso. per consentire un atterraggio perfetto del
drone.

OPPORTUNITA’ MINACCE

- Il numero di interventi di successo aumente- - Nel momento in cui il servizio di pronto inter-
rebbe significativamente; vento divenisse completamente dipendente da
- Il numero di volontari interessati a lavorare quello di PharmaCopter, un eventuale malfun-
con questa nuova tecnologia sarebbe molto zionamento di un drone potrebbe mettere a
più alto (secondo indagini condotte su repentaglio vite umane.
campioni di studenti).

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 37
Quality function development (QFD)
Questa parte del progetto è volta a scomporre l'attività di realizzazione del prodotto
PharmaCopter in sottoattività fra loro coordinate, il cui risultato finale è il prodotto stesso e tutta
la documentazione ad esso associata.
L’illustrazione del processo di sviluppo del prodotto è svolta principalmente tramite linguaggio
UML, sotto forma di use case, class, activity e sequence diagram e state chart.
Prima di arrivare a tale tipo di rappresentazione, però, è bene analizzare in maniera specifica il
sistema hardware e tracciare il Quality Function Deployment,
Di seguito, viene riportato l’intero QFD, seguito dalla spiegazione puntuale delle sue parti e dei
risultati ottenuti rispettivamente in ognuna di esse.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 38
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 39
Il Quality Function Deployment (QFD) è uno strumento che appartiene all’ultima generazione di
tecniche per la gestione della qualità.
Si tratta, nella fattispecie, di una sorta di metodo per trasformare le necessità (espresse solo in
modo qualitativo) dello stakeholder cui è principalmente rivolto il prodotto/servizio (nel nostro
caso, il farmacista) in parametri quantitativi, al fine di:
 sviluppare le funzioni che caratterizzano la qualità del progetto;

 implementare i metodi che permettono di ottenere la qualità di progettazione per quanto riguarda
sottosistemi, componenti ed elementi specifici del processo di produzione finora analizzato.

Nella pagina precedente si può esaminare la vista della cosiddetta “casa della qualità”. Di seguito si
propone un’analisi più approfondita delle singole parti che la compongono.

Bisogni del farmacista e loro importanza relativa


Le esigenze, o bisogni del cliente sono espresse, di solito, nella forma di caratteristiche qualita tive,
definite genericamente.
Nel nostro caso, sono stati individuati nove bisogni
principali per il farmacista, al cui interno si possono
individuare quattro macrocategorie:

 Capacità di consegna: è importante che abbia


un’ampia portata e venga effettuata in tempi brevi
– importanza complessiva: 16%;

 Customer safety: l’effettiva sicurezza e la sicurezza


percepita – importanza complessiva: 34%

 Precisione delle attività integrate: l’atterraggio e


lo sgancio sono precisi? – importanza
complessiva: 22%
 Validità complessiva dell’acquisto: quanto vale la
pena di effettuare l’investimento in relazione alla
durata del prodotto, al prezzo d’acquisto, ma
anche alla fatica necessaria per imparare ad
usarlo correttamente – importanza complessiva:
27%

Da questa suddivisione appare subito come la cate-


goria di gran lunga più importante sia la customer
safety: è necessario che, per un prodotto che può
causare danni importanti, sia per l’integrità del
prodotto, sia soprattutto per l’incolumità delle per-
sone, il livello di sicurezza garantito (e percepito) sia alto.
Consci di questa necessità, la prima preoccupazione è stata quella di coniugare la tecnologia inizia-
le, già disponibile sul mercato, di droni che effettuano un semplice viaggio point to point (come, ad
esempio, nel progetto Arducopter della 3D Robotics), con un algoritmo integrato di detect and

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 40
warning (identificazione degli ostacoli) appositamente ideato per la presente applicazione. Il carico
del drone, inoltre, è trasportato in una scatola leggera di polistirolo, che atterra sostenuta da un
apposito mini-paracadute, in modo da rallentare la velocità d’impatto ed avere la certezza che
questo sia assolutamente innocuo, perfino per un bambino.
La correttezza di questa scelta è rimarcata anche dalla notevole importanza che assume la
categoria relativa alla precisione delle attività che l’integrazione ha reso disponibili: per un drone
che effettua consegne, l’attività appunto di consegna, in particolare, assume rilevanza critica.

Peso dei bisogni e pianificazione della qualità

Dal confronto tra la situazione AS IS (relativa al prototipo sviluppato e presentato in questa sede) e
la situazione TO BE (relativa alla versione
che verrebbe sviluppata in seguito all’ot-
tenimento di ulteriori finanziamenti, si
possono dividere, stavolta, i bisogni del
farmacista in tre macrocategorie:

 Bisogni già soddisfatti: si tratta di


bisogni soddisfatti appieno dalle
caratteristiche già ottimizzate in fase
prototipale. Nella fattispecie, questa
categoria è costituita dalle
integrazioni create da zero, quali:
- il sistema di sgancio del carico,
ottenuto con un servomotore e
attivato al raggiungimento di
determinate coordinate, che
anticipano quelle del waypoint
fornito dal cliente;
- la tecnologia di atterraggio presso
la sede della farmacia, al
termine del viaggio di ritorno,
tramite il riconoscimento di una
bandiera a scacchi.

 Bisogni parzialmente soddisfatti: si tratta di necessità il cui soddisfacimento si


realizzerebbe o perfezionerebbe in una versione successiva. In particolare, si tratta delle
caratteristiche relative alla customer safety e al ciclo-vita del servizio (la cui prestazione
potrebbe essere ulteriormente migliorata acquistando materiali e batteria di miglior
qualità), nonché all’usabilità del sistema (riguardo al quale potrebbero essere effettuate
delle ricerche e dei miglioramenti anche a livello di software).

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 41
 Bisogni poco o per nulla soddisfatti: si tratta dei bisogni le cui caratteristiche hanno forte
potenzialità di miglioramento in una versione successiva. Specificamente, si parla del raggio
e dei tempi di ogni consegna (dipendenti quasi soltanto dalla qualità della batteria) e del
prezzo (che, nel momento in cui si passasse dalla fase sperimentale ad una produzione in
serie, si ridurrebbe in modo significativo).

Caratteristiche del prodotto


Con caratteristiche del prodotto si intendono quelle caratteristiche globali (di solito grandezze
misurabili) che, se sviluppate in modo corretto, dovranno soddisfare i bisogni del cliente. E’
importante che le caratteristiche corrispondano alle reali esigenze del cliente, e non a quelle
presunte o preventivate.
Per sintetizzarle, si traducono le specifiche generali del sistema in specifiche di dettaglio, con
particolare attenzione ai sottosistemi e ai componenti critici (cioè quelli che consentono di
realizzare le funzioni essenziali per le quali il prodotto è stato progettato).
Nell’interfaccia PharmaCopter sono state individuate quattordici caratteristiche di prodotto, visibili
nell’estratto qui sotto:

Esse possono essere divise in macrocategorie:


 Efficienza dei microcontrollori – importanza complessiva: 15%;

 Efficienza della batteria – importanza complessiva: 9%;

 Qualità dell’hardware – importanza complessiva: 10%;

 Qualità del software – importanza complessiva: 11%;

 Sviluppo del sistema di carico/scarico – importanza complessiva: 17%;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 42
 Qualità del segnale GPS – importanza complessiva: 28%;

 Qualità del sistema di detection and warning – importanza complessiva: 8%.

E’ facile intuire il motivo di una rilevanza così alta del segnale GPS: se questo viene perso, il drone
rischia di vagare a vuoto fino all’esaurimento della batteria!
Altre categorie di rilievo sono lo sviluppo del sistema carico/scarico, che costitui sce la differenza tra
un viaggio fatto a vuoto (o, peggio, un carico perso) e una consegna effettuata correttamente, e
quella riguardante l’efficienza dei microcontrollori, il cui malfunzionamento rischia di compromet-
tere seriamente la buona riuscita del progetto nel suo complesso.

Correlazione tra le caratteristiche


La matrice delle correlazioni,
posta sul “tetto” della House
of Quality ha forma triangola-
re ed è collocata parallela-
mente all’asse delle caratteri-
stiche del prodotto, e sopra di
esso (come visibile in figura).

La matrice delle correlazioni


consente di descrivere la rela-
zione che coesiste fra le varie
caratteristiche tecniche, me-
diante simboli univoci qualita-
tivi, che rappresentano l’anda-
mento positivo o negativo di
ciascuna; in altre parole, essa
identifica quali caratteristiche
si supportano vicendevolmen-
te e quali, invece, sono in con-
flitto tra loro.

L’assegnazione dell’andamen-
to positivo o negativo delle
correlazioni è basata sul
modo col quale ciascuna
proprietà influisce
sull’ottenimento di altre
proprietà, anche in base al
verso di preferenza nel quale si muove il valore di target per la caratteristica (visibile in figura): nel -
le correlazioni positive, una proprietà ne supporta un’altra, in quelle negative, una proprietà com-
porta l’assenza di un’altra, oppure l’innalzamento del livello della prima comporta un abbassamen-
to di quello della seconda.

Evidenziando le relazioni conflittuali (negative o fortemente negative), poi, la matrice favorisce le


s
oluzioni tempestive e i giusti compromessi (trade-off): le correlazioni negative rappresentano situa-
zioni che probabilmente non dovrebbero mai essere ignorate. I compromessi non identificati e i

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 43
compromessi non risolti conducono, infatti, a soddisfare male o per nulla le esigenze dei clienti.

Le correlazioni negative evidenziate nel nostro caso coesistono tra:


 Durata della batteria e peso e dimensioni del velivolo: una batteria più potente o anche
soltanto più capace, di solito, è più ingombrante e pesante;
 Durata della batteria e sistema di riconoscimento della bandiera a scacchi: poiché il rico-
noscimento avviene tramite optical recognition, è necessario elaborare dei dati video, che
richiedono una quantità di energia non indifferente.
Per arrivare alla soluzione ottima, vanno stabiliti dei compromessi, mediante aggiustamenti sui va -
lori di obiettivo delle caratteristiche. Nella fattispecie, l’acquisto di una batteria di miglior qualità
(quindi, con un miglior rapporto capacità/peso) risolverebbe la prima conflittualità, mentre la
seconda richiede l’ottimizzazione dell’algoritmo di riconoscimento della bandiera a scac chi. Un’idea
da sviluppare, in vista di una seconda versione di PharmaCopter, è l’aggiunta di un telemetro laser,
che rileverebbe la distanza da terra, una volta raggiunto il luogo di atterraggio, e che
permetterebbe di utilizzare il riconoscimento ottico per un tempo nettamente inferiore. Tale
installazione, però, andrebbe ad aumentare notevolmente il costo del singolo prototipo. Sono in
corso delle analisi sui trade-off tra la presenza o meno del dispositivo.

Nota
Non sono state effettuate analisi di benchmarking in fase progettuale: il presente progetto ha un
concept compltamente inedito, per cui un confronto con qualsiasi altra azienda che si occupi di
droni non darebbe risultati rilevanti ai fini dell’analisi che si sta conducendo.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 44
Spider Diagram
Si fornisce ora una rappresentazione grafica dei bisogni del cliente 1, riferiti però a tutte le tipologie
di stakeholder, in modo da mettere in evidenza quanto ogni specifica necessità sia attribuibile ad
una certa tipologia di cliente piuttosto che ad un’altra.
I bisogni del cliente sono identificati nelle macrocategorie che hanno costituito l’output del Quality
Function Deployment (QFD) riportato e spiegato più avanti.
Essi sono:
 Capacità di consegna: è importante che abbia un’ampia portata e venga effettuata in tempi
brevi – importanza complessiva: 16%;
 Customer safety: la sicurezza effettiva e la sicurezza percepita – importanza complessiva:
34%
 Precisione delle attività integrate: l’atterraggio e lo sgancio dei farmaci sono precisi? –
importanza complessiva: 22%

 Validità complessiva dell’acquisto: quanto vale la pena di effettuare l’investimento in


relazione alla durata del prodotto, al prezzo d’acquisto, ma anche alla fatica necessaria per
imparare ad usarlo correttamente – importanza complessiva: 27%
E’ interessante scoprire come le altre tipologie di stakeholder evidenzino bisogni e nutrano
interessi analoghi. Ciò però non toglie che possano essercene altri completamente diversi da quelli
del farmacista. In questa sede questi ultimi vengono deliberatamente tralasciati, limitandosi a
considerare quelli sopra elencati.

Nella tabella seguente viene approssimativamente stimato (con una scala da 1 a 5) l’interesse del
singolo stakeholder nei confronti di ognuno di questi macrobisogni.

Venditore di
Società Case Unità
Farmacista farmaci
farmaceutiche farmaceutiche ambulanza
all’ingrosso
Efficacia della
2 4 4 3 4
consegna

Customer safety 5 2 4 5 3

Precisione delle
4 3 2 1 4
attività integrate
Validità complessiva
3 3 5 5 1
dell’acquisto

1I bisogni riportati nel QFD, e così i risultati da esso derivanti, sono stati specificamente studiati in relazione al target
principale di PharmaCopter, costituito dal semplice farmacista

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 45
Si riportano adesso gli spider diagram relativi ai singoli stakeholder e, per concludere, uno spider
diagram completo, che sintetizza tutti gli altri.
Lo spider diagram del farmacista è la rappresentazione grafica dell’output del QFD, le cui
considerazioni sono largamente approfondite più avanti. In breve, il farmacista ha particolarmente
a cuore la salvaguardia del cliente e una buona efficienza delle attività integrate (in modo che la
consegna sia precisa e il ritorno alla base garantito).

Il grossista, come ci si può aspettare, non ha a cuore la sicurezza del farmacista suo cliente ,il quale,
avrà quotidianamente a che fare con droni PharmaCopter (a differenza di quanto ci si possa
aspettare da un comune cittadino). Viceversa, egli è interessato a poter effettuare consegne più ad
ampio raggio e con carichi molto più importanti, ottenendo eventualmente notevoli economie di
gestione.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 46
Le società farmaceutiche hanno interessi prevalentemente economici, per cui il bisogno che
esprimono maggiormente è di comprare un prodotto che valga il prezzo che pagano. Hanno anche
a cuore il buon andamento della tecnologia, in quanto la maggior parte dei loro clienti è costituita
da farmacisti.

Le case farmaceutiche guadagnano da un buon andamento dell’industria dei farmaci, per cui il loro
interesse sta nell’effettuare, tramite questo servizio (ma non differentemente da qualsiasi altra
modalità), il maggior volume di consegne. Ciò si rende possibile nel momento in cui il cliente è
soddisfatto di PharmaCopter e nel momento in cui i droni si possano diffondere il più possibile tra i
farmacisti.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 47
Le unità ambulanza non nutrono particolare interesse in un acquisto a buon mercato, in quanto il
valore morale del servizio è inestimabile.. Ciò che gli interessa è ricevere un drone più o meno in
sicurezza, il più in fretta possibile, che consegni il suo carico nel modo più efficiente possibile.
Inoltre, più i droni migliorano la loro capacità di consegna, più aumenta la loro utilità in ambito di
pronto intervento.

Proponiamo infine, per completezza, lo spider diagram aggregato.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 48
Dissemination plan
Per quanto riguarda l’attività di pubblicizzazione, esistono diversi modi di identificare la procedura
ottimale di autopromozione.
La dissemination identifica il processo con cui i risultati e i deliverable di un progetto vengono
messi a disposizione delle parti interessate e del grande pubblico.
Perché sia efficace, un dissemination plan deve spiegare come i risultati del progetto verranno
condivisi con i soggetti interessati, con le istituzioni competenti, con le organizzazioni e con i
singoli individui. In particolare, si indicano:
 Who (A chi): i soggetti cui esso è destinato;
 What (Cosa): il messaggio che sarà diffuso;

 Why (Perché): lo scopo della diffusione;


 How (Come): il metodo di diffusione;
 When (Quando): la tempistica di diffusione.
Idealmente, una volta che un prodotto viene commercializzato, il dissemination plan si collegherà
con una strategia di più ampia diffusione del programma di cui il prodotto è parte . Esso dovrebbe,
così, essere studiato con i partner del progetto e approvato da un comitato di gestione.

Nel nostro caso, possiamo identificare i seguenti risultati:

Who: i soggetti sono costituiti dagli stakeholders individuati nel paragrafo precedente:
 farmacisti;

 venditori di farmaci all’ingrosso;


 società farmaceutiche;
 case farmaceutiche;

 unità ambulanza.

What: la parte più pubblicizzata del progetto sarà il drone, in quanto la componente hardware è
dotata di maggior appeal, specialmente perché utilizzata in un settore col quale normalmente
non è associata. Tuttavia, la vera ricchezza del progetto sta nel codice generato da zero, sia per
quanto riguarda l’applicazione android che gestisce i flussi di ricerca e l’intero ciclo dell’ordine,
sia per quanto riguarda le integrazioni con il sistema APM.

Why: fondere la tecnologia informatica, elettronica e meccanica per proporre un progetto


innovativo ad un’industria in continua crescita, nonostante la crisi, è indiscutibilmente
un’azione interessante sotto il profilo economico. Al di là dell'interesse finanziario, poi, si
rilevano importanti implicazioni sociali: un servizio come PharmaCopter permette di fornire
con tempestività prodotti farmaceutici presso località disagiate o sul luogo di un incidente: una
risorsa utile, che migliorerebbe la qualità della vita e talvolta potrebbe anche salvare vite
umane.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 49
How: per i prodotti ed i servizi che non possono contare su una tradizione di utilizzo, né su un
marchio forte che sia garanzia d’affidabilità, l’unico modo per affermarsi è quello di espandersi
progressivamente, ottenendo finanziamenti sempre maggiori, man mano che il nome del
prodotto si consolida, diventando esso stesso sinonimo di garanzia.

When: la commercializzazione del prodotto avverrà su larga scala non appena il volo dei droni
potrà garantire un livello di sicurezza accettabile. In Italia, nel momento in cui le normative ENAC
consentiranno la possibilità di effettuare un volo automatico, sarà possibile programmare la
consegna automatizzata, senza subire la complicazione della supervisione a distanza.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 50
Analisi dei problemi
Un problema, generico o specifico che sia, non è mai isolato. E’ connesso e si intreccia con un
insieme di altri problemi, alle volte in modo caotico e indecifrabile.
Nel definire ognuno dei problemi di questo progetto, è necessario inserirlo in un sistema
gerarchico di problemi più generali e dettagliati: esso è causato e influenzato da altri problemi e a
sua volta ne determina altri: una valanga è determinata dall'accumulo di neve, ma a sua volta
determina la distruzione di case e boschi.

Albero dei problemi


In questo tipo di grafico, i problemi vengono rappresentati in forma illustrata. Per la sua stesura, si
colloca ogni problema in un insieme di problematiche più ampie, facendo attenzione a creare tra
ogni problema e quello posto ad un livello gerarchico immediatamente superiore un rapporto di
causa-effetto.
Nella pagina seguente è possibile esaminare l’albero dei problemi relativi a PharmaCopter.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 51
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 52
Come è facile notare, non è stato possibile identificare un problema principe che sia causa di tutti
gli altri. Per esemplificare le conseguenze dovute a tutta una serie di problemi, si è scelto di
utilizzare la formula “Problemi nel funzionamento”.
Le normative ENAC che regolano il volo di aeromodelli e SAPR (Sistemi Aeromobili a Pilotaggio
Remoto) sono piuttosto severe e permettono di volare solo a seguito del conseguimento di una
licenza speciale. Il rischio che un drone sia soggetto ad una caduta o una collisione non è mai nullo
e, specialmente se si tratta di un volo a bassa quota, la possibilità di creare danni a persone o cose
è significativa.
Le principali cause che comportano problemi nel funzionamento sono:
 Rischio di deterioramento: un drone è un apparecchio molto delicato: è possibile che,
specialmente in fase prototipale, alcune parti del PharmaCopter si rovinino. Sebbene al
momento della vendita venga garantita, insieme con il servizio e l’unità drone, anche un
servizio di assistenza tecnica e consulenza, il ciclo-vita della singola unità dev’essere
accettabilmente lungo (anche compatibilmente col prezzo): un drone che ad ogni
atterraggio perda qualche pezzo, o che con qualche millimetro di pioggia si danneggi a tal
punto da richiedere la sostituzione di alcuni pezzi non è proponibile.
 Rischio di rovinare o smarrire il carico: si tratta di un rischio più preoccupante. Un cliente
che ordina delle medicine (delle quali, magari, desidera non si sappia in giro) e si vede
consegnare con abile mossa il carico nel cortile del vicino, di sicuro non richiederà di nuovo
la consegna tramite quadricottero. Se poi si tratta di un venditore all’ingrosso, è probabile
che si perda un’intera rete di clienti.
 Rischio di schiantarsi: rappresenta senza dubbio il rischio più alto, nonché il più pericoloso.
Determinato da una serie articolata di cause, questo insieme di problemi è molto difficile
da controllare: entrano in gioco molte parti meccaniche, alcune delle quali sono difficili da
sostituire. Fortunatamente, però, buona parte delle cause che concorrono al crearsi di
questo rischio sono dovute a limitazioni connesse alla qualità costruttiva, accettabili
soltanto nella economica versione prototipale, mentre sarebbero automaticamente esclusi
o quanto meno drasticamente ridotti in una versione più avanzata, che possa beneficiare di
un budget più generoso.
La prospettiva di uno schianto, purtroppo, ha conseguenze estremamente variabili, e
pertanto non quantificabili. Di sicuro, nel caso di uno schianto, sussiste la probabilità di
dover comparire in tribunale per rispondere in giudizio.
Le principali conseguenze che derivano da un funzionamento inaffidabile si possono dividere in:
 Rischio di ripercussioni legali: L’ipotesi più probabile è quella che un farmacista non si
preoccupi di conseguire l’autorizzazione per il pilotaggio del PharmaCopter e si affidi
totalmente al controllo automatico del velivolo, ma non rispetti una o più tra le
raccomandazioni di sicurezza inserite nel manuale d’uso e manutenzione.
 Cattiva pubblicità: in una campagna promozionale di un prodotto, un incidente è
assimilabile ad un fulmine a ciel sereno! La percezione che la clientela ha di un prodotto
(così come di un marchio, di una società, …) è basata anche sul passaparola. Nel momento
in cui si verifichino dei problemi sulle unità PharmaCopter, in una comunità quale quella
degli operatori del farmaco, fortemente connessa e corporativa, è facile che la notizia si
diffonda, con conseguenze immaginabili [disastrose] sui clienti effettivi e sui potenziali
nuovi clienti.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 53
Analisi delle soluzioni
Se un problema è la formalizzazione di un disagio, l'obiettivo che ne consegue è l'eliminazione o
riduzione di quel disagio: ad ogni problema, quindi, corrisponde un obiettivo. Più è definito con
precisione il problema, meglio sarà definito l'obiettivo.

Albero delle soluzioni


Questo diagramma è il reciproco del diagramma dell’albero dei problemi visto in precedenza, e
rappresenta la situazione che si osserva nel momento in cui i problemi prima descritti vengono
risolti.
Nella pagina seguente, si può esaminare l’albero delle soluzioni relativo a PharmaCopter.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 54
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 55
Dal confronto tra albero dei problemi e albero delle soluzioni, è immediato notare che i due grafici
sono accomunati dalla medesima struttura. Ad ogni problema corrisponde univocamente, infatti,
una soluzione.
Partendo da una situazione in cui il funzionamento è “sicuro ed efficiente”, si può sperare di avere
soltanto ripercussioni positive.
In particolare, per conseguire un funzionamento ottimale del sistema, si devono perseguire i
seguenti miglioramenti:
 Aumento della vita utile del drone: il miglioramento della durata del ciclo-vita è
conseguente all’accortezza di scegliere eliche e motori con un buon rapporto
diametro/potenza. Inoltre, con l’integrazione del nostro software, predisposto per
effettuare l’atterraggio al termine del viaggio di ritorno su una bandiera a scacchi,
identificata tramite riconoscimento ottico, si evita la possibilità di un atterraggio su una
superficie irregolare o instabile, che potrebbe danneggiare il drone. L’integrazione, infine,
con la WWO API, permette di ottenere informazioni sulle condizioni climatiche,
dissuadendo il farmacista dall’effettuare un viaggio con clima avverso, preferendo in tal
caso l’opzione di concordare col cliente un ritiro a mano (casistica già gestita nella nostra
applicazione).
 Alta probabilità di consegna efficace ed efficiente: tramite l’utilizzo di due sistemi GPS
anziché uno, si riesce ad utilizzare il GPS uBlox, collegato all’APM, come una sorta di “pilota”
per le attività ordinarie di viaggio, mentre il GPS del Cooking Hacks si occupa, in parallelo, di
far partire le delicate attività di sgancio del pacco e di riconoscimento ottico in preparazione
all’atterraggio finale, quando lo uBlox non ha ancora raggiunto, in altitudine, le coordinate
fornite in fase di prenotazione.
 Bassa probabilità di schiantarsi: questa formula, accattivante quanto difficile da
raggiungere nella pratica, è il risultato di una fitta serie di migliorie: in primis, l’installazione
di dissipatori e l’acquisto di una batteria migliore (necessità emerse anche dal QFD)
permettono di aumentare l’autonomia di volo. L’integrazione del nostro algoritmo di
obstacle detection and warning (creata tramite l’incrocio dei segnali di sonar HC -SR04 e PIR
HC-SR501 ed un’astuta gestione dell’output da essi generato) permette di monitorare la
presenza di ostacoli in tutte e tre le direzioni in cui il drone si muove (avanti, destra,
sinistra). Infine, l’utilizzo di una scheda Arduino ONE in coppia con una Raspberry PI
permette di dividere il carico di lavoro in maniera intelligente: alla scheda Arduino vengono
affidate le operazioni di calcolo (che non richiedono un alto impiego di risorse né a livello di
calcolatore, né a livello di RAM), come ad esempio quelle relative all’algoritmo di obstacle
detection and warning illustrato poco fa. La scheda Raspberry, invece, si occupa degli
incarichi computazionalmente più pesanti, come l’optical recognition, che richiede risorse
grafiche importanti.

In questo modo, il prodotto offre automaticamente un buon margine di sicurezza (esigenza tra le
più avvertite tra i farmacisti), mentre una buona riuscita della consegna garantisce all’azienda una
reputazione ed una credibilità non discutibile, favorendo così, nel tempo, un aumento della
clientela ed, infine, la possibilità di diventare leader di una più estesa fetta di mercato.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 56
Realizzazione e funzionamento

Diagramma IDEF0
Tramite questo tipo di grafico, si effettua una modellazione funzionale: si analizzano, cioè, le
specifiche funzionali di PharmaCopter, usando un linguaggio di modellazione (sintassi e semantica)
semplice da comprendere per la rappresentazione della parte funzionale di processi.
Ogni rappresentazione è formata da diagrammi correlati fra loro da una struttura gerarchica a più
livelli. In ognuno di questi, le attività dei processi sono rappresentate da figure bidimensionali (di
solito rettangolari), mentre con delle frecce vengono rappresentati i flussi che entrano o escono dai
processi, secondo la seguente logica:
 le frecce posizionate a sinistra del processo rappresentano flussi di informazioni o di materiali
in input;
 le frecce posizionate a destra del processo rappresentano flussi di informazioni o di materiali in
output;
 le frecce posizionate in alto rappresentano dei vincoli all’esecuzione delle attività del processo;
 le frecce posizionate in basso, infine, vengono utilizzate per identificare gli attori del processo,
oppure sistemi di supporto all’esecuzione delle attività o risorse.

Inoltre, le frecce nere stanno a indicare flussi di materiali o informazioni già presenti nel prototipo
che presentiamo in questa sede (situazione AS IS), viceversa le frecce rosse indicano le possibili
variazioni che sono in preventivo in una prima versione commerciale.

I tre grafici successivi presentano diversi livelli gerarchici della struttura funzionale del prodotto:
 livello 0: si ha una visione globale delle specifiche funzionali del prodotto;
 livello 1: i processi sono suddivisi tra APP+SI (parte relativa all’applicazione android) e
DRONE (processi strettamente inerenti al volo, allo scarico e all’atterraggio del drone);
 livello 2: i processi inerenti al drone sono stati ulteriormente esplosi e suddivisi in base al
microcontrollore di riferimento (APM 2.6 oppure Arduino/Raspberry PI + Cooking Hacks
Shield).

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 57
Livello 0

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 58
Livello 1

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 59
Livello 2

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 60
Diagrammi UML
In ingegneria del software, UML (Unified Modeling Language) è un linguaggio di modellazione e
specifica, basato sul paradigma object-oriented, definendo così uno standard industriale unificato.
Esso svolge, quindi, un'importantissima funzione di "lingua franca" nella comunità della
progettazione e programmazione a oggetti: gran parte della letteratura di settore lo utilizza per
descrivere soluzioni analitiche e progettuali in modo sintetico e comprensibile a un vasto pubblico.
Il presente lavoro propone un Use Case Diagram che illustra le principali casistiche d’utilizzo, gli
Activity Diagram di quelle che prevedono maggior interazione utente-macchina, i Sequence
Diagram relativi al funzionamento di tutta la piattaforma (sia hardware, sia software), i relativi
State Chart, infine il Class Diagram inerente alla sola parte elettronica.
Si propone, adesso, una spiegazione sintetica di ognuno

Use Case Diagram


Lo Use Case Diagram (UCD o diagrammi dei casi d'uso) è un diagramma dedicato alla descrizione
delle funzioni e/o dei servizi offerti da un sistema, così come sono percepiti e utilizzati dagli attori
che interagiscono col sistema stesso. Esso si può considerare come uno strumento di rappresenta-
zione dei requisiti funzionali di un sistema, attorno al quale si sviluppano tutte le altre attività del
ciclo di vita del software.
I model element principali utilizzati negli Use Case Diagram UML sono tre:

 System: il sistema nel suo complesso è rappresentato come un rettangolo vuoto. Questo
simbolo viene implicitamente messo in relazione con gli altri: i model element che
rappresentano caratteristiche del sistema verranno posizionati all'interno del rettangolo,
mentre quelli che rappresentano entità esterne (appartenenti al dominio o al contesto del
sistema) sono posizionati all'esterno. In molti diagrammi UML il simbolo per il sistema
viene omesso in quanto la distinzione fra concetti relativi al sistema e concetti relativi al suo
contesto si può in genere considerare implicita.

 Actor: gli attori sono rappresentati graficamente nel diagramma da un'icona che
rappresenta un omino stilizzato. Formalmente, un attore è una classe con stereotipo
«actor». Praticamente, un attore rappresenta un ruolo coperto da un certo insieme di
entità interagenti col sistema (inclusi altri utenti, altri sistemi software, dispositivi
hardware). Un ruolo corrisponde a una certa famiglia di interazioni correlate che l'attore
intraprende col sistema.

 Use case : un caso d'uso è rappresentato graficamente con un'ellisse contenente il suo
nome. Formalmente, esso è un classifier dotato di comportamento; lo si potrebbe
intendere come una classe di comportamenti correlati. Praticamente, invece, esso
rappresenta una funzione offerta dal sistema a uno o più attori, descritta in maniera
completa e significativa dal punto di vista degli attori che vi partecipano.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 61
La relazione fondamentale negli Use Case Diagram è quella che congiunge gli attori con i casi d'uso
a cui essi partecipano, ovvero l'associazione. Un attore può essere associato a un qualsiasi numero
di casi d'uso, e viceversa. Pur non richiedendo ulteriori informazioni, l'associazione fra gli use case
e gli actor, si considera implicitamente dotata di una semantica più specifica rispetto all'associa-
zione generica UML: essa, infatti, implica uno scambio di messaggi fra attori e use case associati.
Sono state stabilite, poi, relazioni di inclusione ed estensione.
La relazione di inclusione fra use case, rappresentata da una linea tratteggiata con indicazione dello
stereotipo «include», indica che la funzione rappresentata da uno dei due use case (quello alla
base della freccia) necessita che quella rappresentata dall’altro (quello alla punta) sia stata svolta
completamente.
La relazione di estensione fra use case, invece, rappresentata da una linea tratteggiata con
indicazione dello stereotipo «extend», indica che la funzione rappresentata dallo use case "esten-
dente" (alla base della freccia) può essere impiegata nel contesto della funzione "estesa" (lo use
case alla punta), ovvero ne rappresenta una sorta di arricchimento.
Si noti che le relazioni di estensione e inclusione rappresentano concetti piuttosto vicini, ma che
l'orientamento delle frecce nei due casi si può descrivere come "opposto". La sottile differenza fra i
due stereotipi è la seguente:
«include» indica un frammento che viene sempre eseguito durante l’esecuzione del caso d'uso alla
base della freccia;
«extend» indica un frammento che può essere eseguito in determinate circostanze del caso d’uso
alla punta della freccia.
Nella pagina successiva, si propone il diagramma del progetto PharmaCopter. Come accennato
prima, vengono trattati soltanto i casi d’uso relativi all’utilizzo ordinario: non viene considerata
l’occorrenza di eventi esterni, né vengono messe in evidenza le integrazioni relative alla consegna
del carico e all’atterraggio, incluse nello use case “Effettua spedizione”.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 62
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 63
Activity Diagram
Secondo la stessa logica, si sviluppa l’activity diagram, che definisce le attività da svolgere per
realizzare una data funzionalità.

Esso può essere utilizzato durante la progettazione del software per dettagliare un determinato
algoritmo. Più in dettaglio, un activity diagram definisce una serie di attività o flusso (anche in
termini di relazioni tra le attività), i responsabili per le singole attività e i punti di decisione.

La struttura del diagramma è divisa come segue:

 Activity: indica una specifica attività che deve essere svolta all'interno della funzione ed è
rappresentata da un rettangolo smussato con una descrizione dell'attività.

 Flusso: il flusso è rappresentato tramite delle frecce orientate, che indicano la sequenza
temporale con cui devono essere effettuate le diverse attività. Con un cerchio pieno si
indica l'inizio del flusso, con due cerchi concentrici il suo termine.
Nel caso in cui due o più attività costituiscano delle alternative, siano cioè svolte o meno
rispetto ad una scelta, il punto di decisione è rappresentato da rombi dai quali partono i
flussi alternativi.
Il punto di ricongiungimento (join) è reso tramite un segmento su cui le frecce si
ricongiungono.

 Responsabilità: Il sistema o l'attore responsabile di una determinata attività è


rappresentato tramite una descrizione a cui afferisce una porzione dello schema,
individuata da una linea verticale (swimlane). Nel caso in analisi, si parla di sistemi software
e hardware, nonché di persone fisiche.

Per gli activity diagram relativi alle singole attività, si rimanda all’Appendice di questo lavoro.

Sequence Diagram
Un sequence diagram (o diagramma di sequenza) è la rappresentazione grafica di uno scenario,
ovvero una determinata sequenza di azioni in cui tutte le scelte sono state già effettuate; in pratica
nel diagramma non compaiono scelte, né flussi alternativi.

Normalmente, un Sequence Diagram tratta in maniera completa ognuna delle alternative che si
creano nelle attività, descrivendo, in termini di messaggi, le relazioni che intercorrono tra attori,
oggetti od entità del sistema che si sta rappresentando (sempre secondo la logica illustrata
precedentemente).

Un messaggio è un'informazione che viene scambiata tra due entità. Solitamente chi invia il
messaggio – la parte attiva – è l'attore.

Il messaggio è sincrono se l'emittente rimane in attesa di una risposta, o asincrono nel caso in cui
l'emittente non aspetti la risposta e questa può arrivare in un secondo momento. Il messaggio che
viene generato in risposta ad un precedente messaggio, al quale si riferisce anche come contenuto
informativo, è detto messaggio di risposta. Un messaggio in cui il ricevente è nello stesso tempo

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 64
l'emittente è, infine, detto ricorsivo.

Nell’Appendice di questo progetto, sono riportati tutti i Sequence Diagram prodotti inerentemente
al progetto in analisi.

Class Diagram
Il Class Diagram consente di descrivere tipi di entità, con le loro caratteristiche e le eventuali
relazioni fra questi tipi.
Gli strumenti concettuali utilizzati sono il concetto di classe del paradigma object-oriented e altri
correlati (come, ad esempio, la generalizzazione, che è una relazione concettuale assimilabile al
meccanismo object-oriented dell'ereditarietà).
I concetti principali trattati da questo tipo di grafico sono:
 Classe: L'elemento di modello principale dei diagrammi delle classi è la classe. Una classe
rappresenta una categoria di entità (istanze), nel caso particolare dette oggetti; il nome
della classe indica la categoria di entità descritta dalla classe. Ogni classe è corredata da un
insieme di attributi (che descrivono le caratteristiche o lo stato degli oggetti della classe) e
operazioni (che descrivono il comportamento della classe). Il simbolo grafico che
rappresenta le classi UML è un rettangolo suddiviso in tre scomparti, rispettivamente
dedicati al nome della classe, agli attributi e alle operazioni.

 Associazione: Due classi possono essere legate da associazioni che rappresentano i legami
(link) che possono sussistere fra gli oggetti delle classi associate. Ogni categoria di
associazione (aggregazione, composizione, dipendenza, generalizzazione, ecc.) viene
rappresentata mediante una particolare freccia che connette le due classi coinvolte. Tali
associazioni possono essere corredate da un insieme di informazioni aggiuntive, per
esempio relative alla molteplicità (il numero di oggetti delle due classi associate che
possono essere coinvolti in un link).

 Dipendenza: Due classi possono essere legate da una relazione di dipendenza, che indica
che la definizione di una delle due fa riferimento alla definizione dell'altra.

 Generalizzazione: Due classi possono essere legate da una relazione di generalizzazione,


che indica che una delle due classi (detta superclasse) si può considerare una
generalizzazione dell'altra (detta sottoclasse).

I diagrammi delle classi UML sono basati su versioni astratte di tali concetti, e possono essere
utilizzati per descrivere sostanzialmente qualsiasi contesto a qualsiasi livello di astrazione
(enfatizzandone, però, solo alcuni aspetti).
Si è scelto di limitarsi alla pubblicazione di quelli relativi ai sistemi custom, omettendo grafici
relativi a componentistica non sviluppata, integrata o applicata in modo originale all’interno del
progetto. Nell’Appendice di questo documento si possono osservare i diagrammi che fanno
riferimento alle Integrazioni complementari illustrate all’inizio.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 65
State Chart Diagram
Lo state chart diagram (o diagramma degli stati) descrive il comportamento di entità o di classi in
termini di stato (equivalentemente ad una macchina a stati): vengono mostrati gli stati che sono
assunti dall'entità o dalla classe in risposta ad eventi esterni.

L'insieme completo di stati che un'entità o una classe può assumere, dallo stato iniziale a quello
finale, ne rappresenta il ciclo di vita.

L’elemento principale rappresentato è lo stato, che si distingue in iniziale, intermedio e finale. Esso
descrive una qualità dell'entità o classe che si sta rappresentando (pratica aperta, in lavorazione,
sospesa, chiusa); l'evento è la descrizione dell'azione che comporta il cambiamento di stato,
l'azione è l'evento che ne consegue, la guardia è l'eventuale condizione che si deve verificare
perché si possa compiere l'azione.

Con questo diagramma, si chiude la trattazione UML sul funzionamento tecnico di PharmaCopter.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 66
Risultati
Nella presente sezione, si illustrano i risultati conseguiti dal progetto, descrivendo le modalità di
funzionamento del sistema da parte degli utilizzatori del servizio erogato da PharmaCopter e
mostrando il prototipo funzionante effettivamente realizzato, scomposto nelle sue componenti
essenziali.
Si premette che la rosa delle casistiche di utilizzo previste all’interno dell’applicazione è molto
complessa, per cui ci si limita ad analizzarne quelle più comuni o maggiormente degne di nota.
Coerentemente con quanto annunciato nella presentazione iniziale, si deve fare distinzione tra il
cliente (l’utente finale) e il farmacista.

Utilizzo del sistema da parte del cliente

Download dell’applicazione
Trattandosi di un’applicazione android, PharmaCopter può essere scaricata normalmente dal Play
Store, oppure dal sito web del progetto www.pharmacopter.tk.

Registrazione
Un cliente può registrare un nuovo account compilando un semplice form, in cui sceglie uno
username (che non sia già registrato) ed una password, ed infine inserisce i suoi dati anagrafici e il
suo indirizzo e-mail.
Viene così registrata una nuova utenza all’interno del database SQL presente sul server di
PharmaCopter.

Login
Il cliente registrato può ora effettuare il login ed accedere al Pannello Utente, inserendo le proprie
credenziali. Una volta effettuato l'accesso, l’utenza viene mantenuta fino al momento del logout.

Login con Facebook


In modo analogo modo, si può effettuare il login con Facebook. Sarà necessario inserire le proprie
credenziali, se l’utente non ha già effettuato il login nell’applicazione Facebook del suo smartphone
e, in ogni caso, al primo accesso si dovrà autorizzare PharmaCopter ad utilizzare i propri dati
d’accesso per il login.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 67
Scelta della farmacia
Prima della creazione di un ordine, l’applicazione manda al
server di PharmaCopter la posizione geografica dello
smartphone in uso; l’utente visualizza (tramite un web service
messo a disposizione da Google Maps) una mappa in cui
compare la sua posizione e quella delle farmacie presenti nelle
immediate vicinanze. Facendo tap sui singoli marker, l'utente
può visualizzarne il nome della farmacia e la distanza dal punto
in cui si trova.
Si evidenzia che, grazie all’integrazione di un ulteriore servizio
sempre firmato Google Maps, i marker vengono inseriti in
modo dinamico, per cui la vista viene aggiornata in base al
numero di farmacie che decidono di offrire il servizio di
consegna degli ordini tramite PharmaCopter.

Visualizzazione del catalogo


Scelta la farmacia, l’utente visualizza il catalogo dei prodotti
presenti al suo interno. La versione attuale visualizza una
lista allineata con un database gentilmente messo a
disposizione per questo progetto da Farmaconsult SRL
(società farmaceutica di San Mauro Torinese), aggiornato in
tempo reale con riferimento alle farmacie sue clienti (circa
l’80% delle farmacie del Piemonte). Per ogni prodotto, viene
visualizzato il prezzo di vendita e il numero di unità
disponibili.

Dettagli del prodotto


Facendo tap su un qualsiasi prodotto, si visualizzano alcune
informazioni aggiuntive ad esso associate, quali la categoria di
appartenenza, la classificazione ATC, il codice MINSAN e il nu-
mero di serie (informazioni utili per controllarne la corrispon-
denza con un medicinale di cui si è già in possesso).
Inserendo la quantità che desidera acquistare (per un valore
inferiore o pari alla disponibilità), il sistema calcola il subtotale
(moltiplicando il prezzo della singola unità per il numero di
elementi da acquistare) e consente di inserire i prodotti
all’interno del carrello virtuale.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 68
Visualizzazione del carrello
L’utente può visualizzare l’ordine nel carrello ed eventualmente perfezionarlo, modificandolo, fino
al momento in cui effettua il logout oppure sceglie di servirsi da una farmacia diversa (per esigenze
di programmazione, si è scelto di legare con una corrispondenza biunivoca ogni ordine ad una e
una sola farmacia). Nel momento in cui il cliente verifica che i prodotti nel carrello e il prezzo totale
siano quelli desiderati, può confermare l’ordine e dare inizio al processo della sua evasione.

Ciclo di evasione dell’ordine e sistema di notifiche


Ogni ordine passa per un ciclo in cui può assumere fino a un massimo di otto diversi stati.
L’attribuzione del primo di questi stati è un processo automatico, che viene scatenato in seguito
alla conferma del carrello, illustrata poco fa; viceversa, in
tutti gli altri casi, il cambiamento di stato di un ordine
avviene in conseguenza a una combinazione di azioni
effettuate sia da parte del cliente, sia da parte del
farmacista.
Al momento del cambio di stato di un ordine, vi è un
utente A che ha causato questo cambio e un utente B che
deve esserne informato, per far sì che il ciclo vada avanti.
A ogni cambio di stato, l’utente B riceve un messaggio di
notifica sul suo smartphone, tramite un sistema di
notifiche push (basato su un server applicativo e un
server sempre in ascolto), messo a disposizione degli
sviluppatori da Google Cloud Messaging.

Si elencano ora quelle azioni che può compiere il cliente:


 effettuare il pagamento di un ordine approvato
dal farmacista;
 contrassegnare un ordine in fase di spedizione
come recapitato;
 laddove il farmacista abbia accertato l’impossibili-
tà di effettuare una consegna tramite drone e
abbia richiesto il ritiro dell’ordine di persona
presso la farmacia, accettare il ritiro a mano; in
questo modo, l’ordine viene prenotato e
trattenuto a disposizione del cliente per una
settimana;
 annullare un ordine in qualsiasi momento, fino
alla fase di spedizione, contrassegnandolo come
respinto. A fronte di un ordine respinto, inoltre,
viene data al cliente la possibilità di contattare il
servizio clienti, al fine di comunicare eventuali
disservizi.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 69
Visualizzazione elenco ordini
Il cliente può visualizzare, in ogni momento, l’elenco degli ordini effettuati dalla propria utenza
presso le diverse farmacie, nonché lo stato di ciascuno di essi.

Barcode Scanner
Un servizio aggiuntivo offerto nel pannel-
lo utente è l’integrazione di un sistema di
riconoscimento di codici a barre o QR,
tramite la fotocamera dello smartphone.
Tramite questa funzione, è ancora più co-
modo ottenere dettagli riguardanti un
medicinale di cui si è già in possesso. L’u-
tente avvia l’apposita funzione e inqua-
dra il codice del medicinale; al momento
del riconoscimento, il sistema indica il
codice MINSAN e il numero di serie del prodotto, ridirigendo l’utente alla relativa pagina di
dettaglio. Il flash della sua fotocamera si avvia automaticamente, se necessario.

Utilizzo del sistema da parte del f armacista

Registrazione
Un farmacista può registrare un’utenza soltanto di persona, mediante la stipula di un contratto in
cui accetta di acquistare l’intero sistema PharmaCopter (drone + utenza farmacista) ed in cui
sottoscrive di disclaimer ove vengono indicate le responsabilità di cui accetta l’onere.

Login
Il farmacista può effettuare il login e accedere al Pannello
Farmacista inserendo le proprie credenziali. Una volta
effettuato l'accesso, l’utenza viene ricordata fino al momento
del logout.

Pannello clima
All’interno di questa vista, grazie ad un’integrazione di un
servizio reso disponibile da World Weather Online, il farmacista
può visualizzare le condizioni climatiche in corrispondenza delle
coordinate statiche del punto in cui la propria utenza è
registrata (differentemente dal cliente, che invece utilizza
coordinate dinamiche, le quali variano ad ogni login).
In particolare, sono visibili i dati relativi alle temperature
minime e massime (espresse in gradi centigradi), la velocità (in
chilometri all’ora) e la direzione (in gradi) del vento, le
condizioni climatiche e l'entità delle precipitazioni (in millimetri
d'acqua).

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 70
Visualizzazione delle condizioni di volo
Prima di approvare una consegna, il farmacista può valutare le condizioni di volo relative alla tratta
che il drone PharmaCopter deve eseguire per effettuare la consegna.
Nella fattispecie, egli può consultare il pannello clima della propria posizione e di quella in cui si
trova il cliente, nonché la mappatura delle altitudini della tratta. Questo servizio, erogato da
Google Elevation e visualizzabile grazie a Google Graph, offre la vista tramite grafico a barre
dell’altimetria di 250 punti tra quello di partenza e quello di arrivo, consentendo configurare in
modo appropriato i parametri di volo, oppure di valutare l’opportunità di non effettuare affatto la
consegna dell’ordine e di richiederne il ritiro a mano presso la farmacia.

Ciclo di evasione dell’ordine e sistema di notifiche


Come già fatto per il cliente, si elencano ora le azioni che può compiere il farmacista:
 Approvare un ordine in attesa di approvazione;
 Contrassegnare un ordine in attesa di approvazione come idoneo unicamente al ritiro a
mano;
 Contrassegnare un ordine in attesa di ritiro a mano come ritirato;
 Spedire un ordine pagato, commutandone, quindi, lo stato in spedito;
 Analogamente al cliente, anche il farmacista può contrassegnare un ordine in fase di
spedizione come recapitato;
 Respingere un ordine in qualsiasi momento.
Anche il farmacista ha la possibilità di contattare il servizio clienti, al fine di comunicare eventuali
disservizi.

Visualizzazione dell'elenco ordini


Al contrario del cliente, il farmacista può visualizzare, in ogni momento, l’elenco degli ordini
effettuati dai diversi utenti presso la sua farmacia, nonché lo stato di ognuno di essi.

Barcode Scanner
Questo servizio è erogato anche al farmacista, che può trarne utilità se, in un momento in cui si
trova fuori sede o lontano dal computer della farmacia (si ripropone l’esempio di farmacisti che
lavorano spesso fuori sede, in diverse filiali, o nel retrobottega) per controllare la presenza o meno
in magazzino (e magari il prezzo al pubblico o il numero di unità) di un determina to farmaco.

Live streaming video


Questo servizio è il risultato dell’integrazione complementare illustrata all’inizio del presente
lavoro.
Tramite una webview, è possibile visualizzare il flusso video ripreso dalla webcam frontale del
drone PharmaCopter all’interno dell’applicazione android.
In futuro, si prevede che questa integrazione, collegata al rilevamento degli ostacoli, permetta il
controllo del velivolo a distanza.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 71
Prototipo del drone realizzato
Si procede ora all’illustrazione del prototipo realizzato. Poiché quest’ultimo costituisce esso stesso
il risultato del lavoro di realizzazione ed assemblaggio delle componenti fisiche ed elettroniche
elencate all’inizio di questo lavoro, questa parte dell’elaborato sarà costituita da contenuti
prevalentemente fotografici.

Configurazione della componentistica


Lo scheletro del prototipo è stato realizzato tramite il frame Turnigy Talon, al quale sono stati
applicati alcuni piccoli pannelli di plexiglas realizzati all’occorrenza.
In questo modo, si sono creati tre diversi livelli, suddivisi a loro volta in piccoli “vani” atti ad ospita -
re le singole componenti.
Nella fattispecie, partendo dal più alto:
 Livello 3: nel vano vero e proprio, su una base ottagonale in plexiglas, è stata collocata una
piccola breadboard, alla quale sono collegati:
- Raspberry PI, cui a sua volta è
collegata la webcam frontale.
Esso alimenta la coppia Ardui-
no/Cooking Hacks Shield (di
cui più avanti) ed è alimentato
dalla Power Bank due livelli
più in basso;
- Arduino UNO: ad esso sono
collegati tre bundle di sensori
PIR/Sonar (uno per ogni dire-
zione di percorrenza), un led
che lampeggia in seguito alla
rilevazione di un ostacolo, un
servomotore atto allo sgancio
del pacco (di cui più avanti),
un pulsante atto al suo azio-
namento manuale;
- Cooking Hacks Shield: ad esso sono collegati un piccolo modulo GPS aggiuntivo, la webcam
inferiore, un’antenna 4G, e le schede di cui sopra;
- Modulo GPS uBlox: controllato dall’APM al livello subito inferiore, è collocato al livello più
alto in modo da ricevere meglio possibile il segnale di georeferenziazione inviato dai satelli-
ti.
 Livello 2: questo livello è il più protetto, poiché, oltre ad essere quello dotato di componentisti-
ca più soggetta a usura, da esso dipende la riuscita o meno di un volo.
Tale parte non è visibile a drone completamente montato, per cui viene proposta in un’immagi-
ne del drone parzialmente assemblato, in fase di messa a punto. Essa è costituita da:

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 72
APM: E’ il “pilota” dell’intero
sistema, controlla i voli, il rag-
giungimento delle coordinate
prestabilite (tramite lo uBlox
di cui sopra) e l’assetto del
drone, nei parametri di yaw,
roll e pitch;
- Power distribution module e
power distribution board:
queste due componenti costi-
tuiscono il sistema di ali-
mentazione dell’APM. Essi col-
legano la batteria direttamen-
te al microcontrollore;
- Ricevitore radio Orange ORX
DSM2 6 canali: nel caso in cui si vogliano eseguire voli pilotati, è necessario che a bordo sia
presente un ricevitore del segnale radio trasmesso dal radiocomando Spectrum DX6i, di cui
si è fatto menzione nella sezione relativa alle tecnologie utilizzate.
- Ulteriore componentistica elettronica/fisica: si tratta di ESC, motori ed eliche.
 Livello 1: questo livello è costituito unicamente dalle componenti atte all’alimentazione e dal
sistema di sgancio del pacco.
Distinguiamo:
- Turnigy 5000 mAh: batteria principale, atta ad alimentare l’APM, gli ESC e i motori;
- Powerbank 2800mAh: batteria secondaria, atta ad alimentare le schede aggiuntive
(Arduino, Raspberry PI e Cooking Hacks Shield), nonché le componenti minori ad esse
collegate;
- Servomotore Hitec 53: è un piccolo motore che viene attivato dalla scheda Arduino e fa
effettuare rotazioni di 90 gradi ad un gancetto innestato al di sopra di esso.

Al di sotto di questo primo


strato, si colloca il pacco di
polistirolo con attaccato il mini-
paracadute usa e getta. Il pacco è
dotato di tre piccole scanalature:
due da un lato, all’interno delle
quali si accoppiano due gancetti
passivi (presenti al di sotto del
pannello di plexiglas inferiore) e
il servomotore di cui sopra. In
questo modo, viene consentito lo
sgancio del pacco una volta
raggiunte le coordinate del punto
di consegna.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 73
Drone pronto per l’uso
Si conclude la sezione relativa al drone PharmaCopter con una sequenza di illustrazioni, relative
alle varie fasi del viaggio del drone ed esemplificative di quello che sarebbe il prodotto
commerciale.

Drone pronto per la partenza

Particolare dell’elettronica

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 74
Fase di sgancio del carico

Drone rientrato alla base

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 75
Conclusioni
In Italia, il volo a pilotaggio remoto è regolamentato tramite le normative ENAC.

Citando testualmente queste ultime, “gli aeromodelli non sono considerati aeromobili ai fini del
loro assoggettamento alle previsioni del Codice della Navigazione e possono essere utilizzati
esclusivamente per impiego ricreazionale e sportivo”.

Per quanto riguarda invece i SAPR (Sistemi Aeromobili a Pilotaggio Remoto), viene fatta distinzione
tra operazioni specializzate non critiche o critiche; queste ultime riguardano l’azione in aree
congestionate, assembramenti di persone, agglomerati urbani o infrastrutture e richiedono
un’autorizzazione specifica, rilasciata solo dopo che l’operatore abbia completato con esito
positivo la relativa attività di volo sperimentale.

Trattandosi della casistica estremamente più frequente, ciò si traduce nella necessità di tempi di
attesa molto lunghi e conseguimento di skill particolari, prima di poter usufruire del servizio.
Questo dimostra come questa nuova tecnologia sia percepita più come una minaccia, che come
una risorsa.

Siamo sicuri che, col tempo, l’organo legislativo si adeguerà all’evoluzione tecnologica e sarà più
disponibile a rischiare un piccolo incidente, piuttosto che privare il popolo italiano di una risorsa
così polivalente. Del resto, anche i fratelli Wright sono stati protagonisti di numerose dispute e
problemi col brevetto.

Col nostro lavoro, non ci aspettiamo di diventare pionieri del settore, né di portare una ventata di
innovazione rispetto alle tecnologie già presenti sul mercato, anche perché è estremamente
improbabile che la ricerca tesa al superamento dei limiti tecnologici che condividiamo con aziende
come Amazon, Google, o Poste Italiane, veda vincitore il nostro team.

Tuttavia, siamo sicuri che i nostri studi possano contribuire a creare una coscienza comune più
matura e nuove prospettive di sviluppo in questo mondo dalle potenzialità così entusiasmanti e
dalle applicazioni ancora così acerbe.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 76
Appendice
Nella presente sezione, vengono riportati tutti i documenti omessi in precedenza per questioni di
coesione e sintesi.

Activity Diagram
Si propongono ora gli activity diagram relativi alle singole attività. Si fa notare che il focus è
incentrato in maniera particolare su quelle che prevedono maggior interazione utente-macchina.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 77
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 78
…continua dalla pagina precedente

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 79
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 80
…continua dalla pagina precedente

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 81
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 82
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 83
Sequence Diagram
Seguono, ora, i Sequence Diagram prodotti inerentemente all’intero progetto in analisi.

Per comodità di lettura, i diagrammi sono stati ordinati in ordine di accadimento dell’attività di
riferimento.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 84
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 85
Nota
Il Sequence Diagram “Richiedi
Coordinate GPS” è relativo alla
casistica in cui il cliente abbia
disattivato il servizio di posi-
zionamento GPS, necessario alla
scelta della farmacia.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 86
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 87
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 88
Nota
Si riportano, da questa pagina in avanti,
per una maggior linearità espositiva, gli
scenari relativi al ciclo di base dell’or-
dine (fino al pagamento), e succes-
sivamente quelli relativi ai casi in cui
questo venga respinto o venga richiesto
il ritiro a mano per impossibilità di
consegnare tramite PharmaCopter.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 89
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 90
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 91
Per concludere, nelle pagine seguenti vengono riportati i sequence diagram relativi alle attività del drone, riguardanti la spedizione, lo sgancio del
carico, il ritorno alla base e l’atterraggio

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 92
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 93
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 94
Class Diagram
I Class Diagram relativi a tali integrazioni sono visibili nelle pagine seguenti.
Viene sottoposto, quindi, all’attenzione del lettore il core del lavoro effettuato su Arduino:
 il sistema di detection and warning, ovvero l’analisi di una delle tre coppie sonar-PIR;
 la comunicazione con i servizi esterni (3G e GPS).

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 95
State Chart Diagram

Con i diagrammi a stati di seguito riportati, si chiude la trattazione sull’UML.

Si è scelto di rappresentare in un solo state chart l’applicazione android, cui normalmente è stata
attribuita maggior importanza, mentre ancora una volta si è voluto evidenziare il funzionamento
delle parti elettroniche, dedicando un diagramma al drone nella sua interezza ed un altro allo
shield Cooking Hacks.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 96
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 97
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 98
PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 99
Codice sorgente
In questa sezione sono illustrati alcuni tra gli output più prettamente tecnici, che si ritiene abbiano
maggior rilevanza ai fini dell’illustrazione del progetto.

Codice android: it.sii.android.pharmacopter

About.java
package it.sii.android.pharmacopter;

import android.text.util.Linkify;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

public class About extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.about);

ImageView img = (ImageView) findViewById(R.id.logo_imageView);


img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent2 = new Intent();
intent2.setAction(Intent.ACTION_VIEW);
intent2.addCategory(Intent.CATEGORY_BROWSABLE);

intent2.setData(Uri.parse("http://www.pharmacopter.tk"));
startActivity(intent2);
}
});

TextView collegamento_textView = (TextView)


findViewById(R.id.link_textView);
collegamento_textView
.setText("Vuoi saperne di più? Visita il nostro sito
www.pharmacopter.tk");
Linkify.addLinks(collegamento_textView, Linkify.WEB_URLS);
}
}

CalcolaDistanze.java
package it.sii.android.pharmacopter;

public class CalcolaDistanze {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 100
double lat1, lat2, lon1, lon2;
double DefLineare = 0.9996;

public CalcolaDistanze() {
super();
}

public Double getDistanza(Double lat1, Double lat2, Double lon1, Double


lon2){

Double latM = Math.max(lat1, lat2);


Double latm = Math.min(lat1, lat2);
Double lonM = Math.max(lon1, lon2);
Double lonm = Math.min(lon1, lon2);

Double distanza = Math.sqrt((latM-latm)*(latM-latm)+(lonM-


lonm)*(lonM-lonm))*DefLineare*100;

return distanza;
}
}

CarrelloView.java
package it.sii.android.pharmacopter;

import it.sii.android.pharmacopter.R;
import it.sii.android.pharmacopter.classes.Prodotto;
import it.sii.android.pharmacopter.classes.CatalogoFill;
import it.sii.android.pharmacopter.classes.ItemCatalogo;
import it.sii.android.pharmacopter.db.DbCredenziali;
import it.sii.android.pharmacopter.task.PutNewOrderTask;

import java.util.List;
import java.util.Vector;
import org.json.JSONException;
import org.json.JSONObject;

import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.model.GraphUser;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class CarrelloView extends Activity {

private ItemCatalogo mProductAdapter;


private List<Prodotto> mCartList = new Vector<Prodotto>();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 101
double totale = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.carrello_view);
// connetto a db locale e copio i dati dell'utente (presi dal
dblocale)
// in usernadbl e pswdbl
// in modo da poterli utilizzare
DbCredenziali mMioDbHelper = null;
mMioDbHelper = new DbCredenziali(getApplicationContext());
SQLiteDatabase db = mMioDbHelper.getWritableDatabase();
final String sql = "SELECT username, password FROM credenziali";
Cursor c = db.rawQuery(sql, null);
final Context context = this;
final ListView listViewCatalog = (ListView)
findViewById(R.id.ListViewCatalog);

// Verifico se l'utente ha eseguito l'accesso da fb

final Session a = Session.getActiveSession();

if (a != null) {

Request request = Request.newMeRequest(a,


new Request.GraphUserCallback() {
@Override
public void onCompleted(GraphUser user,
Response response) {
// If the response is successful
if (a == Session.getActiveSession()) {
if (user != null) {

TextView NomeUtente =
(TextView) findViewById(R.id.NomeUtente);

NomeUtente.setText("Carrello di " + user.getName());


}

if (response.getError() != null)
{
TextView NomeUtente =
(TextView) findViewById(R.id.NomeUtente);
NomeUtente.setText("Il tuo
carrello");
}
}
}
});
request.executeAsync();
}

else if (c.moveToFirst()) {

System.out.println("ACCESSO ESEGUITO DA PAGINA LOGIN");

TextView NomeUtente = (TextView)


findViewById(R.id.NomeUtente);
NomeUtente.setText("Carrello di " + c.getString(0));
c.close();
db.close();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 102
}

mCartList = CatalogoFill.getCartList();
TextView tot = (TextView) findViewById(R.id.tot);

final Button processaOrdine = (Button)


findViewById(R.id.ProcessaOrdine);

if(mCartList.size() != 0)
{
processaOrdine.setVisibility(0);
listViewCatalog.setVisibility(0);

// CANCELLA LE SELECTIONS E COMPUTA IL TOTALE


for(int i=0; i<mCartList.size(); i++) {
totale +=
(mCartList.get(i).getPrezzo())*CatalogoFill.getProductQuantity(mCartList.get(i))
;
}

// CREA LA LISTA
mProductAdapter = new ItemCatalogo(mCartList,
getLayoutInflater());
listViewCatalog.setAdapter(mProductAdapter);

listViewCatalog.setOnItemClickListener(new
OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View
view, int position,
long id) {
// REMOVE OBJECT
}
});
tot.setText("Totale: " + totale + " EUR");
tot.setBackgroundResource(R.drawable.pannello_style);

}
else
{
processaOrdine.setVisibility(View.INVISIBLE);
}

final Button goBackRice = (Button) findViewById(R.id.RiceProd2);


goBackRice.setOnClickListener(new OnClickListener() {

Intent RiceProdIntent = new Intent(getApplicationContext(),


RiceProdLoader.class);

@Override
public void onClick(View v) {

if (v == goBackRice) {
// INTENT
startActivity(RiceProdIntent);
}

}
});

processaOrdine.setOnClickListener(new OnClickListener() {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 103
@Override
public void onClick(View v) {

final JSONObject JSONSendreal = new JSONObject();


int i=0;
for(Prodotto p: mCartList)
{
String n = cleanSpace(p.nome);
try {
JSONObject JSONSend = new JSONObject();
JSONSend.put("nome", n);
JSONSend.put("minsan1", p.minsan1);
JSONSend.put("minsan2", p.minsan2);
JSONSend.put("qta",
CatalogoFill.getProductQuantity(p));
JSONSend.put("prezzo", p.getPrezzo());
JSONSendreal.put("prodotto"+i,JSONSend);

i++;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

try {
JSONSendreal.put("total", totale);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// faccio partire il task passandogli la stringa
json contenente prodotto per prodotto i vari dettagli;
new PutNewOrderTask(CarrelloView.this,
context).execute(JSONSendreal.toString());
// svuoto il carrello
CatalogoFill.clearMap();
}
});
}

@Override
protected void onResume() {
super.onResume();

// Refresh the data


if(mProductAdapter != null) {
mProductAdapter.notifyDataSetChanged();
}
}

//pulisce i valori numerici dalle virgole e le parentesi quadre varie


public static String cleanSpace(String str){
return str.replaceAll(" ","%20");
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 104
CatalogoView.java
package it.sii.android.pharmacopter;

import it.sii.android.pharmacopter.DettagliProdotto;
import it.sii.android.pharmacopter.R;
import it.sii.android.pharmacopter.CarrelloView;
import it.sii.android.pharmacopter.classes.Prodotto;
import it.sii.android.pharmacopter.classes.CatalogoFill;
import it.sii.android.pharmacopter.classes.ItemCatalogo;
import it.sii.android.pharmacopter.db.DbFarmaciaSelezionata;

import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView;

public class CatalogoView extends Activity {

private List<Prodotto> mProductList;

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.catalogo_view);
TextView titoloCata = (TextView)
findViewById(R.id.titoloCata_textView);
TextView noProd = (TextView) findViewById(R.id.noProd_textView);

// STAMPO IL NOME DELLA FARMACIA


DbFarmaciaSelezionata mDbFarmaciaSelezionata = null;
mDbFarmaciaSelezionata = new
DbFarmaciaSelezionata(getApplicationContext());
SQLiteDatabase db = mDbFarmaciaSelezionata.getWritableDatabase();
final String sql = "SELECT nomefarmacia FROM farmacia ";
Cursor c = db.rawQuery(sql, null);
if (c.getCount() != 0) {
c.moveToFirst();
titoloCata.setText("Catalogo dei prodotti\nFarmacia: \"" +
c.getString(0) + "\"");
}
else{
titoloCata.setText("Errore: Nessuna farmacia è stata
selezionata.");
}

final String cStringa;


Bundle bundle = this.getIntent().getExtras();
cStringa = bundle.getString("cServerMsg");

if(cStringa.equals("[]"))

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 105
{
noProd.setText("Nessun prodotto trovato con questi criteri di
ricerca. Prova ad eseguire una nuova ricerca.");
}
else
{
//Setto visibili la LISTVIEW e il bottone "visualizza
carrello"
Button ButtonViewCart = (Button)
findViewById(R.id.ButtonViewCart);
ButtonViewCart.setVisibility(0);
ListView lv = (ListView) findViewById(R.id.ListViewCatalog);
lv.setVisibility(0);

// Ottengo una reference alla pagina che riempie il catalogo


prodotti
mProductList = CatalogoFill.getCatalog(getResources(),
cStringa);

// Create the list


ListView listViewCatalog = (ListView)
findViewById(R.id.ListViewCatalog);
listViewCatalog.setAdapter(new ItemCatalogo(mProductList,
getLayoutInflater()));
listViewCatalog.setOnItemClickListener(new OnItemClickListener() {

// ti porto alla pagina con i dettagli del prodotto


@Override
public void onItemClick(AdapterView<?> parent, View view, int
position,
long id) {
Intent dettagliProdottoIntent = new
Intent(getApplicationContext(), DettagliProdotto.class);
// FORNISCO LA POSIZIONE DELL'ELEMENTO SELEZIONATO

dettagliProdottoIntent.putExtra(CatalogoFill.PRODUCT_INDEX, position);
// FORNISCO I DATI RICEVUTI NELLA RISPOSTA DEL SERVER
dettagliProdottoIntent.putExtra("cServerMsg", cStringa);
startActivity(dettagliProdottoIntent);
}
});
}

//ti porto alla pagina carrello


Button viewShoppingCart = (Button)
findViewById(R.id.ButtonViewCart);
viewShoppingCart.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Intent viewShoppingCartIntent = new
Intent(getBaseContext(), CarrelloView.class);
startActivity(viewShoppingCartIntent);
}
});

}
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 106
Config.java
package it.sii.android.pharmacopter;

public interface Config {

// used to share GCM regId with application server - using php app server
static final String APP_SERVER_URL =
"http://www.pharmacopter.net/GCMNotification?shareRegId=1";
// http://www.pharmacopter.net/sendAll
// GCM server using php:
// http://192.168.1.17/gcm/gcm.php?shareRegId=1
// GCM server using java
// "http://192.168.1.17:8080/GCM-App-Server/GCMNotification?shareRegId=1";

// Google Project Number


static final String GOOGLE_PROJECT_ID = "241071548254";
static final String MESSAGE_KEY = "message";

DettagliOrdine.java
package it.sii.android.pharmacopter;

import it.sii.android.pharmacopter.R;
import it.sii.android.pharmacopter.db.DbAltitude;
import it.sii.android.pharmacopter.task.CambiaStatoTask;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.json.JSONException;
import org.json.JSONObject;

import com.paypal.android.sdk.payments.PayPalAuthorization;
import com.paypal.android.sdk.payments.PayPalConfiguration;
import com.paypal.android.sdk.payments.PayPalFuturePaymentActivity;
import com.paypal.android.sdk.payments.PayPalItem;
import com.paypal.android.sdk.payments.PayPalOAuthScopes;
import com.paypal.android.sdk.payments.PayPalPayment;
import com.paypal.android.sdk.payments.PayPalPaymentDetails;
import com.paypal.android.sdk.payments.PayPalProfileSharingActivity;
import com.paypal.android.sdk.payments.PayPalService;
import com.paypal.android.sdk.payments.PaymentActivity;
import com.paypal.android.sdk.payments.PaymentConfirmation;
import com.paypal.android.sdk.payments.ShippingAddress;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 107
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class DettagliOrdine extends Activity {

private static final String TAG = "paymentExample";


/**
* - Set to PaymentActivity.ENVIRONMENT_PRODUCTION to move real money.
*
* - Set to PaymentActivity.ENVIRONMENT_SANDBOX to use your test
credentials
* from https://developer.paypal.com
*
* - Set to PayPalConfiguration.ENVIRONMENT_NO_NETWORK to kick the
tires
* without communicating to PayPal's servers.
*/
private static final String CONFIG_ENVIRONMENT =
PayPalConfiguration.ENVIRONMENT_NO_NETWORK;

// note that these credentials will differ between live & sandbox
environments.
private static final String CONFIG_CLIENT_ID =
"AT8t8xB384j_EVJFwzrtM3WVxlT_v5kvJO_jLOoVh7Yo48PJpaSxBq1RnmBI";

private static final int REQUEST_CODE_PAYMENT = 1;


private static final int REQUEST_CODE_FUTURE_PAYMENT = 2;
private static final int REQUEST_CODE_PROFILE_SHARING = 3;

String id = "";
String tipo = "";
String farma = "";
String notificationReceiverUsername ="";

private static PayPalConfiguration config = new PayPalConfiguration()


.environment(CONFIG_ENVIRONMENT)
.clientId(CONFIG_CLIENT_ID)
// The following are only used in PayPalFuturePaymentActivity.
.merchantName("Hipster Store")

.merchantPrivacyPolicyUri(Uri.parse("https://www.example.com/privacy"))

.merchantUserAgreementUri(Uri.parse("https://www.example.com/legal"));

@Override
protected void onCreate(Bundle savedInstanceState) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 108
super.onCreate(savedInstanceState);

setContentView(R.layout.dettagli_ordine);

final Context context = this;


Intent intent = new Intent(this, PayPalService.class);
intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
startService(intent);
Bundle bundle = this.getIntent().getExtras();
id = bundle.getString("ID");
farma = bundle.getString("NomeFarma");
final String cli = bundle.getString("NomeCli");
final String data = bundle.getString("Data");
final String stato = bundle.getString("Stato");
tipo = bundle.getString("Tipo");
final String cliLat = bundle.getString("CliLat");
final String cliLon = bundle.getString("CliLon");
final String farmaLat = bundle.getString("FarmaLat");
final String farmaLon = bundle.getString("FarmaLon");

ImageView luce = (ImageView) findViewById(R.id.luce);


TextView idOrdine = (TextView) findViewById(R.id.idOrdine);
TextView date = (TextView) findViewById(R.id.data);
TextView nome = (TextView) findViewById(R.id.nome);
TextView summary = (TextView) findViewById(R.id.summary);
TextView status = (TextView) findViewById(R.id.status2);
TextView totale = (TextView) findViewById(R.id.totale2);
TextView comodo1 = (TextView) findViewById(R.id.comodo1);

// PULIZIA STRINGA JSON CONTENENTE ERRORI


String s0 = bundle.getString("JsonDettagli").replaceAll("\\\\", "");
String s1 = s0.replaceAll("total\":", "total\":\"");
String s2 = s1.replaceAll(",\"prodotto", "\",\"prodotto");
String s3 = s2.replaceAll("prezzo\":", "prezzo\":\"");
String s4 = s3.replaceAll("ordine\":\"", "ordine\":");
String s5 = s4.replace("}}\"}", "}}}");
String s6 = s5.replace("}\",\"prodotto", "},\"prodotto");
String s = s6.replaceAll(",\"minsan2", "\",\"minsan2");

System.out.println("dettagliOrdine: s pulita vale: " + s);


System.out.println("dettagliOrdine: Stato vale: " + stato);
System.out.println("dettagliOrdine: cliLat vale: " + cliLat);
System.out.println("dettagliOrdine: farmaLon vale: " + farmaLon);

final String total;


JSONObject j2 = null;
try {
j2 = new JSONObject(s);
String ord0 = j2.getString("ordine");
JSONObject j = new JSONObject(ord0);
total = j.getString("total");
String elencoTot = "";
boolean consegna = false;
double subt = 0.0;

System.out.println("j è lunga" + j.length());


for(int i=0;i<(j.length()-1);i++)
{
String pr = j.get("prodotto"+i).toString();
JSONObject prodotto = null;
prodotto = new JSONObject(pr);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 109
elencoTot += i+1 + ") " +
prodotto.getString("nome").replaceAll(" ", "") + "\n " +
prodotto.getString("qta") + " unità " + "Prezzo cad.: " +
prodotto.getString("prezzo") + " EUR";
subt +=
Double.parseDouble(prodotto.getString("prezzo"));
elencoTot += "\n SUBTOTALE: " + round(subt,
2) + " EUR\n\n";

// GESTISCO IL PAGAMENTO DELLA CONSEGNA A MANO O TRAMITE


PHARMACOPTER
System.out.println("DETTAGLIORD: Stato vale: " + stato);

if(!stato.contains("consegnaamano") &&
!stato.contains("daritirare"))
{
elencoTot += ">) CONSEGNA TRAMITE PHARMACOPTER" + "\n
Serv. unico " + "Prezzo per consegna: 20 EUR";
subt += 20.0;
elencoTot += "\n SUBTOTALE: " + round(subt,
2) + " EUR\n\n";
consegna = true;
}

System.out.println("elencoTot vale: " + elencoTot);

idOrdine.setText("Ordine n°: #PHA00" + id);

date.setText("del: " + data);

if (tipo.contains("farma"))
{
nome.setText("Effettuato da: " + cli);
}
else if (tipo.contains("cliente"))
{
nome.setText("Effettuato presso: " + farma);
}

summary.setText(elencoTot);

if(stato.contains("nonapprovato")){
status.setText("Stato dell'ordine:\nIN ATTESA DI
APPROVAZIONE");
System.out.println("DETTAGLIORD 1: stato vale: " +
stato);
luce.setBackgroundResource(R.drawable.b_white);;
}
else if(stato.contains("approvato")){
status.setText("Stato dell'ordine:\nAPPROVATO");
System.out.println("DETTAGLIORD 2: stato vale: " +
stato);
luce.setBackgroundResource(R.drawable.b_yellow);;
}
else if(stato.contains("pagato")){
status.setText("Stato dell'ordine:\nPAGATO");
luce.setBackgroundResource(R.drawable.b_green);;
}
else if(stato.contains("spedito")){
status.setText("Stato dell'ordine:\nSPEDIZIONE IN
CORSO...");

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 110
luce.setBackgroundResource(R.drawable.b_blue);;
}
else if(stato.contains("tornato")){
status.setText("Stato dell'ordine:\nRECAPITATO");
luce.setBackgroundResource(R.drawable.b_black);;
}
else if(stato.contains("respinto")){
status.setText("Stato dell'ordine:\nANNULLATO");
luce.setBackgroundResource(R.drawable.b_red);;
}
else if(stato.contains("consegnaamano")){
status.setText("Stato dell'ordine:\nNECESSARIO RITIRO A
MANO");
luce.setBackgroundResource(R.drawable.b_white);;
}
else if(stato.contains("daritirare")){
status.setText("Stato dell'ordine:\nIN ATTESA DI RITIRO
A MANO");
luce.setBackgroundResource(R.drawable.b_black);;
}

if (consegna)
{
totale.setText("TOTALE: " +
round((Double.parseDouble(total)+20),2) + " EUR ");
}
else
{
totale.setText("TOTALE: " + total + " EUR ");
}

Button gen1 = (Button) findViewById(R.id.genericButton);


Button gen2 = (Button) findViewById(R.id.genericButton2);
Button gen3 = (Button) findViewById(R.id.genericButton3);
Button gen4 = (Button) findViewById(R.id.genericButton4);

if(stato.contains("nonapprovato"))
{
if (tipo.contains("farma"))
{
gen1.setVisibility(0);
gen1.setText("Valuta condizioni di volo");

gen1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

Double mialat =
Double.parseDouble(cliLat);
Double mialon =
Double.parseDouble(cliLon);
Double clientelat =
Double.parseDouble(farmaLat);
Double clientelon =
Double.parseDouble(farmaLon);

// chiamo la funzione per salvare i


dati dell'altitudine,

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 111
getvalori(mialat, mialon, clientelat,
clientelon);

Intent googlegraph = new


Intent(getApplicationContext(),
GoogleGraph.class);
// aggiungo questi dati così nella pag
successiva posso usare nuovamente le weather api.
googlegraph.putExtra("clientelat",
clientelat);
googlegraph.putExtra("clientelon",
clientelon);
googlegraph.putExtra("mialat",
mialat);
googlegraph.putExtra("mialon",
mialon);

startActivity(googlegraph);
finish();
closeContextMenu();
}
});

gen2.setVisibility(0);
gen2.setText("Approva ordine");

gen2.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

notificationReceiverUsername = cli;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("approvato
");
Toast.makeText(context,
"L'ordine è stato
approvato.",
Toast.LENGTH_SHORT).show();
}
});

gen3.setVisibility(0);
gen3.setText("Respingi ordine");

gen3.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"RESPINTO"

notificationReceiverUsername = cli;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("respinto"
);
Toast.makeText(context,
"L'ordine è stato
annullato.",
Toast.LENGTH_SHORT).show();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 112
}
});

gen4.setVisibility(0);
gen4.setText("Richiedi consegna a mano");

gen4.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"RICHIEDI CONSEGNA A MANO"
notificationReceiverUsername = cli;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("consegnaa
mano");
Toast.makeText(context,
"Hai richiesto il ritiro a
mano per quest'ordine.",
Toast.LENGTH_SHORT).show();

}
});

}
else if(tipo.contains("cliente"))
{
comodo1.setText("Quest'ordine non è ancora stato
approvato. Si prega di ricontrollare più tardi.");
gen1.setVisibility(0);
gen1.setText("Annulla ordine");

gen1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"RESPINTO"
notificationReceiverUsername = farma;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("respinto"
);
Toast.makeText(context,
"L'ordine è stato
annullato.",
Toast.LENGTH_SHORT).show();
}
});
}
}

else if(stato.equals("approvato"))
{
if (tipo.contains("cliente"))
{
gen2.setVisibility(0);
gen2.setText("Paga adesso");
comodo1.setText("Il tuo ordine è stato approvato
come idoneo alla consegna tramite PharmaCopter.");

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 113
gen2.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

JSONObject ordineJson = new


JSONObject();
try {
ordineJson.put("id", id);
ordineJson.put("totale",total);
ordineJson.put("farmacia",farma);
ordineJson.put("data", data);
} catch (JSONException e) {
// TODO Auto-generated catch
block
e.printStackTrace();
}

// chiamo paypal

// QUESTI SONO I PARAMETRI CHE TI


PASSO: FATTELI BASTARE; L'ELENCO PRODOTTI VIENE VISUALIZZATO PRIMA
// STICAZZI SE NON C'è NELLA PARTE DI
PAYPAL. BASTERANNO L'ID E LA DATA E L'ORA, ECCHECCAZZO??
// BE', IO CI AGGIUNGO PURE USERNAME E
FARMACIA -.-
// INOLTRE L'INTEGRAZIONE SARA' PIU'
FACILE

// OCCHIO: NELLA PAGINA PAYPAL.CLASS,


ALLA FINE DEL PAGAMENTO, LO STATO DELL'ORDINE VA PORTATO A "PAGATO"

// Intent paypal = new


Intent(context,
// //Paypal.class);
// About.class);
//
// paypal.putExtra("ID", id); // DA
UTILIZZARE PER IMPOSTARE NEL DATABASE L'ORDINE A PAGATO
// paypal.putExtra("IDvistoDalCli",
"PHARMA00"+id); // DA MOSTRARE SULLA RICEVUTA DI PAYPAL
// paypal.putExtra("farma", farma);
// paypal.putExtra("cliente", cli);
// paypal.putExtra("data", data);
//
// startActivity(paypal);

// NO: new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo).execute("pagato");
// Toast.makeText(context,
// "L'ordine è stato pagato
correttamente.",
// Toast.LENGTH_SHORT).show();
/*
* PAYMENT_INTENT_SALE will cause the
payment to complete immediately.
* Change PAYMENT_INTENT_SALE to
* - PAYMENT_INTENT_AUTHORIZE to only
authorize payment and capture funds later.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 114
* - PAYMENT_INTENT_ORDER to create a
payment for authorization and capture
* later via calls from your server.
*
* Also, to include additional payment
details and an item list, see getStuffToBuy() below.
*/
PayPalPayment thingToBuy = null;
try {
thingToBuy =
getStuffToBuy(PayPalPayment.PAYMENT_INTENT_SALE,ordineJson.toString());
} catch (JSONException e) {
// TODO Auto-generated catch
block
e.printStackTrace();
}

/*
* See getStuffToBuy(..) for examples of
some available payment options.
*/

Intent intent = new


Intent(DettagliOrdine.this, PaymentActivity.class);

intent.putExtra(PaymentActivity.EXTRA_PAYMENT, thingToBuy);

startActivityForResult(intent,
REQUEST_CODE_PAYMENT);

}
});

gen3.setVisibility(0);
gen3.setText("Annulla ordine");

gen3.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"RESPINTO" - va fatto su database
notificationReceiverUsername = farma;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("respinto"
);
Toast.makeText(context,
"L'ordine è stato
annullato.",
Toast.LENGTH_SHORT).show();

}
});
}
else if(tipo.contains("farma"))
{
comodo1.setText(cli + " non ha ancora pagato
quest'ordine. Si prega di ricontrollare più tardi.");
gen1.setVisibility(0);
gen1.setText("Respingi ordine");

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 115
gen1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"RESPINTO" - va fatto su database
notificationReceiverUsername = cli;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("respinto"
);
Toast.makeText(context,
"L'ordine è stato
respinto.",
Toast.LENGTH_SHORT).show();

}
});
}
}

else if(stato.equals("pagato"))
{
if (tipo.contains("cliente"))
{
comodo1.setText("Il tuo pagamento è stato
correttamente ricevuto. Un PharmaCopter verrà spedito a breve");
}
else if (tipo.contains("farma"))
{
comodo1.setText(cli + " ha regolarmente pagato
l'ordine ed è in attesa della spedizione.");
gen1.setVisibility(0);
gen1.setText("Effettua la spedizione");

gen1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"SPEDITO"
notificationReceiverUsername = cli;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("spedito")
;
Toast.makeText(context,
"L'ordine è stato segnalato
come spedito.",
Toast.LENGTH_SHORT).show();

}
});
}
}

else if(stato.equals("spedito"))
{
if (tipo.contains("cliente"))
{
comodo1.setText("Il tuo ordine è stato spedito e
sarà recapitato a momenti.");

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 116
gen1.setVisibility(0);
gen1.setText("Segnala come ricevuto");

gen1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"TORNATO"
notificationReceiverUsername = farma;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("tornato")
;
Toast.makeText(context,
"La ricezione dell'ordine è
stata correttamente segnalata.",
Toast.LENGTH_SHORT).show();

}
});

}
else if (tipo.contains("farma"))
{
comodo1.setText("Un PharmaCopter è stato spedito a
" + cli + ".");
gen1.setVisibility(0);
gen1.setText("Segnala come recapitato");

gen1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"TORNATO"
notificationReceiverUsername = farma;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("tornato")
;
Toast.makeText(context,
"Hai segnalato l'ordine
come recapitato.",
Toast.LENGTH_SHORT).show();

}
});
}
}

else if(stato.equals("tornato"))
{
comodo1.setText("L'ordine è contrassegnato come
recapitato.");
gen1.setVisibility(0);
gen1.setText("Qualcosa è andato storto? Contatta il
nostro servizio clienti!");
gen1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
String toDial = "tel:+393206271908";

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 117
startActivity(new Intent(Intent.ACTION_CALL,
Uri.parse(toDial)));
}
});
}

else if(stato.equals("respinto"))
{
comodo1.setTextColor(R.color.red);
comodo1.setText("L'ordine è stato respinto in quanto
momentaneamente non idoneo alla consegna tramite PharmaCopter.");

gen1.setVisibility(0);
gen1.setText("Qualcosa è andato storto? Contatta il
nostro servizio clienti!");
gen1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
String toDial = "tel:+393206271908";
startActivity(new Intent(Intent.ACTION_CALL,
Uri.parse(toDial)));
}
});
}

else if(stato.equals("consegnaamano"))
{
if (tipo.contains("cliente"))
{
comodo1.setText("Il tuo ordine è momentaneamente
non idoneo alla consegna tramite PharmaCopter.\nTuttavia, puoi richiederne il
blocco ed effettuare il ritiro a mano presso la farmacia " + farma + " entro 7
giorni lavorativi dal momento dell'evasione.\nRisparmierai le spese del
PharmaCopter!");
gen2.setVisibility(0);
gen2.setText("Scegli ritiro a mano");
gen2.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"DARITIRARE" - va fatto su database
notificationReceiverUsername = farma;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("daritirar
e");
Toast.makeText(context,
"Hai accettato il ritiro a
mano per quest'ordine.",
Toast.LENGTH_SHORT).show();

}
});

gen3.setVisibility(0);
gen3.setText("Respingi ordine");

gen3.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 118
// CAMBIA STATO DELL'ORDINE IN
"RESPINTO"

notificationReceiverUsername = farma;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("respinto"
);
Toast.makeText(context,
"L'ordine è stato
annullato.",
Toast.LENGTH_SHORT).show();

}
});
}
else if (tipo.contains("farma"))
{
comodo1.setText("Per quest'ordine è stato
richiesto il ritiro a mano.\nDa ritirare entro: " + dataExp(data));
gen1.setVisibility(0);
gen1.setText("Respingi ordine");

gen1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"RESPINTO" - va fatto su database
notificationReceiverUsername = cli;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("respinto"
);
Toast.makeText(context,
"L'ordine è stato
annullato.",
Toast.LENGTH_SHORT).show();

});
}
}

else if(stato.equals("daritirare"))
{
comodo1.setText("Quest'ordine è stato bloccato per
essere ritirato a mano.\nDa ritirare entro: " + dataExp(data));
if (tipo.contains("cliente"))
{
gen1.setVisibility(0);
gen1.setText("Annulla ordine");
gen1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"RESPINTO" - va fatto su database
notificationReceiverUsername = farma;
new
CambiaStatoTask(DettagliOrdine.this,

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 119
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("respinto"
);
Toast.makeText(context,
"L'ordine è stato
annullato.",
Toast.LENGTH_SHORT).show();

}
});
}
else if (tipo.contains("farma"))
{
gen1.setVisibility(0);
gen1.setText("Respingi ordine");

gen1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// CAMBIA STATO DELL'ORDINE IN
"RESPINTO" - va fatto su database
notificationReceiverUsername = cli;
new
CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("respinto"
);
Toast.makeText(context,
"L'ordine è stato
respinto.",
Toast.LENGTH_SHORT).show();

}
});
}
}

} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

///// ROBBA DI PAYPAL ///////

private PayPalPayment getThingToBuy(String paymentIntent,String


ordineJson) throws JSONException {
JSONObject OrdineJson = new JSONObject(ordineJson);
String id = OrdineJson.getString("id");
String total = OrdineJson.getString("totale");
String farmacia = OrdineJson.getString("farmacia");
String data = OrdineJson.getString("data");

return new PayPalPayment(new BigDecimal(total), "EUR",


"Ordine PharmaCopter n°: #PHA00" +id+" \nEffettuato presso la farmacia:
"+farmacia+"\n In Data: "+ data+"\n PREZZO TOTALE: " +total+"EUR",
paymentIntent);
}

/*

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 120
* This method shows use of optional payment details and item
list.
*/
private PayPalPayment getStuffToBuy(String paymentIntent,String
ordineJson) throws JSONException {

JSONObject OrdineJson = new JSONObject(ordineJson);


String id = OrdineJson.getString("id");
String total = OrdineJson.getString("totale");
String farmacia = OrdineJson.getString("farmacia");
String data = OrdineJson.getString("data");

//--- include an item list, payment amount details


PayPalItem[] items =
{
new PayPalItem("Ordine n°: #PHA00" +id, 1, new
BigDecimal(Double.parseDouble(total)), "EUR",
"pene")
};
BigDecimal subtotal = PayPalItem.getItemTotal(items);
BigDecimal shipping = new BigDecimal("20");
BigDecimal tax = new BigDecimal("0");
PayPalPaymentDetails paymentDetails = new
PayPalPaymentDetails(shipping, subtotal, tax);
BigDecimal amount = subtotal.add(shipping).add(tax);
PayPalPayment payment = new PayPalPayment(amount, "EUR",
"Ordine n°: #PHA00" +id, paymentIntent);
payment.items(items).paymentDetails(paymentDetails);

//--- set other optional fields like invoice_number, custom


field, and soft_descriptor

payment.custom("Ordine: #PHA00"+id+"\nEffettuato presso:


"+farmacia+"\nIl: "+ data);
return payment;
}

/*
* Add app-provided shipping address to payment
*/
private void addAppProvidedShippingAddress(PayPalPayment
paypalPayment) {
ShippingAddress shippingAddress =
new ShippingAddress().recipientName("Alberto
Lisanti").line1("Via Sestriere, 137")

.city("Rivoli").state("TO").postalCode("10090").countryCode("IT");
paypalPayment.providedShippingAddress(shippingAddress);
}

/*
* Enable retrieval of shipping addresses from buyer's PayPal
account
*/

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 121
public void onProfileSharingPressed(View pressed) {
Intent intent = new Intent(DettagliOrdine.this,
PayPalProfileSharingActivity.class);

intent.putExtra(PayPalProfileSharingActivity.EXTRA_REQUESTED_SCOPES,
getOauthScopes());
startActivityForResult(intent,
REQUEST_CODE_PROFILE_SHARING);
}

private PayPalOAuthScopes getOauthScopes() {


/* create the set of required scopes
* Note: see
https://developer.paypal.com/docs/integration/direct/identity/attributes/ for
mapping between the
* attributes you select for this app in the PayPal
developer portal and the scopes required here.
*/
Set<String> scopes = new HashSet<String>(
Arrays.asList(PayPalOAuthScopes.PAYPAL_SCOPE_EMAIL,
PayPalOAuthScopes.PAYPAL_SCOPE_ADDRESS) );
return new PayPalOAuthScopes(scopes);
}

@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == REQUEST_CODE_PAYMENT) {
if (resultCode == Activity.RESULT_OK) {
PaymentConfirmation confirm =

data.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION);
if (confirm != null) {
try {
Log.i(TAG,
confirm.toJSONObject().toString(4));
Log.i(TAG,
confirm.getPayment().toJSONObject().toString(4));
/**
* TODO: send 'confirm' (and possibly
confirm.getPayment() to your server for verification
* or consent completion.
* See
https://developer.paypal.com/webapps/developer/docs/integration/mobile/verify-
mobile-payment/
* for more details.
*
* For sample mobile backend interactions,
see
* https://github.com/paypal/rest-api-sdk-
python/tree/master/samples/mobile_backend
*/
Toast.makeText(
getApplicationContext(),
"PaymentConfirmation info received
from PayPal", Toast.LENGTH_LONG)
.show();

} catch (JSONException e) {
Log.e(TAG, "an extremely unlikely failure
occurred: ", e);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 122
}
}

// qui ci devo far partire l'asynk task


notificationReceiverUsername = farma;
new CambiaStatoTask(DettagliOrdine.this,
getApplicationContext(),id,tipo,notificationReceiverUsername).execute("pagato");

} else if (resultCode == Activity.RESULT_CANCELED) {


Log.i(TAG, "The user canceled.");
} else if (resultCode ==
PaymentActivity.RESULT_EXTRAS_INVALID) {
Log.i(
TAG,
"An invalid Payment or PayPalConfiguration
was submitted. Please see the docs.");
}
} else if (requestCode == REQUEST_CODE_FUTURE_PAYMENT) {
if (resultCode == Activity.RESULT_OK) {
PayPalAuthorization auth =

data.getParcelableExtra(PayPalFuturePaymentActivity.EXTRA_RESULT_AUTHORIZATION);
if (auth != null) {
try {
Log.i("FuturePaymentExample",
auth.toJSONObject().toString(4));

String authorization_code =
auth.getAuthorizationCode();
Log.i("FuturePaymentExample",
authorization_code);

sendAuthorizationToServer(auth);
Toast.makeText(
getApplicationContext(),
"Future Payment code received from
PayPal", Toast.LENGTH_LONG)
.show();

} catch (JSONException e) {
Log.e("FuturePaymentExample", "an extremely
unlikely failure occurred: ", e);
}
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Log.i("FuturePaymentExample", "The user canceled.");
} else if (resultCode ==
PayPalFuturePaymentActivity.RESULT_EXTRAS_INVALID) {
Log.i(
"FuturePaymentExample",
"Probably the attempt to previously start
the PayPalService had an invalid PayPalConfiguration. Please see the docs.");
}
} else if (requestCode == REQUEST_CODE_PROFILE_SHARING) {
if (resultCode == Activity.RESULT_OK) {
PayPalAuthorization auth =

data.getParcelableExtra(PayPalProfileSharingActivity.EXTRA_RESULT_AUTHORIZATION)
;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 123
if (auth != null) {
try {
Log.i("ProfileSharingExample",
auth.toJSONObject().toString(4));

String authorization_code =
auth.getAuthorizationCode();
Log.i("ProfileSharingExample",
authorization_code);

sendAuthorizationToServer(auth);
Toast.makeText(
getApplicationContext(),
"Profile Sharing code received from
PayPal", Toast.LENGTH_LONG)
.show();

} catch (JSONException e) {
Log.e("ProfileSharingExample", "an extremely
unlikely failure occurred: ", e);
}
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Log.i("ProfileSharingExample", "The user
canceled.");
} else if (resultCode ==
PayPalFuturePaymentActivity.RESULT_EXTRAS_INVALID) {
Log.i(
"ProfileSharingExample",
"Probably the attempt to previously start
the PayPalService had an invalid PayPalConfiguration. Please see the docs.");
}
}
}

private void sendAuthorizationToServer(PayPalAuthorization


authorization) {

/**
* TODO: Send the authorization response to your server,
where it can
* exchange the authorization code for OAuth access and
refresh tokens.
*
* Your server must then store these tokens, so that your
server code
* can execute payments for this user in the future.
*
* A more complete example that includes the required app-
server to
* PayPal-server integration is available from
* https://github.com/paypal/rest-api-sdk-
python/tree/master/samples/mobile_backend
*/

@Override
public void onDestroy() {
// Stop service when done
stopService(new Intent(this, PayPalService.class));

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 124
super.onDestroy();
}

public static double round(double value, int places) {


if (places < 0) throw new IllegalArgumentException();

long factor = (long) Math.pow(10, places);


value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}

// funzione per creare 256 punti nel path e ottenere 256 valori di
// altitudine sfruttando la funzione getElevation from google maps
public void getvalori(Double longitude, Double latitude, Double
longitude2,
Double latitude2) {
Double valorelat;
Double valorelong;
Double longPartenza = longitude;
Double latPartenza = latitude;
Double longArrivo = longitude2;
Double latArrivo = latitude2;
Double longLength = (Math.max(longArrivo, longPartenza) -
Math.min(
longArrivo, longPartenza)) / (40 - 1);
Double latLength = (Math.max(latArrivo, latPartenza) -
Math.min(
latArrivo, latPartenza)) / (40 - 1);
int i = 0;
DbAltitude mMioDbAltitude = null;
mMioDbAltitude = new DbAltitude(getApplicationContext());
SQLiteDatabase db = mMioDbAltitude.getWritableDatabase();
db.execSQL("DELETE FROM coordinate_ALTITUDE");
for (i = 0; i < 40; i++) {
valorelat = (Math.min(latArrivo, latPartenza) + i *
latLength);
valorelong = (Math.min(longArrivo, longPartenza) + i *
longLength);
getElevationFromGoogleMaps(valorelat, valorelong);
}
db.close();
}

//ottengo le altitudini da gmaps

public void getElevationFromGoogleMaps(double longitude, double


latitude) {
final double longitudine = longitude;
final double latitudine = latitude;
final HttpClient httpClient = new DefaultHttpClient();
final HttpContext localContext = new BasicHttpContext();
String url = "http://maps.googleapis.com/maps/api/elevation/"
+ "xml?locations=" + String.valueOf(latitude) +
","
+ String.valueOf(longitude);
final HttpGet httpGet = new HttpGet(url);
new Thread(new Runnable() {
double result = Double.NaN;
@Override
public void run() {
try {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 125
HttpResponse response =
httpClient.execute(httpGet,
localContext);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream =
entity.getContent();
int r = -1;
StringBuffer respStr = new
StringBuffer();
while ((r = instream.read()) != -1)
respStr.append((char) r);
String tagOpen = "<elevation>";
String tagClose = "</elevation>";
if (respStr.indexOf(tagOpen) != -1) {
int start =
respStr.indexOf(tagOpen)
+ tagOpen.length();
int end =
respStr.indexOf(tagClose);
String value =
respStr.substring(start, end);
result =
(Double.parseDouble(value));
// SALVO I DATI SU DB LOCALE
cosicchè li possa
// riprendere fuori dal thread
DbAltitude mMioDbAltitude = null;
mMioDbAltitude = new DbAltitude(

getApplicationContext());
SQLiteDatabase db =
mMioDbAltitude

.getWritableDatabase();
ContentValues contentValues = new
ContentValues();
contentValues.put("latitude",
latitudine);
contentValues.put("longitude",
longitudine);
contentValues.put("altitude",
result);
db.insert("coordinate_ALTITUDE",
null,
contentValues);
}
instream.close();
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
}
}).start();
DbAltitude mMioDbAltitude = null;
mMioDbAltitude = new DbAltitude(getApplicationContext());
SQLiteDatabase db = mMioDbAltitude.getWritableDatabase();
final String sql = "SELECT * FROM coordinate_ALTITUDE ";
Cursor c = db.rawQuery(sql, null);
Double altitude = 00.00;
if (c.getCount() != 0) {
c.moveToFirst();
altitude = c.getDouble(3);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 126
}
c.close();
db.close();
}

public String dataExp(String data)


{
String[] parts = data.split(" ");
int d1 = 0, d2 = Integer.parseInt(parts[1]);
String m1 = parts[2];
String y1 = parts[3];

if(parts[0].contains("Gio"))
{
d1 = 11;
}
else if(parts[0].contains("Ven"))
{
d1 = 10;
}
else
{
d1 = 9;
}

d2 += d1;
if(parts[2].contains("Nov") || parts[2].contains("Apr") ||
parts[2].contains("Giu") || parts[2].contains("Set"))
{
if ((Integer.parseInt(parts[1])+d1)>30)
{
d2 = (Integer.parseInt(parts[1])+d1)-30;
if(parts[2].contains("Nov"))
{
m1 = "Dic";
}
if(parts[2].contains("Apr"))
{
m1 = "Mag";
}
if(parts[2].contains("Giu"))
{
m1 = "Lug";
}
if(parts[2].contains("Set"))
{
m1 = "Ott";
}
}
}
else if(parts[2].contains("Feb"))
{
if ((Integer.parseInt(parts[1])+d1)>28)
{
d2 = (Integer.parseInt(parts[1])+d1)-28;
m1 = "Mar";
}
}
else
{
if ((Integer.parseInt(parts[1])+d1)>31)
{
d2 = (Integer.parseInt(parts[1])+d1)-31;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 127
if(parts[2].contains("Dec"))
{
m1 = "Gen";
int annoNuovo =
Integer.parseInt(parts[3])+1;
y1 = String.valueOf(annoNuovo);
}
if(parts[2].contains("Gen"))
{
m1 = "Feb";
}
if(parts[2].contains("Mar"))
{
m1 = "Apr";
}
if(parts[2].contains("Lug"))
{
m1 = "Ago";
}
if(parts[2].contains("Ago"))
{
m1 = "Set";
}
if(parts[2].contains("Ott"))
{
m1 = "Nov";
}
if(parts[2].contains("Mag"))
{
m1 = "Giu";
}
}
}
return d2 + " " + m1 + " " + y1 + ", dalle ore 09:00 alle ore
17:30";
}
}

DettagliProdotto.java
package it.sii.android.pharmacopter;

import it.sii.android.pharmacopter.R;
import it.sii.android.pharmacopter.classes.Prodotto;
import it.sii.android.pharmacopter.classes.CatalogoFill;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 128
public class DettagliProdotto extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {

final Context context = this;


super.onCreate(savedInstanceState);
setContentView(R.layout.productdetails);
Bundle bundle = this.getIntent().getExtras();
String cStringa = bundle.getString("cServerMsg");

List<Prodotto> catalog = null;


catalog = CatalogoFill.getCatalog(getResources(), cStringa);
int productIndex =
getIntent().getExtras().getInt(CatalogoFill.PRODUCT_INDEX);
final Prodotto selectedProduct = catalog.get(productIndex);

// SETTO IL VALORE DELLE TEXTVIEW


ImageView productImageView = (ImageView)
findViewById(R.id.Immagine);
productImageView.setImageDrawable(selectedProduct.productImage);

TextView productTitleTextView = (TextView)


findViewById(R.id.NomeProdotto);
productTitleTextView.setText(selectedProduct.nome);

TextView productDetailsTextView = (TextView)


findViewById(R.id.TipoProdotto);
productDetailsTextView.setText("Tipo prodotto: " +
selectedProduct.tipo);

TextView mins1 = (TextView) findViewById(R.id.Minsan1);


mins1.setText(selectedProduct.minsan1);

TextView mins2 = (TextView) findViewById(R.id.Minsan2);


mins2.setText(selectedProduct.minsan2);

TextView price = (TextView) findViewById(R.id.Price);


price.setText("Prezzo: " + selectedProduct.getPrezzo().toString() +
" EUR");

TextView ATC = (TextView) findViewById(R.id.ATC);


ATC.setText("Classificazione ATC: " + selectedProduct.atc);

TextView Disp = (TextView) findViewById(R.id.Disponibilita);


if(selectedProduct.disponibilita.equals("illimitata"))
{
Disp.setText("Disponibilità illimitata");
}
else
{
Disp.setText("Disponibilità: " + selectedProduct.disponibilita
+ " unità");
}

final Button tv = (Button)findViewById(R.id.ButtonAddToCart);


final TextView total = (TextView) findViewById(R.id.Total);

final EditText editTextQuantity = (EditText)


findViewById(R.id.editTextQuantity);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 129
TextWatcher onSearchFieldTextChanged = new TextWatcher(){
@Override
public void afterTextChanged(Editable s) {
if(editTextQuantity.getText().toString().equals("") ||
editTextQuantity.getText().toString().equals(null))
{
total.setText("");
tv.setVisibility(View.INVISIBLE);
}
else
{
int q =
Integer.parseInt(editTextQuantity.getText().toString());
if (q!=0)
{
tv.setVisibility(0);
tv.setText("Acquista " +
editTextQuantity.getText().toString() + " unità");
Double d =
Double.parseDouble(editTextQuantity.getText().toString());
Double tot = selectedProduct.getPrezzo()*d;
total.setText("Subtotale: " + round(tot, 2) + "
EUR");
}
else
{
total.setText("");
tv.setVisibility(View.INVISIBLE);
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int
count, int after){
//your business logic before text is changed
}

@Override
public void onTextChanged(CharSequence s, int start, int
before, int count){
//your business logic while text has changed
}
};

editTextQuantity.addTextChangedListener(onSearchFieldTextChanged);

// editTextQuantity.addTextChangedListener(new TextWatcher(){
// public void afterTextChanged(Editable s) {
// tv.setText("Acquista" + editTextQuantity.getText().toString() + "
unità");
// Double d =
Double.parseDouble(editTextQuantity.getText().toString());
// total.setText("Subtotale: " + selectedProduct.getPrezzo()*d + "
EUR");
// }
// });

// GESTISCO L'AGGIUNTA NEL CARRELLO


tv.setOnClickListener(new OnClickListener() {

@Override

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 130
public void onClick(View v) {

// CONTROLLO SINTASSI QUANTITA'


int quantity = 0;

quantity =
Integer.parseInt(editTextQuantity.getText().toString());

int disp = 0;
if
(selectedProduct.disponibilita.equals("illimitata"))
{
disp = 9999999;
}
else if (disp<0)
{
disp = 0;
}
else
{
disp =
Integer.parseInt(selectedProduct.disponibilita);
}

if(quantity > disp)


{
System.out.println("disp vale: " + disp + ",
quantity = " + quantity);
AlertDialog.Builder alertDialogBuilder = new
AlertDialog.Builder(context);
alertDialogBuilder.setTitle("Attenzione!");
alertDialogBuilder.setMessage("Ci sono solo
" + disp + " unità disponibili.");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setNeutralButton("Ok",
new DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface dialog, int whichButton) {

}
});
AlertDialog alertDialog =
alertDialogBuilder.create();
alertDialog.show();
}

else if (quantity == 0)
{
Toast.makeText(getBaseContext(),
"Devi inserire una quantità
maggiore di zero.",
Toast.LENGTH_SHORT).show();
}

else
{
// INSERISCO LA QUANTITA' NEL CARRELLO
CatalogoFill.setQuantity(selectedProduct,
quantity);
Toast.makeText(getBaseContext(), "" +

editTextQuantity.getText().toString() + " unità inserite nel carrello.",

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 131
Toast.LENGTH_SHORT).show();
finish();
}

// } catch (Exception e) {
// Toast.makeText(getBaseContext(),
// "Devi inserire una quantità
numerica.",
// Toast.LENGTH_SHORT).show();
// System.out.println("DettagliProdotto:
qta vale: " + editTextQuantity.getText().toString());
// return;

});
}

public static double round(double value, int places) {


if (places < 0) throw new IllegalArgumentException();

long factor = (long) Math.pow(10, places);


value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}

GCMBroadcastReceiver.java
package it.sii.android.pharmacopter;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;

public class GCMBroadcastReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
ComponentName comp = new ComponentName(context.getPackageName(),
GCMNotificationIntentService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}

GCMNotificationIntentService.java
package it.sii.android.pharmacopter;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 132
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;

public class GCMNotificationIntentService extends IntentService {

public static final int NOTIFICATION_ID = 1;


private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;

public GCMNotificationIntentService() {
super("GcmIntentService");
}

public static final String TAG = "GCMNotificationIntentService";

@Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);

String messageType = gcm.getMessageType(intent);

if (!extras.isEmpty()) {
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(messageType)) {
sendNotification("Deleted messages on server: "
+ extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType)) {

for (int i = 0; i < 3; i++) {


Log.i(TAG,
"Working... " + (i + 1) + "/5 @ "
+
SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}

}
Log.i(TAG, "Completed work @ " +
SystemClock.elapsedRealtime());

sendNotification("un ordine richiede la tua attenzione!


"
+ extras.get(Config.MESSAGE_KEY));
Log.i(TAG, "Received: " + extras.toString());
}
}
WakefulBroadcastReceiver.completeWakefulIntent(intent);
}

private void sendNotification(String msg) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 133
Log.d(TAG, "Preparing to send notification...: " + msg);
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0,


new Intent(this, Login.class), 0);

NotificationCompat.Builder mBuilder = new


NotificationCompat.Builder(
this).setSmallIcon(R.drawable.draw_button)
.setContentTitle("Pharmacopter Notification")
.setStyle(new
NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);

mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
Log.d(TAG, "Notification sent successfully.");
}
}

GoogleGraph.java
package it.sii.android.pharmacopter;

import it.sii.android.pharmacopter.db.DbAltitude;
import it.sii.android.pharmacopter.task.GetWeatherClienteTask;
import it.sii.android.pharmacopter.task.GetWeatherFarmacistaTask;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

@SuppressLint({ "SetJavaScriptEnabled", "NewApi" })


public class GoogleGraph extends Activity {

TextView intestazione;
TextView tempMax_textView;
TextView tempMin_textView;
TextView windSpeed_textView;
TextView windDirection_textView;
TextView precipit_textView;
ImageView url;

TextView possovolare;
TextView intestazione2;
TextView tempMaxCliente_textView;
TextView tempMinCliente_textView;
TextView windSpeedCliente_textView;
TextView windDirectionCliente_textView;
TextView precipitCliente_textView;
ImageView urlCliente;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 134
@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {

// richiedo username e psw dal db locale


DbAltitude mDbAltitude = null;
mDbAltitude = new DbAltitude(getApplicationContext());
SQLiteDatabase db = mDbAltitude.getWritableDatabase();
final String sql = "SELECT latitude, longitude, altitude FROM
coordinate_ALTITUDE ";
Cursor c = db.rawQuery(sql, null);
String latitude = "";
String longitude = "";
String altitude = "";
String altitudeMax = "-100000000";
String longitudeMax = "";
String latitudeMax = "";
// TextView altitudine_textview ;
// altitudine_textview= (TextView) findViewById(R.id.altitudine);
// final Button ottieni_altitudine;
// ottieni_altitudine= (Button)
findViewById(R.id.ottieni_altitudine);

super.onCreate(savedInstanceState);
setContentView(R.layout.google_graph);

tempMax_textView = (TextView) findViewById(R.id.tempMax);


intestazione = (TextView) findViewById(R.id.intestazione);
intestazione2 = (TextView) findViewById(R.id.intestazione2);

tempMin_textView = (TextView) findViewById(R.id.tempMin);


windSpeed_textView = (TextView) findViewById(R.id.windSpeed);
windDirection_textView = (TextView)
findViewById(R.id.windDirection);
precipit_textView = (TextView) findViewById(R.id.precipit);
url = (ImageView) findViewById(R.id.url);
possovolare = (TextView) findViewById(R.id.possoVolare);

tempMaxCliente_textView = (TextView) findViewById(R.id.tempMax2);


tempMinCliente_textView = (TextView) findViewById(R.id.tempMin2);
windSpeedCliente_textView = (TextView)
findViewById(R.id.windSpeed2);
windDirectionCliente_textView = (TextView)
findViewById(R.id.windDirection2);
precipitCliente_textView = (TextView) findViewById(R.id.precipit2);
urlCliente = (ImageView) findViewById(R.id.url2);

WebView webview = (WebView) findViewById(R.id.webView12);


String content = "<html>"
+ " <head>"
+ " <script type=\"text/javascript\"
src=\"https://www.google.com/jsapi\"></script>"
+ " <script type=\"text/javascript\">"
+ " google.load(\"visualization\", \"1\",
{packages:[\"corechart\"]});"

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 135
+ " google.setOnLoadCallback(drawChart);"
+ " function drawChart() {"
+ " var data =
google.visualization.arrayToDataTable(["
+ " ['latlong', 'altitudine', { role: 'style'
}],";

// prendo i dati dal database


c.moveToFirst();
for (int i = 0; i < c.getCount() - 1; i++) {
c.moveToPosition(i);
latitude = c.getString(0);
longitude = c.getString(1);
altitude = c.getString(2);
content += "['Latitudine: " + latitude + " Longitudine: "
+ longitude + "', " + altitude + ",'stroke-width:
6'],";
System.out.println(latitude + " "+ longitude + " "
+altitude);

if (Double.valueOf(altitude) > Double.valueOf(altitudeMax)) {


altitudeMax = altitude;
longitudeMax = longitude;
latitudeMax = latitude;
System.out.println(latitudeMax + " " + longitudeMax + "
"
+ altitudeMax);

c.moveToLast();
latitude = c.getString(0);
longitude = c.getString(1);
altitude = c.getString(2);
// System.out.println(latitude + " "+ longitude + " " +altitude);

content += "['Latitudine: "


+ latitude
+ " Longitudine: "
+ longitude
+ "', "
+ altitude
+ ",'stroke-width: 6']"
+ " ]);"
+ " var options = {"
+ " title: 'Altitudini',"
+ " hAxis: {title: 'Osservazioni',
titleTextStyle: {color: 'red'}}"
+ " };"
+ " var chart = new
google.visualization.ColumnChart(document.getElementById('chart_div'));"
+ " chart.draw(data, options);"
+ " }"
+ " </script>"
+ " </head>"
+ " <body>"
+ " <div id=\"chart_div\" style=\"width: 300px;
height: 130px;\"></div>"
+ " </body>" + "</html>";

WebSettings webSettings = webview.getSettings();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 136
webSettings.setJavaScriptEnabled(true);
webview.requestFocusFromTouch();
webview.canZoomIn();
webview.canZoomOut();
webview.loadDataWithBaseURL("file:///android_asset/", content,
"text/html", "utf-8", null);
// webview.loadUrl("file:///android_asset/Code.html"); // Can be
used in
// this way too.

// prendo i dati dall'intent e ottengo i dati del tempo alla


partenza e all'arrivo

Double mialat = getIntent().getExtras().getDouble("mialat");


Double mialon = getIntent().getExtras().getDouble("mialon");
Double clientelat = getIntent().getExtras().getDouble("clientelat");
Double clientelon = getIntent().getExtras().getDouble("clientelon");
final String clienteLat = String.valueOf(clientelat);
final String clienteLon = String.valueOf(clientelon);
c.close();
db.close();

Button aggiornaDati = (Button) findViewById(R.id.aggiornaDati);


aggiornaDati.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {

new
GetWeatherClienteTask(GoogleGraph.this,tempMinCliente_textView,tempMaxCliente_te
xtView,windSpeedCliente_textView,windDirectionCliente_textView,precipitCliente_t
extView,urlCliente, clienteLat,clienteLon,possovolare).execute("asd");
new
GetWeatherFarmacistaTask(GoogleGraph.this,tempMin_textView,tempMax_textView,wind
Speed_textView,windDirection_textView,precipit_textView,url).execute("asd");

}
}

);

@Override
public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is


present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}

GPSTracker.java
package it.sii.android.pharmacopter;

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 137
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;

public class GPSTracker extends Service implements LocationListener {

private final Context mContext;

// flag for GPS status


boolean isGPSEnabled = false;

// flag for network status


boolean isNetworkEnabled = false;

// flag for GPS status


boolean canGetLocation = false;

Location location; // location


double latitude; // latitude
double longitude; // longitude

// The minimum distance to change Updates in meters


private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10
meters

// The minimum time between updates in milliseconds


private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

// Declaring a Location Manager


protected LocationManager locationManager;

public GPSTracker(Context context) {


this.mContext = context;
getLocation();
}

public Location getLocation() {


try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);

// getting GPS status


isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);

// getting network status


isNetworkEnabled = locationManager

.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

if (!isGPSEnabled && !isNetworkEnabled) {


// no network provider is enabled
} else {
this.canGetLocation = true;
// First get location from Network Provider
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 138
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES,
this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager

.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES,
this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager

.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude =
location.getLatitude();
longitude =
location.getLongitude();
}
}
}
}
}

} catch (Exception e) {
e.printStackTrace();
}

return location;
}

/**
* Stop using GPS listener Calling this function will stop using GPS in
your
* app
* */
public void stopUsingGPS() {
if (locationManager != null) {
locationManager.removeUpdates(GPSTracker.this);
}
}

/**
* Function to get latitude
* */
public double getLatitude() {
if (location != null) {
latitude = location.getLatitude();
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 139
// return latitude
return latitude;
}

/**
* Function to get longitude
* */
public double getLongitude() {
if (location != null) {
longitude = location.getLongitude();
}

// return longitude
return longitude;
}

/**
* Function to check GPS/wifi enabled
*
* @return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}

/**
* Function to show settings alert dialog On pressing Settings button will
* lauch Settings Options
* */
public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

// Setting Dialog Title


alertDialog.setTitle("GPS is settings");

// Setting Dialog Message


alertDialog
.setMessage("GPS is not enabled. Do you want to go to
settings menu?");

// On pressing Settings button


alertDialog.setPositiveButton("Settings",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int
which) {
Intent intent = new Intent(

Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});

// on pressing cancel button


alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int
which) {
dialog.cancel();
}
});

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 140
// Showing Alert Message
alertDialog.show();
}

@Override
public void onLocationChanged(Location location) {
}

@Override
public void onProviderDisabled(String provider) {
}

@Override
public void onProviderEnabled(String provider) {
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}

@Override
public IBinder onBind(Intent arg0) {
return null;
}

Login.java
package it.sii.android.pharmacopter;

import it.sii.android.pharmacopter.classes.Utente;
import it.sii.android.pharmacopter.db.DbCredenziali;
import it.sii.android.pharmacopter.task.HTTPConnectTask;
import it.sii.android.pharmacopter.task.LoginTask;

import java.io.IOException;
import org.json.JSONObject;

import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.model.GraphUser;
import com.google.android.gms.gcm.GoogleCloudMessaging;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 141
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.CheckBox;
import android.widget.Toast;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;

@SuppressLint("NewApi")
public class Login extends Activity {

Intent intent;
SharedPreferences loginPreferences;
SharedPreferences.Editor loginPrefsEditor;
CheckBox saveLoginCheckBox;
private Boolean saveLogin;
String username , password ;
private String resp;
private String errorMsg;
TextView error_textView;
boolean fblogged = false;
Context ctx;
ProgressBar attesa;
private ProgressDialog progressDialog;

//variabili per GCM

GoogleCloudMessaging gcm;
String regId;
ShareExternalServer appUtil;

AsyncTask<Void, Void, String> shareRegidTask;


public static final String REG_ID = "regId";
private static final String APP_VERSION = "appVersion";

static final String TAG = "Register Activity";

// G E S T I S C E I L P U L S A N T E B A C K ...
@Override
public void onBackPressed() {
new AlertDialog.Builder(this)

.setIcon(android.R.drawable.ic_dialog_alert).setTitle("Esci")
.setMessage("Sei sicuro di voler uscire?")
.setPositiveButton("Sì", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int
which) {
callFacebookLogout(getApplicationContext());
Intent intent = new
Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);// ***Change

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 142
// Here***
startActivity(intent);
Login.this.finish();

System.exit(0);
closeContextMenu();

}).setNegativeButton("No", null).show();
}

//
// public void onStart(Bundle savedInstanceState){
// super.onCreate(savedInstanceState);
//
//
// }
//

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);

final EditText username_inputText = (EditText)


findViewById(R.id.username_inputText);
final EditText psw_inputText = (EditText)
findViewById(R.id.psw_inputText);
fblogged = false;
ctx = this;
attesa = (ProgressBar) findViewById(R.id.attesa);

// on start controller se l'utente è gia loggato su fb


Intent giaLoggato = new Intent(Login.this, PannelloUtente.class);
if (isLoggedIn() == true) {
startActivity(giaLoggato);
}

// richiedo username e psw dal db locale


DbCredenziali mMioDbHelper = null;
mMioDbHelper = new DbCredenziali(getApplicationContext());
SQLiteDatabase db = mMioDbHelper.getWritableDatabase();
final String sql = "SELECT username, password FROM credenziali ";
Cursor c = db.rawQuery(sql, null);

// on start controller se l'utente è già loggato

if (c.getCount() != 0) {

c.moveToFirst();
final String usernamedbl = c.getString(0);
final String pswdbl = c.getString(1);

// parte di controllo che i dati presenti sul db locale sono


// presenti anche sul server fatta senza usare ssl;

new Thread(new Runnable() {

@Override
public void run() {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 143
String response = null;
try {

ApplicationInfo ai = ctx.getPackageManager()

.getApplicationInfo(ctx.getPackageName(),

PackageManager.GET_META_DATA);
response = HTTPConnectTask.executeHttpGet(

ai.metaData.getString("urlservernonsicuro")
+
"login.do?username="+usernamedbl+"&password="+pswdbl);
resp = response.toString();

System.out.println("resp vale: " + resp);

JSONObject resp2 = new JSONObject(resp);


boolean success =
resp2.getBoolean("success");
JSONObject utente =
resp2.getJSONObject("user");
String tipo =
resp2.getJSONObject("user").getString("tipo");

// nel momento in cui ricevo la risposta,


(faccio le
// trasformazioni del caso) => success ==
true allora
// sei già loggato! e ti mando al pannello
utente

if (success == true &&


tipo.equals("cliente")) {
Intent intent2 = new Intent(
getApplicationContext(),
PannelloUtente.class);
startActivity(intent2);

}else if(success == true &&


tipo.equals("farmacista")) {

Intent intent2 = new Intent(


getApplicationContext(),
PannelloFarmacista.class);
startActivity(intent2);

}
else {
resp = "errore";
loginPrefsEditor.clear();
}

} catch (Exception e) {
e.printStackTrace();
errorMsg = e.getMessage();
}

}).start();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 144
}

// roba di albio
final String pkg = getPackageName();
final AlertDialog.Builder miaAlert = new AlertDialog.Builder(this);

intent = new Intent(getApplicationContext(), PannelloUtente.class);

// immagine con link al sito


ImageView img = (ImageView) findViewById(R.id.logo_imageView);
img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent2 = new Intent();
intent2.setAction(Intent.ACTION_VIEW);
intent2.addCategory(Intent.CATEGORY_BROWSABLE);

intent2.setData(Uri.parse("http://www.pharmacopter.tk"));
startActivity(intent2);
}
});

TextView registrati_textView = (TextView)


findViewById(R.id.register_textView);
TextView aProposito_textView = (TextView)
findViewById(R.id.about_textView);

final Button login = (Button) findViewById(R.id.login_button);


loginPreferences = getSharedPreferences("loginPrefs", MODE_PRIVATE);
loginPrefsEditor = loginPreferences.edit();
saveLoginCheckBox = (CheckBox) findViewById(R.id.checkBox1);

final float scale = this.getResources().getDisplayMetrics().density;


if (android.os.Build.VERSION.SDK_INT <= 16) {

saveLoginCheckBox.setPadding(saveLoginCheckBox.getPaddingLeft()
+ (int) (25.0f * scale + 0.5f),
saveLoginCheckBox.getPaddingTop(),
saveLoginCheckBox.getPaddingRight(),
saveLoginCheckBox.getPaddingBottom());
}

registrati_textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent registerIntent = new
Intent(getApplicationContext(),
Register.class);
startActivity(registerIntent); // facciamo partire la
seconda
//
activity
}

});

aProposito_textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent aPropositoIntent = new
Intent(getApplicationContext(),

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 145
About.class);
startActivity(aPropositoIntent); // facciamo partire
l'activity
//
About
}

});

saveLogin = loginPreferences.getBoolean("saveLogin", false);


if (saveLogin == true) {

username_inputText.setText(loginPreferences.getString("username",
""));
psw_inputText.setText(loginPreferences.getString("password",
""));
saveLoginCheckBox.setChecked(true);
}

error_textView = (TextView) findViewById(R.id.error_textView);

login.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
if (v == login) {
Utente u = new Utente(username_inputText.getText()
.toString(),
psw_inputText.getText().toString());
boolean error = false;
if
(username_inputText.getText().toString().equals("")) {
error_textView.setText("Inserisci lo
username!");
error=true;
}

// VOLENDO UTILIZZARE L'ALERT (in alternativa al


messaggio
// di errore):
// if (username.equals("")) {
// miaAlert.setTitle("Errore");
// miaAlert.setMessage("Non hai inserito lo
username!");
// AlertDialog alert = miaAlert.create();
// alert.show();
// miaAlert.setIcon(R.drawable.error_icon);
// }

else if
(psw_inputText.getText().toString().equals("")) {
error_textView.setText("Inserisci la
password!");
error=true;
}

else {
if (saveLoginCheckBox.isChecked()) {

loginPrefsEditor.putBoolean("saveLogin", true);
loginPrefsEditor.putString("username",
username_inputText.getText().toString());

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 146
loginPrefsEditor.putString("password",
psw_inputText.getText().toString());
loginPrefsEditor.commit();
} else {
loginPrefsEditor.clear();
loginPrefsEditor.commit();
}

if(error==false){

// ------------------ registrazione a
servizio di google
if (TextUtils.isEmpty(regId)) {
regId = registerGCM();

Toast.makeText(getApplicationContext(), "RegId is empty!",


Toast.LENGTH_LONG).show();
}

appUtil = new ShareExternalServer();

Log.d("Login", "regId: " + regId);

final Context context =


getApplicationContext();
shareRegidTask = new AsyncTask<Void,
Void, String>() {
@Override
protected String
doInBackground(Void... params) {
String result =
appUtil.shareRegIdWithAppServer(context,
regId,username_inputText.getText().toString());
return result;
}

@Override
protected void
onPostExecute(String result) {
shareRegidTask = null;

Toast.makeText(getApplicationContext(), result,

Toast.LENGTH_LONG).show();
}

};
shareRegidTask.execute(null, null,
null);

// ---------- log in server-------------//


new LoginTask(Login.this, error_textView,
getApplicationContext()).execute(u);

//

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 147
// // ///////////////////////////////////
controlli sul
// server
//
// new Thread(new Runnable() {
//
// @Override
// public void run() {
// ArrayList<NameValuePair> postParameters =
new
// ArrayList<NameValuePair>();
// postParameters.add(new
BasicNameValuePair(
// "username", username_inputText.getText()
// .toString()));
// postParameters.add(new
BasicNameValuePair(
// "password", psw_inputText.getText()
// .toString()));
//
// String response = null;
// try {
// response = HTTPConnectTask
// .executeHttpPost(
//
"http://10.0.2.2:8080/LoginServer2/login.do",
// postParameters);
// resp = response.toString();
//
// JSONObject resp2 = new JSONObject(resp);
// boolean success =
resp2.getBoolean("success");
// JSONObject utente =
resp2.getJSONObject("user");
// String nome =
utente.getString("userName");
// String password =
utente.getString("password");
//
// System.out.println(nome);
// if (success == true) {
// startActivity(intent);
// } else {
// resp = "Username o password non validi.";
// loginPrefsEditor.clear();
// }
//
// } catch (Exception e) {
// e.printStackTrace();
// errorMsg = e.getMessage();
// }
// }
//
// }).start();
// try {
// /** wait a second to get response from
server */
// Thread.sleep(1000);
// /**
// * Inside the new thread we cannot update
the main
// * thread So updating the main thread
outside the new

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 148
// * thread
// */
//
// accesso_textView.setText("Login in
corso...");
// attesa2.setVisibility(0);
//
// if (errorMsg != null &&
!errorMsg.isEmpty()) {
// accesso_textView.setText(errorMsg);
// }
// } catch (Exception e) {
// accesso_textView.setText(e.getMessage());
// }
//
// ////////////////////////////////////
//
// InputMethodManager imm =
(InputMethodManager)
//
getSystemService(Context.INPUT_METHOD_SERVICE);
// imm.hideSoftInputFromWindow(
// username_inputText.getWindowToken(), 0);
//
// username =
username_inputText.getText().toString();
// password =
psw_inputText.getText().toString();
//
// intent.putExtra(pkg + ".myUsername",
username);
// intent.putExtra(pkg + ".myPassword",
password);
//
//
}

}
}
});
}

// login con facebook


public void facebookLogin() {

final Intent intentfb;


final String pkgfb = getPackageName();
intentfb = new Intent(getApplicationContext(),
PannelloUtente.class);
Session.openActiveSession(this, true, new Session.StatusCallback() {

@Override
public void call(Session session, SessionState state,
Exception exception) {
if (session.isOpened()) {

Request.newMeRequest(session,
new Request.GraphUserCallback() {
@Override
public void onCompleted(final
GraphUser user,
final Response
response) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 149
if (user != null) {
error_textView

.setText("Accesso come \""

+ user.getName()

+ "\" in corso...");
fblogged = true;
intentfb.putExtra(
pkgfb +
".myUsername",

user.getName());

startActivity(intentfb);
}
}
}).executeAsync();

} else {
error_textView.setText("Ti sei disconnesso dal
sistema.");
fblogged = false;
}
}
});
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode,
resultCode, data);
facebookLogin();
attesa.setVisibility(0);

public boolean isLoggedIn() {


Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
return true;
}

else {
return false;
}
}

public static void callFacebookLogout(Context context) {


Session session = Session.getActiveSession();
if (session != null) {

if (!session.isClosed()) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 150
session.closeAndClearTokenInformation();
// clear your preferences if saved
}
} else {

session = new Session(context);


Session.setActiveSession(session);

session.closeAndClearTokenInformation();
// clear your preferences if saved

//metodi di gcm

public String registerGCM() {

gcm = GoogleCloudMessaging.getInstance(this);
regId = getRegistrationId(getApplicationContext());

if (TextUtils.isEmpty(regId)) {

registerInBackground();

Log.d("RegisterActivity",
"registerGCM - successfully registered with
GCM server - regId: "
+ regId);
}
else {
Toast.makeText(getApplicationContext(),
"RegId already available. RegId: " + regId,
Toast.LENGTH_LONG).show();
}
return regId;
}

// metodo da cambiare (non riceve nulla, va in un db locale e prende


il regid)
private String getRegistrationId(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(
MainActivity.class.getSimpleName(),
Context.MODE_PRIVATE);
String registrationId = prefs.getString(REG_ID, "");
if (registrationId.isEmpty()) {
Log.i(TAG, "Registration not found.");
return "";
}
int registeredVersion = prefs.getInt(APP_VERSION,
Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion) {
Log.i(TAG, "App version changed.");
return "";
}
return registrationId;
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 151
private static int getAppVersion(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(),
0);
return packageInfo.versionCode;
} catch (NameNotFoundException e) {
Log.d("RegisterActivity",
"I never expected this! Going down, going
down!" + e);
throw new RuntimeException(e);
}
}

private void registerInBackground() {


new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
String msg = "";
try {
if (gcm == null) {
gcm =
GoogleCloudMessaging.getInstance(getApplicationContext());
}
regId =
gcm.register(Config.GOOGLE_PROJECT_ID);
Log.d("RegisterActivity",
"registerInBackground - regId: "
+ regId);
msg = "Device registered, registration ID="
+ regId;

storeRegistrationId(getApplicationContext(),
regId);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
Log.d("RegisterActivity", "Error: " + msg);
}
Log.d("RegisterActivity", "AsyncTask completed: "
+ msg);
return msg;
}
@Override
protected void onPostExecute(String msg) {
Toast.makeText(getApplicationContext(),
"Registered with GCM Server." + msg,
Toast.LENGTH_LONG)
.show();
}
}.execute(null, null, null);
}

private void storeRegistrationId(Context context, String regId) {


final SharedPreferences prefs = context.getSharedPreferences(
MainActivity.class.getSimpleName(),
Context.MODE_PRIVATE);
int appVersion = getAppVersion(context);
Log.i(TAG, "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(REG_ID, regId);
editor.putInt(APP_VERSION, appVersion);
editor.commit();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 152
}
}

MainActivity.java
package it.sii.android.pharmacopter;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;

public class MainActivity extends Activity {

// Rileviamo se viene premuto il pulsante indietro


private boolean mIsBackButtonPressed;
private static final int SPLASH_DURATION = 3000; // 3 secondi

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Handler handler = new Handler();

// Dopo 3 secondi si avvia la home


handler.postDelayed(new Runnable() {

@Override
public void run() {

// Chiudiamo la schermata di splash, evitando che l'utente ci


torni andando indietro
finish();

if (!mIsBackButtonPressed) {
// Avviamo la pagina di login

Intent intent = new Intent(MainActivity.this, Login.class);


MainActivity.this.startActivity(intent);
}

}, SPLASH_DURATION); // durata dello splash

@Override
public void onBackPressed() {

mIsBackButtonPressed = true;
super.onBackPressed();

MappaConMarker.java
package it.sii.android.pharmacopter;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 153
import org.json.JSONException;

import it.sii.android.pharmacopter.classes.CatalogoFill;
import it.sii.android.pharmacopter.db.DbCoordinate;
import it.sii.android.pharmacopter.db.DbCredenziali;
import it.sii.android.pharmacopter.db.DbFarmaciaSelezionata;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.widget.Button;

@SuppressLint("NewApi")
public class MappaConMarker extends Activity {
GoogleMap mMap;
org.json.JSONObject JSONListaFarmacie;
org.json.JSONObject JSONFarmacia;
String Username = "";
Context context = this;

@SuppressLint("NewApi")

// G E S T I S C E I L P U L S A N T E B A C K ...

@Override
public void onBackPressed() {
Intent intent2 = new Intent(
getApplicationContext(),
PannelloUtente.class);
startActivity(intent2);
MappaConMarker.this.finish();
}

@Override
protected void onCreate(Bundle savedInstanceState) {

// intent verso la pagina di ricerca

// // RECUPERO I DATI PASSATI DALL'INTENT DELLA PAGINA PRIMA


// Intent intent=getIntent(); // l'intent di questa activity
//
//
// String pkg=getPackageName();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 154
//
// // Stringa JSON con dentro le coordinate di tutte le farmacie
// String ListaFArmacie = intent.getStringExtra(pkg+".myJSONString");
// int i2 = 0;
// // da Stringa lo faccio diventare JSONobject così lo tratto meglio
// try {
// JSONListaFarmacie = new org.json.JSONObject(ListaFArmacie);
// do{
// JSONFarmacia = JSONListaFarmacie.getJSONObject("farmacia"+i2);
// System.out.println("JSONobject farmacia "+i2+ " vale: " +
JSONFarmacia);
// i2++;
// }
// while(i2<=JSONListaFarmacie.length() );
//
// } catch (JSONException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// System.out.println("JSONobject è costituito da: " +
JSONListaFarmacie.length() + " array");

super.onCreate(savedInstanceState);

//setContentView(R.layout.main);

setContentView(R.layout.mappa_con_marker);

// richiedo latitudine e longitudine dal dblocale


DbCoordinate mDbCoordinate = new
DbCoordinate(getApplicationContext());
SQLiteDatabase db = mDbCoordinate.getWritableDatabase();
final String sqlCoordinate = "SELECT latitude, longitude FROM
coordinate ";
Cursor c = db.rawQuery(sqlCoordinate, null);
final Button scegliFarm = (Button) findViewById(R.id.scegliFarm);
c.moveToFirst();
final Double myLat = c.getDouble(0);
final Double myLong = c.getDouble(1);
System.out.println(myLat);
System.out.println(myLong);
c.close();
db.close();

// richiedo username al dblocale ......fai questo e setta il marker


Array[0].title con il valore che prendi da sto DB (è scritto sopra come fare)

final MarkerOptions[] markerArray = new MarkerOptions[100];

DbCredenziali mDbHelper = new


DbCredenziali(getApplicationContext());
SQLiteDatabase db2 = mDbHelper.getWritableDatabase();
final String sqlUsername = "SELECT username FROM credenziali";
Cursor c2 = db2.rawQuery(sqlUsername, null);
c2.moveToFirst();
Username = c2.getString(0);
c2.close();
db2.close();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 155
if (mMap == null) {
mMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.mymapfragment)).getMap();
if (mMap != null) {

/*
* mMap.addMarker(new MarkerOptions()
.position(POLITECNICO)
* .title("Politecnico di Torino"));
*/
final LatLng mylatlong = new LatLng(myLat,myLong);

// Obtain the map from a MapFragment or MapView.

// Move the camera instantly to Sydney with a zoom of


15.

mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mylatlong, 15));

// Zoom in, animating the camera.


mMap.animateCamera(CameraUpdateFactory.zoomIn());

// Zoom out to zoom level 10, animating with a duration


of 2 seconds.
mMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000,
null);

// Construct a CameraPosition focusing on Mountain View


and animate the camera to that position.
CameraPosition cameraPosition = new
CameraPosition.Builder()
.target(mylatlong) // Sets the center of the
map to Mountain View
.zoom(17) // Sets the zoom
.bearing(90) // Sets the orientation
of the camera to east
.tilt(30) // Sets the tilt of the
camera to 30 degrees
.build(); // Creates a
CameraPosition from the builder

mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

markerArray[0] = new MarkerOptions()


.position(new LatLng(myLat, myLong))
.title(Username)
.snippet("La tua posizione")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.marker_home));

try{

// RECUPERO I DATI PASSATI DALL'INTENT DELLA


PAGINA PRIMA
Intent intent=getIntent(); // l'intent di questa
activity

String pkg=getPackageName();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 156
// Stringa JSON con dentro le coordinate di tutte le
farmacie (arriva dall'async task GetListaFarmacieLocationTask, scatenato dal
pulsante "Effettua Ordine")
String listaFarmacie =
intent.getStringExtra(pkg+".myJSONString");
int j = 1;
// da Stringa lo faccio diventare JSONobject così lo
tratto meglio
try {
JSONListaFarmacie = new
org.json.JSONObject(listaFarmacie);

while(j <= JSONListaFarmacie.length() )


{
JSONFarmacia =
JSONListaFarmacie.getJSONObject("farmacia"+(j-1));

Double latFarm =
Double.valueOf(JSONFarmacia.get("Latitudine").toString());
Double lngFarm =
Double.valueOf(JSONFarmacia.get("Longitudine").toString());
Double latmy = myLat;
Double lngmy = myLong;

CalcolaDistanze cd =new
CalcolaDistanze();
Double distanza =
cd.getDistanza(latFarm, latmy, lngFarm, lngmy);

markerArray[j] = new MarkerOptions()


.position(new
LatLng(Double.valueOf(JSONFarmacia.get("Latitudine").toString()),Double.valueOf(
JSONFarmacia.get("Longitudine").toString())))

.title(JSONFarmacia.getString("NomeFarmacia"))
.snippet("Distanza: " +
round(distanza, 2) + " km")

.icon(BitmapDescriptorFactory

.fromResource(R.drawable.marker_pharm));

System.out.println("JSONobject
farmacia "+j+ " vale: " + JSONFarmacia);

j++;
}

} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("JSONobject è costituito da: " +
JSONListaFarmacie.length() + " array");

}catch (Exception e)
{
System.out.println("ERRORE!!!! ERRORE!!!! JSONobject
è costituito da: " + JSONListaFarmacie.length() + " array");
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 157
for (int k = 0; k < markerArray.length &&
markerArray[k]!=null; k++){
mMap.addMarker(markerArray[k]);
}

final Intent intentRiceProd = new Intent(this,


RiceProdLoader.class);
mMap.setOnMarkerClickListener(new
GoogleMap.OnMarkerClickListener() {

@Override
public boolean onMarkerClick(Marker m) {

// step1: apro il db
DbFarmaciaSelezionata mDbFarmaciaSelezionata
= null;
mDbFarmaciaSelezionata = new
DbFarmaciaSelezionata(getApplicationContext());
SQLiteDatabase db =
mDbFarmaciaSelezionata.getWritableDatabase();
db.execSQL("DELETE FROM farmacia");

// step2: riempio il content da


aggiungere al db ed eseguo l'insert
ContentValues contentValues = new
ContentValues();
contentValues.put("nomefarmacia",
m.getTitle());

contentValues.put("latitudineFarma",m.getPosition().latitude);
contentValues.put("longitudineFarma",
m.getPosition().longitude);
db.insert("farmacia", null, contentValues);
db.close();

if(m.getTitle().equals(Username))
{

scegliFarm.setVisibility(View.INVISIBLE);
}
else
{
scegliFarm.setVisibility(0);
scegliFarm.setText("Scegli \"" +
m.getTitle() + "\"");
}

return false;
}

});

final AlertDialog.Builder alertDialogBuilder = new


AlertDialog.Builder(context);

alertDialogBuilder.setIcon(android.R.drawable.ic_dialog_alert);
alertDialogBuilder.setTitle("Attenzione!");
alertDialogBuilder.setMessage("Al momento della scelta
della farmacia, il carrello verrà svuotato. Vuoi proseguire?");
alertDialogBuilder.setPositiveButton("Ok", new
DialogInterface.OnClickListener() {
@Override

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 158
public void
onClick(DialogInterface dialog, int which) {
CatalogoFill.clearMap();

startActivity(intentRiceProd);
}
});
alertDialogBuilder.setNegativeButton("Annulla", null);

scegliFarm.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
alertDialogBuilder.show();

}
});

}
}
}

public static double round(double value, int places) {


if (places < 0) throw new IllegalArgumentException();

long factor = (long) Math.pow(10, places);


value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}

OrdiniView.java
package it.sii.android.pharmacopter;

import org.json.JSONException;

import it.sii.android.pharmacopter.classes.CatalogoFill;
import it.sii.android.pharmacopter.db.DbCoordinate;
import it.sii.android.pharmacopter.db.DbCredenziali;
import it.sii.android.pharmacopter.db.DbFarmaciaSelezionata;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 159
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.widget.Button;

@SuppressLint("NewApi")
public class MappaConMarker extends Activity {
GoogleMap mMap;
org.json.JSONObject JSONListaFarmacie;
org.json.JSONObject JSONFarmacia;
String Username = "";
Context context = this;

@SuppressLint("NewApi")

// G E S T I S C E I L P U L S A N T E B A C K ...

@Override
public void onBackPressed() {
Intent intent2 = new Intent(
getApplicationContext(),
PannelloUtente.class);
startActivity(intent2);
MappaConMarker.this.finish();
}

@Override
protected void onCreate(Bundle savedInstanceState) {

// intent verso la pagina di ricerca

// // RECUPERO I DATI PASSATI DALL'INTENT DELLA PAGINA PRIMA


// Intent intent=getIntent(); // l'intent di questa activity
//
//
// String pkg=getPackageName();
//
// // Stringa JSON con dentro le coordinate di tutte le farmacie
// String ListaFArmacie = intent.getStringExtra(pkg+".myJSONString");
// int i2 = 0;
// // da Stringa lo faccio diventare JSONobject così lo tratto meglio
// try {
// JSONListaFarmacie = new org.json.JSONObject(ListaFArmacie);
// do{
// JSONFarmacia = JSONListaFarmacie.getJSONObject("farmacia"+i2);
// System.out.println("JSONobject farmacia "+i2+ " vale: " +
JSONFarmacia);
// i2++;
// }
// while(i2<=JSONListaFarmacie.length() );
//
// } catch (JSONException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// System.out.println("JSONobject è costituito da: " +
JSONListaFarmacie.length() + " array");

super.onCreate(savedInstanceState);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 160
//setContentView(R.layout.main);

setContentView(R.layout.mappa_con_marker);

// richiedo latitudine e longitudine dal dblocale


DbCoordinate mDbCoordinate = new
DbCoordinate(getApplicationContext());
SQLiteDatabase db = mDbCoordinate.getWritableDatabase();
final String sqlCoordinate = "SELECT latitude, longitude FROM
coordinate ";
Cursor c = db.rawQuery(sqlCoordinate, null);
final Button scegliFarm = (Button) findViewById(R.id.scegliFarm);
c.moveToFirst();
final Double myLat = c.getDouble(0);
final Double myLong = c.getDouble(1);
System.out.println(myLat);
System.out.println(myLong);
c.close();
db.close();

// richiedo username al dblocale ......fai questo e setta il marker


Array[0].title con il valore che prendi da sto DB (è scritto sopra come fare)

final MarkerOptions[] markerArray = new MarkerOptions[100];

DbCredenziali mDbHelper = new


DbCredenziali(getApplicationContext());
SQLiteDatabase db2 = mDbHelper.getWritableDatabase();
final String sqlUsername = "SELECT username FROM credenziali";
Cursor c2 = db2.rawQuery(sqlUsername, null);
c2.moveToFirst();
Username = c2.getString(0);
c2.close();
db2.close();

if (mMap == null) {
mMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.mymapfragment)).getMap();
if (mMap != null) {

/*
* mMap.addMarker(new MarkerOptions()
.position(POLITECNICO)
* .title("Politecnico di Torino"));
*/
final LatLng mylatlong = new LatLng(myLat,myLong);

// Obtain the map from a MapFragment or MapView.

// Move the camera instantly to Sydney with a zoom of


15.

mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mylatlong, 15));

// Zoom in, animating the camera.


mMap.animateCamera(CameraUpdateFactory.zoomIn());

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 161
// Zoom out to zoom level 10, animating with a duration
of 2 seconds.
mMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000,
null);

// Construct a CameraPosition focusing on Mountain View


and animate the camera to that position.
CameraPosition cameraPosition = new
CameraPosition.Builder()
.target(mylatlong) // Sets the center of the
map to Mountain View
.zoom(17) // Sets the zoom
.bearing(90) // Sets the orientation
of the camera to east
.tilt(30) // Sets the tilt of the
camera to 30 degrees
.build(); // Creates a
CameraPosition from the builder

mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

markerArray[0] = new MarkerOptions()


.position(new LatLng(myLat, myLong))
.title(Username)
.snippet("La tua posizione")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.marker_home));

try{

// RECUPERO I DATI PASSATI DALL'INTENT DELLA


PAGINA PRIMA
Intent intent=getIntent(); // l'intent di questa
activity

String pkg=getPackageName();

// Stringa JSON con dentro le coordinate di tutte le


farmacie (arriva dall'async task GetListaFarmacieLocationTask, scatenato dal
pulsante "Effettua Ordine")
String listaFarmacie =
intent.getStringExtra(pkg+".myJSONString");
int j = 1;
// da Stringa lo faccio diventare JSONobject così lo
tratto meglio
try {
JSONListaFarmacie = new
org.json.JSONObject(listaFarmacie);

while(j <= JSONListaFarmacie.length() )


{
JSONFarmacia =
JSONListaFarmacie.getJSONObject("farmacia"+(j-1));

Double latFarm =
Double.valueOf(JSONFarmacia.get("Latitudine").toString());
Double lngFarm =
Double.valueOf(JSONFarmacia.get("Longitudine").toString());
Double latmy = myLat;
Double lngmy = myLong;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 162
CalcolaDistanze cd =new
CalcolaDistanze();
Double distanza =
cd.getDistanza(latFarm, latmy, lngFarm, lngmy);

markerArray[j] = new MarkerOptions()


.position(new
LatLng(Double.valueOf(JSONFarmacia.get("Latitudine").toString()),Double.valueOf(
JSONFarmacia.get("Longitudine").toString())))

.title(JSONFarmacia.getString("NomeFarmacia"))
.snippet("Distanza: " +
round(distanza, 2) + " km")

.icon(BitmapDescriptorFactory

.fromResource(R.drawable.marker_pharm));

System.out.println("JSONobject
farmacia "+j+ " vale: " + JSONFarmacia);

j++;
}

} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("JSONobject è costituito da: " +
JSONListaFarmacie.length() + " array");

}catch (Exception e)
{
System.out.println("ERRORE!!!! ERRORE!!!! JSONobject
è costituito da: " + JSONListaFarmacie.length() + " array");
}

for (int k = 0; k < markerArray.length &&


markerArray[k]!=null; k++){
mMap.addMarker(markerArray[k]);
}

final Intent intentRiceProd = new Intent(this,


RiceProdLoader.class);
mMap.setOnMarkerClickListener(new
GoogleMap.OnMarkerClickListener() {

@Override
public boolean onMarkerClick(Marker m) {

// step1: apro il db
DbFarmaciaSelezionata mDbFarmaciaSelezionata
= null;
mDbFarmaciaSelezionata = new
DbFarmaciaSelezionata(getApplicationContext());
SQLiteDatabase db =
mDbFarmaciaSelezionata.getWritableDatabase();
db.execSQL("DELETE FROM farmacia");

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 163
// step2: riempio il content da
aggiungere al db ed eseguo l'insert
ContentValues contentValues = new
ContentValues();
contentValues.put("nomefarmacia",
m.getTitle());

contentValues.put("latitudineFarma",m.getPosition().latitude);
contentValues.put("longitudineFarma",
m.getPosition().longitude);
db.insert("farmacia", null, contentValues);
db.close();

if(m.getTitle().equals(Username))
{

scegliFarm.setVisibility(View.INVISIBLE);
}
else
{
scegliFarm.setVisibility(0);
scegliFarm.setText("Scegli \"" +
m.getTitle() + "\"");
}

return false;
}

});

final AlertDialog.Builder alertDialogBuilder = new


AlertDialog.Builder(context);

alertDialogBuilder.setIcon(android.R.drawable.ic_dialog_alert);
alertDialogBuilder.setTitle("Attenzione!");
alertDialogBuilder.setMessage("Al momento della scelta
della farmacia, il carrello verrà svuotato. Vuoi proseguire?");
alertDialogBuilder.setPositiveButton("Ok", new
DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface dialog, int which) {
CatalogoFill.clearMap();

startActivity(intentRiceProd);
}
});
alertDialogBuilder.setNegativeButton("Annulla", null);

scegliFarm.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
alertDialogBuilder.show();

}
});

}
}
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 164
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();

long factor = (long) Math.pow(10, places);


value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}

PannelloFarmacista.java
package it.sii.android.pharmacopter;

import android.app.Activity;
import android.os.Bundle;
import it.sii.android.pharmacopter.db.DbCredenziali;
import it.sii.android.pharmacopter.task.GetElencoOrdiniTask;
import it.sii.android.pharmacopter.task.GetWeatherFarmacistaTask;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class PannelloFarmacista extends Activity {

//elenco textview weather api


TextView tempMax_textView;
TextView tempMin_textView;
TextView windSpeed_textView;
TextView windDirection_textView;
TextView precipit_textView;
ImageView url;
Intent intent = getIntent();
GPSTracker gps;
@SuppressLint("NewApi")
private ProgressDialog progressDialog;

// G E S T I S C E I L P U L S A N T E B A C K

@Override
public void onBackPressed() {
new
AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle("
Esci")
.setMessage("Sei sicuro di voler uscire?")
.setPositiveButton("Sì", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 165
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//***Change Here***
startActivity(intent);
finish();
System.exit(0);
}

}).setNegativeButton("No", null).show();
}
//

@SuppressLint("NewApi") @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pannello_farmacista);
final Button logout = (Button) findViewById(R.id.logout_fb);
final ProgressBar attesa = (ProgressBar) findViewById(R.id.attesa);

tempMax_textView = (TextView) findViewById(R.id.tempMax);


tempMin_textView = (TextView) findViewById(R.id.tempMin);
windSpeed_textView = (TextView) findViewById(R.id.windSpeed);
windDirection_textView = (TextView)
findViewById(R.id.windDirection);
precipit_textView = (TextView) findViewById(R.id.precipit);
url = (ImageView) findViewById(R.id.url);

Button aggiornaDati = (Button) findViewById(R.id.aggiornaDati);


aggiornaDati.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
new
GetWeatherFarmacistaTask(PannelloFarmacista.this,tempMin_textView,tempMax_textVi
ew,windSpeed_textView,windDirection_textView,precipit_textView,url).execute("asd
");
}
}

);
//ottengo i dati sul tempo locale e setto le varie view:
// connetto a db locale e copio i dati dell'utente (presi dal
dblocale)
// in usernadbl e pswdbl
// in modo da poterli utilizzare
DbCredenziali mMioDbHelper = null;
mMioDbHelper = new DbCredenziali(getApplicationContext());
SQLiteDatabase db = mMioDbHelper.getWritableDatabase();
//final String sql = "SELECT username, password FROM credenziali";
final String sql = "SELECT * FROM credenziali";
Cursor c = db.rawQuery(sql, null);

String nome = null;


String citta = null;

// metto un bottone (logout) per cancellare i dati dal DB ed


effettuare il
// logout, ciò comporterà la cancellazione dei vari dati e un
"redirect"
// verso la pagina di login

if (c.moveToFirst()) {
nome = c.getString(3);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 166
citta = c.getString(4);
}

logout.setVisibility(0);
TextView benvenuto, cittaText;
benvenuto = (TextView) findViewById(R.id.benvenuto_textView);
cittaText = (TextView) findViewById(R.id.citta_textView);
benvenuto.setText("Farmacia: " + nome);
cittaText.setText("Città di " + citta);

logout.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
attesa.setVisibility(0);
DbCredenziali mMioDbHelper = null;
mMioDbHelper = new
DbCredenziali(getApplicationContext());
SQLiteDatabase db = mMioDbHelper.getWritableDatabase();
db.execSQL("DELETE FROM credenziali");
Intent intent = new Intent(getApplicationContext(),
Login.class);
startActivity(intent);
db.close();
}
}

);

final Button goOrdini = (Button)


findViewById(R.id.visualizza_ordini);
goOrdini.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

if (v == goOrdini) {

DbCredenziali mMioDbHelper = null;


mMioDbHelper = new
DbCredenziali(getApplicationContext());
SQLiteDatabase db =
mMioDbHelper.getWritableDatabase();
final String sql = "SELECT username FROM
credenziali";
Cursor c = db.rawQuery(sql, null);
c.moveToFirst();
String usernamedb = c.getString(0);

new GetElencoOrdiniTask(PannelloFarmacista.this,
getApplicationContext()).execute(usernamedb);

}
});

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 167
}

PannelloUtente.java
package it.sii.android.pharmacopter;

import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.model.GraphUser;

import it.sii.android.pharmacopter.db.DbCoordinate;
import it.sii.android.pharmacopter.db.DbCredenziali;
import it.sii.android.pharmacopter.task.GetElencoOrdiniFBTask;
import it.sii.android.pharmacopter.task.GetElencoOrdiniTask;
import it.sii.android.pharmacopter.task.GetListaFarmacieLocationTask;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class PannelloUtente extends Activity {


Intent intent = getIntent();
final Context context = this;
GPSTracker gps;
@SuppressLint("NewApi")
TextView error_textView;
private String animation = "right";
private ProgressDialog progressDialog;

protected void onPreExecute() {


//super.onPreExecute();
progressDialog = new ProgressDialog(getApplicationContext());

progressDialog.setMessage(getApplicationContext().getResources().getString
(R.string.caricando2));
progressDialog.show();
}

// G E S T I S C E I L P U L S A N T E B A C K

@Override
public void onBackPressed() {
new AlertDialog.Builder(this)

.setIcon(android.R.drawable.ic_dialog_alert).setTitle("Esci")
.setMessage("Sei sicuro di voler uscire?")

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 168
.setPositiveButton("Sì", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int
which) {

Intent intent = new


Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);// ***Change

// Here***
startActivity(intent);
System.exit(0);
}

}).setNegativeButton("No", null).show();
}

//

@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.pannello_utente);
final Button logout_fb = (Button) findViewById(R.id.logout_fb);
final ProgressBar attesa = (ProgressBar) findViewById(R.id.attesa);

// Gestisce il comportamento del pulsante di logout se sono loggato


con
// fb

logout_fb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
logout_fb.setBackgroundResource(R.drawable.fb_logout2);
callFacebookLogout(getApplicationContext());
Intent registerIntent = new Intent(PannelloUtente.this,
Login.class);
startActivity(registerIntent);

}
});

// connetto a db locale e copio i dati dell'utente (presi dal


dblocale)
// in usernadbl e pswdbl
// in modo da poterli utilizzare
DbCredenziali mMioDbHelper = null;
mMioDbHelper = new DbCredenziali(getApplicationContext());
SQLiteDatabase db = mMioDbHelper.getWritableDatabase();
final String sql = "SELECT username, password FROM credenziali";
Cursor c = db.rawQuery(sql, null);

// Verifico se l'utente ha eseguito l'accesso da fb

final Session a = Session.getActiveSession();

if (a != null) {
System.out.println("ACCESSO ESEGUITO DA fACEBOOK");

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 169
logout_fb.setVisibility(0);
logout_fb.setText("");
logout_fb.setBackgroundResource(R.drawable.fb_logout);
Request request = Request.newMeRequest(a,
new Request.GraphUserCallback() {
@Override
public void onCompleted(GraphUser user,
Response response) {
// If the response is successful
if (a == Session.getActiveSession()) {
if (user != null) {
// Set the Textview's text
to the user's
// name.
TextView benvenuto;
benvenuto = (TextView)
findViewById(R.id.benvenuto_textView);
benvenuto.setText("Ciao, "
+ user.getName()
+ "! ");

//salvo i dati di fb sul db


credenziali
DbCredenziali mMioDbHelper
= null;
mMioDbHelper = new
DbCredenziali(getApplicationContext());
ContentValues contentValues
= new ContentValues();
SQLiteDatabase db =
mMioDbHelper.getWritableDatabase();
db.execSQL("DELETE FROM
credenziali");

contentValues.put("username", user.getName());

contentValues.put("password", "facebook");
contentValues.put("nome",
user.getFirstName());

contentValues.put("cognome", user.getLastName());
contentValues.put("email",
"facebook");
contentValues.put("tipo",
"cliente");

db.insert("credenziali",
null , contentValues);
}
}

if (response.getError() != null) {
TextView benvenuto;
benvenuto = (TextView)
findViewById(R.id.benvenuto_textView);
benvenuto
.setText("Impossibile
recuperare il nome utente. Chiudere l'applicazione e riprovare.");
logout_fb.setVisibility(0);
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 170
}
});
request.executeAsync();
}

// Gestisco il pulsante nel caso di login normale

else if (c.moveToFirst()) {

System.out.println("ACCESSO ESEGUITO DA PAGINA LOGIN");


final String usernamedbl = c.getString(0);
final String pswdbl = c.getString(1);

logout_fb.setVisibility(0);
TextView benvenuto;
benvenuto = (TextView) findViewById(R.id.benvenuto_textView);
benvenuto.setText("Ciao, " + usernamedbl + "! ");

// metto un bottone per cancellare i dati dal DB ed effettuare


il
// logout, ciò comporterà la cancellazione dei vari dati e un
// "redirect"
// verso la pagina di login

logout_fb.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
attesa.setVisibility(0);
DbCredenziali mMioDbHelper = null;
mMioDbHelper = new
DbCredenziali(getApplicationContext());
SQLiteDatabase db =
mMioDbHelper.getWritableDatabase();
db.execSQL("DELETE FROM credenziali");

Intent intent = new


Intent(getApplicationContext(),
Login.class);
startActivity(intent);
}
}

);
}

final Button EffettuaOrdine = (Button) findViewById(R.id.goOrdine);


EffettuaOrdine.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
if (v == EffettuaOrdine) {

// ------- passiamo le coordinate al dbLocale ----


-- //

// create class object


gps = new GPSTracker(PannelloUtente.this);

// check if GPS enabled


if (gps.canGetLocation()) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 171
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();

// SALVO I DATI DELL'UTENTE SU DB LOCALE


DbCoordinate mDbCoordinate = null;
mDbCoordinate = new DbCoordinate(
getApplicationContext());

ContentValues contentValues = new


ContentValues();

SQLiteDatabase db =
mDbCoordinate.getWritableDatabase();
db.execSQL("DELETE FROM coordinate");

contentValues.put("latitude",
String.valueOf(latitude));
contentValues.put("longitude",
String.valueOf(longitude));

db.insert("coordinate", null,
contentValues);
// \n is for new line

// prendo la lista delle farmacie nell'async


task, da
// cui questi vengono spediti all'activity
// MappaConMarker
new
GetListaFarmacieLocationTask(PannelloUtente.this,
error_textView,
getApplicationContext())
.execute("interroga");

} else {
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in
settings
gps.showSettingsAlert();
}

}
}
});

final Button goCarrello = (Button) findViewById(R.id.goCarrello);


goCarrello.setOnClickListener(new OnClickListener() {

Intent carrelloIntent = new Intent(getApplicationContext(),


CarrelloView.class);

@Override
public void onClick(View v) {

if (v == goCarrello) {
// INTENT
startActivity(carrelloIntent);
}

}
});

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 172
final Button goOrdini = (Button) findViewById(R.id.goOrdini);
goOrdini.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

if (v == goOrdini) {
DbCredenziali mMioDbHelper = null;
mMioDbHelper = new
DbCredenziali(getApplicationContext());
SQLiteDatabase db = mMioDbHelper.getWritableDatabase();
final String sql = "SELECT username, password FROM
credenziali";
Cursor c = db.rawQuery(sql, null);
c.moveToFirst();
String usernamedb = null;
System.out.println("PannelloUtente{il nome vale:
"+c.getString(1)+"}");
String usernamedb2 = c.getString(0);
usernamedb = usernamedb2.replaceAll(" ", "_" );
if (a!= null)
{
new GetElencoOrdiniFBTask(PannelloUtente.this,
getApplicationContext()).execute(usernamedb);
}
else if (c.moveToFirst())
{
new GetElencoOrdiniTask(PannelloUtente.this,
getApplicationContext()).execute(usernamedb);
}
else
{
AlertDialog.Builder alertDialogBuilder = new
AlertDialog.Builder(context);
alertDialogBuilder.setTitle("Errore!");
alertDialogBuilder.setMessage("Il server non
riconosce i tuoi dati. Prova ad effettuare il logout e nuovamente l'accesso.");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setNeutralButton("Ok", new
DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface dialog, int whichButton) {
finish();
}
});
AlertDialog alertDialog =
alertDialogBuilder.create();
alertDialog.show();
}

}
});

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 173
// funzione per fb

public void facebookLogin() {

Session a = Session.getActiveSession();

final Intent intentfb;

intentfb = new Intent(getApplicationContext(), About.class);

Session.openActiveSession(this, true, new Session.StatusCallback() {


boolean fblogged2;

@Override
public void call(Session session, SessionState state,
Exception exception) {
System.out.println("STATE IS OPENED: " +
state.isOpened());

if (session.isOpened()) {

Request.newMeRequest(session,
new Request.GraphUserCallback() {
@Override
public void onCompleted(final
GraphUser user,
final Response
response) {

if (user != null) {

fblogged2 = true;
user.getId(); //
prendo l'id dell'utente

// da salvare sul db
}

}
}).executeAsync();

} else {
fblogged2 = false;

});

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode,
resultCode, data);
facebookLogin();

public static void callFacebookLogout(Context context) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 174
Session session = Session.getActiveSession();
if (session != null) {

if (!session.isClosed()) {
session.closeAndClearTokenInformation();
// clear your preferences if saved
}
} else {

session = new Session(context);


Session.setActiveSession(session);

session.closeAndClearTokenInformation();
// clear your preferences if saved

}
}

@Override
public void onResume() {
super.onResume();

if (animation.equals("left")) {
overridePendingTransition(R.anim.slide_right_r,
R.anim.slide_left_r);
} else if (animation.equals("right")) {
overridePendingTransition(R.anim.slide_left,
R.anim.slide_right);
}

Register.java
package it.sii.android.pharmacopter;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;

public class Register extends Activity {

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register);

final String pkg = getPackageName();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 175
ArrayAdapter<String> adapter = createSpinnerAdapter();

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_i
tem);
Spinner spinner = (Spinner) findViewById(R.id.menu_tendina);
spinner.setAdapter(adapter);

spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView,
View selectedItemView, int position, long id) {
String pressedSpin = String.valueOf(position);

final int type = Integer.valueOf(pressedSpin);


TextView descrizione_textView = (TextView)
findViewById(R.id.descrizione_textView);
Button avanti = (Button)
findViewById(R.id.avanti_button);

if (type == 1) {
descrizione_textView
.setText("Permette di richiedere
medicinali somministrabili senza obbligo di prescrizione medica.");
avanti.setVisibility(0);
}

if (type == 2) {
descrizione_textView
.setText("Permette di controllare le
vendite e di gestire il flusso di consegne dei PharmaCopter.");
avanti.setVisibility(0);
TextView registerAmbu = (TextView)
findViewById(R.id.registerAmbu_textView);
registerAmbu.setVisibility(View.INVISIBLE);
avanti.setVisibility(View.INVISIBLE);

TextView chiama_textView = (TextView)


findViewById(R.id.registerFarma_textView);
chiama_textView.setVisibility(0);
chiama_textView.setOnClickListener(new
OnClickListener() {

// funzione per far partire la


chiamata
@Override
public void onClick(View v) {
String toDial =
"tel:+393206271908";
startActivity(new
Intent(Intent.ACTION_CALL, Uri.parse(toDial)));
}
});
}

if (type == 3) {
TextView registerAmbu = (TextView)
findViewById(R.id.registerAmbu_textView);
registerAmbu.setVisibility(0);
descrizione_textView
.setText("Utenza speciale destinata ai
medici in servizio sulle unità ambulanza. Permette di richiedere qualsiasi
medicinale disponibile. La consegna parte anche se non c'è carica sufficiente

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 176
per il viaggio di ritorno.\nQuesto tipo di utenza verrà implementata nella
prossima versione di PharmaCopter (in sede di tesi).");
avanti.setVisibility(View.INVISIBLE);
TextView chiama_textView = (TextView)
findViewById(R.id.registerFarma_textView);
chiama_textView.setVisibility(View.INVISIBLE);
}

avanti.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

if (type == 1) {
Intent register = new Intent(
getApplicationContext(),
RegisterUser.class);
register.putExtra(pkg + ".myType",
type);
startActivity(register);

//
// if (type == 3) {
// Intent register = new Intent(
// getApplicationContext(),
RegisterAmbu.class);
// register.putExtra(pkg + ".myType",
type);
// startActivity(register);
//
// }

});

@Override
public void onNothingSelected(AdapterView<?> parent) {
// TODO Auto-generated method stub
}

});

private ArrayAdapter<String> createSpinnerAdapter() {


String[] data = getResources().getStringArray(R.array.user_choice);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, data);
return arrayAdapter;
}

RegisterUser.java
package it.sii.android.pharmacopter;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 177
import it.sii.android.pharmacopter.classes.Utente;
import it.sii.android.pharmacopter.task.RegisterTask;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class RegisterUser extends Activity {

/** Called when the activity is first created. */

private String errorMsg;


private String errorMsg2;
Context ctx;

@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.register_user);

// questi tre sono quelli che effettivamente uso


final EditText username_inputText = (EditText)
findViewById(R.id.Username_input);
final EditText psw_inputText = (EditText)
findViewById(R.id.Password_input);
final EditText psw2_inputText = (EditText)
findViewById(R.id.RipetiPassword_input);
final int tipo = 1;
final EditText mail_inputText = (EditText)
findViewById(R.id.Email_input);
final EditText mail2_inputText = (EditText)
findViewById(R.id.RipetiEmail_input);
final EditText nome_inputText = (EditText)
findViewById(R.id.Nome_input);
final EditText cognome_inputText = (EditText)
findViewById(R.id.Cognome_input);
final TextView errore_textView = (TextView)
findViewById(R.id.regError_textView);
final TextView errore_textView2 = (TextView)
findViewById(R.id.regError_textView2);

Button Registrati = (Button) findViewById(R.id.Registrati);


Registrati.setOnClickListener(new OnClickListener() {

Intent registratoIntent = new Intent(getApplicationContext(),


PannelloUtente.class);

@Override
public void onClick(View v) {

String errore = "";


//

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 178
if (username_inputText.getText().toString()=="" ||
username_inputText.getText().toString() == null){
errore += "Devi inserire uno username. \n";
}
//
if (psw_inputText.getText().toString()=="" ||
username_inputText.getText().toString() == null){
errore += "Devi inserire una password. \n";
}
if
(!psw_inputText.getText().toString().equals(psw2_inputText.getText().toString())
) {
errore += "Le due password inserite devono essere
uguali. \n";
}

if (mail_inputText.getText().toString().contains("@")
&& ((mail_inputText.getText().toString().endsWith(".com") ||
mail_inputText.getText().toString().endsWith(".it")
||
mail_inputText.getText().toString().endsWith(".org") ||
mail_inputText.getText().toString().endsWith(".eu")))) {

}
else{
errore += "Devi inserire un indirizzo e-mail
valido. \n";
}

if
(!mail_inputText.getText().toString().equals(mail2_inputText.getText().toString(
))) {
errore += "Le due e-mail inserite devono essere
uguali. \n";
}

errore_textView2.setText(errore);

// controllo che lo username nn sia già presente (fatto


a posta con connessione non sicura) questa parte finirà quando leggi -----------
-- HO FINITO-----------------
// new Thread(new Runnable() {
//
// @Override
// public void run() {
//
// ArrayList<NameValuePair> postParameters =
new ArrayList<NameValuePair>();
// postParameters.add(new
BasicNameValuePair("username",
//
username_inputText.getText().toString()));
// postParameters.add(new
BasicNameValuePair("password",
//
psw_inputText.getText().toString()));
// postParameters.add(new
BasicNameValuePair("tipo",
// String.valueOf(tipo)));

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 179
// postParameters.add(new
BasicNameValuePair("mail",
//
mail_inputText.getText().toString()));
// postParameters.add(new
BasicNameValuePair("nome",
//
nome_inputText.getText().toString()));
// postParameters.add(new
BasicNameValuePair("cognome",
//
cognome_inputText.getText().toString()));
// String response = null;
// ArrayList<NameValuePair> postParameters2 =
new ArrayList<NameValuePair>();
// postParameters2.add(new
BasicNameValuePair("username",
//
username_inputText.getText().toString()));
// postParameters2.add(new
BasicNameValuePair("password",
//
psw_inputText.getText().toString()));
// try {
//
//
// ApplicationInfo ai =
ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(),
//
PackageManager.GET_META_DATA);
// String url1 =
ai.metaData.getString("urlservernonsicuro");
// response =
HTTPConnectTask.executeHttpPost(
// url1+"login.do",
// postParameters2);
//
//// response = HTTPConnectTask
////
.executeHttpPost(
////
"http://10.0.2.2:8080/LoginServer2/login.do",
////
postParameters);
// String res = response.toString();
// // http://10.0.2.2:8080
// JSONObject resp = new JSONObject(res);
// JSONObject utente =
resp.getJSONObject("user");
// String nomedacontrollare =
utente.getString("userName");
// System.out.println(resp.toString());
//
//
//
// //System.out.println("ecco il nome da
controllare: " + nomedacontrollare);
//
//System.out.println(username_inputText.getText().toString());
// Boolean successo =
resp.getBoolean("success");
// //se c'è già allora dai l'errore
//

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 180
// if(successo == true ){
//
// errorMsg2 = ("Errore: username
già presente");
// }
// else
// {
// errorMsg = "";
//
// }
//
// } catch (Exception e) {
// e.printStackTrace();
// errorMsg = e.getMessage();
//
// }
// }
//
// }).start();
// try {
// /** wait a second to get response from server */
// Thread.sleep(1000);
// /**
// * Inside the new thread we cannot update the main
// * thread So updating the main thread outside the
new
// * thread
// */
//
//
// errore_textView.setText(errorMsg2);
// if (errorMsg != null && !errorMsg.isEmpty()) {
// errore_textView.setText(errore + errorMsg);
// }
// } catch (Exception e) {
// errore_textView.setText(errore + e.getMessage());
// }
//
// // ----------------- HO FINITO ---------------------
//
//
//
// if (errore.equals("") && errorMsg=="")
// {
//
// ////SALVO I DATI SU DB LOCALE
// DbCredenziali mMioDbHelper = null;
// mMioDbHelper = new
DbCredenziali(getApplicationContext());
// ContentValues contentValues = new ContentValues();
// //
// contentValues.put("username",
username_inputText.getText()
// .toString());
// contentValues.put("password",
psw_inputText.getText()
// .toString());
// contentValues.put("stato", true);
//
// // Accedo al database in scrittura
// SQLiteDatabase db =
mMioDbHelper.getWritableDatabase();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 181
// db.insert("credenziali", null, contentValues); //
Inserisco i
//
// dati
//
// //// ///////////////////////////// SALVO I DATI SU
DB REMOTO
//
//
// /////////////////////////////////////
//
//
//
// //---------- registro in server non sicuro--------
-----//
//// new Thread(new Runnable() {
////
//// @Override
//// public void run() {
////
//// ArrayList<NameValuePair>
postParameters = new ArrayList<NameValuePair>();
//// postParameters.add(new
BasicNameValuePair("username",
////
username_inputText.getText().toString()));
//// postParameters.add(new
BasicNameValuePair("password",
////
psw_inputText.getText().toString()));
//// postParameters.add(new
BasicNameValuePair("tipo",
//// String.valueOf(tipo)));
//// postParameters.add(new
BasicNameValuePair("mail",
////
mail_inputText.getText().toString()));
//// postParameters.add(new
BasicNameValuePair("nome",
////
nome_inputText.getText().toString()));
//// postParameters.add(new
BasicNameValuePair("cognome",
////
cognome_inputText.getText().toString()));
//// String response = null;
//// //
//// try {
//// ApplicationInfo ai =
ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(),
////
PackageManager.GET_META_DATA);
//// response = HTTPConnectTask
////
.executeHttpPostIscrizione(
////
ai.metaData.getString("urlservernonsicuro")+"Register.do",
////
postParameters);
//// String res = response.toString();
//// // http://10.0.2.2:8080
//// JSONObject resp = new
JSONObject(res);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 182
//// JSONObject utente =
resp.getJSONObject("user");
//// String nome =
utente.getString("userName");
////
//// // INTENT
//// String pkg = getPackageName();
//// registratoIntent.putExtra(pkg +
".myUser", nome);
//// startActivity(registratoIntent);
////
//// } catch (Exception e) {
//// e.printStackTrace();
//// errorMsg2 = e.getMessage();
//// }
//// }
////
//// }).start();
//
//
// }
Utente u = new
Utente(String.valueOf(username_inputText.getText()),
psw_inputText.getText().toString(),
mail_inputText.getText().toString(),nome_inputText.getText().toString(),cognome_
inputText.getText().toString(), "utente");
System.out.println("sono qui e questo è il nome che
passo " + username_inputText.getText() + "se metto il stringvalueof: "+
String.valueOf(username_inputText.getText()) );
//---------- registro in server sicurp-------------//
new RegisterTask(RegisterUser.this).execute(u);
}
});

RiceProd.java
package it.sii.android.pharmacopter;

import it.sii.android.pharmacopter.classes.SocketService;
import it.sii.android.pharmacopter.classes.SocketService.LocalBinder;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.view.View.OnClickListener;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 183
public class RiceProd extends Activity implements OnClickListener {

//service
boolean mBounded;
public SocketService s;
private String cStringa;
private Button mCercaBtn;
private Button barcode;
private Button goCarrello;
private String cServerMsg = "";
final Context context = this;
Double latitudine;
Double longitudine;
public int SCANNER_REQUEST_CODE = 123;
TextView tvScanResults;
Button btnScan;

@Override
protected void onStart() {
super.onStart();
Intent mIntent = new Intent(this, SocketService.class);
bindService(mIntent, mConnection, BIND_AUTO_CREATE);
};

ServiceConnection mConnection = new ServiceConnection() {


@Override
public void onServiceDisconnected(ComponentName name) {
mBounded = false;
s = null;
}

@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
mBounded = true;
LocalBinder mLocalBinder = (LocalBinder)service;
s = mLocalBinder.getServerInstance();
}
};

@Override
protected void onStop() {
super.onStop();
if(mBounded) {
unbindService(mConnection);
mBounded = false;
}
};

@SuppressLint("CutPasteId") @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.riceprod);
getWindow().setWindowAnimations(0);

final EditText prodotto = (EditText)


findViewById(R.id.riceProd_editText);
prodotto.setFocusableInTouchMode(true);
prodotto.requestFocus();

mCercaBtn = (Button)findViewById(R.id.ricerca_Server);
mCercaBtn.setOnClickListener(new View.OnClickListener() {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 184
@Override
public void onClick(View v) {
String ricerca = prodotto.getText().toString();
if (ricerca.length() < 3)
{
AlertDialog.Builder alertDialogBuilder = new
AlertDialog.Builder(context);
alertDialogBuilder.setTitle("Attenzione!");
alertDialogBuilder.setMessage("La chiave di
ricerca dev'essere costituita da almeno 3 lettere.");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setNeutralButton("Ok", new
DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface dialog, int whichButton) {

}
});
AlertDialog alertDialog =
alertDialogBuilder.create();
alertDialog.show();
}
else
{
cServerMsg = "";
s.sendMessage("riceprod: [[\"\",\"" + ricerca +
"\"],\"M1\",[\"C111\",\"C134\",\"C116\",\"C141\",\"DEGRASSI\",\"C146\",\"ATC\"]]
");
// Sintassi C111: nome; C134: codici MINSAN; C116:
offerta; C141: giacenza

// inserire tmieout dopo cui effettua un redirect


if (cServerMsg == null)
{
AlertDialog.Builder alertDialogBuilder = new
AlertDialog.Builder(context);
alertDialogBuilder.setTitle("Attenzione!");
alertDialogBuilder.setMessage("La chiave di
ricerca dev'essere costituita da almeno 3 lettere.");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setNeutralButton("Ok", new
DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface dialog, int whichButton) {

}
});
AlertDialog alertDialog =
alertDialogBuilder.create();
alertDialog.show();
}
else
{
while (cServerMsg.isEmpty())
{
cServerMsg = s.line;
}

Intent goRisultati = new Intent


(getApplicationContext(), CatalogoView.class);
goRisultati.putExtra("cServerMsg", cServerMsg);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 185
startActivity(goRisultati);
overridePendingTransition(R.anim.slide_left,
R.anim.slide_right);
}
}
}
});

// faccio sì che anche premendo l'ENTER della tastiera, scateni


l'evento di ricerca.
prodotto.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
// Perform action on key press
mCercaBtn.performClick();

return true;
}
return false;
}
});

final AlertDialog.Builder alertDialogBuilder = new


AlertDialog.Builder(context);

barcode = (Button)findViewById(R.id.barcode);
barcode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == R.id.barcode) {

alertDialogBuilder.setIcon(android.R.drawable.ic_dialog_alert);
alertDialogBuilder.setTitle("BARCODE Scan");
alertDialogBuilder.setMessage("Questa funzione
permette di ricercare un farmaco tramite riconoscimento ottico del suo codice a
barre.\nSi tratta di una funzionalità ancora in fase di testing, per cui c'è il
rischio che l'applicazione smetta di rispondere.");
alertDialogBuilder.setPositiveButton("Ok", new
DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface dialog, int which) {

Intent intent = new


Intent("com.google.zxing.client.android.SCAN");

intent.putExtra("SCAN_MODE", "SCAN_MODE");

startActivityForResult(intent, SCANNER_REQUEST_CODE);
}
});
alertDialogBuilder.setNegativeButton("Annulla",
null);
alertDialogBuilder.show();
}
}
});

goCarrello = (Button)findViewById(R.id.goCarrello);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 186
goCarrello.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

Intent i = new Intent(context,CarrelloView.class);


context.startActivity(i);

}
});
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent
intent) {

if (requestCode == SCANNER_REQUEST_CODE) {
// Handle scan intent
if (resultCode == Activity.RESULT_OK) {
// Handle successful scan
String contents = intent.getStringExtra("SCAN_RESULT");
String formatName =
intent.getStringExtra("SCAN_RESULT_FORMAT");
byte[] rawBytes =
intent.getByteArrayExtra("SCAN_RESULT_BYTES");
int intentOrientation =
intent.getIntExtra("SCAN_RESULT_ORIENTATION", Integer.MIN_VALUE);
Integer orientation = (intentOrientation ==
Integer.MIN_VALUE) ? null : intentOrientation;
String errorCorrectionLevel =
intent.getStringExtra("SCAN_RESULT_ERROR_CORRECTION_LEVEL");

Toast.makeText(this, "Trovato match",


Toast.LENGTH_SHORT).show();

cServerMsg = "";
s.sendMessage("riceprod: [[\"\",\""+ contents +
"\"],\"M1\",[\"C111\",\"C134\",\"C116\",\"C141\",\"DEGRASSI\",\"C146\",\"ATC\"]]
");
// Sintassi C111: nome; C134: codici MINSAN; C116: offerta;
C141: giacenza

while (cServerMsg.isEmpty())
{
cServerMsg = s.line;
}

Intent goRisultati = new Intent


(getApplicationContext(), CatalogoView.class);
goRisultati.putExtra("cServerMsg", cServerMsg);
startActivity(goRisultati);
overridePendingTransition(R.anim.slide_left,
R.anim.slide_right);

} else if (resultCode == Activity.RESULT_CANCELED) {


Toast.makeText(this, "Processo annullato dall'utente.",
Toast.LENGTH_SHORT).show();
Intent i = new Intent(context,RiceProd.class);
context.startActivity(i);
}
} else {
// Handle other intents
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 187
}

@Override
public void onClick(View v) {
// TODO Auto-generated method stub

} }

RiceProdLoader.java
package it.sii.android.pharmacopter;

import it.sii.android.pharmacopter.classes.SocketService;
import it.sii.android.pharmacopter.classes.SocketService.LocalBinder;
import it.sii.android.pharmacopter.db.DbFarmaciaSelezionata;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.widget.TextView;

public class RiceProdLoader extends Activity {

private SocketService s;
boolean mBounded;
final Context context = this;
public String cServermsg;
public String cErrmsg;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.riceprod_loader);
getWindow().setWindowAnimations(0);

// CONTROLLO SE E' STATA MAI SCELTA UNA FARMACIA


DbFarmaciaSelezionata mDbFarmaciaSelezionata = null;
mDbFarmaciaSelezionata = new
DbFarmaciaSelezionata(getApplicationContext());
SQLiteDatabase db = mDbFarmaciaSelezionata.getWritableDatabase();
final String sql = "SELECT nomefarmacia FROM farmacia ";
Cursor c = db.rawQuery(sql, null);
c.moveToFirst();
try{
String nome = c.getString(0);
if(nome.equals("")||nome.equals(null))
{
AlertDialog.Builder alertDialogBuilder = new
AlertDialog.Builder(context);
alertDialogBuilder.setTitle("Errore!");

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 188
alertDialogBuilder.setMessage("Non hai ancora
selezionato nessuna farmacia. Verrai automaticamente reindirizzato nella pagina
di scelta.");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton("Ok", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface
dialog, int whichButton) {
Intent goMappa = new
Intent(context, MappaConMarker.class);
startActivity(goMappa);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
catch (Exception e) {
AlertDialog.Builder alertDialogBuilder = new
AlertDialog.Builder(context);
alertDialogBuilder.setTitle("Errore!");
alertDialogBuilder.setMessage("Non hai ancora selezionato
nessuna farmacia. Verrai automaticamente reindirizzato nella pagina di
scelta.");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setNeutralButton("Ok", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int whichButton) {
Intent goMappa = new Intent(context,
MappaConMarker.class);
startActivity(goMappa);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}

TextView outputView = (TextView) findViewById(R.id.textLoader);


outputView.setText("Connessione ai server della farmacia in
corso...");

// resettiamo i valori per eventuale nuovo giro


cServermsg = "";
cErrmsg = "";

// avvio servizio
Intent intent = new Intent(context, SocketService.class);
context.startService(intent);

// creiamo il timeout dopo l'avvio del servizio


Handler handler = new Handler();
handler.postDelayed(new Runnable() {

@Override
public void run() {

long endTime = System.currentTimeMillis() + 20000; //


timeout 20

// secondi

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 189
while (endTime > System.currentTimeMillis()) {

cServermsg = s.line;
cErrmsg = s.errore;

if (cServermsg != null && !cServermsg.isEmpty() &&


cServermsg.substring(0, 9).equals("login: ok")) {

endTime = 0;

Bundle data = new Bundle();


data.putString("Json", cServermsg);
Intent i = new
Intent(getApplicationContext(), RiceProd.class);
i.putExtras(data); // sto tenendo memoria
della risposta del server
startActivity(i);

finish();

} else if (!cErrmsg.isEmpty()) {
endTime = 1;
}

// se non riusciamo a collegarci?


if (endTime != 0) {

if (cErrmsg.isEmpty()) {
cErrmsg = "Il server di questa farmacia non
risponde. Scegline un'altra oppure riprova in un secondo momento.";
}

// chiudiamo tutto ciò che potrebbe essere aperto


s.closeConnection();
unbindService(mConnection);
mBounded = false;

AlertDialog.Builder alertDialogBuilder = new


AlertDialog.Builder(context);
alertDialogBuilder.setTitle("Errore!");
alertDialogBuilder.setMessage(cErrmsg);
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setNeutralButton("Ok", new
DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface dialog, int whichButton) {finish();}
});
AlertDialog alertDialog =
alertDialogBuilder.create();
alertDialog.show();
}

}
}, 1000); // ritardiamo l'esecuzione di un secondo

@Override
protected void onStart() {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 190
super.onStart();
Intent mIntent = new Intent(this, SocketService.class);
bindService(mIntent, mConnection, BIND_AUTO_CREATE);
};

ServiceConnection mConnection = new ServiceConnection() {

@Override
public void onServiceDisconnected(ComponentName name) {
mBounded = false;
s = null;
}

@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
mBounded = true;
LocalBinder mLocalBinder = (LocalBinder) service;
s = mLocalBinder.getServerInstance();
}
};

@Override
protected void onStop() {
super.onStop();
if (mBounded) {
unbindService(mConnection);
mBounded = false;
}
};

ShareExternalServer.java
package it.sii.android.pharmacopter;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import android.content.Context;
import android.util.Log;

public class ShareExternalServer {

public String shareRegIdWithAppServer(final Context context,


final String regId,final String username) {

String result = "";


Map<String, String> paramsMap = new HashMap<String, String>();
paramsMap.put("regId", regId);
paramsMap.put("username", username);
try {
URL serverUrl = null;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 191
try {
serverUrl = new URL(Config.APP_SERVER_URL);
} catch (MalformedURLException e) {
Log.e("AppUtil", "URL Connection Error: "
+ Config.APP_SERVER_URL, e);
result = "Invalid URL: " + Config.APP_SERVER_URL;
}

StringBuilder postBody = new StringBuilder();


Iterator<Entry<String, String>> iterator =
paramsMap.entrySet()
.iterator();

while (iterator.hasNext()) {
Entry<String, String> param = iterator.next();
postBody.append(param.getKey()).append('=')
.append(param.getValue());
if (iterator.hasNext()) {
postBody.append('&');
}
}
String body = postBody.toString();
byte[] bytes = body.getBytes();
HttpURLConnection httpCon = null;
try {
httpCon = (HttpURLConnection)
serverUrl.openConnection();
httpCon.setDoOutput(true);
httpCon.setUseCaches(false);
httpCon.setFixedLengthStreamingMode(bytes.length);
httpCon.setRequestMethod("POST");
httpCon.setRequestProperty("Content-Type",
"application/x-www-form-
urlencoded;charset=UTF-8");
OutputStream out = httpCon.getOutputStream();
out.write(bytes);
out.close();

int status = httpCon.getResponseCode();


if (status == 200) {
result = "RegId shared with Application Server.
RegId: "
+ regId;
} else {
result = "Post Failure." + " Status: " + status;
}
} finally {
if (httpCon != null) {
httpCon.disconnect();
}
}

} catch (IOException e) {
result = "Post Failure. Error in sharing with App Server.";
Log.e("AppUtil", "Error in sharing with App Server: " + e);
}
return result;
}
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 192
Codice android: it.sii.android.pharmacopter.classes

CatalogoFill.java
package it.sii.android.pharmacopter.classes;

import it.sii.android.pharmacopter.R;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.content.res.Resources;

public class CatalogoFill {

public static final String PRODUCT_INDEX = "PRODUCT_INDEX";


private static String cStringa;
private static List<Prodotto> catalog;
private static Map<Prodotto, ItemCarrello> cartMap = new HashMap<Prodotto,
ItemCarrello>();

public static List<Prodotto> getCatalog(Resources res, String cStr){


cStringa = cStr;
catalog = new Vector<Prodotto>();

String[] parts = null;


parts = cStringa.split("\"");
int i=0;

// R I E M P I O I L C A T A L O G
while (parts[i+8] != "" && i < parts.length-60)
{
String s = cleanDouble(parts[i+14]);
if (!s.matches(".*\\d+.*"))
{
s = "illimitata";
}

String s1 = cleanDouble(parts[i+22]);
if (!s1.matches(".*\\d+.*"))
{
s1 = "";
}

if (parts[i+19].contains("PRODOTTI SANITARI"))
{
catalog.add(new Prodotto(parts[i+3], parts[i+7],
parts[i+9], cleanDouble(parts[i+12]), s, parts[i+19], s1, parts[i+25],
res.getDrawable(R.drawable.p_medico)));
}
else if (parts[i+19].contains("STRUMENTI SANITARI"))
{
catalog.add(new Prodotto(parts[i+3], parts[i+7],
parts[i+9], cleanDouble(parts[i+12]), s, parts[i+19], s1, parts[i+25],
res.getDrawable(R.drawable.p_strum_san)));
}
else if (parts[i+19].contains("AUSILI SANITARI"))

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 193
{
catalog.add(new Prodotto(parts[i+3], parts[i+7],
parts[i+9], cleanDouble(parts[i+12]), s, parts[i+19], s1, parts[i+25],
res.getDrawable(R.drawable.p_siringa)));
}
else if (parts[i+19].contains("ALTRI PROD.VALENZA SANITARIA"))
{
catalog.add(new Prodotto(parts[i+3], parts[i+7],
parts[i+9], cleanDouble(parts[i+12]), s, parts[i+19], s1, parts[i+25],
res.getDrawable(R.drawable.p_farmacia)));
}
else if (parts[i+19].contains("PRODOTTI OMEOPATICI") ||
parts[i+19].contains("ERBORISTERIA") || parts[i+19].contains("COMPL.ALIM.") ||
parts[i+19].contains("DIETETICI"))
{
catalog.add(new Prodotto(parts[i+3], parts[i+7],
parts[i+9], cleanDouble(parts[i+12]), s, parts[i+19], s1, parts[i+25],
res.getDrawable(R.drawable.p_naturale)));
}
else if (parts[i+19].contains("SPEC.MED.DA BANCO"))
{
catalog.add(new Prodotto(parts[i+3], parts[i+7],
parts[i+9], cleanDouble(parts[i+12]), s, parts[i+19], s1, parts[i+25],
res.getDrawable(R.drawable.p_pastiglie)));
}
else if (parts[i+19].contains("PRODOTTI ZOOTECNICI"))
{
catalog.add(new Prodotto(parts[i+3], parts[i+7],
parts[i+9], cleanDouble(parts[i+12]), s, parts[i+19], s1, parts[i+25],
res.getDrawable(R.drawable.p_zoo)));
}
else
{
catalog.add(new Prodotto(parts[i+3], parts[i+7],
parts[i+9], cleanDouble(parts[i+12]), s, parts[i+19], s1, parts[i+25],
res.getDrawable(R.drawable.p_farmacia)));
}
i = i+30;
}
return catalog;
}

public static void setQuantity(Prodotto product, int quantity) {


// PRENDI LO STATO ATTUALE DEL CARRELLO
ItemCarrello curEntry = cartMap.get(product);

// SE IL CARRELLO NON ESISTE, CREALO


if(curEntry == null) {
curEntry = new ItemCarrello(product, quantity);
cartMap.put(product, curEntry);
return;
}
System.out.println("curentry = " + curEntry.toString());

// RIMUOVI I PRODOTTI CON QUANTITA' NEGATIVA


if(quantity <= 0) {
if(curEntry != null)
removeProduct(product);
return;
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 194
// AGGIORNA LA QUANTITA'
curEntry.setQuantity(quantity);
}

// PRENDE LA QUANTITA' DI UN PRODOTTO NEL CARRELLO

// PER FARLO DEVO ANDARE AD ANALIZZARE LA CORRISPONDENZA DI QUESTO


PRODOTTO DENTRO AL CARRELLO
// QUINDI PRENDERE DALLA MAPPA DEI "PRODOTTI NEL CARRELLO" QUELLO UGUALE A
QUELLO CLICCATO.
public static int getProductQuantity(Prodotto product) {
// Prende dalla mappa la entry specifica
ItemCarrello curEntry = cartMap.get(product);
//controlla se esiste l'istanza
if(curEntry != null){
//ritorna la qta nel carrello
return curEntry.getQuantity();
}
return 0;
}

// PRENDE IL PREZZO
public static Double getProductPrice(Prodotto product) {
return product.getPrezzo();
}

//RIMUOVE UN PRODOTTO DAL CARRELLO


public static void removeProduct(Prodotto product) {
cartMap.remove(product);
}

// RIEMPIO LA MAPPA DI PRODOTTI NEL CARRELLO


public static List<Prodotto> getCartList() {
List<Prodotto> cartList = new
Vector<Prodotto>(cartMap.keySet().size());
for(Prodotto p : cartMap.keySet()) {
cartList.add(p);
}
return cartList;
}

//pulisce i valori numerici dalle virgole e le parentesi quadre varie


public static String cleanDouble(String str){
StringBuffer sBuffer = new StringBuffer();
Pattern p = Pattern.compile("[0-9]+.[0-9]*|[0-9]*.[0-9]+|[0-9]+");
Matcher m = p.matcher(str);
while (m.find()) {
sBuffer.append(m.group());
}
String s = sBuffer.toString().replaceAll(",","");
return s;
}

public static void clearMap(){


cartMap.clear();
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 195
Farmacia.java
package it.sii.android.pharmacopter.classes;

public class Farmacia {

public Farmacia(String nomeFarmacia, Double latitudine, Double


longitudine) {
super();
NomeFarmacia = nomeFarmacia;
Latitudine = latitudine;
Longitudine = longitudine;
}

String NomeFarmacia;
Double Latitudine;
Double Longitudine;

public Farmacia() {
super();
}

public String getNomeFarmacia() {


return NomeFarmacia;
}

public void setNomeFarmacia(String nomeFarmacia) {


NomeFarmacia = nomeFarmacia;
}

public Double getLatitudine() {


return Latitudine;
}

public void setLatitudine(Double latitude) {


Latitudine = latitude;
}

public Double getLongitudine() {


return Longitudine;
}

public void setLongitudine(Double longitudine) {


Longitudine = longitudine;
}
}

ItemCarrello.java
package it.sii.android.pharmacopter.classes;

public class ItemCarrello {

private Prodotto prodotto;


private int qta;

//costruttore
public ItemCarrello(Prodotto product, int quantity) {
prodotto = product;
qta = quantity;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 196
}

public Prodotto getProduct() {


return prodotto;
}

// QUANTITA' DA ACQUISTARE
public int getQuantity() {
return qta;
}
public void setQuantity(int quantity) {
qta = quantity;
}

ItemCatalogo.java
package it.sii.android.pharmacopter.classes;

import it.sii.android.pharmacopter.R;
import java.util.List;

import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class ItemCatalogo extends BaseAdapter {

private List<Prodotto> mProductList;


private LayoutInflater mInflater;

public ItemCatalogo(List<Prodotto> list, LayoutInflater inflater) {


mProductList = list;
mInflater = inflater;
}

@Override
public int getCount() {
return mProductList.size();
}

@Override
public Object getItem(int position) {
return mProductList.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewItem prodottoNelCatalogo;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 197
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_catalogo, null);
prodottoNelCatalogo = new ViewItem();

prodottoNelCatalogo.productImageView = (ImageView) convertView


.findViewById(R.id.ImageViewItem);

prodottoNelCatalogo.productTitle = (TextView) convertView


.findViewById(R.id.TextViewItem);

prodottoNelCatalogo.Minsan1 = (TextView) convertView


.findViewById(R.id.Minsan1);

prodottoNelCatalogo.Minsan2 = (TextView) convertView


.findViewById(R.id.Minsan2);

prodottoNelCatalogo.productQuantity = (TextView) convertView


.findViewById(R.id.textViewQuantity);

prodottoNelCatalogo.productPrice = (TextView) convertView


.findViewById(R.id.textViewPrice);

prodottoNelCatalogo.productAvailable = (TextView) convertView


.findViewById(R.id.textViewDisp);

convertView.setTag(prodottoNelCatalogo);
} else {
prodottoNelCatalogo = (ViewItem) convertView.getTag();
}

Prodotto curProduct = mProductList.get(position);

prodottoNelCatalogo.productImageView.setImageDrawable(curProduct.productIm
age);
prodottoNelCatalogo.productTitle.setText(curProduct.nome);

// MOSTRA LA QUANTITA' PRESENTE NEL CARRELLO (solo se >0)


int qta = CatalogoFill.getProductQuantity(curProduct);
double sub = CatalogoFill.getProductPrice(curProduct)*qta;

if(qta>0)
{
prodottoNelCatalogo.productQuantity.setText("Nel carrello: " +
qta + " unità\nSubtotale: " + round(sub, 2) + " EUR");
}
else
{
// NASCONDI LA VISTA
prodottoNelCatalogo.productQuantity.setVisibility(View.GONE);
}

// Mostra il prezzo nella vista (se è in offerta, viene


visualizzato)
double pr = CatalogoFill.getProductPrice(curProduct);
if (curProduct.isOfferta() == true)
{
prodottoNelCatalogo.productPrice.setText("OFFERTA: "
+ round(pr, 2) + " EUR");
}
else
{

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 198
prodottoNelCatalogo.productPrice.setText("Prezzo: "
+ round(pr, 2) + " EUR");
}

// MOSTRA LA DISPONIBILITA'
String ava = curProduct.disponibilita;

if (ava != null && !ava.isEmpty())


{

prodottoNelCatalogo.productAvailable.setText("Disponibilità: " + ava);


}
else
{

prodottoNelCatalogo.productAvailable.setTextColor(R.color.red);

prodottoNelCatalogo.productAvailable.setText("Disponibilità: N/D");
}

// SETTA CODICI MINSAN


prodottoNelCatalogo.Minsan1.setText(curProduct.minsan1);
prodottoNelCatalogo.Minsan2.setText(curProduct.minsan2);

return convertView;
}

private class ViewItem {


ImageView productImageView;
TextView productTitle;
TextView productAvailable;
TextView productQuantity;
TextView productPrice;
TextView Minsan1, Minsan2;
}

public static double round(double value, int places) {


if (places < 0) throw new IllegalArgumentException();

long factor = (long) Math.pow(10, places);


value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}

ItemListaOrdini.java
package it.sii.android.pharmacopter.classes;

import it.sii.android.pharmacopter.R;
import java.util.List;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 199
public class ItemListaOrdini extends BaseAdapter {

private List<Ordine> mOrderList;


private LayoutInflater mInflater;
private String tipo;

public ItemListaOrdini(List<Ordine> list, LayoutInflater inflater, String


type) {
mOrderList = list;
tipo = type;
mInflater = inflater;
}

@Override
public int getCount() {
return mOrderList.size();
}

@Override
public Object getItem(int position) {
return mOrderList.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewItem itemOrdine;

if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_ordine, null);
itemOrdine = new ViewItem();

itemOrdine.orderDate = (TextView) convertView


.findViewById(R.id.DataOrdine);

itemOrdine.nome = (TextView) convertView


.findViewById(R.id.Nome);

itemOrdine.orderPrice = (TextView) convertView


.findViewById(R.id.textViewPrice);

itemOrdine.orderID = (TextView) convertView


.findViewById(R.id.idOrdine);

itemOrdine.stato = (TextView) convertView


.findViewById(R.id.stato);

itemOrdine.statoImm = (ImageView) convertView


.findViewById(R.id.statoIm);;

convertView.setTag(itemOrdine);
} else {
itemOrdine = (ViewItem) convertView.getTag();
}

Ordine currOrder = mOrderList.get(position);


System.out.println(currOrder.data);
itemOrdine.orderDate.setText("Ordine del: " + currOrder.data);
System.out.println("Data: " + currOrder.data);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 200
itemOrdine.orderID.setText("ID: #PHA00" + currOrder.idOrdine);

if(tipo.contains("cliente"))
{
itemOrdine.nome.setText(" presso: " + currOrder.nomeFarma);
}
else if(tipo.contains("farma"))
{
itemOrdine.nome.setText(" - Effettuato da: " +
currOrder.getNomeCli());
}

itemOrdine.orderPrice.setText("Totale: " +
round(Double.parseDouble(currOrder.prezzoTot),2) + " EUR");

if(currOrder.getStato().contains("nonapprovato")){
itemOrdine.stato.setText("Stato dell'ordine:\nIN ATTESA DI
APPROVAZIONE");

itemOrdine.statoImm.setBackgroundResource(R.drawable.b_white);;
}
else if(currOrder.getStato().contains("approvato")){
itemOrdine.stato.setText("Stato dell'ordine:\nAPPROVATO");

itemOrdine.statoImm.setBackgroundResource(R.drawable.b_yellow);;
}
else if(currOrder.getStato().contains("pagato")){
itemOrdine.stato.setText("Stato dell'ordine:\nPAGATO");

itemOrdine.statoImm.setBackgroundResource(R.drawable.b_green);;
}
else if(currOrder.getStato().contains("spedito")){
itemOrdine.stato.setText("Stato dell'ordine:\nSPEDIZIONE IN
CORSO...");
itemOrdine.statoImm.setImageAlpha(R.drawable.b_blue);;
}
else if(currOrder.getStato().contains("tornato")){
itemOrdine.stato.setText("Stato dell'ordine:\nRECAPITATO");

itemOrdine.statoImm.setBackgroundResource(R.drawable.b_black);;
}
else if(currOrder.getStato().contains("respinto")){
itemOrdine.stato.setText("Stato dell'ordine:\nANNULLATO");
itemOrdine.statoImm.setBackgroundResource(R.drawable.b_red);;
}
else if(currOrder.getStato().contains("consegnaamano")){
itemOrdine.stato.setText("Stato dell'ordine:\nNECESSARIO
RITIRO A MANO");

itemOrdine.statoImm.setBackgroundResource(R.drawable.b_white);;
}
else if(currOrder.getStato().contains("daritirare")){
itemOrdine.stato.setText("Stato dell'ordine:\nIN ATTESA DI
RITIRO A MANO");

itemOrdine.statoImm.setBackgroundResource(R.drawable.b_black);;
}

return convertView;
}

public class ViewItem {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 201
TextView orderDate;
TextView orderID;
TextView nome;
TextView orderPrice;
TextView stato;
ImageView statoImm;
}

public static double round(double value, int places) {


if (places < 0) throw new IllegalArgumentException();

long factor = (long) Math.pow(10, places);


value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}

JSONObjectUtils.java
package it.sii.android.pharmacopter.classes;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;

import org.apache.http.NameValuePair;
import org.json.JSONObject;

import android.util.Log;

public class JSONObjectUtils {

public static JSONObject getJSONObjectFromStream(InputStream in){


StringBuilder responseStrBuilder = new StringBuilder();
JSONObject obj = new JSONObject();
try{

BufferedReader streamReader = new BufferedReader(new


InputStreamReader(in, "UTF-8"));
String inputStr;
while ((inputStr = streamReader.readLine()) != null)
responseStrBuilder.append(inputStr);
System.out.println("ecco il response builder: " +
responseStrBuilder.toString());
obj = new JSONObject(responseStrBuilder.toString());
}
catch(Exception e)
{
Log.e("STREAM TO JSON ERROR", ""+e.getMessage());
}

return obj;
}

public static String getQuery(List<NameValuePair> params) throws


UnsupportedEncodingException
{

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 202
StringBuilder result = new StringBuilder();
boolean first = true;

for (NameValuePair pair : params)


{
if (first)
first = false;
else
result.append("&");

result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
}

return result.toString();
}

Ordine.java
package it.sii.android.pharmacopter.classes;

public class Ordine {


String nomeFarma, data, nomeCli;
String cliLat,cliLon,farmaLat,farmaLon;
int idOrdine;
String prezzoTot;
String stato;

public Ordine(int idOrdine, String nomeCli, String nomeFarma, String data,


String d, String stato,String cliLat,String cliLon,String
farmaLat,String farmaLon) {
super();
this.idOrdine = idOrdine;
this.nomeCli = nomeCli;
this.nomeFarma = nomeFarma;
this.data = data;
this.prezzoTot = d;
this.stato = stato;
this.cliLat = cliLat;
this.cliLon = cliLon;
this.farmaLat = farmaLat;
this.farmaLon = farmaLon;

public void setFarmaLon(String farmaLon) {


this.farmaLon = farmaLon;
}

public String getNomeFarma() {


return nomeFarma;
}

public void setNomeFarma(String nomeFarma) {


this.nomeFarma = nomeFarma;
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 203
public String getData() {
return data;
}

public void setData(String data) {


this.data = data;
}

public String getNomeCli() {


return nomeCli;
}

public void setNomeCli(String nomeCli) {


this.nomeCli = nomeCli;
}

public int getIdOrdine() {


return idOrdine;
}

public void setIdOrdine(int idOrdine) {


this.idOrdine = idOrdine;
}

public String getPrezzoTot() {


return prezzoTot;
}

public void setPrezzoTot(String prezzoTot) {


this.prezzoTot = prezzoTot;
}

public String getStato() {


return stato;
}

public void setStato(String stato) {


this.stato = stato;
}

public void setCliLat(String cliLat) {


this.cliLat = cliLat;
}

public String getCliLat() {


return cliLat;
}

public String getCliLon() {


return cliLon;
}

public void setCliLon(String cliLon) {


this.cliLon = cliLon;
}

public String getFarmaLat() {


return farmaLat;
}

public void setFarmaLat(String farmaLat) {


this.farmaLat = farmaLat;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 204
}

public String getFarmaLon() {


return farmaLon;
}

Prodotto.java
package it.sii.android.pharmacopter.classes;

import android.graphics.drawable.Drawable;

public class Prodotto {

public String nomeFarma, data, nomeCli;


public int idOrdine;
public String prezzoTot;
public String stato;
public String nome, minsan1, minsan2, listino, disponibilita, tipo,
offerta, atc;
public Drawable productImage;
public boolean selected;

public Prodotto(String nome, String minsan1, String minsan2, String


prezzo,
String disponibilita, String tipo, String offerta, String atc,
Drawable productImage) {
super();
this.nome = nome;
this.minsan1 = minsan1;
this.minsan2 = minsan2;
this.listino = prezzo;
this.disponibilita = disponibilita;
this.tipo = tipo;
this.offerta = offerta;
this.atc = atc;
this.productImage = productImage;
}

public boolean isOfferta() {


if (offerta=="")
{
return false;
}
else
{
return true;
}
}

// CALCOLO PREZZO DEL PRODOTTO


public Double getPrezzo()
{
if(isOfferta())
{
System.out.println("C'è l'offerta!");
return Double.parseDouble(this.offerta);
}
else
{

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 205
System.out.println("Non c'è l'offerta!");
return Double.parseDouble(this.listino);
}
}

SocketService.java
package it.sii.android.pharmacopter.classes;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;

import org.apache.http.conn.util.InetAddressUtils;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;

public class SocketService extends Service {

private String cLogin;

//socket
public Socket socket;
public static final String SERVER_IP = "poli.farmaconsult.it";
public static final int SERVERPORT = 1047;
public BufferedReader in;
public PrintWriter out;
public String line = "";
public String errore = "";
public static final String TAG = "ifarma";
boolean connect = false;

// dati
private String android_id = Build.SERIAL;
private String android_dev = Build.MODEL;
private String android_ver = "Android " + Build.VERSION.RELEASE;

private final IBinder mBinder = new LocalBinder();

@Override
public IBinder onBind(Intent intent) {
return mBinder;
}

public class LocalBinder extends Binder {


public SocketService getServerInstance() {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 206
return SocketService.this;
}
}

@Override
public void onCreate() {
super.onCreate();
}

public void sendMessage(String message){

line = "";

if (out != null && !out.checkError()) {


out.println(message);
out.flush();

//ci aspettiamo una risposta solo se non è quit


if (message.equals("quit:")) {
closeConnection();
}

}
}

public void closeConnection(){


connect = false;
try {
socket.getOutputStream().close();
socket.getInputStream().close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
socket = null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

super.onStartCommand(intent, flags, startId);


errore = "";

//impostiamo il login
cLogin = "login: ['farma','zefir','Farmacia 1.5','" + android_id +
"','" + android_dev + "','" + android_ver + "']";

Pattern ver_host = Pattern.compile("^([a-zA-Z0-9]|[a-zA-Z0-


9][a-zA-Z0-9\\-]*[a-zA-Z0-9])(\\.([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-
z0-9])){1,10}$");

if (!ver_host.matcher(SERVER_IP).matches()) {
errore = "Il campo telefono non contiene dati validi.";
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 207
if (errore.isEmpty()) {
new Thread(new ClientThread()).start();
}

return Service.START_NOT_STICKY;
}

public class ClientThread implements Runnable {

@Override
public void run() {

errore = "";

try {

// connessione socket
InetAddress serverAddr =
InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);

// stream output ed input


out = new PrintWriter(new
OutputStreamWriter(socket.getOutputStream()));
in = new BufferedReader(new
InputStreamReader(socket.getInputStream(), "Windows-1252"));

// invio login
sendMessage(cLogin);

connect = true;

while (connect) {

line = in.readLine();

} catch (UnknownHostException e1) {


errore = "Host non trovato, verificare numero di
telefono e riprovare.";
e1.printStackTrace();
} catch (IOException e1) {
errore = "Errore di connessione.";
e1.printStackTrace();
} catch (Exception e1) {
errore = "Errore sconosciuto.";
e1.printStackTrace();
}

}
}

public static String getIPAddress(boolean useIPv4) {


try {
List<NetworkInterface> interfaces =
Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces) {
List<InetAddress> addrs =
Collections.list(intf.getInetAddresses());
for (InetAddress addr : addrs) {
if (!addr.isLoopbackAddress()) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 208
String sAddr =
addr.getHostAddress().toUpperCase(Locale.getDefault());
boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
if (useIPv4) {
if (isIPv4)
return sAddr;
} else {
if (!isIPv4) {
int delim = sAddr.indexOf('%'); // drop ip6 port
suffix
return delim<0 ? sAddr : sAddr.substring(0,
delim);
}
}
}
}
}
} catch (Exception ex) { }
return "";
}

@Override
public void onDestroy() {
super.onDestroy();
connect = false;
try {
socket.getOutputStream().close();
socket.getInputStream().close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
socket = null;
}
}

Utente.java
package it.sii.android.pharmacopter.classes;

public class Utente {

String nome;
String password;
String email;
String nomeanagrafe;
String cognomeanagrafe;
String tipo;
String latitudine;
String longitudine;

boolean logged;

// getters and setters

public String getNome() {


return nome;
}
public void setNome(String nome) {
this.nome = nome;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 209
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}

public String getEmail() {


return email;
}
public void setEmail(String email) {
this.email = email;
}

public String getNomeanagrafe() {


return nomeanagrafe;
}
public void setNomeanagrafe(String nomeanagrafe) {
this.nomeanagrafe = nomeanagrafe;
}

public String getCognomeanagrafe() {


return cognomeanagrafe;
}
public void setCognomeanagrafe(String cognomeanagrafe) {
this.cognomeanagrafe = cognomeanagrafe;
}

public String getTipo() {


return tipo;
}
public void setTipo(String tipo) {
this.tipo = tipo;
}

public String getLatitudine() {


return latitudine;
}
public void setLatitudine(String latitudine) {
this.latitudine = latitudine;
}

public String getLongitudine() {


return longitudine;
}
public void setLongitudine(String longitudine) {
this.longitudine = longitudine;
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 210
public Utente(String nome, String password) {
super();
this.nome = nome;
this.password = password;
this.logged = false;
}
public Utente(String nome, String password, String email,
String nomeanagrafe, String cognomeanagrafe, String tipo) {
super();
this.nome = nome;
this.password = password;
this.email = email;
this.nomeanagrafe = nomeanagrafe;
this.cognomeanagrafe = cognomeanagrafe;
this.tipo = tipo;
// TODO Auto-generated constructor stub
}
public boolean isLogged() {
return logged;
}
public void setLogged(boolean logged) {
this.logged = logged;
}

Codice android: it.sii.android.pharmacopter.db

DbAltitude.java
package it.sii.android.pharmacopter.classes;

public class Utente {

String nome;
String password;
String email;
String nomeanagrafe;
String cognomeanagrafe;
String tipo;
String latitudine;
String longitudine;

boolean logged;

// getters and setters

public String getNome() {


return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getPassword() {
return password;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 211
}
public void setPassword(String password) {
this.password = password;
}

public String getEmail() {


return email;
}
public void setEmail(String email) {
this.email = email;
}

public String getNomeanagrafe() {


return nomeanagrafe;
}
public void setNomeanagrafe(String nomeanagrafe) {
this.nomeanagrafe = nomeanagrafe;
}

public String getCognomeanagrafe() {


return cognomeanagrafe;
}
public void setCognomeanagrafe(String cognomeanagrafe) {
this.cognomeanagrafe = cognomeanagrafe;
}

public String getTipo() {


return tipo;
}
public void setTipo(String tipo) {
this.tipo = tipo;
}

public String getLatitudine() {


return latitudine;
}
public void setLatitudine(String latitudine) {
this.latitudine = latitudine;
}

public String getLongitudine() {


return longitudine;
}
public void setLongitudine(String longitudine) {
this.longitudine = longitudine;
}

public Utente(String nome, String password) {


super();
this.nome = nome;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 212
this.password = password;
this.logged = false;
}
public Utente(String nome, String password, String email,
String nomeanagrafe, String cognomeanagrafe, String tipo) {
super();
this.nome = nome;
this.password = password;
this.email = email;
this.nomeanagrafe = nomeanagrafe;
this.cognomeanagrafe = cognomeanagrafe;
this.tipo = tipo;
// TODO Auto-generated constructor stub
}
public boolean isLogged() {
return logged;
}
public void setLogged(boolean logged) {
this.logged = logged;
}

DbCarrello.java
package it.sii.android.pharmacopter.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DbCarrello extends SQLiteOpenHelper {


// Nome del database che vogliamo creare
private static final String DB_NOME = "CARRELLO";

/**
* Numero della versione del database.
*
* La numerazione della vesione del database deve iniziare dal numero 1.
* Quando viene specificata una nuova versione android useguirà la
funzione
* onUpgrade.
*/
private static final int DB_VERSIONE = 1;

public DbCarrello(Context context) {


super(context, DB_NOME, null, DB_VERSIONE);
}

@Override
public void onCreate(SQLiteDatabase db) {
/*
* Stringa contenente la sintassi SQL per la creazione della tabella
* RUBRICA
*/
String sql = "CREATE TABLE carrello";
sql += "(_id INTEGER PRIMARY KEY,";
sql += "JSONobject String NOT NULL);";

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 213
// Eseguiamo la query
db.execSQL(sql);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub

DbCoordinate.java
package it.sii.android.pharmacopter.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DbCoordinate extends SQLiteOpenHelper {


// Nome del database che vogliamo creare
private static final String DB_NOME = "COORDINATE";

/**
* Numero della versione del database.
*
* La numerazione della vesione del database deve iniziare dal numero 1.
* Quando viene specificata una nuova versione android useguirà la
funzione
* onUpgrade.
*/
private static final int DB_VERSIONE = 1;

public DbCoordinate(Context context) {


super(context, DB_NOME, null, DB_VERSIONE);
}

@Override
public void onCreate(SQLiteDatabase db) {
/*
* Stringa contenente la sintassi SQL per la creazione della tabella
* RUBRICA
*/
String sql = "CREATE TABLE coordinate";
sql += "(_id INTEGER PRIMARY KEY,";
sql += "latitude DOUBLE NOT NULL,";
sql += "longitude DOUBLE NOT NULL);";

// Eseguiamo la query
db.execSQL(sql);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 214
DbCredenziali.java
package it.sii.android.pharmacopter.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DbCredenziali extends SQLiteOpenHelper {


// Nome del database che vogliamo creare
private static final String DB_NOME = "CREDENZIALI";

/**
* Numero della versione del database.
*
* La numerazione della vesione del database deve iniziare dal numero 1.
* Quando viene specificata una nuova versione android useguirà la
funzione
* onUpgrade.
*/
private static final int DB_VERSIONE = 1;

public DbCredenziali(Context context) {


super(context, DB_NOME, null, DB_VERSIONE);
}

@Override
public void onCreate(SQLiteDatabase db) {
/*
* Stringa contenente la sintassi SQL per la creazione della tabella
* credenziali
*/
String sql = "CREATE TABLE credenziali";
sql += "(_id INTEGER PRIMARY KEY,";
sql += "username TEXT NOT NULL,";
sql += "password TEXT NOT NULL,";
sql += "nome TEXT NOT NULL,";
sql += "cognome TEXT NOT NULL,";
sql += "tipo TEXT NOT NULL,";
sql += "email TEXT NOT NULL);";

// Eseguiamo la query
db.execSQL(sql);
System.out.println("l ho fatto cazzo!!!");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub

DbFarmaciaSelezionata.java
package it.sii.android.pharmacopter.db;

import android.content.Context;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 215
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DbFarmaciaSelezionata extends SQLiteOpenHelper {


// Nome del database che vogliamo creare
private static final String DB_NOME = "FARMACIA";

/**
* Numero della versione del database.
*
* La numerazione della vesione del database deve iniziare dal numero 1.
* Quando viene specificata una nuova versione android useguirà la
funzione
* onUpgrade.
*/
private static final int DB_VERSIONE = 1;

public DbFarmaciaSelezionata(Context context) {


super(context, DB_NOME, null, DB_VERSIONE);
}

@Override
public void onCreate(SQLiteDatabase db) {
/*
* Stringa contenente la sintassi SQL per la creazione della tabella
* credenziali
*/
String sql = "CREATE TABLE farmacia";
sql += "(_id INTEGER PRIMARY KEY,";
sql += "latitudineFarma DOUBLE NOT NULL,";
sql += "longitudineFarma DOUBLE NOT NULL,";
sql += "nomefarmacia TEXT NOT NULL);";

// Eseguiamo la query
db.execSQL(sql);

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub

Codice android: it.sii.android.pharmacopter.task

CambiaStatoTask.java
package it.sii.android.pharmacopter.task;
import it.sii.android.pharmacopter.*;
import it.sii.android.pharmacopter.classes.JSONObjectUtils;
import it.sii.android.pharmacopter.classes.Utente;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 216
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.json.JSONObject;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;

public class CambiaStatoTask extends AsyncTask<String, Integer, boolean[]> {

private ProgressDialog progressDialog;

Context context;

Intent intent;
String Tipo;
String Id;
String notificationReceiverUsername;

TextView accesso_textView;
Context context2;

public CambiaStatoTask(Context context, Context context2,String id,String


tipo,String notificationReceiverUsername){
super();
this.context = context;
this.context2 = context2;
this.Id = id;
this.Tipo = tipo;
this.notificationReceiverUsername = notificationReceiverUsername;
}

@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(context);

progressDialog.setMessage(context.getResources().getString(R.string.carica
ndo7));
progressDialog.show();
}

@Override
protected boolean[] doInBackground(String... Stato) {

final JSONObject risposta;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 217
boolean[] success = {true};

String stato = Stato[0];


// System.out.println(utente[0].getNome());
// System.out.println(utente[0].getPassword());
try{

ApplicationInfo ai =
context.getPackageManager().getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String url1 = ai.metaData.getString("urlserversicuro");
String surl = url1+
"ModificaStatoOrdine.do"+"?idordine="+Id+"&stato="+stato+"&notificationReceiverU
sername="+notificationReceiverUsername ;

//System.out.println(utente[0].getNome()+" "
+utente[0].getPassword());
// Load CAs from an InputStream (could be a resource/asset, a
file, etc.)
CertificateFactory cf =
CertificateFactory.getInstance("X.509");
InputStream caInput = new
BufferedInputStream(context.getAssets().open("amznserver.crt"));
Certificate ca=null;
try {
ca = cf.generateCertificate(caInput);
Log.i("LocalCACertificateHttpsClientActivity", " ecco il
certificato: "+ ((X509Certificate) ca).toString());
}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
}
finally {
caInput.close();
}

// Create a KeyStore containing the trusted CAs


String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
//System.out.println(keyStore.toString());

// Create a TrustManager that trusts the CAs in the new


KeyStore
String tmfAlgorithm =
TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
//System.out.println(""+ tmf.toString());

// Create a SSLContext that uses the newly created


TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
//HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 218
HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

// Tell the URLConnection to use a SocketFactory from such


SSLContext
URL url = new URL(surl);

//System.out.println(url.getPort());
//System.out.println(surl);
//System.out.println(url);

HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();

urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(hostnameVerifier);
urlConnection.connect();
// System.out.println("ecco loggetto2" +
urlConnection.toString());
risposta =
JSONObjectUtils.getJSONObjectFromStream(urlConnection.getInputStream());

// logged[0] = (risposta.getBoolean("success") &&


risposta.getJSONObject("user").getBoolean(""));
// utente[0].setLogged(logged[0]);
// u = utente[0];

}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
e.printStackTrace();
}

return success;

}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);

if(Tipo.equals("cliente")){
progressDialog.setMessage("Verrai reindirizzato al Pannello utente,
attendi...");
}
if(Tipo.equals("farmacista")){
progressDialog.setMessage("Verrai reindirizzato al Pannello
Farmacista, attendi...");
}

@Override
protected void onPostExecute(boolean logged[]) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 219
if(Tipo.equals("cliente")){
progressDialog.dismiss();
intent = new Intent(context2, PannelloUtente.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context2.startActivity(intent);
}
if(Tipo.equals("farmacista")){
progressDialog.dismiss();
intent = new Intent(context2, PannelloFarmacista.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context2.startActivity(intent);
}

super.onPostExecute(logged);
}

GetElencoOrdiniFBTask.java
package it.sii.android.pharmacopter.task;
import it.sii.android.pharmacopter.*;
import it.sii.android.pharmacopter.classes.JSONObjectUtils;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.json.JSONObject;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

public class GetElencoOrdiniFBTask extends AsyncTask<String, Integer, boolean[]>


{

private ProgressDialog progressDialog;

Context context;
Context context2;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 220
String s;
JSONObject risposta;
Intent i;

TextView error_textView;

public GetElencoOrdiniFBTask(Context context, Context context2){


super();
this.context = context;
this.context2 = context2;

@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(context);

progressDialog.setMessage(context.getResources().getString(R.string.carica
ndo5));
progressDialog.show();
}

@Override
protected boolean[] doInBackground(String... string) {

String username = null;


String username1 = string[0];
if (username1.contains(" "))
{
username = username1.replaceAll(" ", "_");
}
else
{
username = username1;
}

boolean[] logged = {false};

// System.out.println(utente[0].getNome());
// System.out.println(utente[0].getPassword());
try{

ApplicationInfo ai =
context.getPackageManager().getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String url1 = ai.metaData.getString("urlserversicuro");
String surl =
url1+"OttieniElencoOrdiniFB.do"+"?username="+username;
// Load CAs from an InputStream (could be a resource/asset, a
file, etc.)
CertificateFactory cf =
CertificateFactory.getInstance("X.509");
InputStream caInput = new
BufferedInputStream(context.getAssets().open("amznserver.crt"));
Certificate ca=null;
try {
ca = cf.generateCertificate(caInput);
Log.i("LocalCACertificateHttpsClientActivity", " ecco il
certificato: "+ ((X509Certificate) ca).toString());
}
catch(Exception e)
{

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 221
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
}
finally {
caInput.close();
}

// Create a KeyStore containing the trusted CAs


String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
//System.out.println(keyStore.toString());

// Create a TrustManager that trusts the CAs in the new


KeyStore
String tmfAlgorithm =
TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
//System.out.println(""+ tmf.toString());

// Create a SSLContext that uses the newly created


TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
//HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER;
HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

// Tell the URLConnection to use a SocketFactory from such


SSLContext
URL url = new URL(surl);

//System.out.println(url.getPort());
//System.out.println(surl);
//System.out.println(url);

HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();

urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(hostnameVerifier);
urlConnection.connect();
//System.out.println("ecco loggetto2" +
urlConnection.toString());

risposta =
JSONObjectUtils.getJSONObjectFromStream(urlConnection.getInputStream());

System.out.println("ecco loggetto2" + risposta);

if(risposta.length() != 0){
logged[0] = true;
}
else
{
logged[0]=false;
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 222
}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
e.printStackTrace();
}

return logged;

}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// progressDialog.setMessage("Eseguo il login, attendi...");
}

@Override
protected void onPostExecute(boolean logged[]) {
// this.error_textView = asd;

// System.out.println("true se il tipo è effettivamente utente: "+


tipo.equals("utente"));
if(logged[0]==true){

// INTENT
// accesso_textView.setText("Accesso come utente: \"" + username + "\"
in corso...");
// accesso_textView.setTextColor(Color.rgb(0,0,0));
// qui devo prendere la risposta che è un json contenente tante
farmacie(nome farmacia,lat,long) e la devo inserire nel db locale
System.out.println("ci sn riuscito!!!");

//per rendere univoci i nomi delle chiavi passate


//è consigliato (la doc dice 'must') aggiungere il nome del
nostro package davanti al nome

i = new Intent(context2, OrdiniView.class);


i.putExtra("jsonString", risposta.toString());
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context2.startActivity(i);

}
else {
Toast.makeText(context2,
"Non ci sono ordini a tuo nome nel server.",
Toast.LENGTH_SHORT).show();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 223
}
super.onPostExecute(logged);
}

GetElencoOrdiniTask.java
package it.sii.android.pharmacopter.task;
import it.sii.android.pharmacopter.*;
import it.sii.android.pharmacopter.classes.JSONObjectUtils;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.json.JSONObject;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

public class GetElencoOrdiniTask extends AsyncTask<String, Integer, boolean[]> {

private ProgressDialog progressDialog;

Context context;
final Context context2;
String s;
JSONObject risposta;
Intent i;

TextView error_textView;

public GetElencoOrdiniTask(Context context, Context context2){


super();
this.context = context;
this.context2 = context2;

@Override
protected void onPreExecute() {
super.onPreExecute();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 224
progressDialog = new ProgressDialog(context);

progressDialog.setMessage(context.getResources().getString(R.string.carica
ndo5));
progressDialog.show();
}

@Override
protected boolean[] doInBackground(String... string) {

String username = null;


String username1 = string[0];
System.out.println("string0 vale " + string[0]);
if (username1.contains(" "))
{
username = username1.replaceAll(" ", "_");
}
else
{
username = username1;
}

boolean[] logged = {false};

// System.out.println(utente[0].getNome());
// System.out.println(utente[0].getPassword());
try{

ApplicationInfo ai =
context.getPackageManager().getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String url1 = ai.metaData.getString("urlserversicuro");
String surl =
url1+"OttieniElencoOrdini.do"+"?username="+username;
// Load CAs from an InputStream (could be a resource/asset, a
file, etc.)
CertificateFactory cf =
CertificateFactory.getInstance("X.509");
InputStream caInput = new
BufferedInputStream(context.getAssets().open("amznserver.crt"));
Certificate ca=null;
try {
ca = cf.generateCertificate(caInput);
Log.i("LocalCACertificateHttpsClientActivity", " ecco il
certificato: "+ ((X509Certificate) ca).toString());
}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
}
finally {
caInput.close();
}

// Create a KeyStore containing the trusted CAs


String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
//System.out.println(keyStore.toString());

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 225
// Create a TrustManager that trusts the CAs in the new
KeyStore
String tmfAlgorithm =
TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
//System.out.println(""+ tmf.toString());

// Create a SSLContext that uses the newly created


TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
//HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER;
HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

// Tell the URLConnection to use a SocketFactory from such


SSLContext
URL url = new URL(surl);

//System.out.println(url.getPort());
//System.out.println(surl);
//System.out.println(url);

HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();

urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(hostnameVerifier);
urlConnection.connect();
//System.out.println("ecco loggetto2" +
urlConnection.toString());

risposta =
JSONObjectUtils.getJSONObjectFromStream(urlConnection.getInputStream());

System.out.println("ecco loggetto2" + risposta);

if(risposta.length() != 0){
logged[0] = true;
}
else
{
logged[0]=false;
}

}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
e.printStackTrace();
}

return logged;

}
@Override
protected void onProgressUpdate(Integer... values) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 226
super.onProgressUpdate(values);
// progressDialog.setMessage("Eseguo il login, attendi...");
}

@Override
protected void onPostExecute(boolean logged[]) {
// this.error_textView = asd;

// System.out.println("true se il tipo è effettivamente utente: "+


tipo.equals("utente"));
if(logged[0]==true){

// INTENT
// accesso_textView.setText("Accesso come utente: \"" + username + "\"
in corso...");
// accesso_textView.setTextColor(Color.rgb(0,0,0));
// qui devo prendere la risposta che è un json contenente tante
farmacie(nome farmacia,lat,long) e la devo inserire nel db locale
System.out.println("ci sn riuscito!!!");

//per rendere univoci i nomi delle chiavi passate


//è consigliato (la doc dice 'must') aggiungere il nome del
nostro package davanti al nome

i = new Intent(context2, OrdiniView.class);


i.putExtra("jsonString", risposta.toString());
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context2.startActivity(i);

}
else {
Toast.makeText(context2,
"Non ci sono ordini a tuo nome nel server.",
Toast.LENGTH_SHORT).show();
}
progressDialog.dismiss();

super.onPostExecute(logged);
}

GetListaFarmacieLocationTask.java
package it.sii.android.pharmacopter.task;
import it.sii.android.pharmacopter.*;
import it.sii.android.pharmacopter.classes.JSONObjectUtils;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 227
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.json.JSONObject;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;

public class GetListaFarmacieLocationTask extends AsyncTask<String, Integer,


boolean[]> {

private ProgressDialog progressDialog;

Context context;
Context context2;
String s;
JSONObject risposta;
String username;
String tipo;
Intent i;

TextView error_textView;

public GetListaFarmacieLocationTask(Context context, TextView asd, Context


context2){
super();
this.context = context;
this.context2 = context2;

@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(context);

progressDialog.setMessage(context.getResources().getString(R.string.carica
ndo2));
progressDialog.show();
}

@Override
protected boolean[] doInBackground(String... string) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 228
boolean[] logged = {false};

// System.out.println(utente[0].getNome());
// System.out.println(utente[0].getPassword());
try{

ApplicationInfo ai =
context.getPackageManager().getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String url1 = ai.metaData.getString("urlserversicuro");
String surl = url1+"OttieniElencoFarmacie.do"+"?richiesta=vai"
;
// Load CAs from an InputStream (could be a resource/asset, a
file, etc.)
CertificateFactory cf =
CertificateFactory.getInstance("X.509");
InputStream caInput = new
BufferedInputStream(context.getAssets().open("amznserver.crt"));
Certificate ca=null;
try {
ca = cf.generateCertificate(caInput);
Log.i("LocalCACertificateHttpsClientActivity", " ecco il
certificato: "+ ((X509Certificate) ca).toString());
}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
}
finally {
caInput.close();
}

// Create a KeyStore containing the trusted CAs


String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
//System.out.println(keyStore.toString());

// Create a TrustManager that trusts the CAs in the new


KeyStore
String tmfAlgorithm =
TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
//System.out.println(""+ tmf.toString());

// Create a SSLContext that uses the newly created


TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
//HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER;
HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

// Tell the URLConnection to use a SocketFactory from such


SSLContext
URL url = new URL(surl);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 229
//System.out.println(url.getPort());
//System.out.println(surl);
//System.out.println(url);

HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();

urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(hostnameVerifier);
urlConnection.connect();
//System.out.println("ecco loggetto2" +
urlConnection.toString());

risposta =
JSONObjectUtils.getJSONObjectFromStream(urlConnection.getInputStream());

System.out.println("ecco loggetto2" + risposta);

if(risposta.length() != 0){
logged[0] = true;
}
else
{
logged[0]=false;
}

}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
e.printStackTrace();
}

return logged;

}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// progressDialog.setMessage("Eseguo il login, attendi...");
}

@Override
protected void onPostExecute(boolean logged[]) {
// this.error_textView = asd;

// System.out.println("true se il tipo è effettivamente utente: "+


tipo.equals("utente"));
if(logged[0]==true){

// INTENT
// accesso_textView.setText("Accesso come utente: \"" + username + "\"
in corso...");
// accesso_textView.setTextColor(Color.rgb(0,0,0));

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 230
// qui devo prendere la risposta che è un json contenente tante
farmacie(nome farmacia,lat,long) e la devo inserire nel db locale
System.out.println("ci sn riuscito!!!");

//per rendere univoci i nomi delle chiavi passate


//è consigliato (la doc dice 'must') aggiungere il nome del
nostro package davanti al nome

i = new Intent(context2, MappaConMarker.class);


String pkg = context2.getPackageName();
i.putExtra(pkg+".myJSONString", risposta.toString());
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context2.startActivity(i);

}
else {

System.out.println("ci sn riuscito2!!!");
// context.startActivity(i);
//
accesso_textView.setText(context.getResources().getString(R.string.errore)
);
// accesso_textView.setTextColor(Color.rgb(200,20,20));
}
super.onPostExecute(logged);
progressDialog.dismiss();

GetWeatherClienteTask.java
package it.sii.android.pharmacopter.task;
import it.sii.android.pharmacopter.*;
import org.json.JSONObject;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.ImageView;
import android.widget.TextView;

public class GetWeatherClienteTask extends AsyncTask<String, String, String> {

private ProgressDialog progressDialog;

String tempmin;
String tempmax;
String velvento;
String angolvento;
String precipi;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 231
Context context;
TextView tempMinUtente;
TextView tempMaxUtente;
TextView velVentoUtente;
TextView angoloVentoUtente;
TextView precipitUtente;
TextView possoVolare;
ImageView url;
String iconaurl = "";
String clienteLat;
String clienteLon;

public GetWeatherClienteTask(Context context, TextView tempMin, TextView


tempMax,TextView velVento,TextView angoloVentom,TextView precipit, ImageView
url,String clientelat,String clientelon,TextView possovolare){
super();
this.context = context;
this.tempMinUtente = tempMin;
this.tempMaxUtente = tempMax;
this.velVentoUtente = velVento;
this.angoloVentoUtente = angoloVentom;
this.precipitUtente = precipit;
this.url = url;
this.clienteLat = clientelat;
this.clienteLon = clientelon;
this.possoVolare = possovolare;
}

@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(context);

progressDialog.setMessage(context.getResources().getString(R.string.carica
ndo6));
progressDialog.show();

@Override
protected String doInBackground(String... string) {

String success = "";

String coordinatefarmacia = clienteLat+","+clienteLon;


String response = null;
try {

// 48.85,2.35
//richiesta a worldweatheronline
response =
HTTPConnectTask.executeHttpGet("http://api.worldweatheronline.com/free/v1/weathe
r.ashx?key=caa712fd03b2906813c1f9aeb154c4710454b03c&q="+coordinatefarmacia
+"&cc=no&date=2010-04-23&format=JSON");
String resp = response.toString();

JSONObject risposta = new JSONObject(resp);


System.out.println("RESP VALE: " + risposta);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 232
velvento =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getStrin
g("windspeedKmph");
angolvento =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getStrin
g("winddirDegree");
tempmin =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getStrin
g("tempMinC");
tempmax =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getStrin
g("tempMaxC");
precipi =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getStrin
g("precipMM");
iconaurl =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getJSONA
rray("weatherIconUrl").getJSONObject(0).getString("value");
// System.out.println("iconaurl vale: " + iconaurl);
System.out.println("INFORMAZIONI : " + velvento+"
"+angolvento+" "+tempmax+" "+tempmin+" "+precipi);

} catch (Exception e) {
e.printStackTrace();

// System.out.println(utente[0].getNome());
// System.out.println(utente[0].getPassword());
success=tempmax;

return success;

}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);

@Override
protected void onPostExecute(String success) {
progressDialog.dismiss();
// System.out.println("ecco il valore di success: " +success);
// System.out.println("ecco il valore di tempmaxsenza averla passata: "
+tempmax);

tempMinUtente.setText("MIN: "+tempmin.toString() + "°C");


tempMaxUtente.setText("MAX: " + tempmax.toString() + "°C");
velVentoUtente.setText("VEL: " + velvento.toString() + " KM/h");
angoloVentoUtente.setText("WAY: " + angolvento.toString() + "°");
precipitUtente.setText("RAIN: " + precipi.toString() + "mm");
// url.setImageURI(Uri.parse(iconaurl));

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 233
if(iconaurl.contains("sunny"))
{
url.setBackgroundResource(R.drawable.c_sunny);
possoVolare.setText("Il clima è ideale per il volo.");

}
else if(iconaurl.contains("cloud"))
{
url.setBackgroundResource(R.drawable.c_cloudy);
possoVolare.setText("Il clima permette il volo, ma è possibile
che si verifichino precipitazioni.");
}
else if(iconaurl.contains("snow"))
{
url.setBackgroundResource(R.drawable.c_snowy);
possoVolare.setText("E' assolutamente sconsigliato effettuare
un volo.");
}
else if(iconaurl.contains("rain"))
{
url.setBackgroundResource(R.drawable.c_rainy);
possoVolare.setText("E' sconsigliato effettuare un volo.");
}
else
{
url.setBackgroundResource(R.drawable.c_windy);
possoVolare.setText("E' sconsigliato effettuare un volo.");
}
super.onPostExecute(success);
}

GetWeatherFarmacistaTask.java
package it.sii.android.pharmacopter.task;
import it.sii.android.pharmacopter.*;
import it.sii.android.pharmacopter.db.DbCoordinate;
import org.json.JSONObject;
import android.app.ProgressDialog;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.widget.ImageView;
import android.widget.TextView;

public class GetWeatherFarmacistaTask extends AsyncTask<String, String, String>


{

private ProgressDialog progressDialog;

String tempmin;
String tempmax;
String velvento;
String angolvento;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 234
String precipi;

Context context;
TextView tempMin;
TextView tempMax;
TextView velVento;
TextView angoloVentom;
TextView precipit;
ImageView url;
String iconaurl = "";

public GetWeatherFarmacistaTask(Context context, TextView tempMin,


TextView tempMax,TextView velVento,TextView angoloVentom,TextView precipit,
ImageView url){
super();
this.context = context;
this.tempMin = tempMin;
this.tempMax = tempMax;
this.velVento = velVento;
this.angoloVentom = angoloVentom;
this.precipit = precipit;
this.url = url;
}

@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(context);

progressDialog.setMessage(context.getResources().getString(R.string.carica
ndo6));
progressDialog.show();

@Override
protected String doInBackground(String... string) {

String success = "";

// richiedo latitudine e longitudine dal dblocale


DbCoordinate mDbCoordinate = new
DbCoordinate(context.getApplicationContext());
SQLiteDatabase db = mDbCoordinate.getWritableDatabase();
final String sqlCoordinate = "SELECT latitude, longitude FROM
coordinate ";
Cursor c = db.rawQuery(sqlCoordinate, null);
c.moveToFirst();

//eccoti le coordinate che ti servono boilah:


final Double myLat = c.getDouble(0);
final Double myLong = c.getDouble(1);
// System.out.println(myLat);
// System.out.println(myLong);
c.close();
db.close();

String coordinatefarmacia = myLat+","+myLong;


String response = null;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 235
try {

// 48.85,2.35
//richiesta a worldweatheronline
response =
HTTPConnectTask.executeHttpGet("http://api.worldweatheronline.com/free/v1/weathe
r.ashx?key=caa712fd03b2906813c1f9aeb154c4710454b03c&q="+coordinatefarmacia
+"&cc=no&date=2010-04-23&format=JSON");
String resp = response.toString();

JSONObject risposta = new JSONObject(resp);


System.out.println("RESP VALE: " + risposta);
velvento =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getStrin
g("windspeedKmph");
angolvento =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getStrin
g("winddirDegree");
tempmin =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getStrin
g("tempMinC");
tempmax =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getStrin
g("tempMaxC");
precipi =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getStrin
g("precipMM");
iconaurl =
risposta.getJSONObject("data").getJSONArray("weather").getJSONObject(0).getJSONA
rray("weatherIconUrl").getJSONObject(0).getString("value");
System.out.println("iconaurl vale: " + iconaurl);
System.out.println("INFORMAZIONI : " + velvento+"
"+angolvento+" "+tempmax+" "+tempmin+" "+precipi);

} catch (Exception e) {
e.printStackTrace();

// System.out.println(utente[0].getNome());
// System.out.println(utente[0].getPassword());
success=tempmax;

return success;

}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 236
@Override
protected void onPostExecute(String success) {
progressDialog.dismiss();
// System.out.println("ecco il valore di success: " +success);
// System.out.println("ecco il valore di tempmaxsenza averla passata: "
+tempmax);

tempMin.setText("MIN: "+tempmin.toString() + "°C");


tempMax.setText("MAX: " + tempmax.toString() + "°C");
velVento.setText("VEL: " + velvento.toString() + " KM/h");
angoloVentom.setText("WAY: " + angolvento.toString() + "°");
precipit.setText("RAIN: " + precipi.toString() + "mm");
// url.setImageURI(Uri.parse(iconaurl));
if(iconaurl.contains("sunny"))
{
url.setBackgroundResource(R.drawable.c_sunny);
}
else if(iconaurl.contains("cloud"))
{
url.setBackgroundResource(R.drawable.c_cloudy);
}
else if(iconaurl.contains("snow"))
{
url.setBackgroundResource(R.drawable.c_snowy);
}
else if(iconaurl.contains("rain"))
{
url.setBackgroundResource(R.drawable.c_rainy);
}
else
{
url.setBackgroundResource(R.drawable.c_windy);
}
super.onPostExecute(success);
}

HTTPConnectTask.java
package it.sii.android.pharmacopter.task;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

public class HTTPConnectTask {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 237
/** The time it takes for our client to timeout */
public static final int HTTP_TIMEOUT = 30 * 1000; // milliseconds

/** Single instance of our HttpClient */


private static HttpClient mHttpClient;

/**
* Get our single instance of our HttpClient object.
*
* @return an HttpClient object with connection parameters set
*/
private static HttpClient getHttpClient() {
if (mHttpClient == null) {
mHttpClient = new DefaultHttpClient();
final HttpParams params = mHttpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params,
HTTP_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, HTTP_TIMEOUT);
ConnManagerParams.setTimeout(params, HTTP_TIMEOUT);
}
return mHttpClient;
}

/**
* Performs an HTTP Post request to the specified url with the specified
* parameters.
*
* @param url
* The web address to post the request to
* @param postParameters
* The parameters to send via the request
* @return The result of the request
* @throws Exception
*/
public static String executeHttpPost(String url,
ArrayList<NameValuePair> postParameters) throws Exception {
BufferedReader in = null;
try {
HttpClient client = getHttpClient();
HttpPost request = new HttpPost(url);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
postParameters);
request.setEntity(formEntity);
HttpResponse response = client.execute(request);
in = new BufferedReader(new
InputStreamReader(response.getEntity()
.getContent()));

StringBuffer sb = new StringBuffer("");


String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();

String result = sb.toString();


return result;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 238
e.printStackTrace();
}
}
}
}

public static String executeHttpPostIscrizione(String url,


ArrayList<NameValuePair> postParameters) throws Exception {
BufferedReader in = null;
try {
HttpClient client = getHttpClient();
HttpPost request = new HttpPost(url);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
postParameters);
request.setEntity(formEntity);
HttpResponse response = client.execute(request);
in = new BufferedReader(new
InputStreamReader(response.getEntity()
.getContent()));

StringBuffer sb = new StringBuffer("");


String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
System.out.println("String buffer riempito");
System.out.println(sb.toString());
}
in.close();

String result = sb.toString();


return result;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

/**
* Performs an HTTP GET request to the specified url.
*
* @param url
* The web address to post the request to
* @return The result of the request
* @throws Exception
*/
public static String executeHttpGet(String url) throws Exception {
BufferedReader in = null;
try {
HttpClient client = getHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(url));
HttpResponse response = client.execute(request);
in = new BufferedReader(new
InputStreamReader(response.getEntity()
.getContent()));

StringBuffer sb = new StringBuffer("");

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 239
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();

String result = sb.toString();


return result;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

LoginTask.java
package it.sii.android.pharmacopter.task;
import it.sii.android.pharmacopter.*;
import it.sii.android.pharmacopter.classes.JSONObjectUtils;
import it.sii.android.pharmacopter.classes.Utente;
import it.sii.android.pharmacopter.db.DbCoordinate;
import it.sii.android.pharmacopter.db.DbCredenziali;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;
import com.google.android.gms.gcm.GoogleCloudMessaging;

import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.AsyncTask;
import android.text.TextUtils;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 240
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

public class LoginTask extends AsyncTask<Utente, Integer, boolean[]> {

private ProgressDialog progressDialog;

Context context;

Utente u;

String Tipo;
String Username;
String Password;
String Nome;
String Cognome;
String Email;
String FarmaLat;
String FarmaLon;

TextView accesso_textView;
Context context2;

//variabili per GCM

GoogleCloudMessaging gcm;
String regId;
ShareExternalServer appUtil;

AsyncTask<Void, Void, String> shareRegidTask;


public static final String REG_ID = "regId";
private static final String APP_VERSION = "appVersion";

static final String TAG = "Register Activity";

public LoginTask(Context context, TextView asd, Context context2){


super();
this.context = context;
this.context2 = context2;
this.accesso_textView = asd;
}

@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(context);

progressDialog.setMessage(context.getResources().getString(R.string.carica
ndo));
progressDialog.show();
}

@Override
protected boolean[] doInBackground(Utente... utente) {

final JSONObject risposta;


boolean[] logged = {false};

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 241
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", utente[0].getNome()));
params.add(new BasicNameValuePair("password",
utente[0].getPassword()));
// System.out.println(utente[0].getNome());
// System.out.println(utente[0].getPassword());
try{

//---------------------------------parte relativa alla registrazione dello


username su GCM

// if (TextUtils.isEmpty(regId)) {
// regId = registerGCM();
// Log.d("RegisterActivity", "GCM RegId: " + regId);
// } else {
// Toast.makeText(context,
// "Already Registered with GCM Server!",
// Toast.LENGTH_LONG).show();
// }
//
// if (TextUtils.isEmpty(regId)) {
// regId = registerGCM();
// Toast.makeText(context, "RegId is empty!",
// Toast.LENGTH_LONG).show();
// } else {
//
// appUtil = new ShareExternalServer();
//
//
// Log.d("MainActivity", "regId: " + regId);
//
//
// shareRegidTask = new AsyncTask<Void, Void, String>() {
// @Override
// protected String doInBackground(Void... params) {
// String result =
appUtil.shareRegIdWithAppServer(context, regId);
// return result;
// }
//
// @Override
// protected void onPostExecute(String result) {
// shareRegidTask = null;
// Toast.makeText(context, result,
// Toast.LENGTH_LONG).show();
// }
//
// };
// shareRegidTask.execute(null, null, null);

// Intent i = new Intent(context,


// PannelloUtente.class);
// i.putExtra("regId", regId);
// Log.d("RegisterActivity",
// "onClick of Share: Before starting main
activity.");
// context.startActivity(i);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 242
//
// Log.d("RegisterActivity", "onClick of Share: After
finish.");
// }

//------------------------------- fine parte relativa a registrazione con GCM

ApplicationInfo ai =
context.getPackageManager().getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String url1 = ai.metaData.getString("urlserversicuro");
String surl = url1+
"login.do"+"?username="+utente[0].getNome()+"&password="+utente[0].getPassword()
;
System.out.println(utente[0].getNome()+" "
+utente[0].getPassword());
// Load CAs from an InputStream (could be a resource/asset, a
file, etc.)
CertificateFactory cf =
CertificateFactory.getInstance("X.509");
InputStream caInput = new
BufferedInputStream(context.getAssets().open("amznserver.crt"));
Certificate ca=null;
try {
ca = cf.generateCertificate(caInput);
Log.i("LocalCACertificateHttpsClientActivity", " ecco il
certificato: "+ ((X509Certificate) ca).toString());
}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
}
finally {
caInput.close();
}

// Create a KeyStore containing the trusted CAs


String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
//System.out.println(keyStore.toString());

// Create a TrustManager that trusts the CAs in the new


KeyStore
String tmfAlgorithm =
TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
//System.out.println(""+ tmf.toString());

// Create a SSLContext that uses the newly created


TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
//HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER;
HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 243
// Tell the URLConnection to use a SocketFactory from such
SSLContext
URL url = new URL(surl);

//System.out.println(url.getPort());
//System.out.println(surl);
//System.out.println(url);

HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();

urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(hostnameVerifier);
urlConnection.connect();
// System.out.println("ecco loggetto2" +
urlConnection.toString());
risposta =
JSONObjectUtils.getJSONObjectFromStream(urlConnection.getInputStream());

// logged[0] = (risposta.getBoolean("success") &&


risposta.getJSONObject("user").getBoolean(""));
// utente[0].setLogged(logged[0]);
// u = utente[0];
Username =
risposta.getJSONObject("user").getString("userName");
Password =
risposta.getJSONObject("user").getString("password");
Tipo = risposta.getJSONObject("user").getString("tipo");
Nome = risposta.getJSONObject("user").getString("nome_rs");
Cognome =
risposta.getJSONObject("user").getString("cognome_citta");
Email = risposta.getJSONObject("user").getString("mail");
FarmaLat =
risposta.getJSONObject("user").getString("farmaLat");
FarmaLon =
risposta.getJSONObject("user").getString("farmaLon");
System.out.println("FarmaLat: "+FarmaLat);
System.out.println("FarmaLon: "+FarmaLon);

if(risposta.getBoolean("success") == false){
logged[0] = false;
}
else
{
logged[0]=true;

}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
e.printStackTrace();
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 244
return logged;

}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressDialog.setMessage("Rieseguo il login, attendi...");
}

@Override
protected void onPostExecute(boolean logged[]) {

// SALVO I DATI SU DB LOCALE


DbCredenziali mMioDbHelper = null;
mMioDbHelper = new
DbCredenziali(context2.getApplicationContext());

ContentValues contentValues = new ContentValues();

SQLiteDatabase db =
mMioDbHelper.getWritableDatabase();
db.execSQL("DELETE FROM credenziali");

contentValues.put("username", Username);
contentValues.put("password", Password);
contentValues.put("nome", Nome);
contentValues.put("cognome", Cognome);
contentValues.put("email", Email);
contentValues.put("tipo", Tipo);

db.insert("credenziali", null , contentValues);


db.close();

// SALVO I DATI Latitudine e longitudine SU DB


LOCALE
DbCoordinate mDbCoordinate = null;
mDbCoordinate = new DbCoordinate(
context2.getApplicationContext());

ContentValues contentValues2 = new


ContentValues();
SQLiteDatabase db2 =
mDbCoordinate.getWritableDatabase();
db2.execSQL("DELETE FROM coordinate");
contentValues2.put("latitude",
String.valueOf(FarmaLat));

contentValues2.put("longitude",String.valueOf(FarmaLon));
db2.insert("coordinate", null, contentValues2);

db.close();

progressDialog.dismiss();
System.out.println("ecco il tipo : "+ Tipo);
// System.out.println("true se il tipo è effettivamente utente: "+
Tipo.equals("utente"));
if(logged[0]==true && Tipo.equals("cliente")==true ){

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 245
accesso_textView.setText("Accesso come utente: \"" + Username + "\"
in corso...");
accesso_textView.setTextColor(Color.rgb(0,0,0));

Intent i = new Intent(context, PannelloUtente.class);


context.startActivity(i);

}
else if(logged[0]==true && Tipo.equals("farmacista")==true){

accesso_textView.setText("Accesso come farmacista: \"" +


Username + "\" in corso...");
accesso_textView.setTextColor(Color.rgb(0,0,0));

Intent i = new Intent(context,PannelloFarmacista.class);


context.startActivity(i);
}
else {

// Intent i = new Intent(context, About.class);


// context.startActivity(i);

accesso_textView.setText(context.getResources().getString(R.string.errore)
);
accesso_textView.setTextColor(Color.rgb(200,20,20));
}
super.onPostExecute(logged);
}

//metodi di gcm

public String registerGCM() {

gcm = GoogleCloudMessaging.getInstance(this.context);
regId = getRegistrationId(context);

if (TextUtils.isEmpty(regId)) {

registerInBackground();

Log.d("RegisterActivity",
"registerGCM - successfully registered with GCM
server - regId: "
+ regId);
} else {
Toast.makeText(context,
"RegId already available. RegId: " + regId,
Toast.LENGTH_LONG).show();
}
return regId;
}

// metodo da cambiare (non riceve nulla, va in un db locale e prende il


regid
private String getRegistrationId(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(
MainActivity.class.getSimpleName(),
Context.MODE_PRIVATE);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 246
String registrationId = prefs.getString(REG_ID, "");
if (registrationId.isEmpty()) {
Log.i(TAG, "Registration not found.");
return "";
}
int registeredVersion = prefs.getInt(APP_VERSION,
Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion) {
Log.i(TAG, "App version changed.");
return "";
}
return registrationId;
}

private static int getAppVersion(Context context) {


try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionCode;
} catch (NameNotFoundException e) {
Log.d("RegisterActivity",
"I never expected this! Going down, going down!" +
e);
throw new RuntimeException(e);
}
}

private void registerInBackground() {


new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
String msg = "";
try {
if (gcm == null) {
gcm =
GoogleCloudMessaging.getInstance(context);
}
regId = gcm.register(Config.GOOGLE_PROJECT_ID);
Log.d("RegisterActivity", "registerInBackground -
regId: "
+ regId);
msg = "Device registered, registration ID=" +
regId;

storeRegistrationId(context, regId);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
Log.d("RegisterActivity", "Error: " + msg);
}
Log.d("RegisterActivity", "AsyncTask completed: " +
msg);
return msg;
}
@Override
protected void onPostExecute(String msg) {
Toast.makeText(context,
"Registered with GCM Server." + msg,
Toast.LENGTH_LONG)
.show();
}
}.execute(null, null, null);
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 247
private void storeRegistrationId(Context context, String regId) {
final SharedPreferences prefs = context.getSharedPreferences(
MainActivity.class.getSimpleName(),
Context.MODE_PRIVATE);
int appVersion = getAppVersion(context);
Log.i(TAG, "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(REG_ID, regId);
editor.putInt(APP_VERSION, appVersion);
editor.commit();
}
}

OttieniDettagliOrdineTask.java
package it.sii.android.pharmacopter.task;
import it.sii.android.pharmacopter.*;
import it.sii.android.pharmacopter.classes.JSONObjectUtils;
import it.sii.android.pharmacopter.classes.Ordine;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.json.JSONObject;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.util.Log;

public class OttieniDettagliOrdineTask extends AsyncTask<String, Integer,


boolean[]> {

private ProgressDialog progressDialog;

Context context;
Intent dettagliOrdineIntent;
JSONObject risposta;
Context context2;
Ordine o = null;
String id2 = "";
String tipo = "";

public OttieniDettagliOrdineTask(Context context, Context context2, Ordine


ord, String tipo){
super();
this.context = context;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 248
this.context2 = context2;
this.tipo = tipo;
o = ord;

@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(context);

progressDialog.setMessage(context.getResources().getString(R.string.carica
ndo));
progressDialog.show();
}

@Override
protected boolean[] doInBackground(String... id) {

boolean[] logged = {false};


id2 = id[0];

try{

ApplicationInfo ai =
context.getPackageManager().getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String url1 = ai.metaData.getString("urlserversicuro");
String surl = url1+ "OttieniDettagliOrdine.do"+"?id="+id[0] ;

System.out.println("ottieni dettaglio ordine task: l'id


dell'ordine che sto inviando vale :"+id);
// Load CAs from an InputStream (could be a resource/asset, a
file, etc.)
CertificateFactory cf =
CertificateFactory.getInstance("X.509");
InputStream caInput = new
BufferedInputStream(context.getAssets().open("amznserver.crt"));
Certificate ca=null;
try {
ca = cf.generateCertificate(caInput);
Log.i("LocalCACertificateHttpsClientActivity", " ecco il
certificato: "+ ((X509Certificate) ca).toString());
}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
}
finally {
caInput.close();
}

// Create a KeyStore containing the trusted CAs


String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
//System.out.println(keyStore.toString());

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 249
// Create a TrustManager that trusts the CAs in the new
KeyStore
String tmfAlgorithm =
TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
//System.out.println(""+ tmf.toString());

// Create a SSLContext that uses the newly created


TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
//HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER;
HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

// Tell the URLConnection to use a SocketFactory from such


SSLContext
URL url = new URL(surl);

//System.out.println(url.getPort());
//System.out.println(surl);
//System.out.println(url);

HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();

urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(hostnameVerifier);
urlConnection.connect();
// System.out.println("ecco loggetto2" +
urlConnection.toString());
risposta =
JSONObjectUtils.getJSONObjectFromStream(urlConnection.getInputStream());

// logged[0] = (risposta.getBoolean("success") &&


risposta.getJSONObject("user").getBoolean(""));
// utente[0].setLogged(logged[0]);
// u = utente[0];

if(risposta.length()!=0){
logged[0] = true;
}
else
{
logged[0]=false;

}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
e.printStackTrace();
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 250
return logged;

}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressDialog.setMessage("Rieseguo il login, attendi...");
}

@Override
protected void onPostExecute(boolean logged[]) {

progressDialog.dismiss();

dettagliOrdineIntent = new Intent(context2, DettagliOrdine.class);


dettagliOrdineIntent.putExtra("JsonDettagli", risposta.toString());
dettagliOrdineIntent.putExtra("ID", id2);
dettagliOrdineIntent.putExtra("NomeFarma", o.getNomeFarma());
dettagliOrdineIntent.putExtra("NomeCli", o.getNomeCli());
dettagliOrdineIntent.putExtra("Data", o.getData());
dettagliOrdineIntent.putExtra("Stato", o.getStato());
dettagliOrdineIntent.putExtra("Tipo", tipo);
dettagliOrdineIntent.putExtra("CliLat", o.getCliLat());
dettagliOrdineIntent.putExtra("CliLon", o.getCliLon());
dettagliOrdineIntent.putExtra("FarmaLat", o.getFarmaLat());
dettagliOrdineIntent.putExtra("FarmaLon", o.getFarmaLon());

System.out.println("latitudine e longitudine del farmacista e del


cliente valgono rispettivamente:
"+o.getFarmaLat()+o.getFarmaLon()+o.getCliLat()+o.getCliLon());
dettagliOrdineIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(dettagliOrdineIntent);
super.onPostExecute(logged);
}

PutNewOrderTask.java
package it.sii.android.pharmacopter.task;

import it.sii.android.pharmacopter.PannelloUtente;
import it.sii.android.pharmacopter.R;
import it.sii.android.pharmacopter.classes.JSONObjectUtils;
import it.sii.android.pharmacopter.db.DbCoordinate;
import it.sii.android.pharmacopter.db.DbCredenziali;
import it.sii.android.pharmacopter.db.DbFarmaciaSelezionata;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 251
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;

public class PutNewOrderTask extends AsyncTask<String, Integer, boolean[]> {

private ProgressDialog progressDialog;

Context context;
Context context2;
JSONObject risposta;
Intent i;

public PutNewOrderTask(Context context, Context context2){


super();
this.context = context;
this.context2 = context2;

@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(context);

progressDialog.setMessage(context.getResources().getString(R.string.carica
ndo4));
progressDialog.show();
}

@Override
protected boolean[] doInBackground(String... stringJson) {
// recuper la lista dei prodotti passatami quando sn stato chiamato
String[] listaProdottiJson = stringJson;

String totale = null;


try {
JSONObject listaprodotti = new
JSONObject(listaProdottiJson[0]);

try {
totale = String.valueOf(listaprodotti.get("total"));
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 252
} catch (JSONException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}

System.out.println("Ecco il totale: "+totale);

// recupero i dati dell'utente dai vari db


// prendo lo username
DbCredenziali mDbcredenziali = null;
mDbcredenziali = new DbCredenziali(context2);
SQLiteDatabase db = mDbcredenziali.getWritableDatabase();
String sql = "SELECT username FROM credenziali";
Cursor cuser = db.rawQuery(sql, null);
cuser.moveToFirst();
String username = null;
String username1 = cuser.getString(0);
if(username1.contains(" "))
{
username = username1.replaceAll(" ", "_");
}
else
{
username = username1;
}
cuser.close();
db.close();
// prendo lat e lon
DbCoordinate mDbCoordinate = new DbCoordinate(context2);
SQLiteDatabase db2 = mDbCoordinate.getWritableDatabase();
String sqlCoordinate = "SELECT latitude, longitude FROM coordinate
";
Cursor c2 = db2.rawQuery(sqlCoordinate, null);
c2.moveToFirst();
String clientelat = String.valueOf(c2.getDouble(0));
String clientelon = String.valueOf(c2.getDouble(1));
c2.close();
db2.close();

// recupero i dati della farmacia selezionata


DbFarmaciaSelezionata mDbFarmaciaSelezionata = null;
mDbFarmaciaSelezionata = new DbFarmaciaSelezionata(context2);
SQLiteDatabase db3 = mDbFarmaciaSelezionata.getWritableDatabase();
String sqlFarmacia = "SELECT * FROM farmacia";
Cursor c3 = db3.rawQuery(sqlFarmacia, null);
c3.moveToFirst();
String nomefarmacia = String.valueOf(c3.getString(3));
String farmalat = String.valueOf(c3.getDouble(1));
String farmalon = String.valueOf(c3.getDouble(2));

System.out.println(String.valueOf(c3.getDouble(1)));

c3.close();
db3.close();

boolean[] logged = {false};

// System.out.println(utente[0].getNome());
// System.out.println(utente[0].getPassword());

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 253
try{

ApplicationInfo ai =
context.getPackageManager().getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String url1 = ai.metaData.getString("urlserversicuro");

String surl =
url1+"OrdineNuovo.do"+"?username="+username+"&clientelat="+ clientelat
+"&clientelon="+ clientelon +"&nomefarmacia="+ nomefarmacia +"&farmalat="+
farmalat +"&farmalon="+ farmalon + "&JsonOrdine=" +
listaProdottiJson[0]+"&totale="+
totale+"&notificationReceiverUsername="+nomefarmacia;

// Load CAs from an InputStream (could be a resource/asset, a


file, etc.)
CertificateFactory cf =
CertificateFactory.getInstance("X.509");
InputStream caInput = new
BufferedInputStream(context.getAssets().open("amznserver.crt"));
Certificate ca=null;
try {
ca = cf.generateCertificate(caInput);
Log.i("LocalCACertificateHttpsClientActivity", " ecco il
certificato: "+ ((X509Certificate) ca).toString());
}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
}
finally {
caInput.close();
}

// Create a KeyStore containing the trusted CAs


String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
//System.out.println(keyStore.toString());

// Create a TrustManager that trusts the CAs in the new


KeyStore
String tmfAlgorithm =
TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
//System.out.println(""+ tmf.toString());

// Create a SSLContext that uses the newly created


TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
//HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER;
HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 254
// Tell the URLConnection to use a SocketFactory from such
SSLContext
URL url = new URL(surl);

//System.out.println(url.getPort());
//System.out.println(surl);
//System.out.println(url);

HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();

urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(hostnameVerifier);
urlConnection.connect();
//System.out.println("ecco loggetto2" +
urlConnection.toString());

risposta =
JSONObjectUtils.getJSONObjectFromStream(urlConnection.getInputStream());

System.out.println("ecco loggetto2: " +risposta);

if(risposta.length() != 0){
logged[0] = true;
}
else
{
logged[0]=false;
}

}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
e.printStackTrace();
}

return logged;

}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressDialog.setMessage("Ordine effettuato, attendi mentre vieni
reindirizzato...");
}

@Override
protected void onPostExecute(boolean logged[]) {
// this.error_textView = asd;

// System.out.println("true se il tipo è effettivamente utente: "+


tipo.equals("utente"));
if(logged[0]==true){

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 255
// INTENT
// accesso_textView.setText("Accesso come utente: \"" + username + "\"
in corso...");
// accesso_textView.setTextColor(Color.rgb(0,0,0));
// qui devo prendere la risposta che è un json contenente tante
farmacie(nome farmacia,lat,long) e la devo inserire nel db locale
System.out.println("ci sn riuscito!!!");

//per rendere univoci i nomi delle chiavi passate


//è consigliato (la doc dice 'must') aggiungere il nome del
nostro package davanti al nome

i = new Intent(context2, PannelloUtente.class); // PAGINA


VISUALIZZA ELENCO ORDINI
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Toast.makeText(context, "" +
"Ordine evaso correttamente",
Toast.LENGTH_SHORT).show();
context2.startActivity(i);

}
else {

System.out.println("ci sn riuscito2!!!");

// context.startActivity(i);
//
accesso_textView.setText(context.getResources().getString(R.string.errore)
);
// accesso_textView.setTextColor(Color.rgb(200,20,20));
}
super.onPostExecute(logged);
}

RegisterTask.java
package it.sii.android.pharmacopter.task;

import it.sii.android.pharmacopter.*;
import it.sii.android.pharmacopter.classes.JSONObjectUtils;
import it.sii.android.pharmacopter.classes.Utente;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 256
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

public class RegisterTask extends AsyncTask<Utente, Integer, boolean[]> {

private ProgressDialog progressDialog;

Context context;

Utente u;

TextView info;

public RegisterTask(Context context){


super();
this.context = context;
this.info = info;
}

@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(context);

progressDialog.setMessage(context.getResources().getString(R.string.carica
ndo));
progressDialog.show();
}

@Override
protected boolean[] doInBackground(Utente... utente) {
JSONObject risposta;
boolean[] logged = {false};

List<NameValuePair> params = new ArrayList<NameValuePair>();


params.add(new BasicNameValuePair("userName", utente[0].getNome()));
params.add(new BasicNameValuePair("password",
utente[0].getPassword()));
params.add(new BasicNameValuePair("email", utente[0].getEmail()));
params.add(new BasicNameValuePair("nome",
utente[0].getNomeanagrafe()));
params.add(new BasicNameValuePair("cognome",
utente[0].getCognomeanagrafe()));

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 257
System.out.println("sono qui : "+ utente[0].getNome() +"\n email:
" +utente[0].getEmail());

try{

ApplicationInfo ai =
context.getPackageManager().getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String url1 = ai.metaData.getString("urlserversicuro");
String surl = url1+"Register.do"+
"?username="+utente[0].getNome()+"&password="+utente[0].getPassword() +
"&email="+utente[0].getEmail()+"&nomeanagrafe="+utente[0].getNomeanagrafe()
+"&cognomeanagrafe="+utente[0].getCognomeanagrafe()+"&tipo=cliente" ;
// Load CAs from an InputStream (could be a resource/asset, a
file, etc.)
CertificateFactory cf =
CertificateFactory.getInstance("X.509");
InputStream caInput = new
BufferedInputStream(context.getAssets().open("amznserver.crt"));
Certificate ca=null;
try {
ca = cf.generateCertificate(caInput);
Log.i("LocalCACertificateHttpsClientActivity", ""+
((X509Certificate) ca).toString());
}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
}
finally {
caInput.close();
}

// Create a KeyStore containing the trusted CAs


String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);

// Create a TrustManager that trusts the CAs in the new


KeyStore
String tmfAlgorithm =
TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);

// Create a SSLContext that uses the newly created


TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

// Tell the URLConnection to use a SocketFactory from such


SSLContext
URL url = new URL(surl);
System.out.println(url.getPort());
HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 258
urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(hostnameVerifier);
urlConnection.connect();

// OutputStream os = urlConnection.getOutputStream();
// BufferedWriter writer = new BufferedWriter(new
OutputStreamWriter(os, "UTF-8"));
// writer.write(JSONObjectUtils.getQuery(params));
// writer.flush();
// writer.close();
// os.close();

risposta =
JSONObjectUtils.getJSONObjectFromStream(urlConnection.getInputStream());

if(risposta.getBoolean("success") == false){
logged[0] = false;
}
else
{
logged[0]=true;
}
u = utente[0];

}
catch(Exception e)
{
Log.e("LocalCACertificateHttpsClientActivity",
""+e.getMessage());
e.printStackTrace();
}

return logged;
}

@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);

progressDialog.setMessage(context.getResources().getString(R.string.carica
ndo));
}

@Override
protected void onPostExecute(boolean logged[]) {
progressDialog.dismiss();
if(logged[0]){

Intent i = new Intent(context,PannelloUtente.class);


context.startActivity(i);
}
else {

Toast.makeText(
context,"username gia presente",
Toast.LENGTH_LONG).show();

//info.setText(context.getResources().getString(R.string.caricando));
//info.setTextColor(Color.rgb(200,20,20));
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 259
super.onPostExecute(logged);
}

Codice android: it.sii.android.loginserver2.classi

ElencoFarmacie.java
package classi;

import java.util.ArrayList;
import java.util.LinkedList;

import com.sun.org.apache.xpath.internal.operations.String;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

public class ElencoFarmacie {

public final LinkedList<Farmacia> ListaFarmacie= new LinkedList<>();

public void addFarmacia(int i, Farmacia farmacia){

this.ListaFarmacie.add(i, farmacia);

public Farmacia getFarmacia(Integer i){


Farmacia f = this.ListaFarmacie.get(i);
return f;

}
}

ElencoOrdini.java
package classi;

import java.util.ArrayList;
import java.util.LinkedList;

import com.sun.org.apache.xpath.internal.operations.String;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

public class ElencoOrdini {

public final LinkedList<Ordine> elencoOrdini= new LinkedList<>();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 260
public void addOrdine(int i, Ordine ordine){

this.elencoOrdini.add(i, ordine);

public Ordine getOrdine(Integer i){


Ordine o = this.elencoOrdini.get(i);
return o;

}
}

Farmacia.java
package classi;

public class Farmacia {

public String nome1;


public String latitudine2;
public String longitudine2;

//costruttore con fields


public Farmacia(String nome, String latitudine, String longitudine) {

nome1 = nome;
latitudine2 = latitudine;
longitudine2 = longitudine;
}

//costruttore senza fields


public Farmacia(){

//getters and setters


public String getNome() {
return this.nome1;
}
public void setNome(String nome) {
nome1 = nome;
}
public String getLatitudine() {
return this.latitudine2;
}
public void setLatitudine(String latitudine) {
latitudine2 = latitudine;
}
public String getLongitudine() {
return this.longitudine2;
}
public void setLongitudine(String longitudine) {
longitudine2 = longitudine;
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 261
}

Ordine.java
package classi;

import org.json.simple.JSONObject;

public class Ordine {

public int id;


public String clienteNome;
public Double clienteLat;
public Double clienteLon;
public String farmaciaNome;
public Double farmaciaLat;
public Double farmaciaLon;
public String ordinepezzi;
public String stato;
public String time;
public String prezzoTotale;

// costruttore con fields


public Ordine(int id, String clienteNome, Double clienteLat,
Double clienteLon, String farmaciaNome, Double farmaciaLat,
Double farmaciaLon, String stato, String time, String ordine,
String prezzoTotale) {
super();
this.id = id;
this.clienteNome = clienteNome;
this.clienteLat = clienteLat;
this.clienteLon = clienteLon;
this.farmaciaNome = farmaciaNome;
this.farmaciaLat = farmaciaLat;
this.farmaciaLon = farmaciaLon;
this.ordinepezzi = ordine;
this.stato = stato;
this.time = time;
this.prezzoTotale = prezzoTotale;
}

// costruttore senza fields


public Ordine() {
super();
}

// getters and setters

public String getClienteNome() {


return clienteNome;
}

public void setClienteNome(String clienteNome) {


this.clienteNome = clienteNome;
}

public Double getClienteLat() {


return clienteLat;
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 262
public void setClienteLat(Double clienteLat) {
this.clienteLat = clienteLat;
}

public Double getClienteLon() {


return clienteLon;
}

public void setClienteLon(Double clienteLon) {


this.clienteLon = clienteLon;
}

public String getFarmaciaNome() {


return farmaciaNome;
}

public void setFarmaciaNome(String farmaciaNome) {


this.farmaciaNome = farmaciaNome;
}

public Double getFarmaciaLat() {


return farmaciaLat;
}

public void setFarmaciaLat(Double farmaciaLat) {


this.farmaciaLat = farmaciaLat;
}

public Double getFarmaciaLon() {


return farmaciaLon;
}

public void setFarmaciaLon(Double farmaciaLon) {


this.farmaciaLon = farmaciaLon;
}

public String getOrdinepezzi() {


return ordinepezzi;
}

public void setOrdinepezzi(String ordinepezzi) {


this.ordinepezzi = ordinepezzi;
}

public String getStato() {


return stato;
}

public void setStato(String stato) {


this.stato = stato;
}

public String getTime() {


return time;
}

public void setTime(String time) {


this.time = time;
}

public int getId() {


return id;
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 263
public void setId(int id) {
this.id = id;
}

public String getPrezzoTotale() {


return prezzoTotale;
}

public void setPrezzoTotale(String prezzoTot) {


this.prezzoTotale = prezzoTot;
}

Utente.java
package classi;

public class Utente {

Integer idUtente;
String username;
String password;
String tipo;
String mail;
String nome_rs;
String cognome_citta;
String mylat;
String mylon;
String regId;

public String getRegId() {


return regId;
}
public void setRegId(String regId) {
this.regId = regId;
}
public Integer getIdUtente() {
return idUtente;
}
public void setIdUtente(Integer idUtente) {
this.idUtente = idUtente;
}
public String getUsername() {
return username;
}
public void setUsername(String nome) {
this.username = nome;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTipo() {
return tipo;
}
public void setTipo(String tipo) {
this.tipo = tipo;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 264
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getNome_rs() {
return nome_rs;
}
public void setNome_rs(String nome_rs) {
this.nome_rs = nome_rs;
}
public String getCognome_citta() {
return cognome_citta;
}
public void setCognome_citta(String cognome_citta) {
this.cognome_citta = cognome_citta;
}

public Utente(String username, String password, String tipo,


String mail, String nome_rs, String cognome_citta
) {
super();
this.username = username;
this.password = password;
this.tipo = tipo;
this.mail = mail;
this.nome_rs = nome_rs;
this.cognome_citta = cognome_citta;

}
public Utente() {
super();
}
public void setUtente(String username, String password, String tipo,
String mail, String nome_rs, String cognome_citta) {
this.username = username;
this.password = password;
this.tipo = tipo;
this.mail = mail;
this.nome_rs = nome_rs;
this.cognome_citta = cognome_citta;

public void setUtente3(Integer idUtente,String username, String password,


String tipo,
String mail, String nome_rs, String cognome_citta,String
myLat,String myLon) {
this.idUtente = idUtente;
this.username = username;
this.password = password;
this.tipo = tipo;
this.mail = mail;
this.nome_rs = nome_rs;
this.cognome_citta = cognome_citta;
this.mylat = myLat;
this.mylon = myLon;

}
public void setUtente2(Integer idUtente,String username, String
password, String tipo,

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 265
String mail, String nome_rs, String cognome_citta) {
this.idUtente = idUtente;
this.username = username;
this.password = password;
this.tipo = tipo;
this.mail = mail;
this.nome_rs = nome_rs;
this.cognome_citta = cognome_citta;

}
public String getMylat() {
return mylat;
}
public void setMylat(String mylat) {
this.mylat = mylat;
}
public String getMylon() {
return mylon;
}
public void setMylon(String mylon) {
this.mylon = mylon;
}
}

Codice android: it.sii.android.loginserver2.dao

DBConnect.java
package dao;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class DBConnect {

private static DBConnect onlyInstance;

/* reference to the Connection Pool managed by Tomcat */


private DataSource ds = null ;

// the db connect logger


private static Logger logger = Logger.getLogger(DBConnect.class
.getPackage().getName());

// the log identifier


private static String logId = "[DBConnector]: ";

/**
* Empty and private constructor: singleton pattern.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 266
*/
private DBConnect() {
// log the liveness of the DBConnect singleton
DBConnect.logger.log(Level.INFO, DBConnect.logId
+ "Created singleton instance...");

try {
/* JNDI query to locate the DataSource object */
Context initContext = new InitialContext();

// find JNDI standard naming root


Context envContext = (Context)
initContext.lookup("java:/comp/env");

// find stored DataSource, with the given registered name

this.ds = (DataSource) envContext.lookup("jdbc/myDB");

} catch (NamingException e) {
e.printStackTrace();
}
}

/**
* Implements the Singleton pattern - only one instance for this class !
*/
public static DBConnect getInstance() {
// if the sigleton has never been requested, then it mus be created
if (onlyInstance == null) {
// synchronize the creation process
synchronized (DBConnect.class) {
// re-check the singleton, a concurrent thread night
have
// created the singleton meanwhile...(really true?)
if (onlyInstance == null)
// build the singleton
onlyInstance = new DBConnect();

// log the singleton creation


DBConnect.logger.log(Level.INFO, DBConnect.logId
+ "Singleton instance created");

}
}

// log the singleton instance return


DBConnect.logger.log(Level.INFO, DBConnect.logId
+"Singleton instance returned");

return onlyInstance;
}

public void forceGetIstance(){


onlyInstance = new DBConnect();
}

/**
* Gets a connection object for sending queries to the database
*
* @return the {@link Connection} object needed to send DB queries
*/
public Connection getConnection(int sist) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 267
/* Ask DataSource for a connection */
Connection conn = null;
try {

conn = this.ds.getConnection();

} catch (SQLException e) {
e.printStackTrace();
}

return conn;
}

public UtenteDAO getUtenteDAO() {


UtenteDAO m = new UtenteDAO(this) ;
return m ;
}

public ElencoFarmacieDAO getListaFarmaciaDAO() {


ElencoFarmacieDAO f = new ElencoFarmacieDAO(this) ;
return f ;
}

public OrdineDAO getOrdineDAO() {


OrdineDAO o = new OrdineDAO(this) ;
return o ;
}

public ElencoOrdiniDAO getElencoOrdiniDAO() {


ElencoOrdiniDAO eo = new ElencoOrdiniDAO(this) ;
return eo ;
}
}

ElencoFarmacieDAO.java
package dao;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class DBConnect {

private static DBConnect onlyInstance;

/* reference to the Connection Pool managed by Tomcat */


private DataSource ds = null ;

// the db connect logger


private static Logger logger = Logger.getLogger(DBConnect.class
.getPackage().getName());

// the log identifier

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 268
private static String logId = "[DBConnector]: ";

/**
* Empty and private constructor: singleton pattern.
*/
private DBConnect() {
// log the liveness of the DBConnect singleton
DBConnect.logger.log(Level.INFO, DBConnect.logId
+ "Created singleton instance...");

try {
/* JNDI query to locate the DataSource object */
Context initContext = new InitialContext();

// find JNDI standard naming root


Context envContext = (Context)
initContext.lookup("java:/comp/env");

// find stored DataSource, with the given registered name

this.ds = (DataSource) envContext.lookup("jdbc/myDB");

} catch (NamingException e) {
e.printStackTrace();
}
}

/**
* Implements the Singleton pattern - only one instance for this class !
*/
public static DBConnect getInstance() {
// if the sigleton has never been requested, then it mus be created
if (onlyInstance == null) {
// synchronize the creation process
synchronized (DBConnect.class) {
// re-check the singleton, a concurrent thread night
have
// created the singleton meanwhile...(really true?)
if (onlyInstance == null)
// build the singleton
onlyInstance = new DBConnect();

// log the singleton creation


DBConnect.logger.log(Level.INFO, DBConnect.logId
+ "Singleton instance created");

}
}

// log the singleton instance return


DBConnect.logger.log(Level.INFO, DBConnect.logId
+"Singleton instance returned");

return onlyInstance;
}

public void forceGetIstance(){


onlyInstance = new DBConnect();
}

/**
* Gets a connection object for sending queries to the database
*

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 269
* @return the {@link Connection} object needed to send DB queries
*/
public Connection getConnection(int sist) {

/* Ask DataSource for a connection */


Connection conn = null;
try {

conn = this.ds.getConnection();

} catch (SQLException e) {
e.printStackTrace();
}

return conn;
}

public UtenteDAO getUtenteDAO() {


UtenteDAO m = new UtenteDAO(this) ;
return m ;
}

public ElencoFarmacieDAO getListaFarmaciaDAO() {


ElencoFarmacieDAO f = new ElencoFarmacieDAO(this) ;
return f ;
}

public OrdineDAO getOrdineDAO() {


OrdineDAO o = new OrdineDAO(this) ;
return o ;
}

public ElencoOrdiniDAO getElencoOrdiniDAO() {


ElencoOrdiniDAO eo = new ElencoOrdiniDAO(this) ;
return eo ;
}
}

ElencoOrdiniDAO.java
package dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.json.simple.JSONObject;

import classi.ElencoFarmacie;
import classi.ElencoOrdini;
import classi.Farmacia;
import classi.Ordine;
import classi.Utente;

import com.sun.glass.ui.Cursor;

public class ElencoOrdiniDAO {


public DBConnect dbc;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 270
public ElencoOrdiniDAO(DBConnect dbConnect) {
this.dbc=dbConnect;
}

@SuppressWarnings("unused")
public boolean fillElencoOrdiniCliente(ElencoOrdini eo,String clienteNome)
throws SQLException{
CallableStatement cs = null;

ResultSet res = null;


Connection conn = dbc.getConnection(01);

String sql = "SELECT * FROM `pharmacopterdb1`.`ordini` " +


"WHERE `ordini`.`ClienteNome` = ? ;";
cs=conn.prepareCall(sql);
System.out.println(clienteNome);
cs.setString(1,clienteNome);
cs.execute();
res = cs.getResultSet();

res.first();

int i=0;
do{
Ordine ordine1 = new Ordine();
ordine1.setId(res.getInt("idOrdine"));
ordine1.setClienteNome(res.getString("ClienteNome"));
ordine1.setClienteLat(res.getDouble("ClienteLat"));
ordine1.setClienteLon(res.getDouble("ClienteLon"));
ordine1.setFarmaciaNome(res.getString("FarmaciaNome"));
ordine1.setFarmaciaLat(res.getDouble("FarmaciaLat"));
ordine1.setFarmaciaLon(res.getDouble("FarmaciaLon"));
ordine1.setTime(res.getString("dataOra"));
ordine1.setOrdinepezzi(res.getString("JsonOrdine"));
ordine1.setStato(res.getString("Stato"));
ordine1.setPrezzoTotale(res.getString("PrezzoTotale"));
eo.elencoOrdini.add(i,ordine1);
i++;
}while(res.next());

res.close();
conn.close();
if(res!=null){
return true;
}
else
{
return false;
}

@SuppressWarnings("unused")

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 271
public boolean fillElencoOrdiniFarmacia(ElencoOrdini eo,String
clienteNome) throws SQLException{
CallableStatement cs = null;

System.out.println(clienteNome);

ResultSet res = null;


Connection conn = dbc.getConnection(01);

String sql = "SELECT * FROM `pharmacopterdb1`.`ordini` " +


"WHERE `ordini`.`FarmaciaNome` = ? ;";
cs=conn.prepareCall(sql);
cs.setString(1,String.valueOf(clienteNome));
cs.execute();
res = cs.getResultSet();

res.first();

int i=0;
do{
Ordine ordine1 = new Ordine();
ordine1.setId(res.getInt("idOrdine"));
ordine1.setClienteNome(res.getString("ClienteNome"));
ordine1.setClienteLat(res.getDouble("ClienteLat"));
ordine1.setClienteLon(res.getDouble("ClienteLon"));
ordine1.setFarmaciaNome(res.getString("FarmaciaNome"));
ordine1.setFarmaciaLat(res.getDouble("FarmaciaLat"));
ordine1.setFarmaciaLon(res.getDouble("FarmaciaLon"));
ordine1.setTime(res.getString("dataOra"));
ordine1.setOrdinepezzi(res.getString("JsonOrdine"));
ordine1.setStato(res.getString("Stato"));
ordine1.setPrezzoTotale(res.getString("PrezzoTotale"));
eo.elencoOrdini.add(i,ordine1);
i++;
}while(res.next());

res.close();
conn.close();
if(res!=null){
return true;
}
else
{
return false;
}

// metodo per riempire la lista di farmacie;


public boolean fillListaFarmacie(Farmacia f){
return false;

OrdineDAO.java
package dao;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 272
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;

import classi.Ordine;

public class OrdineDAO {

private DBConnect dbc;

public OrdineDAO(DBConnect dbConnect) {


this.dbc=dbConnect;
}

public Boolean aggiungiOrdine(Ordine o){

boolean success = false;

PreparedStatement cs = null;
try{
Boolean uspresente = false;
ResultSet res = null;
Connection conn = dbc.getConnection(01);

String sql = "INSERT INTO `pharmacopterdb1`.`ordini`


(`ClienteNome`,
`ClienteLat`,`ClienteLon`,`FarmaciaNome`,`FarmaciaLat`,`FarmaciaLon`,`JSONOrdine
`,`Stato`,`DataOra`,PrezzoTotale) VALUES (?,?,?,?,?,?,?,?,?,?); ";

cs=conn.prepareStatement(sql,
PreparedStatement.RETURN_GENERATED_KEYS);

cs.setString(1, o.getClienteNome());
cs.setDouble(2, o.getClienteLat());
cs.setDouble(3, o.getClienteLon());
cs.setString(4, o.getFarmaciaNome());
cs.setDouble(5, o.getFarmaciaLat());
cs.setDouble(6, o.getFarmaciaLon());
cs.setString(7, o.getOrdinepezzi());
cs.setString(8, o.getStato());
cs.setString(9, o.getTime());
cs.setString(10, o.getPrezzoTotale());

cs.executeUpdate();

res = cs.getGeneratedKeys();
if (res.next()){
success=true;
}
res.close();
conn.close();

return success;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 273
}
catch (SQLException e) {
e.printStackTrace();
}
return success;
}

public boolean richiediOrdine(Ordine ordine){

boolean success = false;


String username = ordine.getClienteNome();

return success;

//----------------------- IMPORTANTE IMPORTANTE IMPORTANTE IMPORTANTE IMPORTANTE


------------------------------

//Questo stato deve poter essere mandato dall'applicazione, !!SOLO!! quando


l'elenco degli ordini
//viene visualizzato da parte del !!FARMACISTA!! (quindi nell'Activity
visualizza elenco ordini Farmacista),
//nell'istante in cui viene premuta una view (nel visualizza elenco ordini
Farmacista)

//IL CUI CONTENUTO HA LO stato == "non approvato". O ANCORA MEGLIO SE LO SI FA


DALLA PAGINA VISUALIZZA DETTAGLI DELL'ORDINE SPECIFICO.

//[DOVRò FARE UN'ASYNK TASK TIPO QUELLA DI GET LISTA FARMACIE LOCATION TASK]
//Tale informazione la prenderò dall'oggetto json che ho avuto in risposta dal
server
//(nel particolar caso dalla servlet RichiediElencoOrdiniFarmacista) in
precedenza
//(nel particolar caso quando nell'Activity PannelloFarmacista ho premuto il
Button VisualizzaElencoOrdini)

public int CambiaStatoOrdine(Ordine ordine, String stato){


PreparedStatement cs = null;
int successtipo = 0;

try{
Connection conn = dbc.getConnection(01);
int idordine = ordine.getId();
String sql = "UPDATE `pharmacopterdb1`.`ordini` SET `stato`=? WHERE
`idordine`=? ; ";

cs=conn.prepareCall(sql);
cs.setString(1, stato);
cs.setInt(2, idordine);
cs.execute();
cs.close();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 274
}catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("attivitaDao getmetaowner : - ", e)
;
}

return successtipo;

// public boolean fillOrdineRespinto(Ordine o ,String comando){


// boolean success = false;
// PreparedStatement cs = null;
// try{
//
//
// Connection conn = dbc.getConnection(01);
//
//
//
// int idordine = o.getId();
//
//
// String sql = "UPDATE `pharmacopterdb1`.`ordini` SET `stato`=?
WHERE `idordine`=? ; ";
//
// cs=conn.prepareCall(sql);
// cs.setString(1, comando);
// cs.setInt(2, idordine );
// cs.execute();
//
// cs.close();
//
//
// }catch (SQLException e) {
// e.printStackTrace();
// throw new RuntimeException("attivitaDao getmetaowner : -
", e) ;
// }
//
// return success;
// }

// public boolean fillOrdineConsegnaAMano(Ordine o ,String comando){


// boolean success = false;
// PreparedStatement cs = null;
// try{
//
//
// Connection conn = dbc.getConnection(01);
//
//
//
// int idordine = o.getId();
//
//
// String sql = "UPDATE `pharmacopterdb1`.`ordini` SET `stato`=?
WHERE `idordine`=? ; ";
//
// cs=conn.prepareCall(sql);
// cs.setString(1, comando);
// cs.setInt(2, idordine );

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 275
// cs.execute();
//
// cs.close();
//
//
// }catch (SQLException e) {
// e.printStackTrace();
// throw new RuntimeException("attivitaDao getmetaowner : -
", e) ;
// }
//
// return success;
// }
//
//
// public boolean fillOrdineDaRitirare(Ordine o ,String comando){
// boolean success = false;
// PreparedStatement cs = null;
// try{
//
//
// Connection conn = dbc.getConnection(01);
//
//
//
// int idordine = o.getId();
//
//
// String sql = "UPDATE `pharmacopterdb1`.`ordini` SET `stato`=?
WHERE `idordine`=? ; ";
//
// cs=conn.prepareCall(sql);
// cs.setString(1, comando);
// cs.setInt(2, idordine );
// cs.execute();
//
// cs.close();
//
//
// }catch (SQLException e) {
// e.printStackTrace();
// throw new RuntimeException("attivitaDao getmetaowner : -
", e) ;
// }
//
// return success;
// }

public boolean fillOrdineDaId(Ordine ord) {


boolean success = false;
PreparedStatement cs = null;

try{

Connection conn = dbc.getConnection(01);

int id = ord.getId();
System.out.println(id);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 276
String sql = "SELECT * FROM `pharmacopterdb1`.`ordini` WHERE
`idordine`=?; ";

cs=conn.prepareCall(sql);
cs.setInt(1, id);
cs.execute();

ResultSet res = null;


res = cs.getResultSet();

if(res.first()){
success= true;

ord.setOrdinepezzi(String.valueOf(res.getString("JsonOrdine")));

System.out.println(String.valueOf(res.getString("JsonOrdine")));
}

res.close();
conn.close();
cs.close();

}catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("attivitaDao getmetaowner : -
", e) ;
}

return success;

public boolean fillOrdineCoordinate(Ordine ordine) {

boolean success = false;


PreparedStatement cs = null;

try{

Connection conn = dbc.getConnection(01);

String farmalat = ordine.getFarmaciaLat().toString();


String farmalon = ordine.getFarmaciaLon().toString();

int id = ordine.getId();
System.out.println(id);

String sql = "SELECT `ClienteLat`,`ClienteLon`, `MAX(DataOra)`


AS `MostRecentServiceDate` FROM `pharmacopterdb1`.`ordini` WHERE
`Stato`=`pagato` AND `FarmaciaLat`=? AND `FarmaciaLon` = ? GROUP BY
`ClienteLat`, `ClienteLon`; ";

cs=conn.prepareCall(sql);
cs.setString(1, farmalat);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 277
cs.setString(2, farmalon);
cs.execute();

ResultSet res = null;


res = cs.getResultSet();

if(res.first()){
success= true;

ordine.setOrdinepezzi(String.valueOf(res.getString("JsonOrdine")));

System.out.println(String.valueOf(res.getString("JsonOrdine")));
}

res.close();
conn.close();
cs.close();

}catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("attivitaDao getmetaowner : -
", e) ;
}

return success;
}

UtenteDAO.java
package dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import classi.Utente;

public class UtenteDAO {


private DBConnect dbc;

public UtenteDAO(DBConnect dbConnect) {


this.dbc=dbConnect;
}

@SuppressWarnings("unused")
public boolean fillUtenteLogin(Utente u){
CallableStatement cs = null;
try{

ResultSet res = null;


Connection conn = dbc.getConnection(01);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 278
String sql = "SELECT * FROM `pharmacopterdb1`.`utenti` " +
"WHERE `utenti`.`NomeUtente` = ? and
`utenti`.`PswUtente` = ? ;";
cs=conn.prepareCall(sql);

cs.setString(1, u.getUsername());
cs.setString(2, u.getPassword());

cs.execute();

res = cs.getResultSet();
res.next();
do{
u.setUtente3(res.getInt("idutenti"),
res.getString("NomeUtente"), res.getString("PswUtente"),
res.getString("TipoUtente"), res.getString("Mail"),
res.getString("Nome/RagSociale"),
res.getString("Cognome/Citta"),res.getString("Latitudine"),res.getString("Longit
udine"));
}while(res!=null && res.next()) ;

res.first();
if(res!=null){

res.close();
conn.close();
return true;

}
else
{
res.close();
conn.close();
u.setUtente3(-1, "null", "null", "null", "null", "null",
"null","null","null");
return false;
}

}
catch (SQLException e) {
System.out.println("Aggiorno forzatamente la connessione!!");
this.dbc.forceGetIstance();

e.printStackTrace();
throw new RuntimeException("userDao fill user : -
"+u.getUsername(), e) ;
}
}

@SuppressWarnings({ "null", "unused" })


public boolean fillUtente2(Utente u){
CallableStatement cs = null;

try{

ResultSet res = null;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 279
Connection conn = dbc.getConnection(01);

String sql = "SELECT * FROM `pharmacopterdb1`.`utenti` " +


"WHERE `utenti`.`NomeUtente` = ? ;";
cs=conn.prepareCall(sql);

cs.setString(1, u.getUsername());

cs.execute();

res = cs.getResultSet();
res.next();
do{
u.setUtente2(res.getInt("idutenti"),
res.getString("NomeUtente"), res.getString("PswUtente"),
res.getString("TipoUtente"), res.getString("Mail"),
res.getString("Nome/RagSociale"), res.getString("Cognome/Citta"));
}while(res!=null && res.next()) ;

res.first();
if(res!=null){

res.close();
conn.close();
return true;

}
else
{
res.close();
conn.close();
u.setUtente2(-1, "null", "null", "null", "null", "null",
"null");
return false;
}

}
catch (SQLException e) {
System.out.println("Aggiorno forzatamente la
connessione!!");
this.dbc.forceGetIstance();

e.printStackTrace();
throw new RuntimeException("userDao fill user : -
"+u.getUsername(), e) ;
}
}

@SuppressWarnings({ "null", "unused" })


public boolean fillUtente3(Utente u){
CallableStatement cs = null;

boolean b = false;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 280
try{

ResultSet res = null;


Connection conn = dbc.getConnection(01);

String sql = "SELECT * FROM `pharmacopterdb1`.`utenti` " +


"WHERE `utenti`.`NomeUtente` = ? ;";
cs=conn.prepareCall(sql);

cs.setString(1, u.getUsername());

cs.execute();

res = cs.getResultSet();

if(res.next()){
b = true;
}
else{
b= false;
}

}
catch (SQLException e) {
System.out.println("Aggiorno forzatamente la
connessione!!");
this.dbc.forceGetIstance();
e.printStackTrace();

return b;
}

//sdfsdf
public Boolean creaUtente(Utente u){
boolean success = false;

PreparedStatement cs = null;
try{
Boolean uspresente = false;
ResultSet res = null;
Connection conn = dbc.getConnection(01);

// controllo se l'utente è già registrato (metodo fillUtente


restituisce boolean true or false) ed in caso false registra su db il nuovo
utente
uspresente = fillUtente3(u);
if(uspresente == false){

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 281
String sql = "INSERT INTO `pharmacopterdb1`.`utenti`
(`NomeUtente`,
`PswUtente`,`TipoUtente`,`Mail`,`Nome/RagSociale`,`Cognome/Citta`) VALUES
(?,?,?,?,?,?); ";

cs=conn.prepareStatement(sql,
PreparedStatement.RETURN_GENERATED_KEYS);

cs.setString(1, u.getUsername().toString());
cs.setString(2, u.getPassword().toString());
// System.out.println(u.getTipo());
cs.setString(3, u.getTipo().toString());
cs.setString(4, u.getMail().toString());
cs.setString(5, u.getNome_rs().toString());
cs.setString(6, u.getCognome_citta().toString());

//System.out.println(sql);

cs.executeUpdate();

res = cs.getGeneratedKeys();
if (res.next()){
success=true;
}
res.close();
conn.close();
}

return success;

}
catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("attivitaDao getmetaowner : - ", e)
;
}
}

public boolean fillUtenteRegid(Utente u){


CallableStatement cs = null;
String username ="";
String regId = "";

username = u.getUsername();
regId = u.getRegId();
boolean b = false;
try{

ResultSet res = null;


Connection conn = dbc.getConnection(01);

// UPDATE `pharmacopterdb1`.`utenti` SET `Latitudine`='42' WHERE


`idutenti`='2';

String sql = "UPDATE `pharmacopterdb1`.`utenti` SET `regId`= ?


WHERE `NomeUtente`=?";

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 282
// "SELECT * FROM `pharmacopterdb1`.`utenti` " +
// "WHERE `utenti`.`NomeUtente` = ? ;";
cs=conn.prepareCall(sql);
cs.setString(1, regId);
cs.setString(2, username);

System.out.println("qui ci arrivo quando cerco di updatare il


regid--------------- e in più il regId vale: "+ regId + "------------lo username
vale: "+ username);
cs.execute();

res = cs.getResultSet();

}
catch (SQLException e) {
System.out.println("Aggiorno forzatamente la
connessione!!");
this.dbc.forceGetIstance();
e.printStackTrace();

return b;
}

public boolean takeregId(Utente u){


CallableStatement cs = null;
String username ="";
String regId = "";

username = u.getUsername();

boolean b = false;
try{

ResultSet res = null;


Connection conn = dbc.getConnection(01);

String sql = "SELECT regId FROM `pharmacopterdb1`.`utenti` " +


"WHERE `utenti`.`NomeUtente` = ?;" ;
cs=conn.prepareCall(sql);
cs.setString(1, username);

System.out.println("qui ci arrivo quando cerco di ottenere il


regid per inviare il messaggio a chi di dovere------------lo username vale: "+
username);
cs.execute();

res = cs.getResultSet();
res.first();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 283
regId = res.getString("regId");
u.setRegId(regId);

}
catch (SQLException e) {
System.out.println("Aggiorno forzatamente la
connessione!!");
this.dbc.forceGetIstance();
e.printStackTrace();

return b;
} }

Codice android: it.sii.android.loginserver2.servlets

LoginServlet.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.simple.JSONObject;

import classi.Utente;

import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

import dao.DBConnect;
import dao.UtenteDAO;

/**
*
* @author Vienna
*/
public class LoginServlet extends HttpServlet {

/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 284
* @throws IOException if an I/O error occurs
*/

@SuppressWarnings("unchecked")
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession(true);

String username = request.getParameter("username");


String password = request.getParameter("password");

Utente pharmacopterUtente = new Utente();


pharmacopterUtente.setUsername(username);
pharmacopterUtente.setPassword(password);

boolean success = false;

JSONObject user = new JSONObject();


JSONObject user2 = new JSONObject();
UtenteDAO ud = DBConnect.getInstance().getUtenteDAO();

success = ud.fillUtenteLogin(pharmacopterUtente);
System.out.println(pharmacopterUtente.getTipo() + "eccomi qua");
user.put("userName",pharmacopterUtente.getUsername());
user.put("password",pharmacopterUtente.getPassword());
user.put("tipo",pharmacopterUtente.getTipo());
user.put("mail",pharmacopterUtente.getMail());
user.put("nome_rs",pharmacopterUtente.getNome_rs());
user.put("cognome_citta",pharmacopterUtente.getCognome_citta());
user.put("farmaLat", pharmacopterUtente.getMylat());
user.put("farmaLon", pharmacopterUtente.getMylon());

user2.put("userName","null");
user2.put("password","null");
user2.put("tipo","null");
user2.put("mail","null");
user2.put("nome_rs","null");
user2.put("cognome_citta","null");

JSONObject obj = new JSONObject();

if(success)
{
obj.put("user", user);
obj.put("success", success);
System.out.println("sono qui");

session.setAttribute("pharmacopterUtente", pharmacopterUtente);

response.setContentType("application/json");
// Get the printwriter object from response to write the required
json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(obj);
out.flush();
}
else
{

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 285
obj.put("user", user2);
obj.put("success", false);

session.setAttribute("pharmacopterUtente",
pharmacopterUtente);

response.setContentType("application/json");
// Get the printwriter object from response to write the
required json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(obj);
out.flush();
}

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on


the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}

OrdineModificaStatoServlet.java
/*

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 286
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.simple.JSONObject;

import classi.Utente;

import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

import dao.DBConnect;
import dao.UtenteDAO;

/**
*
* @author Vienna
*/
public class LoginServlet extends HttpServlet {

/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/

@SuppressWarnings("unchecked")
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession(true);

String username = request.getParameter("username");


String password = request.getParameter("password");

Utente pharmacopterUtente = new Utente();


pharmacopterUtente.setUsername(username);
pharmacopterUtente.setPassword(password);

boolean success = false;

JSONObject user = new JSONObject();


JSONObject user2 = new JSONObject();
UtenteDAO ud = DBConnect.getInstance().getUtenteDAO();

success = ud.fillUtenteLogin(pharmacopterUtente);
System.out.println(pharmacopterUtente.getTipo() + "eccomi qua");

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 287
user.put("userName",pharmacopterUtente.getUsername());
user.put("password",pharmacopterUtente.getPassword());
user.put("tipo",pharmacopterUtente.getTipo());
user.put("mail",pharmacopterUtente.getMail());
user.put("nome_rs",pharmacopterUtente.getNome_rs());
user.put("cognome_citta",pharmacopterUtente.getCognome_citta());
user.put("farmaLat", pharmacopterUtente.getMylat());
user.put("farmaLon", pharmacopterUtente.getMylon());

user2.put("userName","null");
user2.put("password","null");
user2.put("tipo","null");
user2.put("mail","null");
user2.put("nome_rs","null");
user2.put("cognome_citta","null");

JSONObject obj = new JSONObject();

if(success)
{
obj.put("user", user);
obj.put("success", success);
System.out.println("sono qui");

session.setAttribute("pharmacopterUtente", pharmacopterUtente);

response.setContentType("application/json");
// Get the printwriter object from response to write the required
json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(obj);
out.flush();
}
else
{
obj.put("user", user2);
obj.put("success", false);

session.setAttribute("pharmacopterUtente",
pharmacopterUtente);

response.setContentType("application/json");
// Get the printwriter object from response to write the
required json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(obj);
out.flush();
}

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on


the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 288
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}

OrdineNuovoServlet.java
package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;
import java.util.Calendar;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.simple.JSONObject;

import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;

import classi.Ordine;
import classi.Utente;
import dao.DBConnect;
import dao.OrdineDAO;
import dao.UtenteDAO;

public class OrdineNuovoServlet extends HttpServlet{

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 289
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/

// RICHIESTA NON SICURA: //


http://localhost:8080/LoginServer2/addOrdine.do?username=gio&clientelat=44
.54&clientelon=7.55&nomefarmacia=nomefarma&farmalat=44.65&farmalon=7.56&JsonOrdi
ne=eccolastringachepossoinserirequidentro

// RICHIESTA SICURA: //
https://localhost:8443/LoginServer2/addOrdine.do?username=gio&clientelat=4
4.54&clientelon=7.55&nomefarmacia=nomefarma&farmalat=44.65&farmalon=7.56&JsonOrd
ine=eccolastringachepossoinserirequidentro

private static final String GOOGLE_SERVER_KEY =


"AIzaSyDTt5tV8wpITGVfaKAy7_hXwPIBVw15Jfw";
static final String MESSAGE_KEY = "message";

@SuppressWarnings({ "unchecked", "deprecation" })


protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession(true);

String notificationReceiverUsername =
request.getParameter("notificationReceiverUsername");
String clienteNome = request.getParameter("username");
System.out.println(request.getParameter("clientelat"));
Double clienteLat =
Double.valueOf(request.getParameter("clientelat"));
Double clienteLon =
Double.valueOf(request.getParameter("clientelon"));
String farmaciaNome = request.getParameter("nomefarmacia");
Double farmaciaLat =
Double.valueOf(request.getParameter("farmalat"));
Double farmaciaLon =
Double.valueOf(request.getParameter("farmalon"));
String totale = String.valueOf(request.getParameter("totale"));

String listaordine = request.getParameter("JsonOrdine");

//ISTANZIO L'OGGETTO ORDINE CHE INSERIRO' NEL DB


Ordine ordine = new Ordine();
ordine.setClienteNome(clienteNome);
ordine.setClienteLat(clienteLat);
ordine.setClienteLon(clienteLon);
ordine.setFarmaciaNome(farmaciaNome);
ordine.setFarmaciaLat(farmaciaLat);
ordine.setFarmaciaLon(farmaciaLon);
ordine.setPrezzoTotale(totale);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 290
// notare che al db passerò la lista ordine in formato String
ordine.setOrdinepezzi(listaordine);
ordine.setStato("nonapprovato");
// prendo la data dal server, così non rischio truffe del tipo
cambia la data sul cell e prendo quella
java.sql.Date timeNow = new
Date(Calendar.getInstance().getTimeInMillis());
ordine.setTime("data: "+timeNow.toString()+" ora:
"+timeNow.getTime());

boolean success = false;

//APRO CONNESSIONE AL DB
OrdineDAO od = DBConnect.getInstance().getOrdineDAO();
//USO METODO DEL DAO PER AGGIUNGERE UNA TUPLA AL DB, NEL CASO DI SUCCESSO
MI RESTIUISCE TRUE, FALSE ALTRIMENTI
success = od.aggiungiOrdine(ordine);

//CREO IL JSON DI RISPOSTA AL CLIENT COMPOSTO COME SEGUE:


{"success":true/false}

JSONObject risposta = new JSONObject();

risposta.put("success", success);
risposta.put("data e ora", timeNow.toString()+"
"+String.valueOf(timeNow.getTime()));

response.setContentType("application/json");
// Get the printwriter object from response to write the required
json object to the output stream
PrintWriter out = response.getWriter();

UtenteDAO ud2 = DBConnect.getInstance().getUtenteDAO();


Utente pharmacopterUtente = new Utente();
pharmacopterUtente.setUsername(notificationReceiverUsername);
boolean success2 = ud2.takeregId(pharmacopterUtente);

String regId = pharmacopterUtente.getRegId();

String userMessage = "";


Sender sender = new Sender(GOOGLE_SERVER_KEY);
Message message = new Message.Builder().timeToLive(30)
.delayWhileIdle(true).addData(MESSAGE_KEY,
userMessage).build();
System.out.println("ecco qua il regId del ricevente: " + regId);
Result result = sender.send(message, regId, 1);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 291
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(risposta);
out.flush();

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on


the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}

OttieniCoordinateArrivoServlet.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package servlets;

import java.io.IOException;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 292
import java.io.PrintWriter;
import java.sql.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.simple.JSONObject;

import classi.Ordine;
import classi.Utente;

import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

import dao.DBConnect;
import dao.OrdineDAO;
import dao.UtenteDAO;

/**
*
* @author Vienna
*/
public class OttieniCoordinateArrivoServlet extends HttpServlet {

/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/

@SuppressWarnings("unchecked")
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession(true);

String comando = request.getParameter("comando");


String latfarma = request.getParameter("latFarma");
String lonfarma = request.getParameter("lonFarma");
boolean success = false;
Ordine ordine = new Ordine();
OrdineDAO od = DBConnect.getInstance().getOrdineDAO();
ordine.setFarmaciaLat(Double.valueOf(latfarma));
ordine.setFarmaciaLon(Double.valueOf(lonfarma));
if (comando.equals("ciao")){
success = od.fillOrdineCoordinate(ordine);
}

JSONObject Coordinate = new JSONObject();

if(success)
{
Coordinate.put("lat", ordine.getClienteLat());
Coordinate.put("lon", ordine.getClienteLon());

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 293
session.setAttribute("ordine", ordine);

response.setContentType("application/json");
// Get the printwriter object from response to write the required
json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(Coordinate);
out.flush();
}
else
{

session.setAttribute("ordine", ordine);

response.setContentType("application/json");
// Get the printwriter object from response to write the
required json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print("errore");
out.flush();
}

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on


the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 294
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}

OttieniDettagliOrdineServlet.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.simple.JSONObject;

import classi.Ordine;
import classi.Utente;

import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

import dao.DBConnect;
import dao.OrdineDAO;
import dao.UtenteDAO;

/**
*
* @author Vienna
*/
public class OttieniDettagliOrdineServlet extends HttpServlet {

/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/

// http://localhost:8080/LoginServer2/OtteniDettagliOrdine.do?id=2
// https://localhost:8443/LoginServer2/OtteniDettagliOrdine.do?id=2

Ordine ord = new Ordine();

@SuppressWarnings("unchecked")

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 295
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession(true);

String id = String.valueOf(request.getParameter("id"));

ord.setId(Integer.parseInt(id));

boolean success = false;

OrdineDAO ordDAO = DBConnect.getInstance().getOrdineDAO();

success = ordDAO.fillOrdineDaId(ord);

System.out.println("asd"+ord.getOrdinepezzi());

JSONObject obj = new JSONObject();

if(success)
{
// System.out.println("qui ci arrivo");
// obj.put("idordine", String.valueOf(ord.getId()) );
// ord.getOrdine contiene una stringa Json con un elenco di prodotti
e le relative informazioni.
obj.put("ordine",ord.getOrdinepezzi().toString());

response.setContentType("application/json");
// Get the printwriter object from response to write the required
json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(obj);
out.flush();
}
else
{

response.setContentType("application/json");
// Get the printwriter object from response to write the
required json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(obj);
out.flush();
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 296
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on
the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}

OttieniElencoFarmacieServlet.java
package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.simple.JSONObject;

import classi.ElencoFarmacie;
import classi.Farmacia;
import dao.DBConnect;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 297
import dao.ElencoFarmacieDAO;

public class OttieniElencoFarmacieServlet extends HttpServlet{


/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/

@SuppressWarnings("unchecked")
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession(true);

String richiesta = request.getParameter("richiesta");

if(richiesta.equals("vai")){

Farmacia farmacia2 = null;


ElencoFarmacie elencofarmacie = new ElencoFarmacie();

boolean success = false;

JSONObject listaJSON = new JSONObject();


ElencoFarmacieDAO LF =
DBConnect.getInstance().getListaFarmaciaDAO();

try {
success = LF.fillElencoFarmacie(elencofarmacie);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(success){
for(int i = 0; i < elencofarmacie.ListaFarmacie.size(); i++){
JSONObject farmaciaJSON = new JSONObject();
farmaciaJSON.put("NomeFarmacia",
elencofarmacie.getFarmacia(i).nome1);

System.out.println("Farmacia n° " + i + " = "


+ elencofarmacie.getFarmacia(i).getNome() + " latitudine
= " + elencofarmacie.getFarmacia(i).getLatitudine() + " longitudine = "+
elencofarmacie.getFarmacia(i).getLongitudine() );

farmaciaJSON.put("Latitudine",
elencofarmacie.getFarmacia(i).getLatitudine());

farmaciaJSON.put("Longitudine",elencofarmacie.getFarmacia(i).getLongitudin
e());

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 298
listaJSON.put("farmacia"+i, farmaciaJSON);

// listaJSON.put("farmacia"+i, new JSONObject().put("nomeFarmacia",


elencofarmacie.getFarmacia(i).nome1));

// farmaciaJSON1.put("NomeFarmacia",
elencofarmacie.getFarmacia(1).nome1);
// System.out.println("Farmacia n° 1 = "
// + elencofarmacie.getFarmacia(0).nome1);
// farmaciaJSON2.put("Latitudine",
elencofarmacie.getFarmacia(2).latitudine2);
// System.out.println("Farmacia n° 2 = "
// + elencofarmacie.getFarmacia(1).nome1);
//
farmaciaJSON3.put("Longitudine",elencofarmacie.getFarmacia(3).longitudine2
);
// System.out.println("Farmacia n° 3 = "
// + elencofarmacie.getFarmacia(2).nome1);
// listaJSON.put("farmacia 1: ", farmaciaJSON1);
// listaJSON.put("farmacia 2: ", farmaciaJSON2);
// listaJSON.put("farmacia 3: ", farmaciaJSON3);

System.out.println(listaJSON);
if(success)
{

System.out.println("sono qui");

response.setContentType("application/json");
// Get the printwriter object from response to write the required
json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(listaJSON);
out.flush();
}
else
{

session.setAttribute("pharmacopterUtente", farmacia2);

response.setContentType("application/json");
// Get the printwriter object from response to write the
required json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print("non ci sn farmacie");
out.flush();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 299
}

}
}

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on


the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}

OttieniElencoOrdiniFBServlet.java
package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.simple.JSONObject;

import classi.ElencoFarmacie;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 300
import classi.ElencoOrdini;
import classi.Farmacia;
import classi.Ordine;
import classi.Utente;
import dao.DBConnect;
import dao.ElencoFarmacieDAO;
import dao.ElencoOrdiniDAO;
import dao.OrdineDAO;
import dao.UtenteDAO;

public class OttieniElencoOrdiniFBServlet extends HttpServlet{


/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/

// RICHIESTA NON SICURA: //


http://localhost:8080/LoginServer2/OttieniElencoOrdini.do?username=1234
// RICHIESTA SICURA: //
https://localhost:8443/LoginServer2/OttieniElencoOrdini.do?username=1234

@SuppressWarnings({ "unchecked", "unused" })


protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession(true);

// utente può essere un farmacista o un cliente, la prima cosa che


faccio è capire che utente è (farmacista o cliente)
// per fare ciò mi faccio un bel fillUtenteOrdini(passandogli il
parametro utente con solo lo username settato
// in modo da ottenere la tipologia di tale utente
String username = request.getParameter("username");
{
// in queste due righe istanzio l'oggetto ElencoOrdini, (nb
ElencoOrdini è vuoto
// e la variabile e riutilizzo in seguito la variabile username
che istanzio nuovamente qui dentro)

ElencoOrdini elencoOrdini = new ElencoOrdini();


String clienteNome = username;
// istanzio la classe che accede al DB e riempirà successivamente
la mia istanza di elencoordini
ElencoOrdiniDAO ElencoOrdiniDAO =
DBConnect.getInstance().getElencoOrdiniDAO();
boolean success2;

// metodo per riempire l'oggetto ordine istanziato prima (di cui


avevamo settato solo lo username affinchè
// nel DAO possa fare la query sul database Select * FROM db
WHERE ClienteNome = username;
try {
success2 =
ElencoOrdiniDAO.fillElencoOrdiniCliente(elencoOrdini, clienteNome);
} catch (SQLException e) {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 301
// TODO Auto-generated catch block
e.printStackTrace();
success2 = false;
}

// creo Oggetto Json da mandare indietro


JSONObject dettagliOrdineJSON = new JSONObject();

if(success2){
for(int i = 0; i < elencoOrdini.elencoOrdini.size();
i++){

JSONObject ordineJSON = new JSONObject();

ordineJSON.put("clienteLat",elencoOrdini.getOrdine(i).getClienteLat());

ordineJSON.put("clienteLon",elencoOrdini.getOrdine(i).getClienteLon());
ordineJSON.put("farmaLat",
elencoOrdini.getOrdine(i).getFarmaciaLat());
ordineJSON.put("farmaLon",
elencoOrdini.getOrdine(i).getFarmaciaLon());

ordineJSON.put("idOrdine",elencoOrdini.getOrdine(i).getId());

ordineJSON.put("oraOrdine",elencoOrdini.getOrdine(i).getTime());

ordineJSON.put("nomeCliente",elencoOrdini.getOrdine(i).getClienteNome());

ordineJSON.put("statoOrdine",elencoOrdini.getOrdine(i).getStato());

ordineJSON.put("prezzoOrdine",elencoOrdini.getOrdine(i).getPrezzoTotale())
;
ordineJSON.put("nomeFarmacia",
elencoOrdini.getOrdine(i).getFarmaciaNome());
dettagliOrdineJSON.put("Ordine"+i, ordineJSON);

// listaJSON.put("farmacia"+i, new
JSONObject().put("nomeFarmacia", elencofarmacie.getFarmacia(i).nome1));

}
}

response.setContentType("application/json");
// Get the printwriter object from response to write the
required json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(dettagliOrdineJSON);
out.flush();
}

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on


the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 302
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}

OttieniElencoOrdiniServlet.java
package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.simple.JSONObject;

import classi.ElencoFarmacie;
import classi.ElencoOrdini;
import classi.Farmacia;
import classi.Ordine;
import classi.Utente;
import dao.DBConnect;
import dao.ElencoFarmacieDAO;
import dao.ElencoOrdiniDAO;
import dao.OrdineDAO;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 303
import dao.UtenteDAO;

public class OttieniElencoOrdiniServlet extends HttpServlet{


/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/

// RICHIESTA NON SICURA: //


http://localhost:8080/LoginServer2/OttieniElencoOrdini.do?username=1234
// RICHIESTA SICURA: //
https://localhost:8443/LoginServer2/OttieniElencoOrdini.do?username=1234

@SuppressWarnings({ "unchecked", "unused" })


protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession(true);

// utente può essere un farmacista o un cliente, la prima cosa che


faccio è capire che utente è (farmacista o cliente)
// per fare ciò mi faccio un bel fillUtenteOrdini(passandogli il
parametro utente con solo lo username settato
// in modo da ottenere la tipologia di tale utente
String username = request.getParameter("username");
Utente utente = new Utente();
utente.setUsername(username);
UtenteDAO utenteDAO = DBConnect.getInstance().getUtenteDAO();
boolean successUser = false;

try {
successUser = utenteDAO.fillUtente2(utente);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
successUser = false;
}

String tipo = utente.getTipo();


System.out.println("tipo ="+tipo);

if(tipo.equals("cliente"))

{
// in queste due righe istanzio l'oggetto ElencoOrdini, (nb
ElencoOrdini è vuoto
// e la variabile e riutilizzo in seguito la variabile username
che istanzio nuovamente qui dentro)

ElencoOrdini elencoOrdini = new ElencoOrdini();


String clienteNome = username;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 304
// istanzio la classe che accede al DB e riempirà successivamente
la mia istanza di elencoordini
ElencoOrdiniDAO ElencoOrdiniDAO =
DBConnect.getInstance().getElencoOrdiniDAO();
boolean success2;

// metodo per riempire l'oggetto ordine istanziato prima (di cui


avevamo settato solo lo username affinchè
// nel DAO possa fare la query sul database Select * FROM db
WHERE ClienteNome = username;
try {
success2 =
ElencoOrdiniDAO.fillElencoOrdiniCliente(elencoOrdini, clienteNome);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
success2 = false;
}

// creo Oggetto Json da mandare indietro


JSONObject dettagliOrdineJSON = new JSONObject();

if(success2){
for(int i = 0; i < elencoOrdini.elencoOrdini.size();
i++){

JSONObject ordineJSON = new JSONObject();

ordineJSON.put("clienteLat",elencoOrdini.getOrdine(i).getClienteLat());

ordineJSON.put("clienteLon",elencoOrdini.getOrdine(i).getClienteLon());
ordineJSON.put("farmaLat",
elencoOrdini.getOrdine(i).getFarmaciaLat());
ordineJSON.put("farmaLon",
elencoOrdini.getOrdine(i).getFarmaciaLon());

ordineJSON.put("idOrdine",elencoOrdini.getOrdine(i).getId());

ordineJSON.put("oraOrdine",elencoOrdini.getOrdine(i).getTime());

ordineJSON.put("nomeCliente",elencoOrdini.getOrdine(i).getClienteNome());

ordineJSON.put("statoOrdine",elencoOrdini.getOrdine(i).getStato());

ordineJSON.put("prezzoOrdine",elencoOrdini.getOrdine(i).getPrezzoTotale())
;
ordineJSON.put("nomeFarmacia",
elencoOrdini.getOrdine(i).getFarmaciaNome());
dettagliOrdineJSON.put("Ordine"+i, ordineJSON);

// listaJSON.put("farmacia"+i, new
JSONObject().put("nomeFarmacia", elencofarmacie.getFarmacia(i).nome1));

}
}

response.setContentType("application/json");
// Get the printwriter object from response to write the
required json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 305
out.print(dettagliOrdineJSON);
out.flush();
}

else
if(tipo.equals("farmacista")){
// in queste due righe istanzio l'oggetto ElencoOrdini, (nb
ElencoOrdini è vuoto
// e la variabile e riutilizzo in seguito la variabile username
che istanzio nuovamente qui dentro)

ElencoOrdini elencoOrdini = new ElencoOrdini();


String farmacistaNome = username;
// istanzio la classe che accede al DB e riempirà successivamente
la mia istanza di elencoordini
ElencoOrdiniDAO ElencoOrdiniDAO =
DBConnect.getInstance().getElencoOrdiniDAO();
boolean success2;

// metodo per riempire l'oggetto ordine istanziato prima (di cui


avevamo settato solo lo username affinchè
// nel DAO possa fare la query sul database Select * FROM db
WHERE ClienteNome = username;
try {
success2 =
ElencoOrdiniDAO.fillElencoOrdiniFarmacia(elencoOrdini, farmacistaNome);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
success2 = false;
}

// creo Oggetto Json da mandare indietro


JSONObject ElencoOrdiniJson = new JSONObject();
if(success2){
for(int i = 0; i < elencoOrdini.elencoOrdini.size();
i++){

JSONObject ordineJSON = new JSONObject();

ordineJSON.put("clienteLat",elencoOrdini.getOrdine(i).getClienteLat());

ordineJSON.put("clienteLon",elencoOrdini.getOrdine(i).getClienteLon());
ordineJSON.put("farmaLat",
elencoOrdini.getOrdine(i).getFarmaciaLat());
ordineJSON.put("farmaLon",
elencoOrdini.getOrdine(i).getFarmaciaLon());

ordineJSON.put("idOrdine",elencoOrdini.getOrdine(i).getId());

ordineJSON.put("oraOrdine",elencoOrdini.getOrdine(i).getTime());

ordineJSON.put("nomeCliente",elencoOrdini.getOrdine(i).getClienteNome());

ordineJSON.put("statoOrdine",elencoOrdini.getOrdine(i).getStato());

ordineJSON.put("prezzoOrdine",elencoOrdini.getOrdine(i).getPrezzoTotale())
;
ordineJSON.put("nomeFarmacia",
elencoOrdini.getOrdine(i).getFarmaciaNome());
ElencoOrdiniJson.put("Ordine"+i, ordineJSON);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 306
// listaJSON.put("farmacia"+i, new
JSONObject().put("nomeFarmacia", elencofarmacie.getFarmacia(i).nome1));

}
}

response.setContentType("application/json");
// Get the printwriter object from response to write the
required json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(ElencoOrdiniJson);
out.flush();

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on


the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 307
RegisterServlet.java
package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.simple.JSONObject;

import classi.Utente;

import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

import dao.DBConnect;
import dao.UtenteDAO;

public class RegisterServlet extends HttpServlet {

@SuppressWarnings("unchecked")
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession(true);

String username = request.getParameter("username");


String password = request.getParameter("password");
String tipo = request.getParameter("tipo");
String mail = request.getParameter("email");
String nome = request.getParameter("nomeanagrafe");
String cognome = request.getParameter("cognomeanagrafe");

// System.out.println("ecco la request " + request);


// System.out.println("\n" + cognome);
// System.out.println("\n" + nome);
// System.out.println("\n" + mail);
// System.out.println("\n" + tipo);
// System.out.println("\n" + password);
// System.out.println("\n" + username);

Utente pharmacopterUtente = new Utente();


pharmacopterUtente.setUtente(username, password, tipo, mail, nome,
cognome);

boolean success = false;

JSONObject user = new JSONObject();

UtenteDAO ud = DBConnect.getInstance().getUtenteDAO();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 308
success = ud.creaUtente(pharmacopterUtente);

user.put("userName",pharmacopterUtente.getUsername());
user.put("password",pharmacopterUtente.getPassword());
user.put("tipo",pharmacopterUtente.getTipo());
user.put("id",pharmacopterUtente.getIdUtente());
user.put("logged",pharmacopterUtente.getIdUtente()!=null);

JSONObject obj = new JSONObject();


obj.put("user", user);
obj.put("success", success);

session.setAttribute("pharmacopterUtente", pharmacopterUtente);

response.setContentType("application/json");
// Get the printwriter object from response to write the required
json object to the output stream
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the
following, it will return your json object
out.print(obj);
out.flush();
}

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click


on the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}

sd.java
package servlets;

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 309
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet implementation class sd
*/
@WebServlet("/sd")
public class sd extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* Default constructor.
*/
public sd() {
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
// TODO Auto-generated method stub
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
// TODO Auto-generated method stub
}

Codice android: com.google.android.gcm.demo.server

ApiKeyInitializer.java
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 310
* limitations under the License.
*/
package com.google.android.gcm.demo.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/**
* Context initializer that loads the API key from a
* {@value #PATH} file located in the classpath (typically under
* {@code WEB-INF/classes}).
*/
public class ApiKeyInitializer implements ServletContextListener {

static final String ATTRIBUTE_ACCESS_KEY = "apiKey";

private static final String PATH = "/api.key";

private final Logger logger = Logger.getLogger(getClass().getName());

public void contextInitialized(ServletContextEvent event) {


logger.info("Reading " + PATH + " from resources (probably from " +
"WEB-INF/classes");
String key = getKey();
event.getServletContext().setAttribute(ATTRIBUTE_ACCESS_KEY, key);
}

/**
* Gets the access key.
*/
protected String getKey() {
InputStream stream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(PATH);
if (stream == null) {
throw new IllegalStateException("Could not find file " + PATH +
" on web resources)");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
try {
String key = reader.readLine();
return key;
} catch (IOException e) {
throw new RuntimeException("Could not read file " + PATH, e);
} finally {
try {
reader.close();
} catch (IOException e) {
logger.log(Level.WARNING, "Exception closing " + PATH, e);
}
}
}

public void contextDestroyed(ServletContextEvent event) {


}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 311
BaseServlet.java
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.gcm.demo.server;

import java.io.IOException;
import java.util.Enumeration;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Skeleton class for all servlets in this package.
*/
@SuppressWarnings("serial")
abstract class BaseServlet extends HttpServlet {

// change to true to allow GET calls


static final boolean DEBUG = true;

protected final Logger logger = Logger.getLogger(getClass().getName());

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
if (DEBUG) {
doPost(req, resp);
} else {
super.doGet(req, resp);
}
}

protected String getParameter(HttpServletRequest req, String parameter)


throws ServletException {
String value = req.getParameter(parameter);
if (isEmptyOrNull(value)) {
if (DEBUG) {
StringBuilder parameters = new StringBuilder();

Enumeration<String> names = req.getParameterNames();


while (names.hasMoreElements()) {
String name = names.nextElement();
String param = req.getParameter(name);
parameters.append(name).append("=").append(param).append("\n");
}
logger.fine("parameters: " + parameters);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 312
}
throw new ServletException("Parameter " + parameter + " not found");
}
return value.trim();
}

protected String getParameter(HttpServletRequest req, String parameter,


String defaultValue) {
String value = req.getParameter(parameter);
if (isEmptyOrNull(value)) {
value = defaultValue;
}
return value.trim();
}

protected void setSuccess(HttpServletResponse resp) {


setSuccess(resp, 0);
}

protected void setSuccess(HttpServletResponse resp, int size) {


resp.setStatus(HttpServletResponse.SC_OK);
resp.setContentType("text/plain");
resp.setContentLength(size);
}

protected boolean isEmptyOrNull(String value) {


return value == null || value.trim().length() == 0;
}

Datastore.java
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.gcm.demo.server;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

/**
* Simple implementation of a data store using standard Java collections.
* <p>
* This class is thread-safe but not persistent (it will lost the data when the
* app is restarted) - it is meant just as an example.
*/
public final class Datastore {

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 313
private static final List<String> regIds = new ArrayList<String>();
private static final Logger logger =
Logger.getLogger(Datastore.class.getName());

private Datastore() {
throw new UnsupportedOperationException();
}

/**
* Registers a device.
*/
public static void register(String regId) {
logger.info("Registering " + regId);
synchronized (regIds) {
regIds.add(regId);
}
}

/**
* Unregisters a device.
*/
public static void unregister(String regId) {
logger.info("Unregistering " + regId);
synchronized (regIds) {
regIds.remove(regId);
}
}

/**
* Updates the registration id of a device.
*/
public static void updateRegistration(String oldId, String newId) {
logger.info("Updating " + oldId + " to " + newId);
synchronized (regIds) {
regIds.remove(oldId);
regIds.add(newId);
}
}

/**
* Gets all registered devices.
*/
public static List<String> getDevices() {
synchronized (regIds) {
return new ArrayList<String>(regIds);
}
}

HomeServlet.java
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 314
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.gcm.demo.server;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet that adds display number of devices and button to send a message.
* <p>
* This servlet is used just by the browser (i.e., not device) and contains the
* main page of the demo app.
*/
@SuppressWarnings("serial")
public class HomeServlet extends BaseServlet {

static final String ATTRIBUTE_STATUS = "status";

/**
* Displays the existing messages and offer the option to send a new one.
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();

out.print("<html><body>");
out.print("<head>");
out.print(" <title>GCM Demo</title>");
out.print(" <link rel='icon' href='favicon.png'/>");
out.print("</head>");
String status = (String) req.getAttribute(ATTRIBUTE_STATUS);
if (status != null) {
out.print(status);
}
List<String> devices = Datastore.getDevices();
if (devices.isEmpty()) {
out.print("<h2>No devices registered!</h2>");
} else {
out.print("<h2>" + devices.size() + " device(s) registered!</h2>");
out.print("<form name='form' method='POST' action='sendAll'>");
out.print("<input type='submit' value='Send Message' />");
out.print("</form>");
}
out.print("</body></html>");
resp.setStatus(HttpServletResponse.SC_OK);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
doGet(req, resp);
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 315
RegisterServlet.java
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.gcm.demo.server;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet that registers a device, whose registration id is identified by
* {@link #PARAMETER_REG_ID}.
*
* <p>
* The client app should call this servlet everytime it receives a
* {@code com.google.android.c2dm.intent.REGISTRATION C2DM} intent without an
* error or {@code unregistered} extra.
*/
@SuppressWarnings("serial")
public class RegisterServlet extends BaseServlet {

private static final String PARAMETER_REG_ID = "regId";

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
String regId = getParameter(req, PARAMETER_REG_ID);
Datastore.register(regId);
setSuccess(resp);
}

SendAllMessagesServlet.java
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 316
* limitations under the License.
*/
package com.google.android.gcm.demo.server;

import com.google.android.gcm.server.Constants;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.MulticastResult;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.logging.Level;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet that adds a new message to all registered devices.
* <p>
* This servlet is used just by the browser (i.e., not device).
*/
@SuppressWarnings("serial")
public class SendAllMessagesServlet extends BaseServlet {

private static final int MULTICAST_SIZE = 1000;

private Sender sender;

private static final Executor threadPool = Executors.newFixedThreadPool(5);

@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
sender = newSender(config);
}

/**
* Creates the {@link Sender} based on the servlet settings.
*/
protected Sender newSender(ServletConfig config) {
String key = (String) config.getServletContext()
.getAttribute(ApiKeyInitializer.ATTRIBUTE_ACCESS_KEY);
return new Sender(key);
}

/**
* Processes the request to add a new message.
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
List<String> devices = Datastore.getDevices();
String status;
if (devices.isEmpty()) {
status = "Message ignored as there is no device registered!";
} else {
// NOTE: check below is for demonstration purposes; a real application

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 317
// could always send a multicast, even for just one recipient
if (devices.size() == 1) {
// send a single message using plain post
String registrationId = devices.get(0);
Message message = new Message.Builder().build();
Result result = sender.send(message, registrationId, 5);
status = "Sent message to one device: " + result;
} else {
// send a multicast message using JSON
// must split in chunks of 1000 devices (GCM limit)
int total = devices.size();
List<String> partialDevices = new ArrayList<String>(total);
int counter = 0;
int tasks = 0;
for (String device : devices) {
counter++;
partialDevices.add(device);
int partialSize = partialDevices.size();
if (partialSize == MULTICAST_SIZE || counter == total) {
asyncSend(partialDevices);
partialDevices.clear();
tasks++;
}
}
status = "Asynchronously sending " + tasks + " multicast messages to " +
total + " devices";
}
}
req.setAttribute(HomeServlet.ATTRIBUTE_STATUS, status.toString());
getServletContext().getRequestDispatcher("/home").forward(req, resp);
}

private void asyncSend(List<String> partialDevices) {


// make a copy
final List<String> devices = new ArrayList<String>(partialDevices);
threadPool.execute(new Runnable() {

public void run() {


Message message = new Message.Builder().build();
MulticastResult multicastResult;
try {
multicastResult = sender.send(message, devices, 5);
} catch (IOException e) {
logger.log(Level.SEVERE, "Error posting messages", e);
return;
}
List<Result> results = multicastResult.getResults();
// analyze the results
for (int i = 0; i < devices.size(); i++) {
String regId = devices.get(i);
Result result = results.get(i);
String messageId = result.getMessageId();
if (messageId != null) {
logger.fine("Succesfully sent message to device: " + regId +
"; messageId = " + messageId);
String canonicalRegId = result.getCanonicalRegistrationId();
if (canonicalRegId != null) {
// same device has more than on registration id: update it
logger.info("canonicalRegId " + canonicalRegId);
Datastore.updateRegistration(regId, canonicalRegId);
}
} else {
String error = result.getErrorCodeName();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 318
if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
// application has been removed from device - unregister it
logger.info("Unregistered device: " + regId);
Datastore.unregister(regId);
} else {
logger.severe("Error sending message to " + regId + ": " + error);
}
}
}
}});
}

UnregisterServlet.java
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.gcm.demo.server;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet that unregisters a device, whose registration id is identified by
* {@link #PARAMETER_REG_ID}.
* <p>
* The client app should call this servlet everytime it receives a
* {@code com.google.android.c2dm.intent.REGISTRATION} with an
* {@code unregistered} extra.
*/
@SuppressWarnings("serial")
public class UnregisterServlet extends BaseServlet {

private static final String PARAMETER_REG_ID = "regId";

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
String regId = getParameter(req, PARAMETER_REG_ID);
Datastore.unregister(regId);
setSuccess(resp);
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 319
Codice android: com.javapapers.java.gcm

GCMNotification.java
package com.javapapers.java.gcm;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import classi.Utente;

import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;

import dao.DBConnect;
import dao.UtenteDAO;

@WebServlet("/GCMNotification")
public class GCMNotification extends HttpServlet {
private static final long serialVersionUID = 1L;

// Put your Google API Server Key here


private static final String GOOGLE_SERVER_KEY =
"AIzaSyDTt5tV8wpITGVfaKAy7_hXwPIBVw15Jfw";
static final String MESSAGE_KEY = "message";

public GCMNotification() {
super();
}

protected void doGet(HttpServletRequest request,


HttpServletResponse response) throws ServletException,
IOException {
doPost(request, response);

protected void doPost(HttpServletRequest request,


HttpServletResponse response) throws ServletException,
IOException {

Result result = null;


// shareRegId viene riempito dall'app quando fa la richiesta:
"http://www.pharmacopter.net/GCMNotification?shareRegId=1"
// in modo da entrare nell'if che capisce se la richiesta viene fatta
da qualche parte nel server o dall'app

String share = request.getParameter("shareRegId");

// GCM RedgId of Android device to send push notification

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 320
String regId = "";
String username = "";
if (share != null && !share.isEmpty()) {

// Riconosciuto che la richiesta è stata effettuata da un'app


e nn da lserver,
// Salvo il regId che richiedo con
request.getParameter("regId) dove è necessario salvarlo (DB)
regId = request.getParameter("regId");
username = request.getParameter("username");
System.out.println("ecco il tuo regId = " + regId);

UtenteDAO ud = DBConnect.getInstance().getUtenteDAO();
Utente pharmacopterUtente = new Utente();
pharmacopterUtente.setRegId(regId);
pharmacopterUtente.setUsername(username);
boolean success = ud.fillUtenteRegid(pharmacopterUtente);

PrintWriter writer = new PrintWriter("GCMRegId.txt");


writer.println(regId);
writer.close();
request.setAttribute("pushStatus", "GCM RegId Received.");
request.getRequestDispatcher("gcm2.jsp")
.forward(request, response);

} else {

// Se la richiesta non proviene dall'app bensì dal server


stesso (attualmente dal form nella pagina gcm2.jsp) allora bisognerà richiedere
a chi va indirizzata la notifica
// richiederò quindi un parametro che mi dovrà essere fornito
dal server contenente l'username della persona che dovrà ricevere la notifica in
modo da indirizzare a
// lui tale notifica
try {
// BufferedReader br = new BufferedReader(new FileReader(
// "GCMRegId.txt"));
//
// regId = br.readLine();
//
//
// br.close();

UtenteDAO ud = DBConnect.getInstance().getUtenteDAO();
Utente pharmacopterUtente = new Utente();
pharmacopterUtente.setUsername("giovenice");
boolean success = ud.takeregId(pharmacopterUtente);

regId = pharmacopterUtente.getRegId();

String userMessage = request.getParameter("message");


Sender sender = new Sender(GOOGLE_SERVER_KEY);
Message message = new Message.Builder().timeToLive(30)
.delayWhileIdle(true).addData(MESSAGE_KEY,
userMessage).build();
System.out.println("ecco qua il regId del ricevente: " +
regId);
result = sender.send(message, regId, 1);
request.setAttribute("pushStatus", result.toString());
} catch (IOException ioe) {
ioe.printStackTrace();
request.setAttribute("pushStatus",
"RegId required: " + ioe.toString());

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 321
} catch (Exception e) {
e.printStackTrace();
request.setAttribute("pushStatus", e.toString());
}
request.getRequestDispatcher("gcm2.jsp")
.forward(request, response);
}
}
}

Codice Arduino

Sistema detect and warning:


// VARIABILI LED
int led = 12;

//VARIABILI SERVO
#include <Servo.h>
Servo myservo;
const byte servoPin = 3;

//VARIABILI PIR
const byte motionPin0 = 4;
byte senseMotion0 = 0;
const byte motionPin1 = 7;
byte senseMotion1 = 0;
const byte motionPin2 = 8;
byte senseMotion2 = 0;

//VARIABILI BOTTONE
const int buttonPin = 2; // the pin that the pushbutton is attached to
const int ledPin = 13; // the pin that the LED is attached to
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button

//VARIABILI SONAR
#define echoPin1 A0 // Echo Pin
#define trigPin1 A1 // Trigger Pin

#define echoPin2 A2 // Echo Pin


#define trigPin2 A3 // Trigger Pin

#define echoPin3 A4 // Echo Pin


#define trigPin3 A5 // Trigger Pin

#define LEDPin 13 // Onboard LED


int maximumRange = 200; // Maximum range needed
int minimumRange = 0; // Minimum range needed

long duration1;
long distance1; // Duration used to calculate distance

long duration2;
long distance2; // Duration used to calculate distance

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 322
long duration3;
long distance3; // Duration used to calculate distance

int i1 = 0;
boolean sonar1 = false;
int i2 = 0;
boolean sonar2 = false;
int i3 = 0;
boolean sonar3 = false;

void setup() {
myservo.attach(servoPin);
pinMode(led,OUTPUT);
pinMode(motionPin0, INPUT);
pinMode(motionPin1, INPUT);
pinMode(motionPin2, INPUT);
// initialize the button pin as a input:
pinMode(buttonPin, INPUT);
// initialize the LED as an output:
pinMode(ledPin, OUTPUT);
// initialize serial communication:
Serial.begin(9600);

pinMode(trigPin1, OUTPUT);
pinMode(echoPin1, INPUT);
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
pinMode(trigPin3, OUTPUT);
pinMode(echoPin3, INPUT);
}

void loop() {

//-----------------CODICE DI PROVA PER PIR NON INCROCIATI CON S0NAR


// -------------------------QUI INIZIA IL CODICE PER IL PRIMO PIR
// senseMotion0 = digitalRead(motionPin0);
// if (senseMotion0 == HIGH){
// Serial.print("trovato ostacolo PIR 1\n");
// delay(10);
// }
// -------------------------QUI INIZIA IL CODICE PER IL SECONDO PIR
// senseMotion1 = digitalRead(motionPin1);
// if (senseMotion1 == HIGH){
// Serial.print("trovato ostacolo PIR 2\n");
// delay(10);
// }
// -------------------------QUI INIZIA IL CODICE PER IL TERZO PIR
// senseMotion2 = digitalRead(motionPin2);
// if (senseMotion2 == HIGH){
// Serial.print("trovato ostacolo PIR 3\n");
// delay(10);
// }

// -------------------------QUI INIZIA IL CODICE PER IL PRIMO SONAR

senseMotion0 = digitalRead(motionPin0);
digitalWrite(trigPin1, LOW);
delayMicroseconds(2);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 323
digitalWrite(trigPin1, HIGH);
delayMicroseconds(10);

digitalWrite(trigPin1, LOW);
duration1 = pulseIn(echoPin1, HIGH);

distance1 = duration1/58.2;
delay(100);
if ((distance1 >= maximumRange || distance1 <= minimumRange) &&
senseMotion0==LOW){
sonar1 = false;
// Serial.println("niente ostacoli");
}
else {
sonar1 = true;
}
delay(50);

if (sonar1 == true) // sonar && PIR == true && senseMotion2==HIGH


{
i1++;
}
else
{
i1=0;
}

if (i1>10)
{
Serial.print("Ostacolo su ZONA UNO a distanza ");
Serial.println(distance1);
digitalWrite(led,HIGH);
delay(10);
digitalWrite(led,LOW);

// ---------------------QUI INIZIA IL CODICE PER IL SECONDO SONAR

senseMotion1 = digitalRead(motionPin1);
digitalWrite(trigPin2, LOW);
delayMicroseconds(2);

digitalWrite(trigPin2, HIGH);
delayMicroseconds(10);

digitalWrite(trigPin2, LOW);
duration2 = pulseIn(echoPin2, HIGH);

distance2 = duration2/58.2;
delay(100);
if ((distance2 >= maximumRange || distance2 <= minimumRange) &&
senseMotion1==LOW){
sonar2 = false;
// Serial.println("niente ostacoli");
}
else {
sonar2 = true;
}
delay(50);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 324
if ((sonar2 == true)) // sonar && PIR == true && senseMotion2==HIGH
{
i2++;
}
else
{
i2=0;
}

if (i2>10)
{
Serial.print("Ostacolo su sonar DUE a distanza ");
Serial.println(distance2);

// -------------------------QUI INIZIA IL CODICE PER IL TERZO SONAR

senseMotion2 = digitalRead(motionPin2);
digitalWrite(trigPin3, LOW);
delayMicroseconds(2);

digitalWrite(trigPin3, HIGH);
delayMicroseconds(10);

digitalWrite(trigPin3, LOW);
duration3 = pulseIn(echoPin3, HIGH);

distance3 = duration3/58.2;
delay(100);
if ((distance3 >= maximumRange || distance3 <= minimumRange) && senseMotion2 ==
LOW){
sonar3 = false;
// Serial.println("niente ostacoli");
}
else {
sonar3 = true;
}
delay(50);

if (sonar3 == true ) // sonar && PIR == true && senseMotion2==HIGH


{
i3++;
}
else
{
i3=0;
}

if (i3>10)
{
Serial.print("Ostacolo su sonar TRE a distanza ");
Serial.println(distance3);

//---------------QUI INIZIA IL CODICE PER LO SGANCIO DEL PACCO-----------------


----------------------------------

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 325
// read the pushbutton input pin:
buttonState = digitalRead(buttonPin);

// compare the buttonState to its previous state


if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button
// wend from off to on:
buttonPushCounter++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);
if(buttonPushCounter%2!=0)
myservo.write(90);
else
myservo.write(1);
}
else {
// if the current state is LOW then the button
// wend from on to off:
Serial.println("off");

}
}
// save the current state as the last state,
//for next time through the loop
lastButtonState = buttonState;

// turns on the LED every four button pushes by


// checking the modulo of the button push counter.
// the modulo function gives you the remainder of
// the division of two numbers:
if (buttonPushCounter % 4 == 0) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}

Richiesta coordinate gps (coordinate di arrivo per sgancio pacco)


int8_t answer;
int onModulePin = 2, aux;
int data_size = 0;
int end_file = 0;

char aux_str[100];

char data[250];
int x = 0;
long previous;

char url[ ]="";


int port= 80;
char request[ ]="http://192.168.2.7:8080/LoginServer2/";

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 326
void setup(){

pinMode(onModulePin, OUTPUT);
Serial.begin(115200);

Serial.println("Starting...");
power_on();

delay(3000);

// sets the PIN code


sendATcommand("AT+CPIN=****", "OK", 2000);

delay(3000);

while( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) ||


sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );

// sets APN, user name and password


sendATcommand("AT+CGSOCKCONT=1,\"IP\",\"apn\"", "OK", 2000);
sendATcommand("AT+CSOCKAUTH=1,1,\"user_name\",\"password\"", "OK", 2000);

}
void loop(){

// request the url


sprintf(aux_str, "AT+CHTTPACT=\"%s\",%d", url, port);
answer = sendATcommand(aux_str, "+CHTTPACT: REQUEST", 60000);

if (answer == 1)
{
Serial.println(request);
// Sends <Ctrl+Z>
aux_str[0] = 0x1A;
aux_str[1] = 0x00;
answer = sendATcommand(aux_str, "+CHTTPACT: DATA,", 60000);

x=0;
do{
if (answer == 1)
{
data_size = 0;
while(Serial.available()==0);
aux = Serial.read();
do{
data_size *= 10;
data_size += (aux-0x30);
while(Serial.available()==0);
aux = Serial.read();
}
while(aux != 0x0D);

Serial.print("Data received: ");


Serial.println(data_size);

if (data_size > 0)
{
while(Serial.available() < data_size);

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 327
Serial.read();

for (int y = 0; y < data_size; y++)


{
data[x] = Serial.read();
x++;
}
data[x] = '\0';
}
else
{
Serial.println("Download finished");
}
}
else
{
Serial.println("Error getting the url");
data_size = 0;
}

answer = sendATcommand2("", "+CHTTPACT: DATA,", "+CHTTPACT:0",


20000);

}while (answer != 1);

if (answer == 2)
{
Serial.print("Data received:");
Serial.println(data);
}
else
{
Serial.println("Error getting data");
}
}
else
{
Serial.println("Error waiting the request");
}

delay(10000);

void power_on(){

uint8_t answer=0;

// checks if the module is started


answer = sendATcommand("AT", "OK", 2000);
if (answer == 0)
{
// power on pulse
digitalWrite(onModulePin,HIGH);
delay(3000);
digitalWrite(onModulePin,LOW);

// waits for an answer from the module


while(answer == 0){
// Send AT every two seconds and wait for the answer
answer = sendATcommand("AT", "OK", 2000);
}
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 328
}

int8_t sendATcommand(char* ATcommand, char* expected_answer1,


unsigned int timeout)
{

uint8_t x=0, answer=0;


char response[100];
unsigned long previous;

memset(response, '\0', 100); // Initialize the string

delay(100);

while( Serial.available() > 0) Serial.read(); // Clean the input buffer

Serial.println(ATcommand); // Send the AT command

x = 0;
previous = millis();

// this loop waits for the answer


do{

if(Serial.available() != 0){
response[x] = Serial.read();
x++;
// check if the desired answer is in the response of the module
if (strstr(response, expected_answer1) != NULL)
{
answer = 1;
}
}
// Waits for the asnwer with time out
}
while((answer == 0) && ((millis() - previous) < timeout));

return answer;
}

int8_t sendATcommand2(char* ATcommand, char* expected_answer1,


char* expected_answer2, unsigned int timeout)
{

uint8_t x=0, answer=0;


char response[100];
unsigned long previous;

memset(response, '\0', 100); // Initialize the string

delay(100);

while( Serial.available() > 0) Serial.read(); // Clean the input buffer

Serial.println(ATcommand); // Send the AT command

x = 0;
previous = millis();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 329
// this loop waits for the answer
do{

if(Serial.available() != 0){
response[x] = Serial.read();
x++;
// check if the desired answer is in the response of the module
if (strstr(response, expected_answer1) != NULL)
{
answer = 1;
}
// check if the desired answer is in the response of the module
if (strstr(response, expected_answer2) != NULL)
{
answer = 2;
}
}
// Waits for the asnwer with time out
}
while((answer == 0) && ((millis() - previous) < timeout));

return answer;
}

GPS
int8_t answer;
int onModulePin= 2;
char gps_data[100];
int counter;

void setup(){

pinMode(onModulePin, OUTPUT);
Serial.begin(115200);

Serial.println("Starting...");
power_on();

delay(5000);

// starts GPS session in stand alone mode


answer = sendATcommand("AT+CGPS=1,1","OK",1000);
if (answer == 0)
{
Serial.println("Error starting the GPS");
Serial.println("The code stucks here!!");
while(1);
}
}
void loop(){

answer = sendATcommand("AT+CGPSINFO","+CGPSINFO:",1000); // request info


from GPS
if (answer == 1)
{

counter = 0;
do{
while(Serial.available() == 0);
gps_data[counter] = Serial.read();

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 330
counter++;
}
while(gps_data[counter - 1] != '\r');
gps_data[counter] = '\0';
if(gps_data[0] == ',')
{
Serial.println("No GPS data available");
}
else
{
Serial.print("GPS data:");
Serial.println(gps_data);
Serial.println("");
}

}
else
{
Serial.println("Error");
}

delay(5000);
}

void power_on(){

uint8_t answer=0;

// checks if the module is started


answer = sendATcommand("AT", "OK", 2000);
if (answer == 0)
{
// power on pulse
digitalWrite(onModulePin,HIGH);
delay(3000);
digitalWrite(onModulePin,LOW);

// waits for an answer from the module


while(answer == 0){
// Send AT every two seconds and wait for the answer
answer = sendATcommand("AT", "OK", 2000);
}
}

int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int


timeout)
{

uint8_t x=0, answer=0;


char response[100];
unsigned long previous;

memset(response, '\0', 100); // Initialize the string

delay(100);

while( Serial.available() > 0) Serial.read(); // Clean the input buffer

Serial.println(ATcommand); // Send the AT command

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 331
x = 0;
previous = millis();

// this loop waits for the answer


do{

if(Serial.available() != 0){
response[x] = Serial.read();
x++;
// check if the desired answer is in the response of the module
if (strstr(response, expected_answer1) != NULL)
{
answer = 1;
}
}
// Waits for the asnwer with time out
}
while((answer == 0) && ((millis() - previous) < timeout));

return answer;
}

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 332
Allegati
Per i necessari approfondimenti, si consultino i documenti di seguito elencati:

 Simulazione MapleSim: meccanica, elettronica e breve prova di volo;

 Video “PharmaCopter: Presentazione e simulazione di progetto”;

 Applicazione android “PharmaCopter”, disponibile a breve sul Play Store.

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 333
Sitografia
Per la componentistica elettronica:

 http://www.cooking-hacks.com
 http://www.arduino.com
 http://www.dx.com
 http://www.quadrysteria.com

Per le parti elettro-meccaniche:

 http://www.arducopter.com
 http://www.turnigy.com
 http://www.adafruit.com
 http://www.u-blox.com
 http://www.hobbyking.com
 http://3drobotics.com
 http://diydrones.com/

Per l’integrazione delle API:

 https://developers.facebook.com/
 https://developer.paypal.com/docs/api/
 https://developer.android.com/google/gcm
 https://developers.google.com/maps/
 https://developers.google.com/maps/documentation/elevation/
 http://www.daftlogic.com/sandbox-google-maps-find-altitude.htm
 https://developers.google.com/chart/
 https://developers.amazon.com
 https://www.thefanclub.co.za/how-to/how-setup-usb-3g-modem-raspberry-pi-using-
usbmodeswitch-and-wvdial
 http://blog.miguelgrinberg.com/post/stream-video-from-the-raspberry-pi-camera-to-web-
browsers-even-on-ios-and-android
 http://http://www.worldweatheronline.com

Per l’integrazione di applicazioni/funzionalità esterne:

 http://code.google.com/p/zxing/
 https://github.com/DroidPlanner/droidplanner
 http://code.google.com/p/copter-gcs/
 http://www.instructables.com/id/Arduino-Object-Avoidance-Robot/

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 334
 http://www.duino-robotics.com/obstacle-avoidance.html
 http://www.tomshw.it/cont/news/flygeo-e-il-super-drone-che-vola-e-atterra-da-
solo/59973/1.html

Altre fonti:

 http://www.icao.net
 http://www.nimbus.to.it
 http://www.aibotix.com
 http://www.meccanismocomplesso.org
 http://www.archidron.it/
 http://ece.gmu.edu/
 http://it.wikipedia.org/wiki/Aeromobile_a_pilotaggio_remoto
 http://www.flightglobal.com/
 http://techcrunch.com/2014/09/28/a-wearable-drone-that-launches-off-your-wrist-to-
take-your-selfie/
 http://www.quadrotors.net/why-quadrotors-are-so-popular-for-research/
 http://www.gizmag.com/grasp-nano-quadrotor-robots-swarm/21302/
 http://acl.mit.edu/projects/vpitch_quad.html
 http://www.popularmechanics.com/technology/military/planes-uavs/armed-quadrotors-
are-coming-10720086
 http://www.faa.gov/uas/
 https://www.youtube.com/watch?v=LCret4rv0HE
 http://www.cbsnews.com/pictures/dhls-parcelcopter-drone/
 http://illumin.usc.edu/162/the-quadrotors-coming-of-age/
 http://makezine.com/2010/01/13/how-to-quadrocopter-based-on-arduin/
 http://illumin.usc.edu/162/the-quadrotors-coming-of-age/
 http://ardrone2.parrot.com/
 http://www.cnet.com/news/the-democratization-of-the-drone/
 http://www.aermatica.com
 http://www.aleniaaermacchi.it
 http://www.repubblica.it/esteri/2014/10/29/foto/olanda_drone_ambulanza-99300874/1/
 http://www.corrieredellanotizia.it/droni-tombaroli/
 http://www.difesa.it/SMD_/CASD/IM/CeMiSS/Pubblicazioni/ricerche/Pagine/MilitaryUnma
nnedAircraftSystems.aspx
 http://www.cbsnews.com/pictures/dhls-parcelcopter-drone/
 http://www.repubblica.it/esteri/2014/10/29/foto/olanda_drone_ambulanza-99300874/1/#1

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 335
Bibliografia
 AA.VV. - Come fare business con i droni. Vendita, assemblaggio, noleggio e video riprese -
Ed. Genesis

 Masali Luca - Quadricotteri, multirotori e droni. Guida pratica all'uso dei piccoli droni civili –
Ed. L'Aeroplanino

 Drone Entrepreneurship: 30 Businesses You Can Start - LeMieux, Erry; 2013, Unmanned
Vehicle University Press
 Drone University - Glover, John M., 2014, Droneuniversity

PharmaCopter: Progettazione e realizzazione di una piattaforma integrata per la consegna di farmaci a domicilio… 336

Potrebbero piacerti anche