FUNDAȚIA PENTRU CULTURĂ ȘI ÎNVĂȚĂMÂNT IOAN SLAVICI TIMIȘOARA [615740]
FUNDAȚIA PENTRU CULTURĂ ȘI ÎNVĂȚĂMÂNT „IOAN SLAVICI” TIMIȘOARA
UNIVERSITATEA „IOAN SLAVICI” TIMIȘOARA
FACULTATEA DE INGINERIE
DOMENIUL CALCULATOARE ȘI TEHNOLOGIA INFORMAȚIEI
FORMA DE ÎNVĂȚĂMÂNT – ZI
PROIECT DE DIPLOMĂ
COORDONATOR ȘTIINȚIFIC
Conf.univ.dr.ing. Gabriela -Victoria MNERIE
ABSOLVENT: [anonimizat]
2017
FUNDAȚIA PENTRU CULTURĂ ȘI ÎNVĂȚĂMÂNT „IOAN SLAVICI” TIMIȘOARA
UNIVERSITATEA „IOAN SLAVICI” TIMIȘOARA
FACULTATEA DE INGINERIE
DOMENIUL CALCULATOARE ȘI TEHNOLOGIA INFORMAȚIEI
FORMA DE ÎNVĂȚĂMÂNT – ZI
Aplicație de GPS Tracking pentru
dispozitive mobile Android
COORDONATOR ȘTIINȚIFIC
Conf.univ.dr.ing. Gabriela – Victoria MNERIE
ABSOLVENT: [anonimizat]
2017
UNIVERSITATEA DIN ORADEA
FACULTATEA de Inginerie Electrică și Tehnologia Informației
DEPARTAMENTUL Calculatoare și tehnologia informației
TEMA
Proiectul de Finalizare a studiilor a student: [anonimizat]
1). Tema proiectului de finalizare a studiilor:
Aplicație de GPS Tracking pentru dispozitive mobile Android
2). Termenul pentru predarea proiectului de diplomă 15 iunie 2017
3). Elemente inițiale pentru elaborarea proiectului de finalizare a studiilor
– planul lucrării;
– materialele bibliografice;
– aplicația.
4). Conținutul proiectului de finalizare a studiilor :
Introducere
Capitolul 1 – Tehnologii utilizate pentru dezvoltarea de aplicații mobile
Capitolul 2 – Aplicații de tracking GPS pentru dispozitive Android
Capitolul 3 – Proiectarea și implementarea aplicației
Concluzii
Bibliografie
Anexe
5). Material grafic:
– capturi de ecran;
– scheme;
– grafice,
– poze.
6). Locul de documentare pentru elaborarea proiectului de diplomă:
Universitatea Ioan Slavici – Facultatea de Inginerie
7). Data emiterii temei: noiembrie 2016
Coordonator științific
Conf.univ.dr.ing. Gabriela -Victori a MNERIE
UNIVERSITATEA DIN ORADEA
FACULTATEA DE INGINERIE ELECTRICĂ
ȘI TEHNOLOGIA INFORMAȚIEI
Adresa Oradea, Cod 410087, Bihor, Romania, Strada Universității, nr. 1 ,
Tel/Fax :+40 259/408412, Tel:+40 259/408104; +40 259/408204
REFERAT
PRIVIND PROIECTUL DE DIPLOMĂ
A
ABSOLVENT: [anonimizat]: PUȘCAȘ CRISTIAN
DOMENIUL Calculatoare și tehnologia informației
SPECIALIZAREA Tehnologia informației
PROMOȚIA 2017
1. Titlul proiectului
Aplicație de GPS Tracking pentru dispozitive mobile Android
2. Structura proiectului
● Introducere
● Capitolul 1 – Tehnologii utilizate pentru dezvoltarea de aplicații mobile
● Capitolul 2 – Aplicații de tracking GPS pentru dispozitive Android
● Capitolul 3 – Proie ctarea și implementarea aplicației
● Concluzii
● Bibliografie
● Anexe
3. Aprecieri asupra conținutului proiectului de DIPLOMĂ ( finalizare a studiilor ),
mod de abordare, complexitate, actualitate, deficiențe
Conținutul lucrării poate fi apreciat ca suficient de cuprinzător, făcând referințe la țintele ce se
doresc a fi atinse. Modul de abordare și complexitatea, reflectă în totalitate sistemul și standardele
impuse de Universitatea “Ioan Slavici” Timișoara. În tr-un domeniu în continuă evoluție, s -a reușit
crearea unei lucrări al cărei conținut menține actual dezideratul de a face cât mai eficient un
domeniu de activitate, de o reală importanță.
4. Aprecieri asupra proiectului (se va menționa: numărul titlurilor b ibliografice
consultate, frecvența notelor de subsol, calitatea și diversitatea surselor consultate;
modul în care absolventul a prelucrat informațiile din surse teoretice)
Prin folosirea unei game variat ă de titluri bibliografice consultate, în num ăr de 15, s-a asigurat o
calitate și o diversitate ridicată în abordarea tematicii prezentate, reușind să prelucreze la un înalt
nivel întreaga paletă de informații furnizată prin sursele abordate.
Frecvența trimiterilor bibliografice, este sufi cientă pentru a evidenția principalele surse și titluri
bibliografice folosite în lucrare
(se va menționa: opțional locul de documentare și modul în care absolventul a realizat
cercetarea menționându -se contribuția autorului)
5. Concluzii (coordonatorul pro iectului trebuie să aprecieze valoarea proiectului
întocmit, relevanța studiului întreprins, competențele absolventului, rigurozitatea
pe parcursul elaborării proiectului, consecvența și seriozitatea de care a dat dovadă
absolventul pe parcurs)
……….. …………………………………………………………………………………………………………….. ……………………
…………………………………………………………………………………………….. ……………………………………………..
…………………………………………………………………………………………………………….. ……………………………..
……………………………………. ……………………………………………………………………………………………………..
…………………………………………………………………………………………………………….. ………….. …………………
…………………………………………………………………………………………………………….. ……………………………..
………………………………………………………………… …………………………………………………………………………
6. Redactarea proiectului respectă …………………………………………………. cerințele
academice de redactare (părți, capitole, subcapitole, note de subsol ș i bibliografie).
7. Consider că proiectul îndeplinește/ nu îndeplinește condițiile pentru susținere în
sesiunea de Examen de LICENȚĂ ( finalizare a studiilor ) din IULIE 2017 și propun
acordarea notei ………………
Oradea,
Data Coordonator științific
Conf .univ.dr.ing. Gabriela -Victoria MNERIE
Cuprins
Introducere 2
Capitolul 1 – Tehnologii utilizate pentru dezvoltarea de aplica ț ii mobile 5
1.1 Evolu ț ia World W ide Web-ului 5
1.2 Evolu ț ia telefoane lor mobile 9
1.3 Sistemele de operare ale telefoanelor inteligente. Prezentare Generală. Compara ț ie 11
1.4 Publicarea aplica ț iilor mobile 13
1.4.1 Publicarea aplica ț iilor pe Google Play 13
1.4.2 Publicarea aplica ț iilor pe Apple Store 13
Aplica ț ii open-source 14
Capitolul 2 – Aplica ț ii de tracking GPS pentru dispozitive Android 15
2.1 Find My Device 16
2.2 Cerberus 18
2.3 Glympse 22
Concluzii 26
Capitolul 3 – Proiectarea ș i implementarea aplica ț iei 29
3.1 Dezvoltarea aplica ț iei mobile 29
3.2 Utilizarea aplica ț iei mobile 40
3.3 Dezvoltarea aplica ț iei web 41
Concluzii 46
Bibliografie 47
ANEXE 48
Aplica ț ia mobilă 48
Aplica ț ia Web 48
Introducere
În plină eră informa ț ională, societatea a cunoscut ș i cunoa ș te în continuare modificări
dramatice, atât prin natura tehnologiilor folosite cât ș i prin rapiditatea cu care acestea sunt
implementate. De foarte multe ori aceste schimbări ireversibile din cotidian tind să treacă
neobservate, începem să folosim noi servicii ș i tehnologii care ne sunt puse la dispozi ț ie ș i de care
ulterior nu mai suntem con ș tien ț i că le-am adoptat, până în momentul în care ele devin
nefunc ț ionale pentru o scurtă perioadă de timp sau până când, prin diferite complexe de imprejurări,
noi nu mai dispunem de oportunitatea de a le utiliza. Nu trebuie să depunem eforturi semnificative
pentru a ne imagina situa ț ii în care avem un lucru important de făcut, un email urgent de trimis,
suntem într-un ora ș străin ș i avem nevoie de hartă, sau avem nevoie de un număr de telefon din
agenda ș i constatăm că nu mai avem baterie la telefon. Având în vedere nivelul de implicare a
tehnologiei în viata noastră putem considera că numărul persoanelor care nu au fost niciodată într-o
astfel de situa ț ie tinde cu repeziciune spre zero. Aceste momente ne amintesc, din când în când, de
ponderea imensă a ac ț iunilor ș i interacțiunilor noastre sociale care au fost încet dar sigur transferate
sau delegate, poate involuntar, suportului tehnologic.
Tehnologia prezintă un aspect destul de pu ț in dezbătut, ș i anume cu cât este mai bine
implementată, mai func ț ionala ș i mai utilă, cu atât trece mai neobservată. Cu alte cuvinte, cu cât
este mai importantă pentru via ț a noastră, cu atât îi acordăm mai pu ț ina importan ț ă.
Odată cu trecerea de la era industrială la era informa ț ională, tehnologia informa ț iei ne-a
influen ț at din ce în ce mai mult via ț a. Există în istoria modernă extrem de recentă reale momente de
cotitură în tehnologia informa ț iei cum ar fi, de exemplu, momentul în care numărul dispozitivelor
mobile conectate la Internet a depășit numărul dispozitivelor desktop pentru prima dată în istorie.
Astfel de trenduri au fost foarte bine exploatate de unii jucători noi de pe pia ț a IT în detrimentul
unor companii consacrate, dintre care amintim Nokia, care domina pia ț a dispozitivelor mobile la
sfâr ș itul anilor 90 ș i începutul anilor 2000. Aceste noi direc ț ii, avansul tehnologic ș i concuren ț a
acerbă în acest domeniu au determinat intrarea pe pia ț ă a tot mai multor modele de dispozitive
mobile din ce în ce mai performante ș i din ce în ce mai ieftine. În acest context, este evident că tot
mai multe persoane fizice ș i mai ales micii întreprinzători au încercat ș i încearcă să se folosească
într-o măsura cât mai mare de tehnologii care până nu demult erau accesibile numai companiilor
foarte mari, cu bugete exorbitante. Printre aceste facilită ț i putem aminti posibilitatea de a efectua
videoconferin ț e, conectar e la Internet de mare viteză oriunde există o re ț ea de telefonie celulară,
posibilitatea de a lucra în echipă la documente sau proiecte din loca ț ii fizice diferite, posibilitatea de
a avea o imagine în timp real a situa ț iei tuturor ma ș inilor unei firme, backup la sistemul contabil în
timp real ș i lista poate con tinua.
2
Ideea pe care doresc să o subliniez se referă la faptul că tehnologii care în urma cu câ ț iva ani
erau folosite numai în cadrul firmelor de IT sau dezvoltatoare de solu ț ii informatice se regăsesc azi
în idei de business care nu au nicio legătură cu domeniul IT. Firme de taximetrie folosesc tablete
pentru a cunoa ș te în timp real pozi ț ia fiecărei ma ș ini, unele chiar folosesc aceste poziții în tandem
cu algoritmi software pentru a determina cui îi este trimisă următoarea comandă, în funcție de
disponibilitate ș i de dista nta până la locul unde se află clientul. Marea majoritate a firmelor mici
care încearcă să implementeze solu ț ii de acest gen încearcă să ob ț ină beneficii reale cu costuri cât
mai mici, cum ar fi reducerea costurilor operative, fidelizarea clien ț ilor printr-o mai bună
comunicare ș i prin imbu nătă ț irea calită ț ii serviciilor sau, nu în ultimul rând, un mai bun control
asupra pierderilor rezultate din neglijen ț ă, lipsa de productivitate sau diferite forme de fraudă.
Am luat ca model o firmă care administrează mai multe vehicule ș i dispune de un buget
foarte limitat în acest sens. Aceasta poate fi o firmă care are ca obiect de activitate furnizarea de
servicii, distribu ț ie, curie rat sau poate fi un restaurant care dore ș te să ș tie în cât timp se întoarce cea
mai apropiată ma ș ină care a plecat să facă 3-4 livrări la domiciliu la adrese diferite. Cunoscând
detalii precum pozi ț ia fiecărei ma ș ini ș i ora estimativă la care aceasta se va întoarce, se poate face
planificarea astfel încât următoarea comanda să nu fie livrată rece, dar să nici nu dureze prea mult
până când ajunge la clientul care probabil, de cele mai multe ori, comandă constant mâncare din
acel loc. Acesta poate fi o idee de fidelizare a clientelei ș i, totodata, un mod de a fi cu un pas în fa ț a
unor întreprinzători mai reticen ț i la solu ț iile digitale ș i care preferă modele de afaceri mai clasice.
Proiectul de fa ț ă este constituit în prima sa parte dintr-un studiu de caz efectuat în încercarea
de a găsi o solu ț ie de tracking GPS pentru o firmă similară cu cea descrisă în paragraful anterior.
S-au căutat solu ț ii gratuit e sau solu ț ii care să nu implice costuri recurente suplimentare celor pentru
serviciul de date de pe telefon sau tableta utilizată. Orice dispozitiv mobil conectat la Internet
presupune un cost pentru serviciul de date, însă majoritatea furnizorilor de aplica ț ii de urmărire a
flotei ( fleet tracking ) percep un cost lunar suplimentar pentru acel serviciu. Am decis evitarea
adoptării unei solu ț ii de acest gen ș i, în urma studiului de caz, am ajuns la ideea de a implementa o
aplica ț ie care oferă o func ț ie simplă de tracking ș i la care se mai pot adaugă alte func ț ionalită ț i, în
functie de nevoile beneficiarului.
În cea de-a doua parte a licen ț ei este prezentată implementarea solu ț iei, implementare care
are, la rândul ei, două părti ș i anume implementarea aplica ț iei mobile care se instalează pe
dispozitivul cu Android, ș i implementarea aplica ț iei web, care afi ș ează în timp real
administratorului sau coordonatorului informa ț ii despre vehicule.
Am ales sistemul Android dată fiind ponderea extrem de mare pe pia ț ă a dispozitivelor care
rulează acest sistem de operare ș i a faptului că publicarea aplica ț iei pe Google Play Store, portalul
de aplica ț ii condus de Google, este mult mai u ș oară decât opera ț iunea similară pentru o aplica ț ie
dezvoltată pentru dispozitive Apple. De asemenea, am luat în calcul ș i costurile dispozitivelor
mobile – cele care rulează Android tind să coste o frac ț iune (în cazul în care nu este vorba de
3
dispozitive high end) din costul celor produse de Apple, care rulează sistemul de operare proprietar
Apple, iOS.
În concluzie, sistemul de operare Android pentru dispozitive mobile, pre ț ul tot mai accesibil
al dispozitivelor care rulează această platforma, precum ș i faptul că este open source , conferă
dezvoltatorului o solu ț ie extrem de facilă ș i flexibilă pentru dezvoltarea de produse adresate
afacerilor de talie mica sau care sunt la început, mai ales în contextul în care serviciile de localizare
GPS, serviciul Google Maps, precum ș i alte op ț iuni ș i servicii sunt puse la dispozitie gratuit, pentru
o utilizare în regim rezonabil.
4
Capitolul 1 – Tehnologii utilizate pentru dezvoltarea de aplica ț ii mobile
Pentru a avea o imagine corectă asupra modului în care au luat avânt aplica ț iile mobile,
trebuie urmărite următoarele aspecte:
1. Evolu ț ia World W ide Web-ului
2. Evolu ț ia utilizării telefoanelor mobile
Cele două au evoluat în paralel până în momentul în care cre ș terea lungimii de bandă pentru
dispozitivele mobile ș i transformarea telefoanelor în mini-calculatoare, care a dus la mai mult decât
intersec ț ia lor. A fost creat un mediul propice pentru dezvoltarea de aplica ț ii mobile care să utilizeze
servicii de pe web, fără probleme cauzate de viteză sau costuri prea mari. Numărul de utilizatori a
crescut exponen ț ial, deoa rece nu mai are limitat de accesul la un desktop. Aplica ț iile mobile care
rulau pe telefoanele inteligente puteau fi accesate la orice oră, din orice loca ț ie. Programatorii au
sim ț it schimbarea ș i au început să dezvolte aplica ț ii native pentru sistemele de operare ale
telefoanelor inteligente. O nouă pia ț ă s-a născut: cea a aplica ț iilor mobile. Google Store, Apple
Store sunt platforme care permit publicarea ș i achizi ț ionarea de aplica ț ii pentru dispozitivele
mobile.
1.1 Evolu ț ia World Wid e Web-ului
Este greu de crezut că au trecut doar 25 de ani de la apari ț ia World Wide Web-ului, acum,
într-o epocă în care prima pornire este să verifici pe Google, în care informa ț ia abundă ș i este doar
la un click distan ț ă, în care dic ț ionarele sunt online, hăr ț ile sunt actualizate cu situa ț ia traficului în
timp real, într-o perioadă în care no ț iunea de virtualitate face parte din vocabularul uzual.
În anul 1989, Sir Tim Berners-Lee făcea prima propunere a ceea ce urma să fie WWW-ul,
într-o perioadă în care lucra la CERN, Organiza ț ia Europeană pentru Cercetare Nucleară. Respinsă
ini ț ial, în varianta din octombrie 1980, propunerea con ț inea cele trei tehnologii fundamentale care
continuă să fie baza Web-ului actual:
1. HTML – Hypertext Markup Language – limbajul de marcare pentru Web
2. URI – Uniform Resource Identifier – adresă unică utilizată pentru identificarea fiecărei
resurse pe web
3. HTTP – Hypertext Transfer Protocol
Tim Berners-Lee a creat primul editor / browser pentru paginile Web (WorldWideWeb.app)
ș i primul server Web (httpd). Până la sfâr ș itul anului 1990, prima pagină Web a fost livrată pe
5
Internet, iar în anul 1991, oameni din afara CERN-ului au fost invita ț i să se alăture comunită ț ii
Web.
Pe măsură ce Web-ul a început să crească, creatorul lui a realizat că adevăratul poten ț ial al
Web-ului putea fi atins doar dacă oricine putea să-l folosească, fără a cere permisiunea sau a plăti
pentru asta:
“Dacă tehnologia (care sta la baza Web-ului) ar fi fost proprietate privată ș i sub controlul
meu, probabil că nu ar fi cunoscut o asemenea amploare. Nu po ț i propune ceva care se vrea a
constitui un spatiu universal ș i, în acela ș i timp, să păstrezi contro lul complet asupra lui.”
Tim s-a mutat de la CERN la MIT (Massachusetts Institute of Technology) în anul 1994 ș i a
înfiin ț at W3C (World Wide Web Conso ț ium), o comunitate interna ț ională al cărei interes era
dezvoltarea de standarde web deschise. La ora actuală, Sir Tim Berners-Lee continuă să fie
Directorul acestui consor ț iu. (“History of the Web,” n.d.) . 1
Accesarea WWW-ului se face prin intermediul unei conexiuni la Internet, iar statisticile
publicate în 2016 de către InternetLiveStats.com, arată că numărul de utilizatori conecta ț i la Internet
a crescut de la sub 500.000 în anul 2000, la peste 3 miliarde în anul 2016 (“Number of Internet
Users (2016) – Internet Live Stats,” n.d.) . 2
Cre ș terea număru lui de utilizatori cu acces la Internet, faptul că World wide Web-ul a rămas
o tehnologie gratuită, că s-a bazat pe o metodologie simplă de a partaja documente prin intermediu
Internetului, trecerea telefoanelor mobile spre telefoane inteligente care a dus la rezultatul că
Web-ul nu a mai fost limitat la utilizarea doar de pe calculatoare, faptul că în ultimii ani au apărut
standarde ș i aplica ț ii care permit dezvoltarea de aplica ț ii mobile-first, toate acestea au dus la un
boom al WWW-ului, după cum poate fi observat ș i în Figura 1, un infograph care con ț ine evolu ț ia
web-ului din anul 1991 ș i până în 2012, publicat la http://www.evolutionoftheweb.com/ .
1 “History of the Web.” World Wide Web Foundation . Web. 19 June 2016
2 “Number of Internet Users (2016) – Internet Live Stats.” , Web. 19 June 2016
6
7
Acela ș i site web ne oferă ș i o imagine a evolu ț iei numărului de utilizatori ai Internet-ului,
prezentată în Figura 2. Se poate observa că, în 21 de ani de la apari ț ia web-ului, numărul de
utilizatori a ajuns la 2,27 de miliarde de utilizatori.
Una dintre cele mai cunoscute previziuni cu privire la evolu ț ia utilizării Internetului pe
dispozitivele mobile, a fost cea făcută de Mary Meeker, în anul 2009. Aceasta estima că în anul
2014, utilizarea Internetului de pe dispozitivele mobile va depă ș i utilizarea Internetului de pe
desktop (Ingram, n.d.) . Din statisticile publicate de comScore, se poate observa că realitatea s-a 3
apropiat de estimări (“Mobile marketing statistics 2016,” 2016) , numărul de utilizatori care se 4
conectează la Internet de pe telefonul mobil fiind mai mare decât numărul de utilizatori care
accesează Internetul de pe dispozi ț ive de tip desktop.
3 Ingram, Mathew. “Gigaom | Mary Meeker: Mobile Internet Will Soon Overtake Fixed Internet.”, n.d. Web.
18 June 2016
4 “Mobile Marketing Statistics 2016.” Smart Insights ., 27 Apr. 2016.
8
1.2 Evolu ț ia telefoanelor mobile
Telefoanele mobile au fost ini ț ial create pentru a putea fi folosite din automobile.
Prima convorbire telefonică de pe un telefon mobil a fost făcută în 3 Aprilie 1973, când Martin
Cooper, inginer la Motorola, a telefonat unei companii de telecomunica ț ii rivale ș i i-a informat că
vorbe ș te de pe un telefon mobil. Telefonul pe care l-a utilizat Cooper avea 1.1 kg ș i dimensiunile
228.6x127x44.4mm. Acest prototip permitea o conversație de 30 de minute ș i necesita 10 ore
pentru a se încărca.
În 1983, Motorola a lansat primul telefon mobil comercial, cunoscut sub numele de
Motorola DynaTAC 8000X. Dispozitivul permitea convorbiri de 30 de minute, 6 ore de standby ș i
putea stoca până la 30 de numere. ș i costa 4000$. (“The History of Mobile Phones From 1973 To
2008: The Handsets That Made It ALL Happen,” n.d.) 5
Înainte de apari ț ia telefonului DynaTAC 8000X, mai multe evolu ț ii majore au deshis calea
către primul telefon mobil. Astfel, în timpul primului război mondial, armata germană a testat
telefoane fără fir pe trenuri care circulau între Berlin ș i Zossen. în timpul celui de-al doilea război
mondial, for ț ele armate din toată lumea au utilizat legăturile telefonice radio. Începând cu anul
1940, receptoarele radio portabile au fost disponibile la scară largă. Toate aceste tehnologii au
inspirat cercetătorii de la Bell Labs să creeze un telefon portabil pentru automobile. în 1946, Bell
Labs a început să ofere servicii telefonice pe vehiculele din St. Louis, Missouri. Câteva săptămâni
mai târziu, AT&T a venit cu o contra-ofertă, un serviciu denumit Serviciu Telefonic Portabil, care
consta într-o gamă largă de servicii pentru dispozitive portabile, în general incompatibile, care
ofereau zone de acoperire limitate ș i un număr redus de canale disponibile.
În cele din urmă, AT & T ș i Bell Labs au introdus tehnologia celulară, ceea ce a permis
reutilizarea frecven ț elor în zonele acoperite de către transmi ț ătoarele de mică putere. Acest lucru a
permis telefoanele mobile să fie mai mult decât un vis: ele au devenit un produs fezabil din punct de
vedere economic, care ar putea fi profitabil pentru Bell ș i AT & T.
Între 1957 ș i 1961, inventatorul sovietic Leonid Kupriyanovich a dezvoltat o serie de telefoane
mobile care semănau surprinzător de mult cu telefoanele mobile moderne. Unul dintre telefoanele
lui Leonid cântărea 70 de grame.
Serviciu Telefonic Portabil, lansat de AT&T în 1949, necesita pentru func ț ionare instalarea
unui echipament de 36kg în automobil, existau doar 3 canale, ceea ce însemna că doar 3 clien ț i din
orice ora ș puteau ini ț ia o convorbire la un moment dat ș i era foarte scump. (“History of Cell Phones
-,” n.d.) 6
La începutul anilor 1990 au intrat pe scenă ș i Nokia ș i NEC. Primul telefon mobil lansat de
Nokia, Mobira Cityman 900, cântărea 800g. La sfâr ș itul anilor 1990, telefoanele mobile au început
să devină frecvente.
5 “The History of Mobile Phones From 1973 To 2008: The Handsets That Made It ALL Happen.” Know
Your Mobile ., Web. 20 June 2016
6 “History of Cell Phones -.” N.p., n.d. Web. 20 June 2016
9
O evolu ț ie vizua lă a felului în care au arătat telefoanele mobile de-a lungul anilor este
prezentată în următoarea figură (preluată de pe http://www.dreamstime.com/):
Diferite studii publicate la sfârșitul anului 2015, prezintă evoluția uimitoare a Internetului, a
telefoniei mobile ș i a utili zării dispozitivelor mobile. Astfel:
● În 2015 arată că existau peste 2 miliarde de utilizatori de telefoane inteligente ș i că 83% din
conexiunile la Internet sunt realizate de pe dispozitive mobile. (Srivastava, 2014) 7
● Numărul de abonamente la telefonie mobilă a crescut de la 738 de milioane în anul 2000 la
peste 7 miliarde în anul 2015, potrivit raportului publicat de Uniunea Internațională a
Telecomunicațiilor. ( ICT Facts&Figures, The World in 2015 , n.d.) 8
● Numărul de conexiuni la Internet a crescut de la 400 de milioane în anul 2000, la 3.2
miliarde până la sfârșitul anului 2015, un număr cu atât mai promițător cu cât 2 miliade de
utiliyatori fac parte din țările în curs de dezvoltare. (Nair, 2015) 9
7 Srivastava, Anshul. “2 Billion Smartphone Users By 2015: 83% of Internet Usage From Mobiles [Study].”
Dazeinfo . N.p., 23 Jan. 2014. Web. 20 June 2016
8 ICT Facts&Figures, The World în 2015 ., Web. 23 June 2016
9 Nair, Rajeesh. “Internet & Mobile Phone Users Worldwide 2015: 50% Population Is On Internet
[REPORT].” Dazeinfo , 27 May 2015. Web. 23 June 2016
10
1.3 Sistemele de operare ale telefoanelor inteligente. Prezentare Generală. Compara ț ie
Sistemele de operare pentru mobile sunt sisteme de operare care func ț ionează pe telefoane
inteligente, PDA-uri, tablete ș i alte dispozitive mobile. Principalele sisteme de operare mobile sunt:
Android (Google), iOS (Apple), Windows Phone (Microsoft), RIM Bada ș i Symbian.
Potrivit statisticilor publicate de GSMA Intelligence, la ora actuală sunt peste 4.5 miliarde
de abona ț i unici la un serviciu de telefonie mobilă, jumătate din popula ț ia lumii are un abonament
pentru telefonie mobilă, fa ț ă de 1 din 5, cum era acum 10 ani. (“The Mobile Economy 2015,” n.d.)
10
Android
Firma Android Inc. a fost fondată de Andy Rubin, fost inginer la Apple (“Android History,”
2015) . Concentrându-se pe cea mai bună experien ț ă web pe care ar putea-o oferi ș i creând un 11
mediu în care orice dezvoltator ar putea lucra, Android a avut un plan de afaceri solid în momentul
în care l-a prezentat în fa ț a investitorilor, în 2005. Page ș i Brin, fondatorii Google, aveau nevoie de
un telefon care să concureze cu Microsoft ș i Blackberry ș i, în acela ș i timp î ș i doreau mai multe
telefoane care să aibă Google ca motor de căutare implicit. O platformă deschisă ca Android le
oferea exact aceste lucruri. Mai multe prototipuri au fost proiectate ș i respinse până când modelul
G1 a fost finalizat ș i lansa t, în anul 2008.
Cu toate că nucleul Android OS este open-source (cu sursă deschisă), o mare parte a
sistemului de operare nu este. Aplica ț iile Google incluse pe majoritatea telefoanelor Android
vândute în Occident sunt cu sursă închisă.
iOS
iOs este sistemul de operare ale telefoanelor iPhone. Primul iOS a apărut în anul 2007, nu a
oferit suport pentru copy/paste, 3G, ata ș are fi ș iere la email, MMS ș i nu permitea func ț ionarea
aplica ț iilor externe. Actu alizările ulterioare au inclus iTunes Music Store, permi ț ând utilizatorilor,
pentru prima dată, achizi ț ionarea de melodii direct de pe telefon (prin intermediul unei conexiuni
WIFI) ș i schimbarea tonului de apel. Începând cu 2007, în fiecare an a apărut o nouă versiune de
iOS. Versiunea din 2015, iOS 9, a venit cu o serie nouă de caracteristici, printre care: durată mai
lungă de via ț ă pentru baterie, noul rol al lui Siri ca asistent de căutare ș i o nouă tastatură. (Williams,
2015) 12
Windows Phone
Primul Windows Phone, în varianta în care este cunoscut la ora actuală, a fost lansat în anul
2010 la Barcelona ș i este rezultatul colaborării dintre Microsoft ș i Nokia. Începând cu această
10 “The Mobile Economy 2015.” GSMA Intelligence , Web. 20 June 2016
11 “Android History.” Android Central , 21 Oct. 2015. Web. 19 June 2016
12 Williams, Rhiannon. “Apple iOS: A Brief History.” Telegraph.co.uk , 17 Sept. 2015. Web. 20 June 2016
11
variantă, sistemul de operare a fost regândit pentru dispozitive mobile, diferen ț iindu-se complet de
varianta pentru desktop. Dispozitivele pe care rulează sistemul de operare sunt produse de Nokia.
(Guru & Guru, 2012) 13
Potrivit statisticilor publicate de Statistica.com, cel mai popular sistem de operare pentru
dispozitive mobile este, de câ ț iva ani, Android, urmat de iOS (“Global smartphones sales by
operating system 2009-2015 | Statistic,” n.d., “Smartphone OS global market share 2009-2016 |
Statistic,” n.d.) : 14 15
13 Guru, and Guru. “Top 10 Mobile Phones Operating Systems.” ShoutMeLoud 23 Aug. 2012. Web. 20 June
2016
14 “Global Smartphones Sales by Operating System 2009-2015 | Statistic.” Statista , Web. 19 June 2016
15 “Smartphone OS Global Market Share 2009-2016 | Statistic.” Statista , Web. 18 June 2016
12
1.4 Publicarea aplica ț iilor mobile
Există o diferen ț ă de abordare majoră între cum sunt livrate aplica ț iile mobile prin
intermediul Google Play ș i a ehivalentului său – Apple Store. Pentru a publica o aplica ț ie pe Google
Play regulile sunt mult mai relaxate decât în cazul Apple Store, ceea ce poate fi privit ca un avantaj
(viteză de publicare mult mai mare), dar ș i ca dezavantaj (aplica ț iile nu sunt verificate riguros).
1.4.1 Publicarea aplica ț iilor pe Google Play
Condi ț iile pentru a publica o aplica ț ie pe Google Play sunt urmatoarele (potrivit
informa ț iilor publicate pe site-ul https://developer.android.com/distribute/googleplay/start.html ):
1. Înregistrarea pentru un cont de Editor
a. Navigarea pe site-ul https://play.google.com/apps/publish/signup/
b. Introducerea informa ț iilor de bază despre dezvoltator (aceste informa ț ii pot fi
modificate ulterior)
c. Citirea ș i acceptarea Acordului de Distribuire pentru Dezvoltatori pentru ț ara
dezvoltatorului.
d. Plata unei taxe de înregistrare de 25$.
e. După verificarea înregistrării, dezvoltatorul este notificat prin intermediul adresei de
email introduse la înregistrare.
2. Configurarea unui cont Google pentru plă ț i, în cazul în care se va dori comercializarea
aplica ț iilor publica te
a. Intrarea în cont, la adresa https://play.google.com/apps/publish/
b. Navigarea către pagina Financial Reports
c. Click pe Setup a Merchant Account Now (Configura ț i un cont de comerciant)
3. Explorarea consolei Google Play pentru dezvoltatori, precum ș i a uneltelor de publicare.
Odată creat contul ș i verificată înregistrarea, dezvoltatorul se poate conecta la consola
Dezvoltatorului (Developers Console), care este punctul de plecare pentru opera ț iile de publicare a
aplica ț iilor.
1.4.2 Publicarea aplica ț iilor pe Apple Store
Fiecare aplica ț ie care se dore ș te a fi publicată este supu să unei recenzii bazate pe criterii
tehnnice, de con ț inut ș i de design. Aceste criterii ar trebui avute în vedere în momentul dezvoltării
aplica ț iei ș i ele sunt disponibile la următoarea adresă:
https://developer.apple.com/app-store/review/guidelines/ .
13
Pe site-ul Apple este prezentată o listă de pa ș i care ar trebui urma ț i pentru a dezvolta aplica ț ii pentru
iOS, OS X, watchOS, and tvOS ( https://developer.apple.com/app-store/submissions/ ).
Ace ș tia sunt:
1. Dezvoltarea aplica ț iei folosind Xcode 7 ș i ultima variantă de SDK
2. Actualizarea la ultima variantă a sistemului de operare
3. Dezvoltarea urmând ghidul de revizuire a aplica ț iei
4. Optimizarea aplica ț iei
5. Testare Beta
6. Trimitere spre verificare
Informa ț iile oferit e de Apple sunt mult mai vaste, cuprinzând ș i strategii de alegere a unui
model de business, de atragere a utilizatorilor, de marketing.
Aplica ț ii open-source
Multă lume confundă programele / aplica ț iile open-source (sau cu sursă deschisă) cu
aplica ț iile gratuite, dar diferen ț a dintre ele este majoră. Este adevărat că amândouă îi oferă
utilizatorului interesat posibilitatea de a utiliza aplica ț ia fără a plăti, dar în cazul aplica ț iilor gratuite,
asta este tot ceea ce îi oferă, pe când în cazul aplica ț iilor cu sursă deschisă, utilizatorului îi este
oferită gratuit ș i sursa, pe ntru a o utiliza cum crede de cuviin ț ă.
14
Capitolul 2 – Aplica ț ii de tracking GPS pentru dispozitive Android
Prezentul studiu de caz vizează alegerea unei aplicații de tracking GPS pentru o afacere care
iși doreste un mai bun control asupra vehiculelor și/sau contractorilor implicați în activitatea
economică. Datorită avantajelor pe care le oferă platforma Android, avantaje prezentate în capitolul
anterior, am optat pentru această platformă, considerând ca este solu ț ia cea mai potrivită pentru
oricare dintre cele două abordări: alegerea unui sistem existent sau dezvoltarea unui sistem nou.
Sistemul implementat presupune ca fiecare vehicul să con ț ină un dispozitiv Android (telefon sau
tabletă). Această abordare prezintă ș i un avantaj de cost, astfel, dacă un anume utilizator folosește
deja un dispozitiv pe care rulează Android necesitatea investiției suplimentare în hardware odată cu
folosirea noii tehnologii se anulează.
Printre criteriile pe care le-am urmărit sunt în primul rând facilitățile funcționale, ușurința în
implementare, ușurința în utilizare ș i, în mod evident, prețul.
Aplica ț ia ideală, a r oferi, la un cost cât mai competitiv, următoarele:
● Locația dispozitivului în timp real, cu acuratețe geografică de 50 de metri, în eșantioane
de timp de maxim 5 minute
● Afișarea în timp real a poziției mai multor dispozitive din acela ș i grup; o facilitate utilă
dar de importanță secundară ar consta în abilitatea supervizorului de a organiza
dispozitivele în subgrupuri distincte, după criterii variabile în funcție de necesitățile
caracteristice fiecărei situații, de la caz, la caz
● Afișarea în timp real a vitezei de deplasare a fiecărui dispozitiv
● Generarea rutei pe care un dispozitiv a parcurs-o intr-un interval de timp furnizat de
către supervizor ca date de intrare
● Posibilitatea dispozitivului de a transmite informația prin rețeaua celulară sau WIFI, în
funcție de disponibilitate
● Capacitatea dispozitivului de a detecta în timp real starea conexiunii la internet ș i a
determina daca informațiile au fost transmise cu succes serverului care stocheaza
istoricul deplasărilor; în cazul lipsei conexiunii la internet sau a lipsei unei confirmari de
transfer, aplica ț ia trebuie sa fie prevazută cu un algoritm de backup, care să salveze
local activitatea din intervalul în care conexiunea la internet nu a fost disponibila, ș i
apoi, de indata ce conexiunea este reluata, sa transmita serverului informațiile retroactiv
Studiul de caz reprezintă o evaluare în paralel a 3 aplicații deja existente în Google Play App
Store. Am tinut cont în cazul fiecarei aplicații de urmatoarele:
15
● Nota generală a utilizatorilor (Online User Rating)
● Numărul de recenzii
● Numărul de instalări (Play Store afișează în mod public numărul de instalări ale oricărei
aplicații)
● Ușurința de instalare
● Ușurinta în utilizare
● Funcționalitatea (aici am avut în vedere ș i flexibilitatea pe care aplica ț ia o oferă
utilizatorului de a modifica anumiți parametri de funcționare)
● Calitatea interfeței grafice
Având în vedere că nu am găsit aplica ț ii care să se plieze exact pe cerin ț ele enumerate în
paragraful anterior, am plecat de la aplicații care să îndeplinească în primul rând funcția de bază, ș i
anume capacitatea de a- ș i transmite poziția GPS către un server care sa o stocheze intr-o bază de
date.
Cele 3 aplicații alese sunt:
1. Find My Device
2. Cerberus
3. Glympse
2.1 Find My Device
Find My Device este o aplica ț ie care la momentul realizării acestui studiu de caz are nota
4.3 din 5, din peste 430,000 de recenzii în Google Play. Este o aplica ț ie foarte populara, care se
bucură de un real succes printre utilizatorii acestei platforme. Faptul că este dezvoltată chiar de
către Google constituie cu siguranță unul dintre motivele cărora li se datorează succesul enorm,
purtand amprenta gigantului informatic în ceea ce priveste interfața grafică ș i funcționalitatea.
Conform Google Play, aplica ț ia Find My Device a fost instalată de peste 10 milioane de utilizatori.
Privind din poziția publicului țintă caruia i se adresează, această aplica ț ie reprezintă cu
succes ideea de bază care a catalizat popularizarea dispozitivelor inteligente din ultimii ani, în
detrimentul dispozitivelor de tip desktop, ș i anume, simplitate pe toate planurile, funcții relativ
reduse la număr dar puternice prin eficacitate, instalare ușoară, configurări aproape inexistente. La
capitolul “User Friendliness” această aplica ț ie ar putea obține lejer nota maximă.
Revenind la publicul țintă, Find My Device, este o aplica ț ie care se dorește a fi un concurent
direct la adresa aplica ț iei omoloage dezvoltate de competitorul Apple, ș i anume Find my
Iphone/Find my Ipad.
16
Panoul de control al aplica ț iei este web-based ș i se poate accesa la urmatoarea adresă:
https://www.google.com/android/devicemanager?u=0
Odată conectat, utilizatorul are la dispozitie o hartă Google Maps pe care urmează a fi
indicată locația propriului dispozitiv ș i un numar de exact 5 op ț iuni posibile, care sunt
● aflarea locației dispozitivului la un anumit moment dat
● posibilitatea de a comanda dispozitivul să sune în cazul în care utilizatorul nu îl
găsește
● schimbarea de la distanță a codului de acces la dispozitiv, blocarea dispozitivului sau
afisarea pe displayul dispozitivului a unui mesaj stabilit de administrator prin
interfața web
● ștergerea completă a conținutului în cazul în care dispozitivul este considerat pierdut
sau furat
● redenumirea dispozitivului
Având în vedere cele 5 facilități enumerate mai sus, este evident că acest dispozitiv nu
întrunește aproape niciunul dintre criteriile care stau la baza prezentului demers ș i se poate
considera că Find My Device este mai repede o aplica ț ie de securitate decât una de tracking în
adevăratul sens al cuvântului. De fiecare dată când utilizatorul dorește să obțină locația unui
dispozitiv trebuie să solicite acest lucru manual, ceea ce constituie un mare minus în contextul
studiului de față. De asemenea, nu se poate afla dacă dispozitivul este sau nu în mișcare, fapt care
ne duce către concluzia inerentă că posibilitatea aflării vitezei de deplasare este exclusă.
17
Find My Device este, așadar, o aplica ț ie limitată care nu a fost dezvoltată special pentru
tracking. Nefiind o aplica ț ie dedicată acestui scop, precum ș i faptul că prezintă neajunsurile
enumerate mai sus, m-au determinat să notez faptul că această aplica ț ie întrunește principala funcție
dorită, aceea de a-și transmite propria locație GPS ș i cam atât, din ceea ce ne interesează.
2.2 Cerberus
Cerberus este o aplica ț ie care din punct de vedere al func ț ionalită ț ii se aseamănă cu Find My
Device, fiind dezvoltată ca o aplica ț ie de găsire a dispozitivului în cazul în care este pierdut, dar
include un set mai vast de op ț iuni decât cea dezvoltata de Android. Aceste op ț iuni, nu se incadrează
neaparat printre criteriile studiului de caz, dar merită amintite pentru că pot fi utile în cazul utilizării
acestei aplicații în tandem cu o aplica ț ie de tracking dedicată. în continuare vom vedea în primul
rând cât de tare Cerberus se apropie de un astfel de scop ș i anume, GPS tracking.
Instalarea ș i configurarea sunt relativ facile, dupa ce s-a instalat aplica ț ia, se deschide o
fereastra de LogIn, unde utilizatorul are op ț iunea de a- ș i introduce numele ș i parola sau se poate
opta pentru crearea unui cont nou, op ț iune care durează mai pu ț in de un minut, fiind necesare doar
numele utilizator ales, adresa de email ș i parola dorita. De men ț ionat este faptul că odată creat acest
cont în aplica ț ia de pe dispozitivul mobil, se potate folosi acela ș i set nume/parola pentru conectarea
la interfa ț a web. Cu alte cuvinte, accountul se creează de pe tableta ș i se poate accesa ulterior ș i prin
web. Acest aspect u ș urează mult utilizarea aplica ț iei ș i scurteaza mult timpul de la instalare până la
prima funcționare a dispozitivului.
În momentul în care utilizatorul interfeței web se conectează, acesta are la dispoziție
comenzile “Start tracking” ș i “Stop tracking”. ceea ce înseamnă că tracking-ul unui anume
18
dispozitiv conectat la acel cont trebuie pornit manual, iar după un interval anume de timp, această
funcție se dezactivează automat. Mai exact, dupa 5 minute de inactivitate, interfața web se închide
automat, moment în care ș i func ț ia de tracking a dispozitivulu i este imediat dezactivată. Acest
aspect aduce cu sine incapacitatea de a folosi func ț ia de tracking în fundal, pentru a păstra o istorie
permanentă a rutei parcurse. În aceasta aplica ț ie, spre deosebire de precedentă, avem totu ș i op ț iunea
de a genera un istoric al rutei parcurse într-un interval de timp selectat de utilizator.
Afi ș area în timp real a vitezei de deplasare nu este însă o op ț iune, la fel cum nu apare nici în
rapoartele generate ulterior. Viteza de deplasare ar constitui un real plus, dar chiar ș i în absen ț a
acesteia, faptul că putem genera un istoric al rutei parcurse constituie un pas înainte fa ț ă de Find My
Device. Un alt minus, din perspectiva mea, îl constituie faptul că, de ș i se poate genera un istoric al
rutei parcurse, acesta este unul în mod grafic, ș i nu oferă op ț iunea translatării loca ț iilor în adrese
reale prin Reverse Geocoding, astfel încât această colec ț ie de informa ț ii să poată fi exportată mai
apoi în format CSV sau orice alt format care poate fi manipulat în Excel sau importat într-o altă
aplica ț ie ș i care să con ț ină adrese reale, inteligibile. Consider că op ț iunea de a putea genera un astfel
de raport CSV ar constitui o facilitate foarte puternică. Pe de altă parte nu trebuie scăpat din vedere
faptul ca această aplica ț ie nu a fost concepută ca una de “fleet tracking”.
În figura de mai jos se poate vedea modul în care istoricul rutei este afișat.
Figura de mai sus afi ș ează istoricul loca ț iilor pe o harta Google standard, putându-se opta ș i
pentru Sattelite View dacă se dore ș te.
Printre func ț ional ită ț ile acestei aplica ț ii care merită amintite se numără câteva chiar foarte
utile, în ceea ce privește securitatea dispozitivului, ș i anume:
● posibilitatea de a bloca dispozitivul de la distan ț ă cu un cod diferit de cel prestabilit
● executarea de backup de la distan ț ă
19
● folosirea camerei tabletei/telefonului pentru a fotografia persoana care operează
dispozitivul în acel moment
● afi ș area un ui mesaj de alertă / urgen ț ă pe ecran
● efectuarea de capturi ale display-ului
● ș tergerea întregului con ț inut al tabletei / telefonulu i, inclusiv al cardului SD, pentru a
asigura protec ț ia informa ț iilor stocate pe acesta.
Backup-ul la distan ț ă se poate realiza printr-una din cele două metode puse la dispozi ț ie de
dezvoltatorul aplica ț iei ș i anume, există posibilitatea de conec tare a dispozitivului cu un cont
Google Drive sau Dropbox, astfel încât, în cazul pierderii sau furtului acestuia, utilizatorul poate
comanda de la distan ț ă un backup efectuat chiar într-unul dintre aceste medii de stocare
cloud-based, iar apoi se poate proceda la ș tergerea informa ț iilor de pe dispozitiv, pentru securitate.
După cum men ț ionam mai sus, aceste facilită ț i ș i op ț iuni de func ț ionare nu sunt neapărat specifice
unei aplica ț ii dezvoltate în primul rând pentru tracking de vehicule sau subcontractori anagaja ț i în
activită ț i care implică deplasarea pe teren, cazuri în care tracking-ul în timp real reprezintă o
componentă esen ț ială a m otorului logistic al afacerii.
Figura de mai jos constituie un printscreen de pe dispozitivul mobil de această dată, figură
care afi ș ează o parte din op ț iunile disponibile, inclusiv cele men ț ionate mai sus, referitoare la
posibila conectare la Google Drive sau Dropbox. De asemenea se mai pot observa op ț iuni oarecum
neobi ș nuite, dar totodată nelipsite unei aplica ț ii care se dore ș te a fi luată în considerare în ceea ce
prive ș te solu ț iile pentru securitate, ș i anume “Block Power Menu” ș i “Block Status Bar”. Acestea
permit blocarea op ț iunilo r de oprire / resetare a dispozitivului, precum ș i accesul la meniul de setări
rapide. Aceste op ț iuni se pot dovedi deosebit de utile în situa ț ia în care telefonul sau tableta pe care
rulează aplica ț ia ar cădea în mâini nedorite conferindu-i administratorului aflat în fa ț a interfe ț ei web
posibilitatea de a-si minimiza / limita daunele în urma unui astfel de incident.
Toate aceste facilită ț i amintite pe scurt mai sus nu ne duc neapărat mai aproape de solu ț ia
ideală sau completă pentru problema pe care acest studiu de caz încearcă să o rezolve, dar pot
produce un alt efect, ș i anume unul complementar. În contextul în care tableta sau telefonul pe care
am avea instalată solu ț ia de tracking aleasă ar fi folosite în scop comercial, probabil s-ar impune
securizarea dispozitivului. Este bine ș tiut că în era informa ț ională, foarte multe firme decid să
opteze pentru solu ț ii software ultramobile în activitatea agentilor, subcontractorilor, etc. Aceste
solu ț ii pot include acceptarea comenzilor, înregistrarea de semnături digitale de la clien ț i în
momentul livrării produselor, etc. În acest sens, putem considera Cerberus ca pe o solu ț ie pentru
asigurarea securită ț ii dispozitivului. Pe de altă parte, această aplica ț ie mai detine o op ț iune prin care
prezenta aplica ț ie pe dispozitiv poate fi ascunsă, ceea ce îi poate permite administratorului să
porneasca o monitorizare silen ț ioasă ( silent tracking ), dacă principala aplica ț ie de tracking este
dezactivată.
20
Din punct de vedere al func ț ionalită ț ii ș i al facilită ț ilor oferite, această aplica ț ie este departe
de ceea ce căutam dar, dupa cum precizam anterior, poate constitui o solu ț ie complementară, ș i
anume securizarea dispozitivului cu posibilitatea de tracking în regim de urgen ț ă (în cazul în care
principala solu ț ie de track ing este dezactivată).
21
Avantaje :
● Instalare facilă, extrem de u ș or de creat un nou cont
● Putem ob ț ine un istoric al loca ț iilor
● Multiple op ț iuni de securitate
● Înregistrare audio
● Posibilitatea de silent tracking
Dezavantaje :
● Nu afi ș eaza viteza de deplasare
● Modul de tracking trebuie activat manual ș i func ț ionează doar pe perioada în care
utilizatorul este logat la interfa ț a web
● Istoricul loca ț iilor nu poate fi exportat intr-un format care sa con ț ină adrese fizice în
mod CSV
● Necesită abonare separată
Reluând ideile expuse anterior, concluzionez că Cerberus poate fi mai degrabă o solu ț ie de
scuritate, decât una de tracking dar consider în continuare că poate constitui o alternativă în cazuri
extreme, pentru perioade scurte de timp.
Aplica ț ia Cerberu s a fost descărcată de peste 1.000.000 de utilizatori de pe platforma
Google Play ș i are nota 4.4 din peste 98.000 de recenzii, ceea ce dovede ș te faptul că aplica ț ia se
bucură de notorietate ș i este un produs a cărui func ț ionalitate nu lasa de dorit.
2.3 Glympse
Glympse oferă inclusiv o variantă pentru business, despre care nu există, însă, foarte multe
detalii pe site-ul companiei, în afara unui număr de telefon la care poten ț ialii clien ț i pot apela
departamentul de vânzări al companiei. Pentru scopul acestui studiu de caz, pe parcursul acestei
lucrări, ne vom referi în continuare la varianta gratuită a acestei aplica ț ii.
Glympse este o aplica ț ie extrem de u ș or de instalat de pe platforma Google Play ș i totodată
extrem de u ș or de utiliza t. U ș urin ț a în instalare este observată imediat prin faptul că nu necesită
crearea unui cont online ș i nici autentificarea cu un cont creat în prealabil pe un dispozitiv desktop
sau într-un browser web. Aplica ț ia se instalează ușor, dupa ce este descărcată din Google Play.
Instalarea se face automat, iar când aceasta este completă, utilizatorul trebuie doar să o pornească ș i
din acel moment o poate utiliza fără niciun fel de configurare suplimentară, întrucât la instalare
aplica ț ia cere permisiune a să acceseze aproximativ toate resursele tabletei, atât hardware, cât ș i
software, necesare func ț ionării. Printre acestea se numără accesul la componenta GPS, la contacte,
22
la identitate ș i la conturile la care utilizatorul este deja conectat, în vederea transmisiei loca ț iei, după
cum se poate observa în figura de mai jos.
Aplica ț ia este relativ flexibilă în ceea ce-l prive ș te pe utilizatorul dispozitivului pe care
aceasta se instalează. Acesta oferă posibilitatea de a opta pentru afi ș area vitezei, pentru a folosi
sistemul metric sau pe cel standard, pentru a introduce destina ț ia înspre care se îndreaptă ș i, mai
ales, de a permite aplica ț iei să se conecteze la contul său de Facebook sau Twitter, printre altele.
Aceste op ț iuni aduc cu sine o u ș urin ț ă ș i mai mare în utilizarea aplica ț iei, având în vedere că
transmiterea informa ț iei către destinatari urmează a se face prin intermediul contului de email,
Facebook, Twitter sau altele la care utilizatorul este conectat. Meniul de op ț iuni are o interfa ț ă
simplă, curată, nu este încărcat cu informa ț ii sau op ț iuni care nu sunt necesare, este foarte intuitiv ș i
u ș or de folosit de către un utilizator amator, ceea ce nu putem spune neapărat ș i despre Cerberus.
Aplica ț ia prezentată anterior are câteva op ț iuni puternice de altfel, dar care necesită cuno ș tinte
relativ avansate de utilizare a dispozitivelor mobile pentru a putea fi utilizată pe deplin de către
utilizatorul final. Meniul de op ț iuni al aplica ț iei Glympse poate fi observat în figura de mai jos.
23
U ș urin ț a instalării ș i faptul că nu necesită crearea unui cont, chiar aceste aspecte care, fără
îndoiala, au participat la popularizarea aplica ț iei sunt ș i cele care constituie neajunsuri din
perspectiva mea, având în vedere solu ț ia “de nișă” pe care o caut.
În varianta gratuită, aplica ț ia este extrem de simplu de folosit, utilizatorul poate selecta
op ț iunea “Share Location ” din Meniu, iar apoi este afi ș ată o activitate care prezintă 4 op ț iuni:
● Destinatarii cărora urmează să le fie dezvăluita loca ț ia utilizatorului
● Perioada de timp pentru care loca ț ia să fie disponibilă
● Se poate ata ș a un mesaj către destinatari
● Se poate selecta o destina ț ie finală.
După ce se selectează aceste op ț iuni, în momentul în care se apasă comanda Send aflată în
partea din dreapta-sus a displayului, se generează un link unic ș i dispozitivul începe să î ș i transmită
24
pozi ț ia ș i, după caz, viteza, sau alte informa ț ii selectate din meniul de op ț iuni, către un server al
dezvoltatorului aplica ț iei. Informa ț iile sunt transmise pe toată perioada de timp selectată de către
utilizator sau până în momentul ajungerii la destina ț ie, dacă această op ț iune a fost selectată. Apoi,
utilizatorul trimite acel link unic generat de aplica ț ie către destinatarii care sunt invita ț i să
urmarească pozi ț ia utiliza torului. De notat este faptul că acel link se poate transmite prin Facebook,
Twitter, email, mesaj text, sau se poate copia în clipboard-ul dispozitivului ș i se poate trimite prin
orice altă aplica ț ie care suportă func ț ia de messaging. Un aspec t important îl constituie faptul că
oricine intra în posesia acelui link pe perioada în care acesta este activ ș i poate vedea toate
informa ț iile făcute public e de către utilizatorul care a generat acel link. Figura de mai jos reprezintă
un screenshot al activită ț ii cu cele 4 op ț iuni ș i butonul de Send în dreapta, sus.
Glympse este o aplica ț ie care prezintă mult mai multe op ț iuni decât cele testate anterior,
printre acestea fiind viteza de deplasare, posibilitatea de a transmite mesaje ș i op ț iunea de a
specifica destina ț ia înspre care se indreaptă utilizatorul. Acestea reprezintă reale plusuri în raport cu
celelalte aplica ț ii, însă am constatat un mare minus în ceea ce prive ș te modul în care aplica ț ia este
concepută.
După cum reiese ș i din explicarea caracteristicilor asupra cărora am insistat mai sus,
func ț ionalitatea acesteia este una oarecum inversă unei aplica ț ii clasice de tracking, ș i anume,
utilizatorul care urmăre ș te dispozitivul prin interfa ț a web sau prin intermediul unui alt dispozitiv
mobil este, de fapt, clientul, ș i nu invers. Posesorul dispozitivului este cel care hotără ș te momentul
în care dore ș te să facă publică unuia sau mai multor clien ț i loca ț ia sa, hotără ș te durata pe parcursul
căreia aceste informa ț ii sunt publice, ș i le poate opri oricând prin intermediul op ț iunilor din meniul
aplica ț iei.
25
Am constatat că aplica ț ia este una robustă, simplă ș i extrem de func ț ională, fapt pentru care
se ș i explică atât cele peste 5 milioane de descărcări de pe platforma Google Play, cât ș i nota 4.5 din
cele aproape 100,000 de recenzii ale utilizatorilor. Totodată am constatat că această aplica ț ie nu
oferă posibilitatea unui a ș a numit administrator de grup să urmarească permanent activitatea mai
multor dispozitive în timp real. Acest lucru este posibil doar pentru o perioadă limitată, la ini ț iativa
utilizatorului dispozitivului mobil. Cred că se poate afirma că în scenariul propus la începutul
acestui studiu clientul ar trebui să fie utilizatorul mobil ș i nu invers, a ș a cum se întâmplă în cadrul
aplica ț iei Glympse.
Concluzii
Primele criterii – notă utilizatori (user rating, număr recenzii ș i număr de instalări) sunt
informa ț ii preluate direct de pe platforma Google Play, iar pentru a evalua ultimele 4 caracteristici,
am considerat un sistem de notare de la 1 la 5, unde 5 este cea mai mare notă, iar 1 cea mai mică.
Spre exemplu, la u ș urin ț a de instalare, nota 1 ar însemna o insta lare foarte dificilă, pe când nota 5
presupune o instalare rapidă ș i u ș oară. în mod similar am evaluat ș i u ș urin ț a de utilizare,
func ț ionalitatea ș i interfa ț a grafică.
Nota
Utilizat
ori Nr.
recenzii Nr.
instalari U ș urin ț ă
instalare U ș urin ț ă
utilizare Func ț ion
alitate Interfa ț ă
Grafică
Find My Device 4.3 >434 k >10 mil 5 5 2 5
Cerberus 4.4 >98 k >1 mil 4 3 3 4
Glympse 4.5 >94 k >5 mil 5 5 3 5
Am evaluat aplica ț iile, după cum precizam mai sus, având în vedere 4 criterii care se pot
dovedi subiective. În fond, această evaluare nu se dore ș te a fi una obiectivă, întrucât criteriile
stabilite la începutul evaluării sunt ele însele subiective. O aplica ț ie foarte bine construită poate
avea sau nu o anumită func ț ionalitate cerută de utilizator. Absen ț a unei astfel de func ț ii sau op ț iuni
aduce cu sine, implicit, o nota mai mică.
1. Find My Device este o aplica ț ie extrem de simplă care face foarte bine un singur
lucru din cele care ne interesează, ș i anume afi ș ează în timp real loca ț ia
dispozitivului. Nu există probleme de compatibilitate, aplica ț ia fiind dezvoltată de
Google ș i afișând rezultatele pe o hartă Google. Din cele 7 criterii de evaluare,
26
primele 3 sunt implicite, valorile acestora în toate cazurile fiind luate direct de pe
Google Play.
a. U ș urin ț ă Instalare: 5 – aplica ț ia se instalează foarte u ș or ș i recunoa ș te contul
Google la care este conectată tableta, astfel încât utilizatorul trebuie doar să-l
confime sau să aleagă altul, dacă dore ș te, după instalare.
b. U ș urin ț ă Utilizare: 5 – Utilizarea este extrem de facilă, dat fiind faptul că
setările sunt practic inexistente, utilizatorul neavând acces la nicio op ț iune.
Tocmai absen ț a op ț iunilor îi conferă aplica ț iei un grad de u ș urința extrem de
ridicat în utilizare.
c. Func ț ionalitate: 2 – Principalul criteriu pe care l-am urmărit prin prisma
cerin ț elor problemei; din cele cerute, această aplica ț ie transmite loca ț ia
curentă a dispozitivului ș i nimic altceva. Din acest motiv, am considerat că la
acesta aspect aplica ț ia merită nota 2 din 5.
d. Interfa ț a Grafică: 5 – Aici am notat practic interfa ț a grafică a Google Maps.
2. Cerberus prezintă numeroase alte func ț ii pe lângă transmiterea loca ț iei GPS dar
multe dintre ele sunt altele decât cele specificate în criteriile de la începutul studiului.
a. U ș urin ț ă Instalare: 4 – Utilizatorul are nevoie de un cont la instalare. Dacă
nu are, î ș i poate crea, dar acesta trebuie să existe.
b. U ș urin ț ă Utilizare: 3 – Prezintă setari ș i op ț iuni care se pot dovedi
problematice pentru utilizatorul final, dacă acesta nu este unul experimentat.
c. Func ț ionalitate: 3 – Func ț ia de tracking trebuie activată manual, transmite
istoricul pozi ț iilor dar nu transmite viteza de deplasare, nu oferă op ț iune de
export al istoricului.
d. Interfa ț a Grafică: 4 – aplica ț ia folose ș te harta Google Maps dar
dezactivează op ț iunea de a mări sau mic ș ora harta cu func ț ia de scroll a
mouse-ului.
3. Glympse este o aplica ț ie bună, special concepută pentru tracking. Nu prezintă totu ș i
avantajele scontate întrucât permite utilizatorului să oprească func ț ia de transmitere a
loca ț iei.
a. U ș urin ț ă Instalare: 5 – Instalare extrem de facilă, aplica ț ia nu necesită
niciun cont suplimentar.
b. U ș urin ț ă Utilizare: 5 – Foarte u ș or de configurat, interfa ț ă intuitivă, aspect
curat.
27
c. Functionalitate: 3 – Transmite pozi ț ia în timp real, viteza de deplasare ș i
istoricul loca ț iilor, dar pune aceste func ț ionalită ț i în totalitate sub controlul
utilizatorului tabletei sau telefonului.
d. Interfa ț a Grafică: 5 – Interfa ț a este asigu rată de către Google Maps, include
op ț iunea de afi ș are a traficului în timp real.
În concluzie, toate cele 3 aplica ț ii testate în prezentul studiu folosesc func ț iile GPS
furnizate de mediul Android. Însă nici una dintre acestea nu constituie o solu ț ie de sine
stătătoare la problema enun ț ată, dat fiind faptul că fiecare dintre ele prezintă deficien ț e
constructive. De exemplu, viteza de deplasare, care este un aspect absolut important pentru
scopul unei asemena aplica ț ii, lipse ș te la 2 din cele 3 aplica ț ii testate, iar singura aplica ț ie
care prezintă această func ț ionalitate nu îndepline ș te alte cerințe esen ț iale.
Există pe pia ț ă furnizori de solu ț ii de tracking ș i fleet management, care dispun de
infrastructura dedicată pentru astfel de solu ț ii ș i au dezvoltat aplica ț ii pentru astfel de
scopuri, însă aceste solu ț ii pot deveni extrem de costisitoare, iar obiectul acestui studiu
presupunea găsirea unei solu ț ii gratuite sau extrem de accesibile, pentru firme de dimensiuni
mici, sau întreprinzători care sunt la început de drum ș i, implicit, dispun de un buget limitat.
Având în vedere că toate dispozitivele Android con ț in func ț ia de localizare prin GPS ș i că
Google pune la dispozi ț ie acces la sistemul lor de hăr ț i în mod gratuit, pentru utilizatori cu
un număr rezonabil de interogări pe zi, am considerat că pot găsi sau implementa o solu ț ie
care să reducă sau chiar să minimizeze costurile recurente ale unui astfel de utilizator, cu
resurse limitate.
În continuare, am decis implementarea unui astfel de sistem, în care utilizatorul
dispozitivului Android instalează aplica ț ia, iar aceasta transmite pozi ț ia ș i viteza către o bază
de date aflată pe un server web. Aplicația nu se dorește a fi o soluție completă sau
profesională, însă propune o soluție functională, în jurul căreia se pot dezvolta în continuare
alte aspecte sau facilități. În continuare sunt elaborate câteva principii constructive si metode
care au fost aplicate in dezvoltarea aplicației.
28
Capitolul 3 – Proiectarea ș i implementarea aplica ț iei
În dezvoltarea aplica ț iei m-am axat pe două mari componente:
– aplica ț ia mobilă
– aplica ț ia web
Aplica ț ia mobilă are ca scop transmiterea loca ț iei unui utilizator mobil, pe când aplica ț ia
web are ca scop oferirea unei priviri de ansamblu asupra localizării tuturor utilizatorilor
mobili(client) pe hartă.
Ambele aplica ț ii vor utiliza aceea ș i bază de date, aplica ț ia mobilă pentru a introduce
coordonatele ș oferilor în baza de date, iar aplica ț ia web pentru a extrage aceste informa ț ii ș i a le
afi ș a în browser. Ca urmare a acestui fapt, proiectarea bazei de date a fost primul pas în dezvoltarea
aplica ț iei. La rândul ei, extinderea ș i normalizarea bazei de date se va face pe parcurs, odată cu
cre ș terea numărului de utilizatori. Într-o primă variantă, baza de date con ț ine o singură tabelă, cu
toate informa ț iile ș oferilor, urmând ca în următoare itera ț ie să creez o tabelă separată doar pentru
datele ș oferilor ș i să fac legătura cu tabela care con ț ine informa ț iile legate de traseu. Câmpurile din
tabela creată sunt cele din figura de mai jos:
3.1 Dezvoltarea aplica ț iei mobile
Aplicația mobilă dezvoltată se numește UniTracer. În continuare, de fiecare dată când ne
vom referi, în cadrul acestui proiect, la această aplicație in particular, ne vom referi la UniTracer.
Toate resursele Java pentru acest proiect sunt stocate în folderul \java , în pachetul com.unitracer .
29
Pentru dezvoltarea aplica ț iei mobile am folosit mediul de dezvoltare Android Studio care la
ora actuală este solu ț ia standard pentru dezvoltarea de aplica ț ii Android. Proiectele Android sunt
structurate într-o anume ierarhie. Fi ș ierul AndroidManifest.XML con ț ine pe lângă al ț i parametri ai
aplica ț iei ș i punctul de pornire al acesteia, punct care indică activ itatea care urmează să fie rulată în
momentul în care aplica ț ia este lansată. Acest fi ș ier este localizat în următoarea loca ț ie:
\app\src\main\AndroidManifest.XML . Structura fișierelor în cadrul proiectului se poate observa
în imaginea de mai jos.
Resursele interfe ț ei grafice sunt localizate în folderul “ \src\main\res\layout ”, acestea fiind
scrise in XML. Android Studio con ț ine ș i un editor vizual pentru interfa ț a grafică, având op ț iunea
30
de a comuta din modul vizual în modul text foarte rapid. Fiecărei activită ț i îi corespunde o schemă
(layout) care descrie elementele grafice și de interac ț iune cu utilizatorul, modul în care acestea sunt
dispuse, cum sunt aliniate, precum și funcționalitatea lor. De asemenea, fiecărei activită ț i îi
corespunde o clasă Java care con ț ine logica execu ț iei activită ț ii respective. Fiecare activitate a
aplica ț iei are un layout XML ș i un fi ș ier Java. Fișierele Java se află într-un pachet, în folderul
“ \app\src\main\java ”.
Aceste fi ș iere XML ș i Java sunt conectate între ele, corespondența lor fiind stabilită în
manifestul aplica ț iei, And roidManifest.XML, după cum se poate vedea mai jos.
În tag-ul <application/> primele declarații stabilesc parametri de funcționare (posibilitatea
de backup), android:icon indica pictograma aplicației când este instalată pe dispozitivul mobil și
care totodată este asociată aplicației când aceasta este publicată in Google Play Store. Aceasta,
conform declarației se află în folderul res\drawable și este un fișier imagine cu numele
ic_launcher. De menționat este faptul că există mai multe foldere res\drawable , fiecare dintre ele
conținând un sufix care indică resursele conținute in funcție de rezoluția displayului de pe
dispozitivul pentru care este concepută aplicația. Structura acestor foldere arată în felul urmator:
Dacă aplicația este instalată pe dispozitive cu rezoluții diferite, sistemul va scala resursele
pentru rezoluția nativă a dispozitivului, însă oferă totodată dezvoltatorului opțiunea extrem de facilă
pentru a optimiza interfața grafică in funcție de fiecare familie de display-uri in parte. Spre
exemplu, s-ar putea ca un dezvoltator să vrea să utilizeze diferit spațiul vizual al aplicației când
aceasta rulează pe o tabletă cu display de 10”, față de situația când aceasta este instalată pe un
telefon cu display de 4”. În acest scop, sunt puse la dispoziție aceste foldere, astfel încât resursele
grafice să fie personalizate pentru fiecare familie de display-uri separat, sufixurile “hdpi”, “mdpi”,
“xhdpi “, “xxhdpi” indicând fiecare categoria de resurse grafice pe care le contine folderul
respectiv.
Declarația android :label= "@string/app_name" indică numele aplicatiei, asa cum urmează sa
fie identificată pe telefon sau tabletă, odată instalată, precum și în Google Play Store. Numele
efectiv este stocat în fișierul strings.xml, impreună cu definiții ale altor resurse în mod text. Toate
acestea sunt definite in strings.xml, in folderul \app\src\main\res\values .
Declarația android :theme= "@android:style/Theme.Light.NoTitleBar" indică tematica
grafică pe care aplicația o va folosi pentru ferestre, meniuri și butoane.
31
Declara ț ia < action android :name= "android.intent.action.MAIN" /> din cadrul primului
tag de tip <activity/> semnalează că această activitate este punctul de pornire a aplica ț iei atunci
când este lansată în execu ț ie.
< application
android :allowBackup= "true"
android :icon= "@drawable/ic_launcher"
android :label= "@string/app_name"
android :theme= "@android:style/Theme.Light.NoTitleBar" >
< activity
android :name= "com.unitracer.Splash_activity"
android :label= "@string/app_name" >
< intent-filter >
< action android :name= "android.intent.action.MAIN" />
< category android :name= "android.intent.category.LAUNCHER" />
</ intent-filter >
</ activity >
< activity
android :name= "com.unitracer.Create_account_activity"
android :label= "@string/app_name"
android :windowSoftInputMode= "stateHidden"
android :screenOrientation= "portrait" />
< activity
android :name= "com.unitracer.Track_location"
android :label= "@string/app_name"
android :windowSoftInputMode= "stateHidden"
android :screenOrientation= "portrait" >
</ activity >
< meta-data
android :name= "com.google.android.maps.v2.API_KEY"
android :value= "AIzaSyD6dLL0Z-BRJVNd5H0LzNSRzF4_DCmrI48"
/>
< meta-data
android :name= "com.google.android.gms.version"
android :value= "@integer/google_play_services_version" />
Fiecare aplica ț ie Android con ț ine în mod obligatoriu cel pu ț in o activitate. În func ț ie de ce
func ț ionalită ț i oferă aplica ț ia respectivă, poate avea mai multe activită ț i care sunt apelate în func ț ie
de ce selectează utilizatorul sau în funcție de cum decurge execu ț ia. Numai o activitate poate fi
activă la un moment dat, existând un așa numit Activity_Lifecyle , ilustrat foarte bine în imaginea de
mai jos. În momentul în care o anume activitate este lansată, este automat apelată o secven ț ă de
metode în ordinea sugerată de schema Activity_Lifecycle , ș i anume, mai întâi este apelată metoda
32
onCreate (), urmata de metoda onStart () si apoi onResume (), urmând ca apoi aplica ț ia să fie activă ș i
în prim plan.
Se poate observa în schemă că dacă sistemul afi ș ează un mesaj de alertă sau o notificare cu
prioritate mai mare apare în prim plan, activitatea curentă trece în fundal, chiar dacă este încă
vizibilă, moment în care este automat apelată de către sistem metoda onPause (). O observa ț ie care
merită notată aici este faptul că, odată ce activitatea intră în aceasta stare, dacă sistemul decide că
trebuie sa elibereze memorie pentru alte procese cu prioritate mai ridicată, acesta poate decide
oprirea completă a activită ț ii, caz în care orice date sau informa ț ii ob ț inute în urma evolu ț iei
33
activității vor fi pierdute, dacă nu sunt salvate în prealabil. Acesta este motivul pentru care, de
obicei, dezvoltatorii de aplica ț ii aleg să implementeze la începutul acestei metode instruc ț iuni de
salvare a informa ț iilor pe care activitatea le prelucrează pe suportul de stocare al dispozitivului. De
re ț inut de asemenea că, dacă este vorba de cantită ț i relativ mari de informa ț ii, se recomandă
salvarea acestora concomitent cu derularea aplica ț iei pentru a se proteja integritatea lor ș i pentru a
nu încetini dispozitivul în momentul în care sunt afișate alerte de către sistem.
Metoda onStop () este apelată atunci când activitatea nu mai este vizibilă, de exemplu când
utilizatorul navighează către o altă aplica ț ie sau atunci când apasă pe butonul Home . Metoda
onDestroy () este apelată când activitatea este fie oprită prin comanda din interiorul aplica ț iei, fie
când sistemul decide să o termine pentru a elibera memorie.
Activitatea principală, care este pornită din oficiu, când aplicația este lansată în execuție este
Splash_activity , implementată în fișierul Splash_activity.java. In cadrul acestei clase este de
asemenea implementată o altă clasă MyReceiver care extinde clasa BroadcastReceiver (), care este
o clasa din pachetul android.content . Aceasta clasa implementeaza metode pentru receptionarea
intent-urilor trimise prin sendBroadcast(intent). În cadrul UniTracer, acestea sunt implementate în
clasa MyLocationListener si sunt explicate mai jos.
class MyReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
Log. i ( "Receiver" , "Broadcast received: " + action);
if (action.equals( "Hello.World" )){
latitute =intent.getExtras().getString( "Latitude" );
longitude =intent.getExtras().getString( "Longitude" );
typevalue =getSharedPreferences( USER_TYPE_VALUES , MODE_PRIVATE );
type_editor = typevalue .edit();
type_editor .putString( "latitude" , latitude );
type_editor .putString( "longitude" , longitude );
type_editor .commit();
}
}
}
Această clasă suprascrie metoda onReceive(Context context, Intent intent), în implementare
stocând informa ț iile prim ite prin parametrul intent în variabila action , apoi se verifică dacă
intent-ul con ț ine String-u l “Hello.World”, care este de fapt o constantă transmisă ca parametru
34
atunci când intent-ul a fost creat în cadrul clasei LocationService; declara ț ia acesteia este prezentată
în codul de mai jos.
public class LocationService extends Service
{
public static final String BROADCAST_ACTION = "Hello.World" ;
private static final int TWO_MINUTES = 1000 * 60 * 2 ;
public LocationManager locationManager ;
public LocationListener listener ;
public Location previousBestLocation = null ;
Intent intent ;
int counter = 0 ;
@Override
public void onCreate()
{
super .onCreate();
intent = new Intent( BROADCAST_ACTION );
}
@Override
public void onStart(Intent intent, int startId)
{
locationManager = (LocationManager)
getSystemService(Context. LOCATION_SERVICE );
listener = new MyLocationListener();
locationManager .requestLocationUpdates(LocationManager. NETWORK_PROVIDER ,
4000 , 0 , listener );
locationManager .requestLocationUpdates(LocationManager. GPS_PROVIDER , 4000 ,
0 , listener );
}
Apoi, prin urmatoarele linii de cod,
latitute =intent.getExtras().getString( "Latitude" );
longitude =intent.getExtras().getString( "Longititude" );
sunt extrase din intent informațiile care conțin latitudinea și longitudinea locației geografice
transmise, prin metoda getExtras().getString. Informațiile sunt stocate în intent sub forma unor
perechi de genul (key, value), unde key-ul este un text (in acest caz "Latitude" sau "Longitude" ,
iar valorile returnate sunt de tip String, pentru ca au fost salvate ca String atunci când au fost puse în
intent (vezi pagina 36), clasa MyLocationListener.
Pentru reprezentarea loca ț iilor geografice, sistemul Android pune la dispoziție clasa numită
Location , din pachetul android.location . Obiectele generate de aceasta clasă pot con ț ine atribute
op ț ionale cum ar fi direc ț ia, altitudinea, viteza ș i altele, dar con ț in în mod obligatoriu latitudinea,
longitudinea ș i un timest amp (data + ora). Clasa LocationManager din același pachet furnizează
accesul la servicii sistem prin care se poate actualiza automat loca ț ia dispozitivului sau se pot emite
comenzi de tip Intent pentru ca actualizarea pozi ț iei geografice să fie posibilă ș i dacă activitatea a
35
fost distrusă. Acest lucru se poate face printr-un serviciu sendBroadcast () care prime ș te ca
argument un obiect de tip Intent.
Aceasta metodă a fost aleasă pentru monitorizarea modificării loca ț iei în orice moment, prin
clasa MyLocationListener care implementează interfa ț a LocationListener prezentă în acela ș i
pachet android.location. Din cele 4 metode impuse de interfa ț ă, onLocationChanged () este cea
care implementeaza soluția, în codul de mai jos:
public class MyLocationListener implements LocationListener
{
public void onLocationChanged( final Location loc)
{
Log. i ( "****************" , "Location changed" );
if (isBetterLocation(loc, previousBestLocation )) {
loc.getLatitude();
loc.getLongitude();
Log. d ( "lat////" , "" +loc.getLatitude());
Log. d ( "long////" , "" +loc.getLongitude());
intent .putExtra( "Latitude" , loc.getLatitude());
intent .putExtra( "Longitude" , loc.getLongitude());
intent .putExtra( "Provider" , loc.getProvider());
sendBroadcast( intent );
}
}
public void onProviderDisabled(String provider)
{
Toast. makeText ( getApplicationContext(), "Gps Disabled" , Toast. LENGTH_SHORT )
.show();
}
public void onProviderEnabled(String provider)
{
Toast. makeText ( getApplicationContext(), "Gps Enabled" , Toast. LENGTH_SHORT )
.show();
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
Întrucât clasa MyLocationListener implementează interfața LocationListener, ea trebuie să
ofere o implementare pentru toate cele 4 metode din interfa ț ă ( onLocationChanged,
onProviderDisabled, onProviderEnabled, onStatusChanged ). În cazul de fa ț ă, doar metoda
onLocationChanged con ț ine cod util, următoarele două afi ș ând doar mesaje când sunt apelate, iar
ultima este goală pentru că nu este apelată nicăieri.
36
Instructiunile de tip Log,
Log. d ( "lat////" , "" +loc.getLatitude());
Log. d ( "long////" , "" +loc.getLongitude());
sunt folosite strict pentru depanarea codului, afisand mesaje în consolă, utile în faza de
dezvoltare a codului pentru detectarea erorilor. Pentru eventuale ulterioare iterații, am decis sa nu le
înlătur din cod, deși inlăturarea acestora nu ar avea impact asupra funcționării aplicației.
Se poate observa că metoda onLocationChanged () apelează o metodă care returnează o
valoare de tip boolean, isBetterLocation ( Location , Location ) , metodă care prime ș te doi parametri
de tip Location, pe care apoi îi compară. Primul parametru care îi este adresat este loca ț ia care
tocmai a fost primită, iar cel de-al doilea parametru con ț ine ultima loca ț ie care a fost salvată. Aceste
doua variabile sunt comparate, iar dacă cea primită mai recent are un timestamp mai recent, sau o
pozi ț ie de o acurate ț e mai mare, loca ț ia nouă este salvata ș i este totodată considerată ultima loca ț ie
validată; următoarea valoare va fi comparată cu aceasta din urmă. În această situa ț ie metoda
returnează valoarea true . Codul acestei metode este mai jos, această idee fiind preluata de pe site-ul
oficial al dezvoltatorilor Android, de la aceasta loca ț ie:
https://developer.android.com/guide/topics/location/strategies.html
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null ) {
// A new location is always better than no location
return true ;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() – currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES ;
boolean isSignificantlyOlder = timeDelta < – TWO_MINUTES ;
boolean isNewer = timeDelta > 0 ;
// If it's been more than two minutes since the current location, use the new
location
// because the user has likely moved
// PC:
if (isSignificantlyNewer) {
return true ;
// If the new location is more than two minutes older, it must be worse
} else if (isSignificantlyOlder) {
return false ;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = ( int ) (location.getAccuracy() –
currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0 ;
boolean isMoreAccurate = accuracyDelta < 0 ;
boolean isSignificantlyLessAccurate = accuracyDelta > 200 ;
37
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
return true ;
} else if (isNewer && !isLessAccurate) {
return true ;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true ;
}
return false ;
}
Am considerat că metoda de mai sus este una extrem de eficientă, aceasta ajutând la
asigurarea integrită ț ii datelor transmise. În primul rând se verifică dacă coordonatele primite au fost
ob ț inute mai recent decât precedentele, ceea ce este important, asigurându-se astfel secven ț ialitatea
rutei reconstruite de către aplica ț ia web. De asemenea, pozi ț ia ob ț inută prin re ț eaua celulară poate
prezenta abateri de la pozi ț ia exactă, de ș i se ob ț ine o pozi ț ie ini ț ială mai rapidă, iar dacă următoarea
pozi ț ie este ob ț inută prin satelit, aceasta poate fi mai exactă decât prima. De asemenea, pachetul
android.location con ț ine metode pentru verificarea felului în care loca ț ia a fost ob ț inută ș i numele
furnizorului, astfel încât se poate opta între diferiți furnizori, în func ț ie de ce criterii dore ș te
utilizatorul a fi implementate.
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. create_account );
login_username = (EditText) findViewById(R.id. login_username );
name = login_username .getText().toString();
login_password = (EditText) findViewById(R.id. login_password );
password = login_password .getText().toString();
login_email = (EditText) findViewById(R.id. login_email );
email = login_email .getText().toString();
login_submit_button = (Button) findViewById(R.id. login_submit_button );
gps = new GPSTracker(Create_account_activity. this );
// check if GPS enabled
if ( gps .canGetLocation()) {
latitude = gps .getLatitude();
longitude = gps .getLongitude();
38
slatitude = "" + latitude ;
slongitude = "" + longitude ;
geocoder = new Geocoder(Create_account_activity. this , Locale. getDefault ());
try {
addresses = geocoder .getFromLocation( latitude , longitude , 1 );
if ( addresses .isEmpty()) {
Toast. makeText (Create_account_activity. this , "waiting for the location" ,
Toast. LENGTH_SHORT ).show();
text_location.setText( "Unable to fetch your location" );
} else {
if ( addresses .size() > 0 ) {
address = addresses .get( 0 ).getAddressLine( 0 );
city = addresses .get( 0 ).getLocality();
state = addresses .get( 0 ).getAdminArea();
loc = address + "," + city + "," + state ;
Log. d ( "location is////" , "" + loc );
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
login_submit_button .setOnClickListener( new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
name = login_username .getText().toString();
password = login_password .getText().toString();
email = login_email .getText().toString();
email_pattern = "[a-zA-Z0-9._-]+@[a-z]+ \\ .+[a-z]+" ;
if ( name == "" || password == "" || email == "" ) {
Toast. makeText (Create_account_activity. this , "Please fill all the
mandatory fields." , Toast. LENGTH_SHORT ).show();
} else if (! email .matches( email_pattern )) {
Log. d ( "inside" , "email" );
Toast. makeText (Create_account_activity. this , "Invalid Email address" ,
Toast. LENGTH_SHORT ).show();
} else {
//
if (!Utils. isNetworkAvailable (Create_account_activity. this )) {
Toast. makeText (Create_account_activity. this , "Pls check your internet
connection" , Toast. LENGTH_SHORT ).show();
} else {
loadData();
}
//
}
}
});
Mai sus este parte din implementarea clasei Create_account_activity. Ca in cazul oricărei
activități Android, prima metoda apelata este onCreate(Bundle savedInstanceState) . Parametrul
savedInstanceState conține starea prealabila a activității, dacă aceasta a mai rulat în trecut și a fost
39
oprita de către utilizator sau de către sistem în timp ce rula în fundal; odată repornită, aceasta își
încarcă ultima stare salvată.
Se poate observa ca se apelează metoda onCreate a superclasei Activity pe care aceasta o
moștenește, iar apoi este setat suportul grafic prin instrucțiunea
setContentView(R.layout. create_account );
Apoi sunt declarate câmpurile pentru login_username, login_password si login_email,
acestea fiind de tipul EditText, care este o clasa din packetul android.widget . Butonul Submit este
de tipul Button, și aceasta făcând parte din același pachet, fiind subclase ale
android.widget.TextView , care la rândul ei este subclasa a android.widget.View .
super .onCreate(savedInstanceState);
setContentView(R.layout. create_account );
login_username = (EditText) findViewById(R.id. login_username );
login_password = (EditText) findViewById(R.id. login_password );
login_email = (EditText) findViewById(R.id. login_email );
login_submit_button = (Button) findViewById(R.id. login_submit_button );
Metoda findViewById este o metoda a clasei View, și returnează implicit un obiect de tip
View, ceea ce înseamnă că pentru a identifica un anume obiect de tip EditText sau Button, ca în
codul de mai sus și a-i atribui o valoare, obiectul returnat de metodă trebuie convertit prin
operatorul cast la tipul corespunzător. În cazul nostru (EditText) sau (Button).
În continuare, este implementata logica butonului Submit printr-un Listener. Această
implementare conectează Listener-ul la buton prin metoda setOnClickListener() care, după cum se
vede în codul de mai jos, implementează interfața OnClickListener printr-o clasa anonimă care
implica o singură semnatură de metodă abstractă, și anume onClick() :
login_submit_button .setOnClickListener( new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
name = login_username .getText().toString();
password = login_password .getText().toString();
email = login_email .getText().toString();
email_pattern = "[a-zA-Z0-9._-]+@[a-z]+ \\ .+[a-z]+" ;
if ( name == "" || password == "" || email == "" ) {
Toast. makeText (Create_account_activity. this , "Please fill all the
mandatory fields." , Toast. LENGTH_SHORT ).show();
} else if (! email .matches( email_pattern )) {
Log. d ( "inside" , "email" );
Toast. makeText (Create_account_activity. this , "Invalid Email address" ,
Toast. LENGTH_SHORT ).show();
} else {
//
if (!Utils. isNetworkAvailable (Create_account_activity. this )) {
Toast. makeText (Create_account_activity. this , "Pls check your internet
connection" , Toast. LENGTH_SHORT ).show();
} else {
40
loadData();
}
//
}
}
});
În cadrul acestei metode, sunt atribuite valorile citite din formularul de logare în variabilele
name , password , email , care sunt declarate de tip String la începutul clasei
Create_account_activity . Metoda prin care această operațiune este implementată este getText() iar
apoi valoarea este convertita la tipul String() cu metoda toString() . Apoi urmează un algoritm de
validare a datelor introduse care folosește operatorul “||” (Sau Logic ) pentru a valida ca nu a rămas
niciun câmp necompletat, în caz contrar se afișeaza o notificare (Toast) prin metoda
Toast.makeText(). De asemenea este implementata și logica de verificare a adresei de email, dacă
aceasta este în format corespunzător, adică text + @ + text.text . Aceasta este implementata în
următoarele doua linii de cod, se definește o variabilă email_pattern , cu care apoi valoarea
continută în variabila email este comparată prin metoda matches() care returnează o valoare de tip
boolean.
email_pattern = "[a-zA-Z0-9._-]+@[a-z]+ \\ .+[a-z]+" ;
if ( name == "" || password == "" || email == "" ) {
Toast. makeText (Create_account_activity. this , "Please fill all the mandatory
fields." , Toast. LENGTH_SHORT ).show();
} else if (! email .matches( email_pattern )) {
Log. d ( "inside" , "email" );
Toast. makeText (Create_account_activity. this , "Invalid Email address" ,
Toast. LENGTH_SHORT ).show();
Dacă acestea nu corespund, este afișat mesajul “Invalid Email Address”. În caz contrar,
execuția merge mai departe și se verifica conexiunea la internet prin metoda
Utils.isNetworkAvailable() . Daca nu exista conexiune la internet se afișeaza un mesaj de eroare,
altfel, se apelează metoda loadData() care pornește un proces asincron implementat prin clasa
AsyncLoadData, care moștenește clasa AsyncTask. Aceasta este folosită pentru procesul de logare
și durează un interval relativ redus de timp. AsyncTask se pretează pentru astfel de operațiuni. Se
recomandă folosirea acestei clase atunci când operațiunile pe care le implementează sunt de durată
relativ redusă, de maximum câteva secunde. În astfel de situații, când se lucrează cu interfața
grafică se recomandă folosirea de procese asincrone deoarece rulează în paralel cu firul de execuție
în care rulează interfața grafica și nu sacadează sau nu afectează fluiditatea interfeței grafice. Totuși,
în cazul în care se dorește implementarea cu fire de execuție a căror durata de viata este preconizata
41
la mai mult de câteva secunde, se recomanda implementarea cu ajutorul claselor Handler sau
Thread . Thread este o clasa nativa Java și face parte din pachetul java.lang iar Handler este
implementată în Android, face parte din pachetul de baza a sistemului de operare, android.os .
Aplicatia conține mai multe procese asincrone, întrucât, după cum precizam mai sus, sunt
lansate servicii care implementează algoritmii de localizare și care functionează în background
indiferent de starea curenta a activităților aplicației, deoarece acestea trebuie să transmită indiferent
de activitatea utilizatorului, atât timp cât există acces direct la semnalul GPS prin sateliți sau la
serviciile de localizare prin rețeaua celulară, cât și conexiune la internet.
3.2 Utilizarea aplica ț iei m obile
În momentul în care aplicația este pornită, utilizatorul are op ț iunea de a- ș i crea un cont,
informa ț iile care trebuies c introduse rezumându-se doar la nume, adresă de email ș i setarea unei
parole. Interfa ț a acestei activită ț i este foarte simplă, intuitivă ș i nu prezintă dificultă ț i de utilizare.
Ea este afi ș ată în imagi nea de mai jos. După ce utilizatorul ș i-a introdus datele de conectare,
aplica ț ia afi ș ează pozi ț ia dispozitivului pe harta GoogleMaps, op ț iunile fiind extrem de limitate,
întrucât scopul aplica ț iei, în aceasta formă prevede strict op ț iunea de tracking a loca ț iei într-o
aplica ț ie web.
În imaginea de mai jos este prezentată pozi ț ia dispozitivului pe GoogleMaps, după ce
utilizatorul s-a conectat.
42
3.3 Dezvoltarea aplica ț iei web
Pentru dezvoltarea aplica ț iei web am avut nevoie de un server web, de PHP ș i MySQL ș i am
considerat XAMPP ( https://www.apachefriends.org/index.html ), un pachet de programe cu sursă
deschisă, ca fiind cea mai rapidă ș i mai facilă solu ț ie pentru a ob ț ine un server local, fără cuno ș tin ț e
de instalare ș i configurar e de servere. Pa ș ii sunt simpli, descărca rea unei arhive, dezarhivarea ei ș i
instalarea programelor. Prin câteva click-uri am ob ț inut un server web cu PHP ș i un server de baze
de date.
Pentru dezvoltarea aplica ț iei web am folosit Codeigniter (https://codeigniter.com/), un
framework PHP care permite construirea de aplica ț ii web dinamice, bazându-se pe modelul MVC
(model-view-controller) care realizează separarea logicii de interfa ț a grafică. Codeigniter vine cu o
serie de clase ș i modele gata implementate pentru a realiza câteva dintre ac ț iunile de bază într-o
aplica ț ie web mobilă, cum ar fi partea de înregistrarea utilizatorilor, gestionarea sesiunilor ș i
conectarea la baza de date. Dacă, la o primă privire, pare destul de greu de utilizat, există o destul
43
de vastă documenta ț ie (https://www.codeigniter.com/docs) ș i tutoriale online, care permit
eficientizarea procesului de învă ț are. Framework-urile gen codeigniter mic ț orează considerabil
perioada în care se poate ob ț ine o aplica ț ie web dinamică fa ț ă de varianta în care s-ar dezvolta totul
de la zero.
Alica ț ia we presu pune existen ț a unei hăr ț i pe care să fie vizibile toate caminoanele, cu
posibilitatea de a da click pe marker ș i de a afla nume ș oferului, viteza ș i loca ț ia în care se află.
Figura de mai jos prezintă implementarea acestei interfe ț e.
Pentru a desena harta în pagină se folose ș te API-ul oferit gratuit de Google ș i apelat la
începutul paginii, prin următoarele linii de cod:
<script
type="text/javascript"
src=" https://maps.googleapis.com/maps/api/js?key=AIzaSyCefOgb1ZWqYtj7raV
SmN4PL2WkTrc-KyA ">
</script>
44
Toate semnele de marcaj ( pin -urile) de pe hartă reprezintă loca ț iile transmise de
dispozitivele Android ș i salvate apriori în baza de date. Primul pas este introducerea hăr ț ii în pagina
web, urmată de desenarea punctelor de marcaj ș i de redesenarea (reflesh) lor la un anumit interval
de timp. Toate acestea sunt realizate prin intermediul func ț iei load() , care con ț ine următorul cod
JavaScript:
function load() {
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(41.6864807,-87.6285099),
zoom: 4,
mapTypeId: 'roadmap'
});
var infoWindow = new google.maps.InfoWindow;
// Change this depending on the name of your PHP file
downloadUrl("<?=base_url("admin/map_salesrep/getcoordinates")?>",
function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + address;
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon
});
bindInfoWindow(marker, map, infoWindow, html);
}
});
}
În prima parte a metodei se crează obietul map , de tipul google.maps.Map, care este
utilizat pentru a stabili următoarele:
45
– pozi ț ia în care va fi incărcată harta în pagina, prin intermediul metodei
getElementById("map") – caută în pagina HTML tag-ul cu id-ul map ș i în interiorul
acestuia va încărca harta.
– punctul central al hăr ț ii, prin intermediul longitudinii ș i latitudinii punctului respectiv,
transmise ca parametri func ț iei LatLng în modul următor:
center: new google.maps.LatLng(41.6864807,-87.6285099)
– nivelul de detaliu al hăr ț ii, care poate lua valori între 1 (pentru reprezentarea întregului
Pământ) ș i 20 (reprezentarea clădirilor). În cazul aceasta nivelul de zoom a fost stabilit
la 4, pentru a putea vedea întreaga Românie într-o fereastră web.
– tipul hăr ț ii, care poate fi roadmap (hartă rutieră standard), satellite, terrain (imaginea
fizică a reliefului, cu teren ș i vegeta ț ie) ș i hybrid (hibrid între harta rutieră standard ș i
cea prin satelit, suprapunând un strat transparent de străzi principale ș i numele de locuri
peste imaginea prin satelit) . În acest caz am utilizat roadmap.
Odată desenată harta, se face o primă interogare a bazei de date (prin apelarea metodei
getcoordinates, al cărei cod este prezentat în Figura 3.12), pentru a ob ț ine informa ț ii cu privire
la loca ț iile la care se află dispozitivele Android care ș i-au transmis coordonatele.
În metoda getcoordinates se realizează următoarele:
– interogarea bazei de date (comanda SELECT * FROM tbl_location este utilizată
pentru a returna toate înregistrările din tabela tbl_location)
– crearea, pregătirea marcajelor (preluarea numelui, a vitezei ș i a loca ț iei – longitudine
ș i latitudin e) ș i pregătirea lor pentru pozi ț ionarea pe hartă (variabila $output ).
$result=$this->db->query("SELECT * FROM tbl_location")->result_array();
$output = "<markers>";
if (count($result)>0) {
for ($i=0;$i<count($result);$i++) {
$output.='<marker ';
$output.= 'name="'.$result[$i]['name'].'" ';
$output.= 'speed="Speed : '.$result[$i]['speed'].' " ';
$output.= 'location="location : '.$result[$i]['location'].' " ';
$output.= 'lat="' . $result[$i]['latitude'] . '" ';
$output.= 'lng="' . $result[$i]['longitude'] . '" ';
$output.= 'type="Family member" ';
$output.= '/>';
}
}
$output.="</markers>";
46
Odată op ț inute informa ț iile cu privire la loca ț iile dispozitivelor Android de pe drum, loca ț ii
salvate în baza de date, se trece la desenarea acestora pe hartă (func ț ia getxml(infoWindow ).
Prin func ț ia window.setInterval( function() { getxml(infoWindow,map); },
5000 ) se reapelează func ț ia getxml(infoWindow ) la un interval de 5000 de ms, în acest caz,
reapelare care determină o nouă interogare a bazei de date ș i o nouă redesenare a marcajelor, în
func ț ie de ultimele înregis trări din baza de date.
La un click pe oricare dintre marcajele de pe hartă ob ț inem informa ț ii cu privire de ș ofer,
(numele acestuia, viteza ș i adresa), după cum se poate vedea în cele două figuri de mai jos. În
momentul în care cele 5000 de ms au trecut ș i se face o nouă interogare a bazei de date, deci o
reactualizare a marcajelor pe hartă, caseta cu informa ț iile suplimentare va dispărea.
47
Concluzii
Acest proiect propune o rezolvare, pentru o posibilă problemă a unui antreprenor sau al unei
mici afaceri care iși dorește să își eficientizeze modul în care operează sau sa își îmbunătațească
modelul de business pe care l-a adoptat.
În prima parte, în Capitolul 2, s-a efectuat un studiu de caz în care s-au testat 3 aplicații care
prezintă functionalități de GPS tracking, dar care aplicații sunt fiecare diferite de celelalte doua prin
modul în care au fost concepute, prin funcțiile pe care le oferă, prin posibilitățile de configurare sau
prin particularități în ceea ce privește strict utilizarea. S-a urmărit găsirea unor soluții gratuite sau
care sa nu prezinte costuri recurente, după cum aminteam mai sus, altele decât cele aferente
serviciului de date percepute de către operatorul de telefonie mobila.
Dintre aplicațiile testate, Find My Device, dezvoltată de Google nu impresionează practic
prin nimic, fiind o aplicație cât se poate de simpla care afișează poziția dispozitivului la un anumit
moment dat, poziția trebuie solicitată constant, localizarea nefiind recurentă și nu afișează viteza de
deplasare a dispozitivului.
Cerberus este mai degrabă o aplicație de securitate pentru dispozitiv decât una de tracking,
însă am inclus-o în acest studiu de caz pentru că prezintă opțiunea de localizare și transmitere a
coordonatelor GPS ale dispozitivului pe care se afla instalata. Unul dintr neajunsurile acestei
aplicații constă în faptul ca utilizatorul web trebuie sa pornească funcția de tracking manual de
fiecare dată când se conectează la sistem, iar când se deconectează, serviciul de tracking care
rulează în fundal pe aparatul mobil este automat oprit în acel moment. Are opțiunea de a afișa un
istoric al locațiilor, dar numai pentru acea perioada în care funcția de tracking a fost activată, adică
exact pentru perioada în care un utilizator este conectat la panoul web al aplicației și solicită explicit
serviciul de tracking. De asemenea, la minusuri aș nota absenta posibilității de a afișa viteza curentă
de deplasare.
Pe de alta parte, Cerberus prezintă o serie de funcții foarte interesante în ceea ce priveste
securitatea. Dintre acestea, amintesc
● Blocarea dispozitivului și schimbarea codului de acces de la distanță
● Fotografierea de la distanță a utilizatorului, cât și posibilitatea de a porni funcția de
înregistrare audio de la distanță pentru a putea depista împrejurimile în cazul în care
dispozitivul a fost furat sau pierdut
● Efectuarea de snapshot al ecranului de la distanță
● Stergerea conținutului tabletei/telefonului, inclusiv a cardului SD de la distanta, ca
măsură de protecție în caz de furt/pierdere
● Salvarea conținutului întregii tablete/telefonului în cloud, prin Google Drive sau
Dropbox în caz de furt/pierdere.
În acest context, referitor la această aplicație concluzionăm că având în vedere că aceasta nu
prezintă nici măcar opțiunea transmiterii vitezei de deplasare, consider ca nu ar putea constitui o
opțiune viabilă pentru ceea ce am căutat în cadrul acestui demers, însă poate constitui o excelenta
soluție de securitate care ar putea fi folosita în tandem cu o aplicație de GPS tracking dezvoltată
special pentru flote de autovehicule. Multe firme care decid să-și doteze vehiculele cu tracking GPS
prin tablete folosesc aceste dispozitive și pentru alte servicii cum ar fi colectarea de semnături sau
documente în format electronic, înregistrarea de comenzi sau trimiterea de comenzi agenților de pe
48
teren. În contextul în care aceste dispozitive pot conține documente și/sau informații mai mult sau
mai puțin sensibile ale firmei, soluția amintită mai sus poate fi una extrem de viabilă pentru a
acoperi aspectul securității, mai ales în contextul în care prezintă și funcția de GPS tracking care ar
putea fi folosită în regim de urgență. În situația în care principala aplicație de tracking nu ar mai
funcționa din varii motive, administratorul poate recurge la această soluție de siguranță pentru că
află poziția dispozitivului și în funcție de natura situației, poate recurge chiar la unele dintre soluțiile
enumerate mai sus. Așadar, consider această aplicație o soluție foarte bună mai mult pentru
securitate, nu pentru tracking.
Glympse prezintă o soluție extrem de interesantă, care ofera funcții de generare a istoricului
locațiilor, oferă posibilitatea afișării vitezei de deplasare în timp real, însă lasă această opțiune la
latitudinea utilizatorului mobil. Aceasta, după cum precizam și în studiul de caz, se datorează
principiului constructiv al aplicației, și anume a faptului că utilizatorul mobil este cel care
inițializează funcția de tracking, se generează un link, care este apoi trimis clientului care poate
urmări poziția geografică și evoluția acesteia în timp real, sau generarea rutei parcurse, ulterior.
Utilizatorul mobil care inițiază activitatea de tracking stabilește la început perioada de timp pentru
care link-ul generat este valabil, dar totodată poate decide sa oprească această funcție în orice
moment, la fel cum poate opri transmiterea vitezei curente.
Aceasta este o aplicație simplă, robustă, foarte bine implementată, cu recenzii remarcabile.
Din păcate nu constituie o soluție viabila pentru situația de față, dat fiind faptul că nu există un așa
numit administrator care să poată urmări constant poziția si mișcarea dispozitivului, dacă acest
proces nu este inițiat de către utilizatorul mobil.
Partea a doua a lucrării prezintă în capitolul 3 soluția implementată, care constă într-o
aplicație web, pe de-o parte și o soluție mobilă, pe cealaltă parte. Aplicația web afișează poziția
dispozitivelor mobile într-un browser web, pe o hartă Google utilizând un API GoogleMaps.
Aplicația mobilă a fost implementată în Android Studio, și prezintă o abordare relativ simplă
a soluției, în sensul că afișează pe displayul dispozitivului mobil poziția pe harta GoogleMaps și
transmite această poziție și viteza în timp real aplicației web. Aplicația mobilă cotinuă să transmită
aceste informații componentei web și după ce aceasta nu mai este in prim plan sau rulează în fundal,
optându-se pentru implementarea cu servicii de broadcast, intent-uri si task-uri asincrone care
rulează în fire de execuție paralele cu activitatea principală a aplicației și care iși continuă execuția
chiar daca aceasta din urmă este pusă în hold sau este distrusă temporar de catre sistem.
Această soluție implementată reprezintă o soluție simplă, care oferă o singură funcție, și
anume transmiterea locației GPS către o baza de date de pe un server care apoi sunt afișate într-un
browser web. Scopul acesteia este să ofere, pe lângă această funcție, un punct de plecare pentru alte
implementări care să optimizeze fluxul de lucru în firme mici cu activități în care eficiența în timp
este foarte importantă. Ca posibile idei sau direcții ulterioare pentru dezvoltarea aplicației am
considerat posibilitatea de a implementa un “ geofence ”, adică stabilirea de către adiministrator a
unui perimetru astfel încât dispozitivul să trimită o alerta administratorului sau utilizatorului mobil,
după caz, în momentul în care s-a depașit acel perimetru. Sau, pe de alta parte, se poate alege un
punct de pe hartă și se poate crea un geofence circular, alerta fiind trimisa în momentul în care
dispozitivul se apropie sau se îndepartează de/la o raza prestabilita de acea locație stabilită prin acel
punct.
O altă idee, daca aplicația ar fi folosită, după cum precizam anterior, de un restaurant pentru
a-și urmări masinile care livrează mâncare la domiciliu, ar exista varianta dezvoltării unui modul
suplimentar pentru aplicatia web, în care administratorul/operatorul web sa introducă toate
49
comenzile, apoi s-ar poate implementa un algoritm care să calculeze drumul optim până la client,
având totodată opțiunea de a combina mai multe comenzi într-un singur drum, ținând totuși cont de
întârzieri și stabilind parametri astfel încât să nu dureze foarte mult livrările. În acest context, dacă
restaurantul folosește o soluție informatică pentru comenzi, odată ce operatorul care ia comanda
prin telefon și selectează opțiunea de livrare, în momentul în care comanda este completă, s-ar putea
implementa un API care sa transfere comenzile pt livrare la domiciliu, din software-ul de comenzi
în sistemul de tracking GPS. O alta idee ar fi ca software-ul pentru comenzi să aibă opțiunea de a
seta un timp standard în care fiecare produs cald de pe meniu este gata, împachetat, gata de livrare,
de la bucătărie. Acesti timpi se pot determina si modifica pe percurs. Astfel, avand timpii la care au
fost puse comenzile, timpii de gătire, pozițiile mașinilor, se poate construi un astfel de algoritm care
sa determine când ajunge înapoi următoarea mașină, unde trebuie sa meargă comanda următoare,
dacă mai există comenzi care merg în acea direcție și, de asemenea, dacă merită ca șoferul să
astepte inca 2-3 minute până când o altă comandă care merge în aceeași zonă sau direcție va fi gata
de livrare. Dacă se va merge pe o astfel de idee, atunci s-ar mai impune și înregistrarea stării
comenzii:
● în curs de pregatire
● ridicată, în curs de livrare
● livrată
În momentul în care ultima comandă disponibilă va fi livrată, starea mașini va fi actualizată
la “disponibil in _ minute” și ar putea afișa operatorului web în cât timp va avea restaurantul
următoarea mașină disponibilă pentru livrare.
Concluzionând, putem spune că direcțiile în care această aplicație poate fi dezvoltată pe
viitor sunt practic nelimitate, în funcție de modelul de business pentru care este aleasă, industria în
care operează firma, necesitățile clientului, creativitatea celui care scrie proiectul pentru
îmbunătățiri sau dezvoltare și maniera de implementare a dezvoltatorilor, un aspect fiind totuși de
necontestat, și anume faptul ca există o sumedenie de business-uri mici sau în curs de dezvoltare
care caută soluții ieftine și funcționale pentru a crește si se dezvolta.
50
Bibliografie
“Android History.” Android Central , 21 Oct. 2015. Web. 19 June 2016.
“Global Smartphones Sales by Operating System 2009-2015 | Statistic.” Statista , Web. 19 June 2016.
Guru, and Guru. “Top 10 Mobile Phones Operating Systems.” ShoutMeLoud 23 Aug. 2012. Web. 20 June
2016.
“History of Cell Phones -.” N.p., n.d. Web. 20 June 2016.
“History of the Web.” World Wide Web Foundation . Web. 19 June 2016.
ICT Facts&Figures, The World în 2015 ., Web. 23 June 2016.
Ingram, Mathew. “Gigaom | Mary Meeker: Mobile Internet Will Soon Overtake Fixed Internet.”, n.d. Web.
18 June 2016.
“Mobile Marketing Statistics 2016.” Smart Insights ., 27 Apr. 2016. Web. 19 June 2016.
Nair, Rajeesh. “Internet & Mobile Phone Users Worldwide 2015: 50% Population Is On Internet
[REPORT].” Dazeinfo , 27 May 2015. Web. 23 June 2016.
“Number of Internet Users (2016) – Internet Live Stats.” , Web. 19 June 2016.
“Smartphone OS Global Market Share 2009-2016 | Statistic.” Statista , Web. 18 June 2016.
Srivastava, Anshul. “2 Billion Smartphone Users By 2015: 83% of Internet Usage From Mobiles [Study].”
Dazeinfo . N.p., 23 Jan. 2014. Web. 20 June 2016.
“The History of Mobile Phones From 1973 To 2008: The Handsets That Made It ALL Happen.” Know Your
Mobile ., Web. 20 June 2016.
“The Mobile Economy 2015.” GSMA Intelligence , Web. 20 June 2016.
Williams, Rhiannon. “Apple iOS: A Brief History.” Telegraph.co.uk , 17 Sept. 2015. Web. 20 June 2016.
51
ANEXE
Aplica ț ia mobila
AndroidManifest.XML
<? xml version= "1.0" encoding= "utf-8" ?>
< manifest xmlns: android = "http://schemas.android.com/apk/res/android"
package= "com.unitracer"
android :versionCode= "1"
android :versionName= "1.0" >
< uses-permission android :name= "android.permission.ACCESS_COARSE_LOCATION" />
< uses-permission android :name= "android.permission.ACCESS_FINE_LOCATION" />
< uses-permission android :name= "android.permission.ACCESS_NETWORK_STATE" />
< uses-permission android :name= "android.permission.INTERNET" />
< uses-permission
android :name= "com.google.android.providers.gsf.permission.READ_GSERVICES" />
< uses-permission android :name= "android.permission.WRITE_EXTERNAL_STORAGE" />
< uses-permission android :name= "com.unitracer.permission.MAPS_RECEIVE" />
< uses-permission android :name= "android.permission.GET_TASKS" />
< uses-permission android :name= "android.permission.WAKE_LOCK" />
< uses-sdk
android :minSdkVersion= "8"
android :targetSdkVersion= "19" />
< permission
android :name= "com.unitracer.permission.MAPS_RECEIVE"
android :protectionLevel= "signature" />
< application
android :allowBackup= "true"
android :icon= "@drawable/ic_launcher"
android :label= "@string/app_name"
android :theme= "@android:style/Theme.Light.NoTitleBar" >
< activity
android :name= "com.unitracer.Splash_activity"
android :label= "@string/app_name" >
< intent-filter >
< action android :name= "android.intent.action.MAIN" />
< category android :name= "android.intent.category.LAUNCHER" />
</ intent-filter >
</ activity >
< activity
android :name= "com.unitracer.Create_account_activity"
android :label= "@string/app_name"
android :windowSoftInputMode= "stateHidden"
android :screenOrientation= "portrait" />
< activity
android :name= "com.unitracer.Track_location"
android :label= "@string/app_name"
android :windowSoftInputMode= "stateHidden"
android :screenOrientation= "portrait" >
</ activity >
< meta-data
android :name= "com.google.android.maps.v2.API_KEY"
android :value= "AIzaSyD6dLL0Z-BRJVNd5H0LzNSRzF4_DCmrI48"
/>
< meta-data
android :name= "com.google.android.gms.version"
52
android :value= "@integer/google_play_services_version" />
< receiver android :name= "com.unitracer.Splash_activity" android :enabled= "true" >
< intent-filter >
< action android :name= "Hello.World" />
<!– and some more actions if you want –>
</ intent-filter >
</ receiver >
< service
android :name= "com.unitracer.LocationService"
android :enabled= "true"
android :exported= "false" />
<!–
Optionally, register CampaignTrackingReceiver and CampaignTrackingService
to enable
installation campaign reporting
–>
< receiver
android :name= "com.google.android.gms.analytics.CampaignTrackingReceiver"
android :exported= "true" >
< intent-filter >
< action android :name= "com.android.vending.INSTALL_REFERRER" />
</ intent-filter >
</ receiver >
< service android :name= "com.google.android.gms.analytics.CampaignTrackingService"
/>
</ application >
</ manifest >
Create_account.xml
<? xml version= "1.0" encoding= "utf-8" ?>
< LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
android :layout_width= "match_parent"
android :layout_height= "match_parent"
android :orientation= "vertical" >
< RelativeLayout
android :id= "@+id/header"
android :layout_width= "match_parent"
android :layout_height= "60dp"
android :layout_alignParentTop= "true"
android :background= "@drawable/header_2x" >
< TextView
android :id= "@+id/textView1"
android :layout_width= "wrap_content"
android :layout_height= "wrap_content"
android :layout_centerHorizontal= "true"
android :layout_centerVertical= "true"
android :text= "Create Account"
android :textColor= "#fff"
android :textSize= "22dp"
android :textStyle= "bold" />
</ RelativeLayout >
< LinearLayout
android :id= "@+id/login_username_lnr"
53
android :layout_width= "match_parent"
android :layout_height= "wrap_content"
android :layout_below= "@+id/header"
android :layout_marginTop= "20dp"
android :orientation= "vertical"
android :gravity= "center" >
< EditText
android :id= "@+id/login_username"
android :layout_width= "match_parent"
android :layout_height= "50dp"
android :layout_marginLeft= "20dp"
android :layout_marginRight= "20dp"
android :layout_marginBottom= "5dp"
android :layout_marginTop= "25dp"
android :paddingLeft= "15dp"
android :hint= "NAME"
android :textColor= "#000"
android :textStyle= "bold"
android :singleLine= "true"
android :background= "@drawable/textbox_2x"
android :ems= "10" />
< EditText
android :id= "@+id/login_email"
android :layout_width= "match_parent"
android :layout_height= "50dp"
android :layout_marginLeft= "20dp"
android :layout_marginRight= "20dp"
android :layout_marginBottom= "5dp"
android :layout_marginTop= "10dp"
android :paddingLeft= "15dp"
android :hint= "EMAIL"
android :textStyle= "bold"
android :singleLine= "true"
android :background= "@drawable/textbox_2x"
android :ems= "10" />
< EditText
android :id= "@+id/login_password"
android :layout_width= "match_parent"
android :layout_height= "50dp"
android :layout_marginLeft= "20dp"
android :layout_marginRight= "20dp"
android :layout_marginBottom= "5dp"
android :layout_marginTop= "10dp"
android :paddingLeft= "15dp"
android :hint= "PASSWORD"
android :textStyle= "bold"
android :singleLine= "true"
android :background= "@drawable/textbox_2x"
android :ems= "10"
android :inputType= "textPassword" />
< Button
android :id= "@+id/login_submit_button"
android :layout_width= "match_parent"
android :layout_height= "50dp"
android :layout_marginLeft= "20dp"
android :layout_marginRight= "20dp"
android :layout_marginBottom= "5dp"
android :layout_marginTop= "25dp"
android :textSize= "22sp"
android :text= "SUBMIT"
android :textStyle= "bold"
android :background= "@drawable/header_2x"
android :textColor= "#FFF" />
54
</ LinearLayout >
</ LinearLayout >
Track_location.xml
<? xml version= "1.0" encoding= "utf-8" ?>
< LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
android :layout_width= "match_parent"
android :layout_height= "match_parent"
android :orientation= "vertical" >
< RelativeLayout
android :id= "@+id/header"
android :layout_width= "match_parent"
android :layout_height= "60dp"
android :layout_alignParentTop= "true"
android :background= "@drawable/header_2x" >
< TextView
android :id= "@+id/textView1"
android :layout_width= "wrap_content"
android :layout_height= "wrap_content"
android :layout_centerHorizontal= "true"
android :layout_centerVertical= "true"
android :textColor= "#fff"
android :textSize= "22dp"
android :textStyle= "bold"
android :text= "Map" />
</ RelativeLayout >
< fragment
android :id= "@+id/map_frag"
android :name= "com.google.android.gms.maps.MapFragment"
android :layout_width= "match_parent"
android :layout_height= "match_parent" />
</ LinearLayout >
Create_account_activity.java
public class Create_account_activity extends Activity {
private ProgressDialog pDialog ;
ArrayList<LatLng> latlongg ;
private String slatitude ;
JSONObject jsonObject = new JSONObject();
private String slongitude , email_pattern ;
private double latitude ;
double add_miles ;
GPSTracker gps ;
private double longitude ;
private String progress_dialog_msg = "" ;
private static final int LOAD_QUESTION_SUCCESS = 2 ;
private final int SHOW_PROG_DIALOG = 0 ;
private final int HIDE_PROG_DIALOG = 1 ;
Location startLocation = new Location( "start" );
55
Location endLocation = new Location( "end" );
double distance ;
private ProgressDialog progress_dialog ;
String distance_reduce = "" , name = "" , email = "" , password = "" ;
double final_miles_double ;
String final_miles ;
Marker m ;
;
int nn ;
int pos ;
int flagvalue ;
String status = "" , result1 , speed = "" ;
String first_name , user_id = "" ;
String slatitude_prev_four_digit , slongitude_prev_four_digit ;
String slatitude_after_four_digit , slongitude_after_four_digit ;
String address , city , state , loc = "" ;
Geocoder geocoder ;
List<Address> addresses ;
EditText login_username , login_password , login_email ;
Button login_submit_button ;
public static final String USER_TYPE_VALUES = "user_type_value" ;
SharedPreferences typevalue ;
SharedPreferences.Editor type_editor ;
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. create_account );
login_username = (EditText) findViewById(R.id. login_username );
login_password = (EditText) findViewById(R.id. login_password );
login_email = (EditText) findViewById(R.id. login_email );
login_submit_button = (Button) findViewById(R.id. login_submit_button );
gps = new GPSTracker(Create_account_activity. this );
// check if GPS enabled
if ( gps .canGetLocation()) {
latitude = gps .getLatitude();
longitude = gps .getLongitude();
slatitude = "" + latitude ;
slongitude = "" + longitude ;
geocoder = new Geocoder(Create_account_activity. this , Locale. getDefault ());
try {
addresses = geocoder .getFromLocation( latitude , longitude , 1 );
if ( addresses .isEmpty()) {
Toast. makeText (Create_account_activity. this , "waiting for the location" ,
Toast. LENGTH_SHORT ).show();
text_location.setText( "Unable to fetch your location" );
} else {
if ( addresses .size() > 0 ) {
address = addresses .get( 0 ).getAddressLine( 0 );
city = addresses .get( 0 ).getLocality();
state = addresses .get( 0 ).getAdminArea();
loc = address + "," + city + "," + state ;
Log. d ( "location is////" , "" + loc );
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
login_submit_button .setOnClickListener( new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
name = login_username .getText().toString();
56
password = login_password .getText().toString();
email = login_email .getText().toString();
email_pattern = "[a-zA-Z0-9._-]+@[a-z]+ \\ .+[a-z]+" ;
if ( name == "" || password == "" || email == "" ) {
Toast. makeText (Create_account_activity. this , "Please fill all the
mandatory fields." , Toast. LENGTH_SHORT ).show();
} else if (! email .matches( email_pattern )) {
Log. d ( "inside" , "email" );
Toast. makeText (Create_account_activity. this , "Invalid Email address" ,
Toast. LENGTH_SHORT ).show();
} else {
//
if (!Utils. isNetworkAvailable (Create_account_activity. this )) {
Toast. makeText (Create_account_activity. this , "Pls check your internet
connection" , Toast. LENGTH_SHORT ).show();
} else {
loadData();
}
//
}
}
});
LocationManager locationManager = (LocationManager) this
.getSystemService(Context. LOCATION_SERVICE );
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
location.getLatitude();
speed = "" + location.getSpeed();
Log. d ( "sppeeed/////" , "" + speed );
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
};
if (ActivityCompat. checkSelfPermission ( this ,
android.Manifest.permission. ACCESS_FINE_LOCATION ) != PackageManager. PERMISSION_GRANTED
&& ActivityCompat. checkSelfPermission ( this ,
android.Manifest.permission. ACCESS_COARSE_LOCATION ) !=
PackageManager. PERMISSION_GRANTED ) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[]
permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the
documentation
// for ActivityCompat#requestPermissions for more details.
return ;
}
locationManager.requestLocationUpdates(LocationManager. GPS_PROVIDER , 0 ,
0 , locationListener);
}
Handler mHandler = new Handler( new Handler.Callback() {
57
public boolean handleMessage(Message msg) {
// switch case
switch (msg. what ) {
case SHOW_PROG_DIALOG :
showProgDialog();
break ;
case HIDE_PROG_DIALOG :
hideProgDialog();
break ;
case LOAD_QUESTION_SUCCESS :
//GotoData();
break ;
default :
break ;
}
return false ;
}
});
private AsyncLoadData asyncLoad ;
private void loadData() {
if ( asyncLoad == null
|| asyncLoad .getStatus() != AsyncTask.Status. RUNNING ) {
asyncLoad = new AsyncLoadData();
asyncLoad .execute();
}
}
class AsyncLoadData extends AsyncTask<String, Void, Void> {
boolean flag = false ;
@SuppressWarnings ( "unused" )
@Override
protected Void doInBackground(String… params) {
//maincat=new ArrayList<MainCategoryEntity>();
mHandler .sendEmptyMessage( SHOW_PROG_DIALOG );
progress_dialog_msg = "loading…" ;
LoadApi api= new LoadApi();
try {
Log. d ( "msg////" , "" + name );
Log. d ( "msg////" , "" + slatitude );
Log. d ( "msg////" , "" + slongitude );
Log. d ( "msg///" , "" + password );
Log. d ( "msg////" , "" + email );
Log. d ( "msg////" , "" + speed );
jsonObject =LoadApi. registrartion ( name , slatitude , slongitude , email ,
password , speed , loc );
result1 = jsonObject .getString( "msg" );
user_id = jsonObject .getString( "user_id" );
Log. d ( "msg" , "" + result1 );
Log. d ( "userid" , "" + user_id );
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null ;
58
}
@SuppressLint ( "NewApi" )
@Override
protected void onPostExecute(Void result) {
mHandler .sendEmptyMessage( HIDE_PROG_DIALOG );
// mHandler.sendEmptyMessage(LOAD_QUESTION_SUCCESS);
try {
if ( result1 .equals( "Registration successfully" )){
AlertDialog.Builder alert;
if (Build.VERSION. SDK_INT >= 11 ) {
alert = new AlertDialog.Builder(Create_account_activity. this ,
AlertDialog. THEME_HOLO_LIGHT );
} else {
alert = new AlertDialog.Builder(Create_account_activity. this );
}
alert.setTitle( "Successful" );
alert.setMessage( "You are successfully registered.Press OK to continue." );
alert.setPositiveButton(android.R.string. ok , new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Create_account_activity. this ,
Track_location. class );
typevalue =getSharedPreferences( USER_TYPE_VALUES , MODE_PRIVATE );
type_editor = typevalue .edit();
type_editor .putString( "user_id" , user_id );
type_editor .commit();
startActivity(intent);
finish();
dialog.dismiss();
}
});
try {
Dialog dialog = alert.create();
dialog.requestWindowFeature(Window. FEATURE_NO_TITLE );
dialog.show();
} catch (Exception e){
e.printStackTrace();
}
}
else if ( result1 .equals( "Email already exist" )){
AlertDialog.Builder alert;
if (Build.VERSION. SDK_INT >= 11 ) {
alert = new AlertDialog.Builder(Create_account_activity. this ,
AlertDialog. THEME_HOLO_LIGHT );
} else {
alert = new AlertDialog.Builder(Create_account_activity. this );
}
//alert.setTitle("Registration!");
alert.setMessage( "Your Email is Already Registered with us" );
alert.setPositiveButton(android.R.string. ok , new
DialogInterface.OnClickListener() {
59
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Create_account_activity. this ,
Track_location. class );
typevalue =getSharedPreferences( USER_TYPE_VALUES , MODE_PRIVATE );
type_editor = typevalue .edit();
type_editor .putString( "user_id" , user_id );
type_editor .commit();
startActivity(intent);
finish();
dialog.dismiss();
}
});
try {
Dialog dialog = alert.create();
dialog.requestWindowFeature(Window. FEATURE_NO_TITLE );
dialog.show();
} catch (Exception e){
e.printStackTrace();
}
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
@SuppressLint ( "InlinedApi" ) private void showProgDialog() {
progress_dialog = null ;
try {
if (Build.VERSION. SDK_INT >= 11 ) {
progress_dialog = new ProgressDialog(Create_account_activity. this ,
AlertDialog. THEME_HOLO_LIGHT );
} else {
progress_dialog = new
ProgressDialog(Create_account_activity. this );
}
progress_dialog .setMessage( progress_dialog_msg );
progress_dialog .setCancelable( false );
progress_dialog .show();
} catch (Exception e){
e.printStackTrace();
}
}
// hide progress
private void hideProgDialog() {
try {
if ( progress_dialog != null && progress_dialog .isShowing())
progress_dialog .dismiss();
} catch (Exception e){
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super .onDestroy();
if ( progress_dialog != null ) {
progress_dialog .dismiss();
progress_dialog = null ;
}
}
60
}
Splash_activity.java
package com.unitracer;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.os.Bundle;
import android.os.Handler;
import android.util.Base64;
import android.util.Log;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Splash_activity extends Activity {
int Splash_time_Out = 3000 ;
public static final String USER_TYPE_VALUES = "user_type_value" ;
SharedPreferences typevalue ;
MyReceiver myreceiver ;
SharedPreferences.Editor type_editor ;
String user_id ;
String latitute , longitude ;
protected void onCreate(Bundle savedInstanceState)
{
super .onCreate(savedInstanceState);
setContentView(R.layout. splash_layout );
typevalue =getSharedPreferences( USER_TYPE_VALUES , MODE_PRIVATE );
user_id = typevalue .getString( "user_id" , "" );
Log. d ( "user////" , "" + user_id );
try {
PackageInfo info = getPackageManager().getPackageInfo(
"com.unitracer" ,
PackageManager. GET_SIGNATURES );
for (Signature signature : info. signatures ) {
MessageDigest md = MessageDigest. getInstance ( "SHA" );
md.update(signature.toByteArray());
Log. d ( "KeyHash:" , Base64. encodeToString (md.digest(), Base64. DEFAULT ));
}
} catch (NameNotFoundException e) {
} catch (NoSuchAlgorithmException e) {
}
new Handler().postDelayed( new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
if (! user_id .equals( "" )){
61
Intent intenttt= new Intent(Splash_activity. this ,
Track_location. class );
startActivity(intenttt);
// final Intent intent = new
Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
// startActivity(intent);
}
else
{
Intent intt = new Intent(Splash_activity. this ,
Create_account_activity. class );
startActivity(intt);
// final Intent intent = new
Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
// startActivity(intent);
finish();
}
} catch (Exception e) {
// TODO: handle exception
}
}
}, Splash_time_Out );
myreceiver = new MyReceiver();
}
class MyReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
Log. i ( "Receiver" , "Broadcast received: " + action);
if (action.equals( "Hello.World" )){
latitute =intent.getExtras().getString( "Latitude" );
longitude =intent.getExtras().getString( "Longititude" );
Log. d ( "lat////splash" , "" + latitute );
Log. d ( "long////" , "" + longitude );
typevalue =getSharedPreferences( USER_TYPE_VALUES , MODE_PRIVATE );
type_editor = typevalue .edit();
type_editor .putString( "latitute" , latitute );
type_editor .putString( "longitude" , longitude );
type_editor .commit();
}
}
}
protected void onPause() {
// TODO Auto-generated method stub
super .onPause();
// finish();
}
}
62
Location_service.java
package com.unitracer;
import android.app.Service;
import android.content.Context;
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.util.Log;
import android.widget.Toast;
public class LocationService extends Service
{
public static final String BROADCAST_ACTION = "Hello.World" ;
private static final int TWO_MINUTES = 1000 * 60 * 2 ;
public LocationManager locationManager ;
public LocationListener listener ;
public Location previousBestLocation = null ;
Intent intent ;
int counter = 0 ;
@Override
public void onCreate()
{
super .onCreate();
intent = new Intent( BROADCAST_ACTION );
}
@Override
public void onStart(Intent intent, int startId)
{
locationManager = (LocationManager) getSystemService(Context. LOCATION_SERVICE );
listener = new MyLocationListener();
locationManager .requestLocationUpdates(LocationManager. NETWORK_PROVIDER , 4000 , 0 ,
listener );
locationManager .requestLocationUpdates(LocationManager. GPS_PROVIDER , 4000 , 0 ,
listener );
}
@Override
public IBinder onBind(Intent intent)
{
return null ;
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null ) {
// A new location is always better than no location
return true ;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() – currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES ;
boolean isSignificantlyOlder = timeDelta < – TWO_MINUTES ;
63
boolean isNewer = timeDelta > 0 ;
// If it's been more than two minutes since the current location, use the new
location
// because the user has likely moved
// PC:
if (isSignificantlyNewer) {
return true ;
// If the new location is more than two minutes older, it must be worse
} else if (isSignificantlyOlder) {
return false ;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = ( int ) (location.getAccuracy() –
currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0 ;
boolean isMoreAccurate = accuracyDelta < 0 ;
boolean isSignificantlyLessAccurate = accuracyDelta > 200 ;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
return true ;
} else if (isNewer && !isLessAccurate) {
return true ;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true ;
}
return false ;
}
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null ) {
return provider2 == null ;
}
return provider1.equals(provider2);
}
@Override
public void onDestroy() {
// handler.removeCallbacks(sendUpdatesToUI);
super .onDestroy();
Log. v ( "STOP_SERVICE" , "DONE" );
locationManager .removeUpdates( listener );
}
public static Thread performOnBackgroundThread( final Runnable runnable) {
final Thread t = new Thread() {
@Override
public void run() {
try {
runnable .run();
} finally {
}
}
};
t.start();
return t;
}
64
public class MyLocationListener implements LocationListener
{
public void onLocationChanged( final Location loc)
{
Log. i ( "****************" , "Location changed" );
if (isBetterLocation(loc, previousBestLocation )) {
loc.getLatitude();
loc.getLongitude();
Log. d ( "lat////" , "" +loc.getLatitude());
Log. d ( "long////" , "" +loc.getLongitude());
intent .putExtra( "Latitude" , loc.getLatitude());
intent .putExtra( "Longitude" , loc.getLongitude());
intent .putExtra( "Provider" , loc.getProvider());
sendBroadcast( intent );
}
}
public void onProviderDisabled(String provider)
{
Toast. makeText ( getApplicationContext(), "Gps Disabled" , Toast. LENGTH_SHORT
).show();
}
public void onProviderEnabled(String provider)
{
Toast. makeText ( getApplicationContext(), "Gps Enabled" ,
Toast. LENGTH_SHORT ).show();
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
}
Aplica ț ia Web
home.php
<?php
class Home extends CI_Controller {
function __construct() {
parent::__construct();
65
$this->load->library("session");
$this->load->helper('url');
$this->load->model(array("user"));
$this->load->database();
}
function index() {
$this->load->view('home');
}
function getcoordinatees() {
$result=$this->db->query("SELECT * FROM tbl_user")->result_array();
$output.="<markers>";
if(count($result)>0) {
for($i=0;$i<count($result);$i++)
{
$output.='<marker ';
$output.= 'name="'.$result[$i]['name'].'" ';
$output.= 'address=" Email : '.$result[$i]['email'].'" ';
$output.= 'speed="Speed : '.$result[$i]['speed'].' " ';
$output.= 'location="location : '.$result[$i]['location'].' " ';
$output.= 'lat="' . $result[$i]['latitude'] . '" ';
$output.= 'lng="' . $result[$i]['longitude'] . '" ';
$output.= 'type="Family member" ';
$output.= '/>';
}
}
$output.="</markers>";
$this->output->set_header("Content-type: text/xml");
$this->output->set_output($output);
}
}
?>
map.php
<?php
class Map extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->helper('url');
$this->load->helper('form');
$this->load->model('general');
$this->load->database();
}
function index() {
66
$data=array();
$this->load->view('map_show',$data);
}
function getcoordinatees() {
$result=$this->db
->query("SELECT * FROM ko_employess_new limit 0,20000 ")->result_array();
$output.="<markers>";
if(count($result)>0)
{
for($i=0;$i<count($result);$i++)
{
$output.='<marker ';
$output.= 'name="'.$result[$i]['District_Manager'].'" ';
$output.= 'address=" Email : '.$result[$i]['email'].' Phone : '.$result[$i]['phone'].' " ';
$output.= 'lat="' . $result[$i]['latitude'] . '" ';
$output.= 'lng="' . $result[$i]['longitude'] . '" ';
$output.= 'type="restaurant" ';
$output.= '/>';
}
}
$output.="</markers>";
$this->output->set_header("Content-type: text/xml");
$this->output->set_output($output);
}
}
?>
Profileadmin.php (Controller)
<?php
class Profileadmin extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->helper('url');
$this->load->helper('form');
$this->load->database();
}
function index() {
$this->load->library('form_validation');
$this->load->view('adminprofile');
}
function adminpro() {
$email = $this->input->post('email');
$password = $this->input->post('password');
$result=$this->db->query("SELECT * FROM admin")->row_array();
if( $this->input->post('password')!='') {
$password = $this->input->post('password');}else{ $password = $result['password'];
67
}
if( $this->input->post('email')!='') {
$username = $this->input->post('email');}else{ $username = $result['username'];
}
$this->db->query("update admin set username='".$username
."',password='".$password."' where adminid='1'");
$this->data['updated_success']="Updated successfully";
$this->load->view('adminprofile',$this->data);
}
}
?>
profileadmin.php (View)
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Dashboard I Admin Panel</title>
<link rel="stylesheet" href="<?=base_url();?>assets/css/layout.css" type="text/css"
media="screen" />
<script src="<?=base_url();?>assets/js/jquery-1.5.2.min.js" type="text/javascript"></script>
<script src="<?=base_url();?>assets/js/hideshow.js" type="text/javascript"></script>
<script src="<?=base_url();?>assets/js/jquery.tablesorter.min.js"
type="text/javascript"></script>
<script type="text/javascript" src="<?=base_url();?>assets/js/jquery.equalHeight.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".tablesorter").tablesorter();
}
);
$(document).ready(function() {
//When page loads…
$(".tab_content").hide(); //Hide all content
$("ul.tabs li:first").addClass("active").show(); //Activate first tab
$(".tab_content:first").show(); //Show first tab content
//On Click Event
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active"); //Remove any "active" class
$(this).addClass("active"); //Add "active" class to selected tab
$(".tab_content").hide(); //Hide all tab content
var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to
identify the active tab + content
$(activeTab).fadeIn(); //Fade in the active ID content
return false;
});
});
</script>
68
<script type="text/javascript">
$(function(){
$('.column').equalHeight();
});
</script>
</head>
<body>
<?php include("includes/sidebar_header.php");?>
<section id="main" class="column">
<div class="clear"></div>
<article class="module width_full">
<header><h3>Admin Profile</h3></header>
<?php
$result=$this->db->query("SELECT * FROM admin where adminid=1")->row_array();
echo form_open('admin/profileadmin/adminpro/'); ?>
<input type="hidden" name="hadn" value="add">
<div class="module_content">
<fieldset>
<label>username</label>
<input type="text" name="email" id="email" value="<?=$result['username'];?>">
</fieldset>
<fieldset>
<label>Password</label>
<input type="text" name="password" id="service_phone"
value="<?=$result['password'];?>">
</fieldset>
<div class="clear"></div>
</div>
<footer>
<div class="submit_link">
<input type="submit" value="Submit" class="alt_btn">
</div>
</footer>
<?php echo form_close(); ?>
</article>
<div class="spacer"></div>
</section>
</body>
</html>
map_show.php
<?php
if (!isset($this->session->userdata['adminid']))
{
header("location: http://seemcodersapps.com/komet/admin/");
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
69
<title>Dashboard I Admin Panel</title>
<link rel="stylesheet" href="<?=base_url();?>assets/css/layout.css" type="text/css"
media="screen" />
<script src="<?=base_url();?>assets/js/jquery-1.5.2.min.js" type="text/javascript"></script>
<script src="<?=base_url();?>assets/js/hideshow.js" type="text/javascript"></script>
<script src="<?=base_url("assets/js/jquery.tablesorter.min.js");?>"
type="text/javascript"></script>
<script type="text/javascript" src="<?=base_url("assets/js/jquery.equalHeight.js");
?>"></script>
<script type="text/javascript">
$(document).ready(function()
{
$(".tablesorter").tablesorter();
}
);
$(document).ready(function() {
//When page loads…
$(".tab_content").hide(); //Hide all content
$("ul.tabs li:first").addClass("active").show(); //Activate first tab
$(".tab_content:first").show(); //Show first tab content
//On Click Event
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active"); //Remove any "active" class
$(this).addClass("active"); //Add "active" class to selected tab
$(".tab_content").hide(); //Hide all tab content
var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to
identify the active tab + content
$(activeTab).fadeIn(); //Fade in the active ID content
return false;
});
});
</script>
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCjNOx6cs7liIp6mq-V4KdFFRO1Do
NPnoA"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
var customIcons = {
restaurant: {
icon: 'http://labs.google.com/ridefinder/images/mm_20_blue.png'
},
bar: {
icon: 'http://labs.google.com/ridefinder/images/mm_20_red.png'
}
};
70
function load() {
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(41.6864807,-87.6285099),
zoom: 4,
mapTypeId: 'roadmap'
});
var infoWindow = new google.maps.InfoWindow;
// Change this depending on the name of your PHP file
downloadUrl("<?=base_url("admin/map_salesrep/getcoordinatees")?>", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + address;
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon
});
bindInfoWindow(marker, map, infoWindow, html);
}
});
}
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
71
}
//]]>
</script>
</head>
<body onload="load()">
<?php include("includes/sidebar_header.php");?>
<section id="main" class="column">
<article class="module width_full">
<header><h3 class="tabs_involved">Sales Representatives</h3>
</header>
<div class="tab_container">
<div id="tab1" class="tab_content">
<div id="map" style="width: 1000px; height: 800px"></div>
</div>
</div>
</article>
<div class="spacer"></div>
</section>
</body>
</html>
login.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Super Admin Login</title>
<link rel="stylesheet" type="text/css" href="
<?=base_url('assets/css/styleadmin.css')?>" />
</head>
<body>
<div class="container">
<div class="codrops-top">
<span class="right">
<a href="#">
<strong>Unitracer Admin</strong>
</a>
</span>
</div>
<header>
<h1><strong>Unitracer</strong> Admin</h1>
</br> </br> </br>
<h3 align="center" style="color:red"><?=$error?></h3>
</header>
<section class="main">
<form class="form-1" Method="post" id="admindetail" name="form">
<p class="field">
<input type="text" name="username" required="required"
placeholder="Username">
<i class="icon-user icon-large"></i>
72
</p>
<p class="field">
<input type="password" name="password" required="required"
placeholder="Password">
<i class="icon-lock icon-large"></i>
</p>
<p class="submit">
<button type="submit" id="submitDetails" class="submitDetails"
name="submitDetails" onClick="document.form.submit()">
<i class="icon-arrow-right icon-large"></i></button>
</p>
</form>
</section>
</div>
</body>
</html>
73
DECLARAȚIE DE AUTENTICITATE
A
PROIECTULUI DE FINALIZARE A STUDIILOR
Titlul proiectului
Aplicație de GPS Tracking pentru dispozitive mobile Android
Autorul proiectului PUȘCAȘ CRISTIAN
Proiectul de final izare a studiilor este elaborat în vederea susținerii examenului
de finalizare a studiilor organizat de către Facultatea
_______________ I.E.T.I. _______________ ________ __ din cadrul Universității di n
Oradea, sesiunea________iulie _________ a anului universitar __ 2017 __________ _.
Prin prezenta, subsemnatul (nume, prenume, CNP)_____________ ________ _
PUȘCAȘ CRISTIAN , CNP: a
_________________________________________________________ __________ _,
declar pe proprie răspundere că aceast proiect a fost scris de către mine, fără nici un
ajutor neautoriz at și că nici o parte a proiectului nu conține aplicații sau studii d e caz
publicate de alți autori.
Declar, de asemenea, că în proiect nu există idei, tabele, grafice, hărți sau alte
surse folosite fără respectarea legii române și a convențiilor internaționale privind
drepturile de autor.
Oradea,
Data Semnătura
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: FUNDAȚIA PENTRU CULTURĂ ȘI ÎNVĂȚĂMÂNT IOAN SLAVICI TIMIȘOARA [615740] (ID: 615740)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
