Sistem de localizare în timp real a dispozitivelor inteligente [612623]

Universitatea “Politehnica” din București
Facultatea de Electronic ă, Telecomunicații și Tehnologia Informației

Sistem de localizare în timp real a dispozitivelor inteligente
bazate pe platforma Android și asistență la navigare către
destinații fixe sau în mișcare

Proiect de diplom ă

prezentat ca cerință parțială pentru obținerea titlului de
Inginer în domeniul Inginerie Electronică și Telecomunicații
programul de studii de licență Rețele și Software de Telecomunicații

Coordonator științific Absolvent
S.L. dr. Laurențiu B OICESC U Radu -Daniel BOLCAȘ

2017

Copyright © 2017 Bolcaș Radu -Daniel

Toate drepturile rezervate

Autorul acord ă UPB dreptul de a reproduce și de a distribui public copii pe hîrtie sau
electronice ale acestei lucr ări, în form ă integral ă sau par țială.

Cuprins

Cuprins ………………………….. ………………………….. ………………………….. ………………………….. ……………. 9
Lista cu Figuri: ………………………….. ………………………….. ………………………….. ………………………….. … 11
Lista cu Acronime ………………………….. ………………………….. ………………………….. ………………………… 13
Introducer e ………………………….. ………………………….. ………………………….. ………………………….. ……… 15
Capitolul 1: Aspecte teoretice. Tehnologii folosite ………………………….. ………………………….. …………. 17
Capitolul 2: Arhitectura sistemului de localizare ………………………….. ………………………….. ……………. 21
2.1 Descrierea arhitecturii și funcționalitatea modulelor ………………………….. ………………………….. . 21
2.2 Cazuri de utilizare ………………………….. ………………………….. ………………………….. ……………….. 26
Capitolul 3: Sistemul de localizare ………………………….. ………………………….. ………………………….. ….. 27
3.1 Baza de date și serviciile web ………………………….. ………………………….. ………………………….. … 27
3.2 Aplicația Android ………………………….. ………………………….. ………………………….. ………………… 39
3.3 Interfața grafică ………………………….. ………………………….. ………………………….. …………………… 58
3.4 Elemente de securitate ………………………….. ………………………….. ………………………….. ………….. 63
Concluzii ………………………….. ………………………….. ………………………….. ………………………….. ……….. 65
Bibliografie ………………………….. ………………………….. ………………………….. ………………………….. …….. 67
Anexe 1: Activitățiile aplicației Android și AndroidManifest ………………………….. ……………………….. 69
Anexa 2: Interfața grafică ………………………….. ………………………….. ………………………….. ………………. 87
Anexa 3: Fișierele PHP ………………………….. ………………………….. ………………………….. …………………. 93
Anexa 4: Structura bazei de date ………………………….. ………………………….. ………………………….. …….. 97

Lista cu Figuri :

Figura 1.1: Arhitectura Android ………………………….. ………………………….. ………………………….. ……… 17
Figura 2.1: Arhitectura sistemului de localizare ………………………….. ………………………….. ……………… 22
Figura 2.2: Arhitectura clientului ………………………….. ………………………….. ………………………….. …….. 22
Figura 2.3: Controlul autentificării și autorizării ………………………….. ………………………….. …………….. 24
Figura 2.4: Activitatea principală a sistemului (FF) ………………………….. ………………………….. ………… 25
Figura 2.5: Modul secundar. Direcția către o locație dată (FL) ………………………….. ……………………… 25
Figura 2.6: Modul Google Maps ………………………….. ………………………….. ………………………….. ……… 26
Figura 3.1: Componența bazei de date ………………………….. ………………………….. ………………………….. 27
Figura 3.2: Ierarhia activităților ………………………….. ………………………….. ………………………….. ………. 39
Figura 3.3: Interfața grafică a activității Login ………………………….. ………………………….. ……………….. 59
Figura 3.4: Interfața grafică a activității Register ………………………….. ………………………….. ……………. 60
Figura 3.5: Interfața grafică a activității Meniu ………………………….. ………………………….. ………………. 60
Figura 3.6: Interfața grafică a activității MapsActivity ………………………….. ………………………….. …….. 61
Figura 3.7: Interfața grafică a activităților InsertCoord și GetID ………………………….. ……………………. 61
Figura 3.8: Interfața grafică a activității MainActivity ………………………….. ………………………….. …….. 62
Figura 3.9: Interfața grafică a activității FindLoc ………………………….. ………………………….. ……………. 62

Lista cu Acronime

Acronim Engleza Denumire(en) Denumire(ro)
API Application programming
interface –
DB Database Bază de date
DBMS Database management system Sistemele de gestiune a bazelor
de date
GUI/UI Graphical/User interface Interfață grafică
HAL Hardware Abstract Level Nivelul de abstractizare
hardware
IDE Integrated development
environment Mediul de dezvoltare integrat
LAMP Linux Apache MySQL PHP –
RDBMS Relational DBMS Sistemele de gestiune a bazelor
de date relaționale
REST Representational state transfer –
SDK Software development kit Kit de dezvoltare software
SQL Structured query language –
URI Uniform Resource Identifier Identificator uniform de resurse
URL Uniform Resource Locator Localizator uniform de resurse
XML Extensible Markup Language –

15 Introducere

Nevoia de comunicare, de a transmite într -un timp cât mai scurt informa ții, a devenit în zilele
noastre o necesitate primordială. Niciodată oamenii nu au comunicat atât de clar și rapid unii cu al ții,
depășind limita de timp și spa țiu.
Considerată una din cele mai puternice platforme de dezvoltare mobilă din lume , Android are
sute de milio ane de utilizatori în peste 190 de țări din lume [1]. Prin aplica țiile, jocurile și serviciile pe
care le pune la dispozi ție, Android oferă numeroase posibilități de dezvoltare atât pentru producătorii
de telefoane și dispozitive inteligente cât și pentru dezvoltatorii de software și aplicații.
Proiectul de diplomă cu titlul “ Sistem de localizare în timp real a dispozitivelor inteligente
bazate pe platforma Androi d și asistență la navigare către destinații fixe sau în mișcare” a fost
dezvoltat pe platform a Android, deoarece este una dintre cele mai utilizate platforme software în
momentul actual, având un impact uriaș la nivel mondial.

Obiectivul lucrării
Nevoia de mișcare, de a cunoaște noi oameni și locuri, face să ajungem în zone necunoscute, să
nu mai știm unde ne aflăm și cum să ajungem la destinația finală.
Aplicația realizată este un sistem care vine în ajutorul persoanelor care doresc să se întâlnească
și nu sunt familiarizate cu o anumită locație, fie că e vorba de prieteni, colegi sau alte persoane
necunoscute. Atunci când nu se cunoaște o locație , există tendința de a oferi indicații generale, care nu
ajută la localizare prin mijloacele obișnuite și anum e prin apelul telefonic. Aceste indicații sau repere
pot fi vagi sau necunoscute de ambele părți, moment în care apare o confuzie.
În acest proiect, scopul urmărit este de a ghida două dispozitive mobile, unul către celălalt, în
timp real și oferind asiste nță la navigare. Destinația poate să fie fixă (o locație anume) sau dispozitivul
partener pe care îl presupunem în mișcare. Dispozitivele pot fi telefoane mobile inteligente, tablete,
SmartWatch -uri sau orice alt dispozitiv de tipul“HandHeld” [ 2].

Contri buția practică, originală a proiectului constă în faptul că:
 S-a proiecta t și implement o aplicație de monitorizare a poziției GPS pentru terminale mobile
inteligente, cu sistem de operare Android, pe baza unei arhitecturi client -server.
 Aplicația va permite monitorizarea poziției GPS a terminalului mobil cu ajutorul unui API
HTTP securizat, precum și navigarea către alte dispozitive mobile aflate în sistem, dar și către
destinații fixe prestabilite, cu condiția respectării intimității ut ilizatorilor și a condițiilor de
securitate ale conturilor acestora .

Tema proiectului prezintă noutate prin faptul că, deși în momentul actual există un număr mare de
sisteme ce au funcții similare, acestea sunt gândite pentru aplicații diferite și sunt puține cele care dau
posibilitatea ca ambele dispozitive să fie în mișc are având localizarea făcută în timp real.
Prin localizarea cu ajutorul GPS -ului telefoanelor mobile ale celor doi parteneri și cu ajutorul
interfeței grafice, se arată direcția necesară pentru a micșora distanța dintre ei, economisind timp și
evitând o s ituație neplăcută.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
16 Majoritatea aplicațiilor sunt sisteme care sunt implementate in domeniul militar, inaccesibi le
publicului larg, care să fie utilizate în via ța cotidiană.
Prin realizarea acestui proiect, am urmărit posibilitatea utilizării lui în do meniu l medical și
social, atât î n supravegherea persoanelor bolnave de diabet, inima, Alzheimer etc, dar și în cazurile
sociale ca: pierderea copiilor in diferite loca ții, a persoanelor în excursii, dezorientarea b ătrânilor etc.

Structura și implementarea proi ectului
In realizarea practică a acestui sistem de localizare s-a implementat:
– Server -ul central de monitorizare și serviciul web pentru interacți unea cu dispozitivele mobile,
precum și baza de date aferentă;
– Interfața grafică de navigare și orientar e a utilizatorilor în cadrul aplicației pentru dispozitivele
mobile;
– Sistemul de control al accesului utilizatorilor (autentificare) și autorizarea acestora;
– Sistemul de comunicație între utilizatori și transmitere a poziției GPS.
Au fost utilizate următoarele tehnologii sau platforme: Java și PHP, MySQL și arhitectura
REST, tehnologie care st ă la baza serviciilor web, etc.

Structura lucrării
In cadrul acestui proiect de diploma, capitolele sunt structurate astfel:
 Primul capitol prezint ă aspectele teoretice ale tehnologiile folosite: realizarea bazei de dat e
(DB) cu ajutorul limbajul SQL, clase Java, limbajul P HP, arhitectura REST bazata pe
protocolul HTTP, realizarea interf eței grafice cu ajutorul limbajului XML.
 Capitolul al doilea pr ezintă arhitectura sistemului de localizare în timp real a dispozitivelor
inteligente, interac țiunea dintre componentelor hardware și software dar, și interdependen ța
dintre componentele software ce permit func ționarea lui.
 Capitolul al treilea prezintă modul de implementare a bazei de date și a serviciului web bazat pe
protocolul de comunica ție HTTP, prezentarea modului de func ționare a func țiilor PHP, a
codului sursa Java care stă la baza aplica ției Android, dar și interfa ța grafic ă ce permite
interacți unea cu utilizatorul. Totodat ă se prezintă și elementele de control și securitate al
accesului utilizatorilor, autorizarea lor și modul de protejare a informa ției.

17 Capitolul 1: Aspecte teoretic e. Tehnologii folosite

În realizarea sistemului de localizare s -a utilizat platforma Android, dezvoltat ă de Google pe
baza nucleul Linux. Acesta permite crearea de aplicații și jocuri inovative pentru dispozitive mobile în
limbajul Java [3].
Android este gândit să funcționeze pe un număr mare de dispozitive diferite între ele , el fiind o
aplicație de tip ,,open -source”. El este apoi adaptat de producătorii de telefoane mobile pentru
echipamentele lor hardware. Se pot adapt a anum ite resurse pentru a facilita această compatibilitate. De
exemplu : se pot crea fișiere grafice XML pentru fiecare dimensiune de ecran și sistemul alege fișier ul
XML potrivit [3].
Aplicațiile sunt programe software ce extind funcționalitatea dispoziti vului și se comportă ca
niște utilizatori ai sistemului Linux, fiind izolate între ele [4].

Figura 1. 1: Arhitectura Android [5]

În figura 1.1 se poate observa arhitectura unui sistem ce rulează Android. Un program ce are
rolul de a crea o interfață între componentele hardware și cele software se num ește d river. Nucleul
Linux conține toți driverii necesari utilizării componentelor hardware de bază printre care cel de WIFI,
GPS, ecran, tastatură, senzori, etc. Urmează nivelu l de abstractizare hardware (HAL) ce constă în mai
multe tipuri de bilioteci, fiecare implementând o interfață pentru o anumită componentă precum
modulele de senzori, bluetooth, interfețe grafice, GPS și altele. El oferă interfețe standard care pun la
dispoziție capabilitățile hardware nivelului Java API Framework.
Nivelul Android Runtime se bazează pe nucleul Linux pentru a crea fire de execuție și a
gestiona o valoare mică de memorie, fiecare aplicație având propriul proces și propria instanță de
Android Runtime. El este gândit să ruleze mai multe mașini virtuale pe dispozitive cu memorie puțină.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
18 S-a implementat după versiunea Android 5.0, pâna atunci existând Dalvik. Multe dintre componentele
și serviciile sistemului Android, precum HAL și Android Runtim e, sunt scrise în limbajele C și C++.
Pentru a putea fi accesate și utilizate de către API de pe nivelul superior, s -a introdus nivelul cu librării
native C/C++. Tot setul de caracteristici al sistemului de operare Android sunt accesibile prin API
scrise î n limbajul Java. Aceste API reprezintă blocurile necesare pentru a crea aplicații Android
simplificând reutilizarea nucl eului, componente și servicii modulare ale sistemului . Printre aceastea se
numără : Resource Manager ce permite accesul la resurse ca fiș iere grafice, elemente grafice, poze s au
fișiere ce conțin informații; Activity Manager ce gestionează ciclul de viață a unei aplicații și ajută cu
navigarea în interiorul ei.
Ultimul nivel îl reprezintă aplicațiile. Acestea funcționează pe baza nivelelor inferioare.
Aplicația sistemului de localizare numită WhichWayIGo funcționează tot la acest nivel [5].
Dispozitivele moderne Android sunt mult mai mult decât simple platforme ce permit doar
simple comunicații sau navigare pe internet. Ele sunt dispozitive extra -senzoriale ce folosesc senzori
hadware. Sensor Manager este utilizat pentru a administra senzorii pe dispozitivele Android. Se preferă
ca să nu se interacțion eze cu senzorii hardware direct. A ceștia sunt reprezentați de obiectele Sensor ce
descriu pr oprietățile senzorului . Printre aceste proprietăți se numără: tipul senzorului , numele,
producătorul , precum și detalii le despre precizie și domeniu de valori [ 6].
Începând cu 2015 , Google a decis ca mediul de dezvoltare integrat (IDE) oficial să devină
Android Studio . Exist ă și medii de dezvoltare alternative, printre cele mai cunoscu te fiind Eclipse și
NetBeans. Acestora li se adaugă un plugin specific pentru a putea crea aplicaț ii.
În realizarea acestui proiect s -a utilizat Android Studio , care permit e configur area unui
emulator, oferă instrumente de urmărire a performanței aplicației și depanarea ei. Acesta conține un
număr mare de biblioteci specifice fiind susținut de Google . În componența lui are și un editor al
interfeței ce permite modificarea și plasa mentul componentele grafice . Se oferă posibilitatea de a
configura un emulator care să simuleze aplicația ce a fost scris ă folosind limbajul Java , dar și urmărirea
performanțelor, a utilizării conexiunii la internet, memoria ocupată și multe altele.
Elementele cele mai des utilizate în creare a unei aplicații realizate în Android Studio sunt:
 Fișierele ce conțin codul sursă Java ,
 Fișierul Manifest ce conține AndroidManifest.xml furnizează informațiile generale
referito are la aplicație (activitățile definite, permisiunile, etc) ,
 Fișierele cu resurse ce conțin fișierele grafice XML, șiruri de caractere ale UI , imagini, etc.
Clasa AsyncTask este o clasă abstractă ce este utilizată în implementare, care se extinde și oferă
cadrul de bază p entru un proces asincron de lungă durată. Ea conține 3 metode principale :
 onPreExecute( ) ce rulează pe firul de execuție principal, pregătește procesul și anunță printr –
un mesaj utilizatorul că urmează procesul ,
 doInBackground( ) rulează pe un alt fir de execuție și conține codul pentru procesul de lungă
durată ce trebuie executat ,
 onPostExecute( ) este ap elată când procesul s -a terminat. Lucrează pe firul de execuție
principal și primește valorile rezultate de la doInBackground [7].
Fișierele XML definesc în limbaj de marcare XML, interfețele grafice ale aplicației Android.
Fiecare dint re acestea conține un con tainer layout. Etichetele XML sunt fragmente din aceste fișiere
care sunt utilizate pentru a defini atât tipul containerelor layout, cât și elemente le interfeței grafice.

Capitolul 1: Aspecte teoretice. Tehnologii folosite.
19 Aceste elemente Android le numește widget și există în interiorul containerului layout. Se folosesc
etichetele părinte pentru a defini containerul layout și etichetele copil pentru a popula acest container
cu widget -urlie interfeței grafice [ 8]. Astfel, interfața pentru fiecare componentă a aplicației este
definită utilizând o ierarhie a obiectelor. Acest arbore ierarhic poate fi simplu sau complex, dar
simplitatea oferă cea mai bună performanță [9].
Conexiunea la internet se realizează prin protocolul HTTP S. Pentru a se realiza această
conexiune este necesară definirea unei permisiuni în fișierul Manifest (anexa 1.10) . Se creează
conexiunea utilizând un URL și se întoarce o secvență ce se poate citi. Se pot , de asemenea seta diferiți
parametri precum metoda HTTP S utilizată , și altele [10]. Printre metodele cele mai utilizate sunt GET,
POST, DELETE, etc. În particular, metoda GET este utiliz ată în implementarea sistemului. Ea întoarce
informația ce este definită de UR L. Se poate ca informația întoarsă să fie adăugată în memorii le cache
spre deosebire de POST [11]. Protocolul HTTP stă la baza serviciilor web de tipul REST, WDSL,
SOAP asigurând transportul de informație.
Serviciile web sunt servere web create cu scopul de a ajuta cu funcționalitățile unui site sau unei
aplicații. Programele client utilizează un API pentru a comunica cu serviciile web. Dacă un API
respectă stilul arhitectural REST ne rezultă un REST API, ac esta constând într -un ansamblu de resurse
interconectate . Modul prin care REST API adresează o anumită resursă este prin URI [ 12]. Arhitectura
REST se bazează pe protocolul HTTP pentru a apela o anumită resursă.
Serviciile web REST impun anumite caracteris tici în crearea arhitecturii sistemului:
1)Client -Server – Constrângerea principală este reprezentată de separarea și tratarea separată a
serverului și a clientului. World Wide Web sau doar Web este un sistem în care clienții și serverele au
funcții diferi te și se pot implementa folosind orice limbaj de programare sau tehnologie atâta timp cât
au o interfață uniformă.
2)Uniform interface – Interacțiunile dintre componentele Web – adică clien ții, serverele și alte
elemente din re țea – depind de uniformitatea interfețelor lor . Dacă oricare dintre componente se
îndepărtează de standardele stabilite, atunci sistemul de comunica ții Web se întrerupe.
3)Layered System – Constrângerile de sistem stratificat permit diferitelor elemente intermediare
din rețea, cum ar fi proxy -urile și gateway -urile, să fie distribuite în mod transparent între un client și
server folosind interfa ța uniformă a Web -ului. În general, un element intermediar din re țea va
intercepta comunicarea client -server cu un anumit scop. Dispozitive din rețea sunt folosite în mod
obișnuit pentru a asigura securitatea, cache -ul de răspuns și echilibrarea încărcării.
4)Cache – Pentru a îmbunătă ți eficiența rețelei, se adaugă stilului REST contextele cache .
Folosirea memoriilor cache pentru salvarea copiilor anumitor resurse reprezintă una dintre cele mai
importante constrângeri ale arhitecturii web. Constrângerile de cache instruiesc un server web să
declare în ce măsură se poate adăuga în cache datele fiecărui răspuns. Datele de răspuns din cache po t
contribui la reducerea laten ței percepute de client, la cre șterea disponibilită ții și fiabilității globale a
unei aplica ții și la controlul încărcării unui server web. Altfel spus, cache -ul reduce costul global al
Web-ului. O memorie cache poate exista o riunde de -a lungul căii de re țea între client și server.
5)Stateless – Constrângerea lipsei de stare dictează faptul că un server web nu este obligat să
memoreze starea aplica țiilor clientului. În consecin ță, fiecare client trebuie să includă toate inform ațiile
contextuale pe care le consideră relevante pentru fiecare interac țiune cu serverul web. Serverele web
solicită clien ților să gestioneze complexitatea comunicării stării aplica ției, astfel încât serverul web să

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
20 poată servi un număr mult mai mare de c lienți. Acest compromis este un factor care contribuie la
scalabilitatea stilului arhitectural al Web -ului.
6) Code on demand – Web-ul utilizează des codul la cerere, o constrângere care permite
serverelor web să transfere temporar către clien ți programe e xecutabile , cum ar fi script -uri sau plug in-
uri. Codul la cerere tinde să stabilească o legătură tehnologică între serverele web și clienții lor,
deoarece clientul trebuie să poată în țelege și executa codul pe care îl descărcă la cerere de la server.
Din a cest motiv, codul la cerere este singura constrâ ngere a stilului arhitectural Web care este
considerat ă opțional ă [12].
Modelul web, de tip ,,open source”, cunoscut ca și LAMP conține sistemul de operare Linux,
serverul HTTP Apache, sistemul de gestiune a bazelor de date relaționale MySQL și limbajul de
programare PHP. Acest model este ușor de implementat și oferă toate funcționalitățile de bază necesare
unui server web.
,,PHP (acronim recursiv pentru PHP: Hypertext Preprocessor) este un limbaj de scripting de uz
general, cu cod -sursă deschis (open source), utilizat pe scară largă, și care este potrivit în special pentru
dezvoltarea aplicațiilor web și poate fi integrat în HTML ” [13].
„Codul -sursă PHP este încorporat între niște instrucțiuni de procesare de început și de sfârșit
speciale <?php și ?>, care permit intrarea și să ieșirea din "modul PHP". Ceea ce face PHP să difere de
un JavaScript de partea clientului este codul, care este executat pe server, generând HTML care este
apoi trimis către client. Cli entul va primi rezultatele rulării acelui script, fără a putea cunoaște codul –
sursă ce stă la bază. Se poate configura server ul web să proceseze toate fișierele HTML cu PHP, și
atunci nu există nici o modalitate ca utiliz atorii să afle cum funcționează” [13].
PHP este disponibil pentru multe sisteme de operare și pentru serverele web și poate accesa
bazele de date cele mai comune, inclusiv MySQL. PHP poate fi rulat ca un program separat sau
compilat ca un modul de utilizare cu un server Web [1 4].
Un API definește clasele, metodele, funcțiile și variabilele pe care aplicația va trebui să le
apeleze pentru a -și îndeplini sarcinile dorite. În cazul aplicațiilor PHP care au nevoie să comunice cu
bazele de date, API -urile necesare sunt de obicei expuse pr in extensii PHP. În MySQL, termenul
conector se referă la un software care permite aplicației să se conecteze la serverul de baze de date
MySQL . Un driver este un software conceput pentru a comunica cu un anumit tip de server de baze de
date. De asemenea, driver -ul poate apela o bibliotecă Aceste biblioteci implementează protocolul
utilizat pentru a comunica cu serverul de bază de date MySQL [14].
Baza de date MySQL se poate gesti ona fie prin comenzi date în terminal, fie prin instalarea unui
program numit phpMyAdmin ce permite administrarea și gestionarea bazei de date. În crearea bazei de
date și gestionare ei s -a utilizat a doua metodă.
O greșeală ce se poate face de un dezvoltator de software web este să acorde toata încrederea
utilizatorului în introduc erea unei comenzi SQL. O comandă SQL inteligent scrisă poate ocoli
controalele de acces, în consecință să treacă peste metodele de autentificare și verificările de
autorizație, iar câteodată poate chiar să faciliteze accesul la comenzile de sistem. Injecta rea directă a
comenzilor SQL este o tehnică în care atacatorul creează sau modifică comenzile SQL pentru a scoate
la iveală datele sensibile, sau pentru a suprascrie o anumită valoare, sau chiar pentru a executa comenzi
periculoase la nivel de sistem. Aces t lucru este înfăptuit de către aplicația care preia valoarea de intrare
a utilizatorului, îl combină cu parametrii statici pentru a forma o comandă SQL [15].

21 Capitolul 2: Arhitectura sistemului de localizare

2.1 Descrierea arhitecturi i și funcționalitatea modulelor

În realizarea sistemului de localizare în timp real a dispozitivelor inteligente avem nevoie de:
1. Componente Hardware
a. Senzor accelerometru
b. Senzor magnetic
c. Sistemul GPS al telefonului inteligent
d. Server cu conexiune la internet
2. Componente Software
a. Baza de date
b. Funcțiile PHP ce permit gestionarea valorilor în DB
c. Serviciile web ce leagă clientul de DB
d. Codul sursă al aplicației Android
e. Interfața grafică a aplicației Android
f. Elemente de securitate

Telefoanele mobile inteli gente vin echipate cu diferite tipuri de senzori, printre care cei mai
uzuali sunt accelerometrul, senzorul magnetic, senzorul de proximitate, senzorul de lumina, etc.
Sistemul folosește accelerometrul împreună cu senzorul magnetic și cu receptorul GPS pen tru
realizarea funcției de bază și anume localizarea și afișarea direcției de mers pentru a găsi telefonul
partener.
Atunci când accelerometrul detectează mișcare se presupune că s -a schimbat poziția telefonului
și se declanșează procedura de actualizare a locației.
Senzorul magnetic este apelat pentru a indica nordul, direcție cardinală ce este folosită ca un
reper comun între 2 clienți parteneri , facilit ând simplificarea algoritmului de calcul a direcției ce
trebuie urmată de parteneri pentru a se găsi.
Serverul web face legătura între clienții sistemului ce se vor conecta la internet pentru a
introduce în baza de date locația lor curentă . Pe acest server se găsește baza de date și fișierele cu
funcțiile PHP, ce urmează să fie accesate din telefonul inteligent.
Baza de date se folosește ca un mediu comun între telefoanele inteligente. Ea s-a utilizat cu
scopul de a obține o centralizare a tuturor informațiilor necesare localizării (coordonate geografice și
momentul în care au fost introduse în baza de date), dar și pentru a salva detaliile cu cara cter personal
al utilizatorilor pentru autentificare.
În continuare este nevoie ca baza de date să poată să fie accesată de un client în vederea
autentificării, a introducerii de valori și citirea câmpurilor d e interes. În vederea obținerii acestei
legături dintre baza de date și client se folosesc niște funcții scrise în limbaj PHP ce realizează
funcționalit ățile menționate . Se poate astfel defini necesitatea pentru următoarele funcții: Autentificare ,
Deconect are, Creare de cont nou , Introducerea coordonatelor în baza de date , Citire a coordonatelor
telefonului partener din baza de date , Citirea tuturor utilizatorilor .
Aceste funcții sunt scrise în limbajul PHP și conțin operații pe șiruri de caractere și condiții
logice de egalitate. Descrierea modului de funcționare a acestor funcții este prezentată în capitolul 3.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
22 Serviciile web alese pentru a permite funcționalitatea sistemului sunt serviciile REST, ce permit
un schimb ușor de informații între baza de date și client fiind bazate pe metodele de cerere HTTP.
O componentă software importantă o reprezintă codul sursă al aplicației ce înglobează toate
componentele prezentate anterior, făcând posibilă interacțiunea telefonului inteligent cu serverul,
local izarea și memorarea poziției geografice prin activarea GPS -ului și apelarea acestuia la un interval
constant, calculele bazate pe orientarea dispozitivului în spațiu și navigarea acestuia către locația dorită.
În figura 2.1, este prezentată structura arhit ecturii sistemului de localizare. Clienții utiliz ează
protocolul HTTP sau HTTPS pentru a se conecta la server și apelează servicii le REST pentru a se
conecta cu baza de date.

Figura 2.1: Arhitectura sistemului de localizar e

În figura 2 .2, este prezentată arhitectura clientului și se poate observa dependența între codul
sursă ce apelează senzorii dispozitivului inteligent pentru a realiza funcționalitatea sistemului cât și
afișarea diferitelor informații pentru client, spre exemp lu direcția de urmat și distanța până la partener.

Figura 2.2: Arhitectura clientului

Capitolul 2: Arhitectura sistemului de localizare
23 Interfața grafică este bazată pe fișierele XML ce se asociază activităților aplicației Android. În
acest mod se adaugă toate elementele grafice necesare afișării direcției de urmat și a altor informații
referitoare la poziția partenerului cât și editoarele de text ce se folosesc la introducerea de informații ce
urmează să fie prelucrate.
Elementele de securitate se referă la măsurile luate pentru a proteja datele cu caracter personal
al utilizatorilor, elementele de autentificare și autorizare și nu în ulti mul rând la transportul informație i
printr -un protocol securizat și anume HTTPS.
Sistemul de localizare funcționează cu multe valori , însă cele mai importante sunt: coordonatele
geografice, data și ora când acestea au fost introduse în baza de date, ID -ul utilizatorului căruia îi
corespund coordonatele, gradul de disponibilitate ce indic ă posibilitatea ca el să fie localizat de alți
utilizatori, informațiile de autentificare și autorizare, dacă un anumit utilizator este sau nu autentificat.
Aceste informați i se găsesc atât în baza de date cât și în aplicația Android.
În dezvoltarea codului sursă ce rulează pe telefonul clientului s-au definit următoarel e 3 moduri
de funcționare:

1. Modul principal: cu un dispozitiv inteligent alegem un partener ce se află la d istanță și pe care
dorim să îl localizăm. Localizarea se face prin intermediul telefonului inteligent pe care acest
partener îl are asupra sa. Se afișează direcția de mers, dar și distanța rămasă până la întâlnirea
celor doi. Acesta este referit în lucrare ca FF ( FriendFinder ).
2. Modul secundar: se introduc de la tastatură coordonatele geografice a unei locații și se afișează
direcția și distanța p ână la ea, referit în lucrare și ca FL ( FindLocation ).
3. Modul Google Maps: prin folosirea API de la Google pentru hărțile lor, aplicația ne arată pe
hartă locația curentă și locația telefonului căutat.

Aceste moduri de funcționare sunt bazate pe următoarele 9 activități din aplicația Android :
1. Login
2. Register
3. Logout
4. Meniu
5. GetID
6. MainActivity
7. InsertCoord
8. FindLoc
9. MapsAct ivity

Activitățile principale al e sistemului de localizare sunt MainActivity, FindLoc și
MapsActivity ce corespund celor 3 moduri de funcționare și sunt prezentate împreună cu controlul
autentificării și autorizării.
În figura 2.3 se poate observa existen ța claselor Login, Logout și Register ce e xind clasa
Activity și clasele A ttemptLogin, AttemptLogout și AttemptRegister ce extind clasa AsyncTask, ultima
este o clasă ce permite rularea ultimilor 3 pe firul de execuție a interfeței grafice. Aceste 6 clase
lucrează împreună în realizează funcțiile de autentificare, deconectare și crearea unui cont nou.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
24

Figura 2 .3: Controlul autentificării și autorizării

În figura 2.4 se arată dependența claselor Meniu, GetID, MainA ctivity de clasa Activity, clasă
ce o extind. De asemenea, MainActivity implementează interfata SensorEventListener, interfață ce face
posibil accesul la valorile furnizate de senzorii dispozitivului inteligent. Clasa MyLocationListener
implementează inter fața LocationListener , care permite localizarea telefonului prin GPS.

Capitolul 2: Arhitectura sistemului de localizare
25
Figura 2 .4: Activitatea principală a sistemului (FF)
În figura 2.5 este prezentat modul secundar de funcționare, mod ce include clasele
InsertCoord, Meniu și FindLoc ce extind clasa Activity. Clasa InsertCoord implementează interfața
SensorEventListener ce permite obținerea valorilor măsurate de senzori.

Figura 2.5: Modul secundar. Direcția către o locație dată (FL)

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
26 În figura 2.6 se observă extinderea clasei FragmentActivity de către clasa MapsActivity și
implementarea de către MapsActivity a interfeței OnMapReadyCallback, interfața proprie Google și
care permite afișarea hărților și permite un set de funcții specifice.

Figura 2.6: Modul Google Maps

2.2 Cazuri de utilizare

Aplica ția privind sistemul de localizare prezentat î n lucrare vine în asistența persoanelor care doresc să
se întâlnească și care nu sunt familiarizate cu locația în care se află. Pentru a evita furnizarea unor
repere generale ori necunoscute de ambele părți, această aplicație îi va ajuta la navigarea reciproc ă a
unuia către celălalt .
O altă utilizare a aplicației este atunci când cele două persoane se găsesc într -o zonă aglomerată,
moment în care mișcarea continuă cât și lipsa unor repere relevante fac imposibilă întâlnirea.
În ultimii ani, acoperirea rețelelor de telefonie mobilă a crescut foarte mult, aceasta incluzând și
versanți muntoși. Astfel, în cazul unui accident, fie ca se petrece în zone de șes sau în zone montane
greu accesibile, în baza de date va fi memorată ultima locație a telefon ului, locație ce va ajuta
echipaje le de salvare. De asemenea , în cazul unor activități periculoase precum : drumețiile, alpinismul,
vâslirea pe ape repezi ( eng. „rafting”) și multe altele, sistemul poate fi utilizat ca me toda de precauție și
prevenire.
Sistemul de localizare poate fi utilizat și în domeniul medical și social, pentru persoane le
bolnave de diabet, boli de inima, Alzheimer, etc ce necesită supraveghere permanentă, dar și în cazurile
sociale ca: localizarea copiilor în diferite situații , dezorientarea b ătrânilor etc, atâta timp cât presupune
existen ța unui telefon mobil.
O altă utilizare este atunci când se pleacă în grup spre o anumită destinație fie cu mașina sau pe
jos. În cazul în care se folosesc mașinile, în zonele urbane aglomerate, șoferii și -ar dori să știe unde
sunt re stul persoanelor din grup, aplicația venind în ajutorul lor. Același lucru în cazul excursioniștilor .

27 Capitolul 3: Sistemul de localizare

3.1 Baz a de date și serviciile web

În realizarea sistemului , așa cum este menționat in capitolul 2 , este neces ară existența unui
Server care să conțină o bază de date necesară stocării de informații și să permită accesul clienților la
un anumit set de funcții asupra ei . Din motive administrative și de securitate este permisă clienților
modificarea anumitor câmpuri și există condiții de securitate implementate pentru a menține
integritatea sistemului.
Se instalează pe un calculator conectat la internet modelul web , de tip ,,open sour ce”, cunoscut
ca și LAMP , ce conține sistemul de operare Linux, serverul HTTP Apache, sistemul de gestiune a
bazelor de date relaționale MySQ L și limbajul de programare PHP, calculator ce va fi numit acum
server web.
Baza de date MySQL se poate gestiona fie prin comenzi date în terminal, fie prin instalarea unui
program numit phpMyAdmin ce permite administrarea și gestionarea bazei de date. În crearea bazei de
date și gestionare ei s -a utilizat a doua metodă. Structura DB se găsește în anexa 4.
În figura 3. 1 se poate observa baza de date ce va fi folosită în continuare numită „localizare” și
conțin utul ei format din două tabele:
 Tabela ,, utilizatori ”
 Tabela ,, poziții ”

Figura 3 .1: Componența bazei de date

Tabela utilizatori memorează informații despre client , ori de câte ori se realizează înregistrarea
unui cont nou sau când se realizează autentificarea și autorizarea. În aceast ă tabelă se regăsesc
informații privind datele cu caracter personal al e utilizatorilor , precum câmpurile:

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
28  ID este câmpul ce identifică unic fiecare utilizator în parte și după care se face căutarea
și alegerea telefonului partener ,
 NickName este numele pe care clientul îl setează în momentul înregistrării ,
 Pass reprezintă parola pe care utilizatorul a introdus -o în momentul înregistrării ,
 Login este un câmp ce ne arată dacă respectivul utilizator este autentificat sau nu.

Tabela poziții memorează informații referitoare la coordonatele geografice ale utilizatori lor
atunci când baza de date primește aceste date de la aplicația Android. În aceast ă tabelă se găsesc
următoarele câmpuri:
 ID are aceleași funcții ca și în tabela utilizatori ,
 Latitudine ,
 Longitudine ,
 DataTimp reprezintă data și ora când informațiile au fost introduse în baza de date ,
 NickName reprezintă același nume care a fost introdus de client și are aceeași valoare
ca și câmpul din tabela utilizatori ,
 Status este un câmp ce arată disponibilitatea unui clie nt de a fi găsit. Valoarea de 0”
reprezintă modul Invizibil și ”1” modul Vizibil .

În realizarea legăturii clientului cu baza de date este necesară existența unor servicii web.
Serviciile web alese pentru a permite funcționalitatea sistemului sunt serviciile REST, ce permit un
schimb ușor de informații între baza de date și client fiind bazate pe metodele de cerere HTTP. Prin
intermediul arhitecturii REST se interoghează și se lansează cereri serverului web. Metoda HTTP
aleasă este ,,GET” fiind metoda utilizată pentru a obține o resursă de la server fără a oferi un volum
mare de informați i pentru a fi procesate. Fiecare cerere este identificată prin URL și informația este
transmisă pentru a fi introdusă în baza de date sau în cazul descendent, înregistrarea din DB cerută prin
cerere este găsită și serverul răspunde clientului Android cu in formația cerută.
Metoda ,,GET” transmite informații prin adăugarea la sfârșitul URL -ului a datelor ce se doresc
a fi transmise. Lungimea unui URL este limită la 2048 de caractere și din acest motiv metoda ,,GET”
are un volum de informații limitat. În caz ul transmisiunii de informație de la clientul Android la baza
de date, nu există necesita tea de a transmite mai multă informație decât această limită.
În momentul realizării unei cereri a unui servici u, către serverul web, de către aplicația Andoid,
nu se memorează contextul în care aceast ă accesare s -a realizat. Cererea pentru un anumit serviciu
conține toată informația necesară pentru a funcționa serviciul web apelat. În acest caz nu este necesară
memorarea contextului un ei cereri pentru a avea o sesiune interactivă cu utilizatorul cum se întâmplă în
alte cazuri. Astfel nu se alocă memorie dinamic pentru a memora și gestiona informațiile și starea unui
client pe parcursul a mai multor cereri. Acest lucru este de dorit pent ru că în anumite utilizări ale
sistemului, precum cele de salvare, este necesară o introducere în baza de date a coordonatelor cât mai
rapid și simplu. Introducerea se face astfel printr -un singur mesaj și trebuie să nu depind ă de mesajele
anterioare. În c azul în care conexiunea la internet fluctuează , cum se poate întâmpl a în zonele montane
din cauza reliefului, a lipsei de antene de transmisie/recepție ce ar oferi suficientă acoperire , ar putea să
nu se realizeze încărcarea locației dintr -un singur mesaj, situație ce ar putea produce implicații tragice.

Capitolul 3: Sistemul de localizare
29 În cazul unei cereri , răspunsurile primite de către dispozit ivul inteligent de la server, sunt
salvate în memoriile cache ale diferitelor echipamente de rețea intermediare. Informațiile sunt
transmise prin intermediul URL, iar răspunsul este format din tr-un număr mic de caractere. Conexiunea
este făcută prin metoda GET a protocolului HTTP și p ermite unor anumite copii ale acestor informații
să fie salvate prin memoriile cache a le rețelelor, cu scopul reducerii traficului și a încărcării serverului.
Un utilizator când face o cerere către o informație din baza de date nu cunoaște dacă acel server
este serverul final sau dacă este legat la un server intermediar. Acest lucru folosește la o distribuire a
cererilor pe mai multe servere intermediare, reducând încărcarea serverului final. Serverele
intermediare pot fi structurate ierarhic și oferă funcț ii și servicii nivelelor superioare. În implementarea
sistemului de localizare este utilizat un singur server datorită numărului redus de utilizatori creând o
încărcare mică pentru acesta.
O caracteristică a arhitecturii REST este că î n unele cazuri un ser ver poate să extindă sau să
personalizeze funcționalitatea aplicației clientului transferând cod executabil , dar nu este utilizat în
toate cazuri le. Modul în care sistemul de localizare este proiectat , nu utilizează aceasta caracteristică
deoarece tot codu l necesar este inclus în aplicația Android.
Interfața grafică uniformă si mplifică sistemul și permite o dezvoltare ulterioară independentă a
fiecărei componente în parte a arhitecturii [12].
În implementarea serviciilor REST se folosește lim bajul PHP care realizează conexiunea și
schimbul de informații dintre clientul Android și server. Fișierele realizate sunt următoarele:
1. Settings – conține setările de bază ,
2. Datacon – realizează conexiunea la baza de date aflată pe server,
3. PutPosition – introduce o nouă locație în baza de date ,
4. GetPosition – citește o anumită înregistrare și o trimite ca răspuns la aplicația Android ,
5. GetIDs – răspunde cu o listă a ID -urilor și NickName -ul aferent,
6. Login ,
7. Logout ,
8. Register .

1. Fișierul Settings

Acesta conține setăril e de bază.

$MySqlHostname = "localhost";
$MySqlUsername = "******** ";
$MySqlPassword = "******** ";
$db = "localizare";

În acest fișier sunt declarate ca variabile hostname -ul serverului, numele de utilizator, parola
acestuia și numele bazei de date apelată. Numele de utilizator și parola se referă la accesul în baza de
date pentru a avea posibilitatea de a modifica și introduce informație. Acestea sunt diferite de ID și
Pass care sunt informațiile de autentificare a clienților către conturile lor.

$row1BgColor = "#FFFFFF";

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
30 $row2BgColor = "#C0C0C0";
$dbConnectionFile = "include( \"datacon.php \");";

Sunt declarate două variabile care reprez intă culorile rândurilor din DB. O ultima variabilă este
setată să includă fișierul de conexiune a bazei de date ,,datacon.php”.

2. Fișierul datacon

Prin intermediul acestui fișier se realizează conecțiunea la baza de date:

include("settings.php");
$dblink=MYSQL_CONNECT($MySqlHostname, $MySqlUsername, $MySqlPassword)
OR DIE("Unable to connect to database");

În acest fișier se include fișierul ,,Settings” și se creează o variabilă care realizează legătura
către baza de date numită ,,dblink” . Se folo sesc informațiile de autentificare pentru baza de date ,
definite în fișierul ,,settings”. În cazul în care nu se poate realiza conexiunea, se afișează un mesaj de
eroare și se iese din script.

@mysql_select_db("$db") or die( "Unable to select database");

În cazul în care conexiunea se realizează, se selectează baza de date definită în fișierul
,,settings.php”, iar dacă eroarea se produce în acest stadiu, se afișează mesajul de eroare prezentat și se
iese din script.

3. Fișierul PutPosition

Această funcție este apelată din aplicația Android printr -un URL pentru a introduce în baza de
date poziția dispozitivului curent . De exemplu pentru următorul U RL, valorile conținute de acesta sunt:

http:// xxx.xxx.xxx.xxx/FF/putPosition.php?id=7&n=Alex&L a=50&Lg=25&st=1
 ID=7
 NickName=,,Alex”
 Latitudine= 50
 Longitudine= 25
 Status=1

Valoarea ,,xxx.xxx.xxx.xxx” reprezintă adresa IP a unui server privat. Dacă câmpul login din
tabela utilizatori este egal cu “1” atunci valorile sunt introduse . În caz contrar se ignora cererea.

include("datacon.php");
$cuvant=$_GET['id'];
$nick=$_GET['n'];
$lat=$_GET['La'];
$lon=$_GET['Lg'];
$st=$_GET['st'];

Capitolul 3: Sistemul de localizare
31 Fișierul include ,,datacon.php” pentru a realiza conexiunea la baza de date și preia din URL
apelat din aplicație , valorile menționate mai sus pe care le salvează în niște variabile.

banlist = array
(
"insert", "select", "update", "delete", "distinct", "having",
"truncate", "replace", "handler", "like", "as", "or", "procedure",
"limit", "order by", "group by", "asc" , "desc"
);

Se creează o matrice cu toate comenzile SQL în vederea realizării unei testări împotriva unui
posibil atac asupra bazei de date, în care se încearcă injectarea de comenzi SQL.

if ( eregi ( "[a -zA-Z0-9]+", $cuvant ) )
{
$cuvant = trim ( str _replace( $banlist,'', strtolower ( $cuvant )));
}
else
{
$cuvant = NULL;
}

Dacă se primește un ID, de format text sau numeric, se elimină spațiile albe și toate eventualele
comenzile SQL ce sunt memorate în matrice și care ar putea fi primite prin această valoare . Valoarea
ID este apoi convertită în litere minuscule. În cazul în care valoarea primită prin ID nu este text, se
setează implicit ca NULL.

$query = "select login from utilizatori where ID=$cuvant";
$result = MYSQL_QUERY($query);
if ($result==1)
{
$queryselect = "select * from pozitii where ID=$cuvant";
$resultselect = MYSQL_QUERY($queryselect);
$numbersearchselect = mysql_Numrows($resultselect);
if ($numbersearchselect>0)
{
$querysearch = "update pozitii set
DataTimp=now(),Latitud ine=$lat, Longitudine=$lon, Status=$st
where ID=$cuvant";
$resultsearch = MYSQL_QUERY($querysearch);
}
else
{
$querysearch = "insert into pozitii
(DataTimp,ID,NickName,Latitudine,Longitudine,Status) VALUES
(now(),$cuvant,'$nick', $lat, $lon,$st)";

$resultsearch = MYSQL_QUERY($querysearch);
}
}

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
32 Se face o interogare a valorii Login din tabela utilizatori . Dacă aceasta este ,,0” cererea se
ignoră, iar dacă aceasta este ,,1” în continuare se generează o interogare a bazei de date unde se
selectează toat e câmpurile din tabela poziții pentru înregistrarea cu valoarea ID.
Dacă există cel puțin un câmp selectat, atunci se realizează o interogare în care se actualizează
pentru această înregistrare data și ora, latitudinea, longitudinea și disponibilitatea. Î n cazul în care nu
există nici un câmp selectat, atunci se introduce informațiile menționate mai sus ca o înregistrare nouă
în tabela poziții .
Această funcție introduce ultima valoare transmisă către server, valori ce reprezintă în
momentul respectiv informațiile despre ultima poziție cunoscută a respectivului client.

4. Fișierul GetPosition

Această funcție este apelată din aplicația Android printr -un URL ce conține ID-ul corespunzător
dispozitivului partener. Forma acestui URL este:

http:// xxx.xxx.xxx.xxx /FF/getPosition.php?id= 45

Funcția ,,getPosition.php” selectează din tabela poziții înregistrarea corespunzătoare a ID-ului și
întoarce aplicației informațiile despre ultima poziție cunoscut ă a telefonului partener. Acestea sunt
următoare le:
 Latitudine
 Longitudine
 Status
 DataTimp

include("datacon.php");
$cuvant=$_GET['id'];

Fișierul include ,,datacon.php” pentru a realiza conexiunea la baza de date și prei a din URL -ul
apelat din aplicație, v aloarea ID-ului cerut ce va fi salvată într -o variabilă.
Ca și în cazul lui ,,putPosition”, deoarece utilizatorul este cel ce introduce valoarea ID este
necesară o verificare împotriva injectării de comenzi SQL. Se definește o matr ice similară ca în cazul
precedent. Aceasta se poate vedea în anexa 3.7.

if ( eregi ( "[a -zA-Z0-9]+", $cuvant ) )
{
$cuvant = trim ( str_replace( $banlist,'', strtolower ( $cuvant )));
}
else
{
$cuvant = NULL;
}

Capitolul 3: Sistemul de localizare
33 În cazul în care valoarea primită prin ID este un caracter alfanumeric , se elimin ă spațiile albe și
toate posibilele comenzile SQL ce pot fi transmise prin ID, acesta fiind comparat cu comenzile
memorate în matrice . Valoarea ID este apoi convertită în litere minuscule. În cazul în care valoarea
primită prin ID nu este text, se salvează variabila ce primește valoarea ID ca NULL.

$querysearch = "select Latitudine,Longitudine,Status, MAX(DataTimp)
from pozitii where ID=$cuvant";

$resultsearch = MYSQL_QUERY($querysearch);
$numbersearch = mysql_Numrows($resultsearch);

În continuare se generează o interogare a bazei de date unde se selectează pentru un ID din
tabela poziții valorile latitudine, longitudine, status, dataTimp .

if ($numbersearch>0)
{
$x=0;
while ($x<$numbersearch)
{
$rom=mysql_result($resultsearch,$x,"Latitudine");
echo $rom; ?>, <?

$eng=mysql_result($re sultsearch,$x,"Longitudine");
echo $eng; ?>,<?

$st=mysql_result($resultsearch,$x, "Status");
echo $st; ?>,<?

$dt=mysql_result($resultsearch,$x,3);
echo $dt;

$x++;
} // end while

$exista='D';
} // end if
else
{
$exista='N';
}

mysql_free_result($resultsearch);

Dacă interogarea a întors cel puțin o înregistrare, atunci se inițializează o variabilă x=0 ce
contorizează câmpurile , urmând să se creeze o bucla while ce va lua fiecare câmp întors de BD și îl va
salva într -o variabilă . Va afișa valorile câmpurilor separate printr -o virgulă. Când s -a terminat bucla,
variabila exista va indica că s-a obținut o înregistrare. În cazul opus, această variabilă va indica că
interogarea bazei de date nu a oferit nici o înregistrare ca răspuns . În final se eliberează variabila ce a
conținut interogarea.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
34
5. Fișierul GetIDs

Această funcție este apelată identic ca și cele prezentate precedent printr -un URL pentru a
selecta din baza de date toate ID-urile și NickName -urile. Forma URL -ului este următoarea:

http:// xxx.xxx.xxx.xxx /FF/getIDs.php

Fișierul ,,getIDs.php” include ,,datacon.php” pentru a realiza conexiunea la baza de date.

$querysearch = "select distinct ID,NickName from pozitii";

$resultsearch = MYSQL_QUERY($querysearch);
$numbersearch = mysql_Numrows($resultsearch);

Se realizează cre ează o interogare a bazei d e date unde se selectează câmpurile ID și NickName
din tabela poziții .

if ($numbersearch>0)
{
$x=0;
while ($x<$numbersearch)
{
$rom=mysql_result($resultsearch,$x,"ID");
echo $rom; echo ", ";

$eng=mysql_result($resultsearch,$x,"NickName");
echo $eng;

$x++;
} // end while
$exista='D';
} // end if
else
{
$exista='N';
}

mysql_free_result($resultsearch);

Dacă interogarea a întors cel puțin o înregistrare, atunci se inițializează un contor x=0, urmând
bucla while ce va lua fiecare pereche de câmpur i ID și NickName întors de BD și salvează fiecare într –
o variabilă . Aceste valori vor fi afișate separate prin rânduri și virgule. Când s -a terminat bucla,
variabila exista va indica că s -a obținut o înregistrare. În cazul opus, această variabilă va indica că
interogarea bazei de date nu a oferit nici o înregistrare ca răspuns. În final se eliberează variabila ce a
conținut interogarea.

Capitolul 3: Sistemul de localizare
35 6. Fișierul Login

Funcția ,,login.php” se ocupă cu cererea de autentificarea a unui utilizator și cu autorizarea
acestuia. Este apelată printr -un URL ce conține ID-ul și Pass -ul ce corespun d dispozitivului partener.
De exemplu pentru următorul U RL, valorile conținute de acesta sunt:

http:// xxx.xxx.xxx.xxx /FF/login.php?id=31&pass=qwe
 ID=31
 Pass= ,,qwe”

include("datacon.php");
$cuvant=$_GET['id'];
$pass=$_GET['pass'];

Fișierul include ,,datacon.php” pentru a realiza conexiunea la baza de date și preia din URL
valorile menționate mai sus pe care le salvează în niște variabile.
Se creează o matrice cu toate comenzile SQL în vederea realizării unei testări împotriva
injectării de comenzi SQL. Această matrice se găsește în anexa 3.3. Este important să nu se poată
accesa baza de date prin această metodă deoarece se poate evita securitatea și accesa conturile tuturor
utlizatorilor.

if ( eregi ( "[a -zA-Z0-9]+", $cuvant ) )
{
$cuvant = trim ( str_replace( $banlist,'', strtolower ( $cuvant )));
}
else
{
$cuvant = NULL;
}

Similar ca și în cazul funcției ,,putPosition.php”, dacă se primește un ID, de format text sau
numeric, se elimin ă spațiile albe și toate eventualele comenzile SQL ce sunt memorate în matrice și
care ar putea fi primite prin această valoare. Valoarea ID este apoi convertită în litere minuscule. În
cazul în care valoarea primită prin ID nu este text, se setează implicit ca NULL.

$queryselect = "select * from utilizatori where ID=$cuvant AND
pass='$pass'";

$resultselect = MYSQL_QUERY($queryselect);
$numbersearchselect = mysql_Numrows($resultselect);

În continuare se selectează din baza de date toate câmpurile din tabela utilizatori unde
înregistrarea conține valorile ID și Pass primit e prin intermediul URL .

if ($numbersearchselect>0)
{

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
36 $querysearch = "update utilizatori set login=1 where ID=$cuvant";

$resultsearch = MYSQL_QUERY($querysearch);
echo("1");
}
else
{
echo("0");
}

În cazul în care există cel puțin un câmp selectat, atunci se realizează o interogare în care se
setează pentru această înreg istrare câmpul Login cu ,,1” din tabela utilizatori și se întoarce o valoare
,,1” către aplicația Android ce semnifică o autentificare realizată cu succes. În cazul în care nu există o
înregistrare cu ID și Pass introduse, atunci se întoarce valoarea ,,0”, autorizare eșuată.

7. Fișierul Logout

Această funcție se ocupă cu cererea de deconectare a unui utilizator. Similar ca la funcția
,,login.php” este apelată printr -un URL ce conține ID-ul și Pass -ul ce corespund dispozitivului
partener . Forma URL este următoarea:

http:// xxx.xxx.xxx.xxx /FF/logout.php?id= 19&pass= rty

Informațiile ce sunt transmise prin intermediul acestui URL sunt:
 ID=19
 Pass= ,, rty”

include("datacon.php");
$cuvant=$_GET['id'];
$pass=$_GET['pass'];

Fișierul include ,,datacon.php” pentru a realiza conexiunea la baza de date și preia din URL
valorile ID si Pass , pe care le salvează în niște variabile.

if ( eregi ( "[a -zA-Z0-9]+", $cuvant ) )
{
$cuvant = trim ( str_replace( $banlist,'', strtolower ( $cuvant )));
}
else
{
$cuvant = NULL;
}

Se creează matricea cu toate comenzile SQL împotriva injectării de comenzi SQL (anexa 3.4) .
Similar funcțiilor precedente, dacă se primește un ID, de format alfanumeric, se elimin ă spațiile albe și
toate eventu alele comenzile SQL memorate în matricea banlist . Valoarea ID este apoi convertită în

Capitolul 3: Sistemul de localizare
37 litere minuscule. În cazul în care valoarea primită prin ID nu este text, se setează variabila utilizată
pentru memorarea ID-ului ca NULL.

$queryselect = "select * from utilizatori where ID=$cuvant AND
pass='$pass'";
$resultselect = MYSQL_QUERY($queryselect);
$numbersearchselect = mysql_Numrows($resultselect);

Se selectează din baza de date toate câmpurile din tabela utilizatori unde înregistrarea conține
valorile ID și Pass primite prin intermediul URL.

if ($numbersearchselect>0)
{
$querysearch = "update utilizatori set login=0 where ID=$cuvant";
$resultsearch = MYSQL_QUERY($querysearch);
}
else
{}

Dacă există un câmp selectat, atunci se creează o cerere în care se setează pentru aceasta
înregistrare câmpul Login cu ,,0” din tabela utilizatori ce semnifică o deconectare realizată cu succes.
Spre deosebire de ,,login.php” nu este necesară transmiterea unui răspuns către aplicația Android dacă
deconectarea s -a realizat cu succes sau nu. Utilizarea parolei pentru deconectarea clientului se face ca o
măsura se securitate.

8. Fișierul Register

Această funcție este apelată din aplicația Android printr -un URL pentru a introduce în baza de date
toate informațiile necesare atunci când un utilizator își creează un cont. De exemplu pentru următorul
URL, valorile conținute de acesta sunt :

http:// xxx.xxx.xxx.xxx /FF/register.php?id=92&n=Ana&pass=ghj
 ID=92
 Nickname= ,,Ana”
 Pass= ,,ghj”

include("datacon.php");
$cuvant=$_GET['id'];
$nick=$_GET['n'];
$pass=$_GET['pass'];

Similar cazurilor precedente, fișierul include ,,datacon.php” pentru a realiza conexiunea la baza
de date și preia din URL apelat din aplicație valor ile menționate mai sus pe care le salvează în niște
variabile.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
38 banlist = array
(
"insert", "select", "update", "delete", "distinct", "having",
"truncate", "replace", "handler", "like", "as", "or", "procedure",
"limit", "order by", "group by", "asc", "de sc"
);

Se creează matricea cu toate comenzile SQL necesară m ăsurilor de securitate (împotriva
injectării de comenzi SQL ).

if ( eregi ( "[a -zA-Z0-9]+", $cuvant ) )
{
$cuvant = trim ( str_replace( $banlist,'', strtolower ( $cuvant )));
}
else
{
$cuvant = NULL;
}

Ca și în cazul funcțiilor precedente, dacă se primește un ID, de format alfanumeric, se elimin ă
spațiile albe și toate eventualele comenzile SQL memorate în matricea banlist . Valoarea ID este apoi
convertită în litere minuscule. În cazu l în care valoarea primită prin ID nu este text, se setează variabila
utilizată pentru memorarea ID-ului ca NULL.

$queryselect = "select * from utilizatori where ID=$cuvant";

$resultselect = MYSQL_QUERY($queryselect);
$numbersearchselect = mysql_Numrows($resultselect);

În continuare se selectează din baza de date toate înregistrările din tabela utilizatori ce conțin e
valoarea ID primite prin intermediul URL -ului.

if ($numbersearchselect>0)
{
echo("exista");
}
else
{
$querysearch = "inser t into utilizatori (ID,NickName,pass,login)
VALUES ($cuvant,'$nick', '$pass',0)";
$resultsearch = MYSQL_QUERY($querysearch);
}

Atunci când există cel puțin un câmp selectat, se întoarce textul ,,exista” către aplicația Android
pentru a anunța clientul s ă aleagă alte date de autentificare. Atunci când nu există nici un câmp selectat,
se realizează o cerere în care se introduce în tabela utilizatori valorile primite prin intermediul URL –
ului, setând implicit utilizatorul ca neautentificat.

Capitolul 3: Sistemul de localizare
39 3.2 Aplicația Android

Aplicația Android reprezintă componenta software ce este instalată pe dispozitivul inteligent al
clientului. Ea este formată din 9 activități:
1) Login
2) Logout
3) Register
4) Meniu
5) GetID
6) MainActivity
7) InsertCoord
8) FindLoc
9) MapsActivity

Activitățile principale ale sistemului de localizare sunt MainActivity, FindLoc și
MapsActivity ce corespund celor 3 moduri de funcționare și sunt prezentate în continuare împreună cu
controlul autentificării și autorizării.
Ca punct de pornire a fost o busolă, ce a furnizat funcțiile pentru interogarea senzorilor și
afișarea pe interfața grafică a direcției către nordul magnetic. Această aplicație Android de tip ,,open
source” a fost în continuare modificată pentru optimizare și pentru a integra toate componentele
sistemului [ 16].

Figura 3 .2: Ierarhia activităților

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
40 În figura 3. 2 se prezintă ierarhia activităților pornind de la Login , prima activitate apelată în
momentul pornirii aplicației . Se indică prin săgeți modul în care se realizează tranziția de la o activitate
la alta. Fiecare dintre cele 9 activități prezentate are propriul fișier grafic ceea ce înseamnă că fiecare
dintre ele reprezintă în același timp un ecran diferit al aplicației . Modul prin care aceste activități
implementează interfețele sistemului este arătat în capitolul 2 al lucrării.
Se va prezenta alcătuirea claselor și metodele ce sunt conținute de acestea precum și modul de
funcți onare. Fiecare activitate este salvată sub un fișier Java sub aceeași nume , conține cel puțin o clasă
și are atașat un fișier grafic prin intermediul căruia va afișa diferite informații și animații.

1) Activitatea Login

În momentul lansării aplicației, aceasta este pri ma activitate ce este încărcată urmând ca apoi să
aștepte intervenția utilizatorului. Cele două clase componente ale activității ,,Login.java” sunt numite
,,Login” și ,,A ttemptLogin”.

public class Login extends Activity {

Button bt1, bt2, bt3;
EditText edt1, edt2;
public static String pass;
public static int m;
static TextView txt1, txt2, txt3;
int k = 4; //numara incercarile de autentificare

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

bt1 = (Button) findViewById(R.id. button); //Login button
edt1 = (EditText) findViewById(R .id.editText ); ///username
edt2 = (EditText) findViewById(R.id. editText2 ); ///password
bt2 = (Button) findViewById(R.id. button2); //Cancel Button
bt3 = (Button) findViewById(R.id. button3); //Register button

txt1 = (TextView) findViewById(R.id. textView3 );
txt2 = (TextView) findViewById(R.id. textView1 );
txt3 = (TextView) findViewById(R.id. textView2 );
txt1.setVisibility(View. GONE);

În clasa Login sunt inițializate butoanele, editoarele de text, varia bila pass ce va fi utilizată
pentru memorarea parolei, variabila m pentru răspunsul funcției ,,login.php” și variabila k ce numără de
câte ori s -a realizat încercarea de autentificare. În continuare, metoda onCreate definește fișierul grafic
XML numit activity_login și stabilește legătura între elementele grafice ale fișierului XML și
variabilele din interiorul codului ce urmează să primească sau să furnizeze valori pentru afișare.

Capitolul 3: Sistemul de localizare
41
bt1.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
MainActivity. iD = edt1.getText().toString();
pass = edt2.getText().toString();
Logout.passLogout =pass;
new attemptLogin().execute();

if (m == 1) {
Toast.makeText (getApplicationContext(), "Redirecting…" ,
Toast.LENGTH_SHORT ).show();
Intent i = new Intent(Login. this, Meniu. class);
startActivity(i);
finish();
} else {
Toast.makeText (getApplicationContext(), "Wrong ID/Password" ,
Toast.LENGTH_SHORT ).show();
txt1.setVisibility(View. VISIBLE);
txt1.setBackgroundColor(Color. RED);
k–;
txt1.setText(Integer. toString (k));
if (k == 0) {
bt1.setEnabled( false);
}
}
}
});

În momentul în care butonul este apăs at, atunci se salvează iD-ul și parola și se pornește firul de
execuție AttemptLogin . Dacă funcția ,,login.php” a autorizat accesul, atunci prin variabila m va avea
valoarea ,,1” și realizăm o accesarea a clasei Meniu , a activității cu același nume. Se opr ește în acest
caz activitatea Login. Dacă m are valoarea ,,0”, atunci apare afișat că informațiile de autentificare sunt
greșite și se decrementează variabila k ce numără încercările nereușite. A tunci când variabila k atinge
valoarea ,,0” se dezactive ază butonul Login și nu se mai permite accesul.

bt2.setOnClickListener( new View.OnClickListener() { //butonul Cancel
@Override
public void onClick(View v) {
finish();
}
});
bt3.setOnClickListener( new View.OnClickListener() { //butonul Register
public void onClick(View v) {
pass = null;
Intent n = new Intent(Login. this, Register. class);
startActivity(n);
finish();
}
});
}

Butonul Cancel oprește activitatea Login și închide aplicația atunci este apăsat. Butonul
Register resetează variabila pass dintr -o posibilă valorare rămasă în editorul de text, în null, apoi el
realizează apelul activității Register prin clasa ce îi poartă numele . Tot el oprește activitatea Login
pentru a nu consuma resursele dispozitivului.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
42
@Override
public void onBackPressed()
{
}
Această metodă suprascrie metoda implicită de revenire la ecranul precedent atunci când se
apasă butonul Back al telefonului. În această configurație dacă se deconectează un utilizator și se
dorește introducerea altor date de autentificare , pentru un cont diferit, o apăsare greșită pe butonul Back
nu va retrimite la ecranul Meniu sau alt ecran ce a fost accesat înainte. Aceasta este una din măsurile de
securitate și de bună funcționare a aplicației care asigură în același timp și ierarhia activităților
prezentată la figura 3. 2.

class attemptLogin extends AsyncTask<Object, Object, Integer>
{

protected Integer doInBackground(Object… urls) {
String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36" ;

try {
trustAllCertificates ();

String str = "https:// xxx.xxx.xxx.xxx/FF/login.php?id=" +
MainActivity. iD + "&pass=" + Login. pass;

URL obj = new URL(str);
HttpsURLConnection conn = (H ttpsURLConnection)
obj.openConnection();

conn.setRequestMethod( "GET");
conn.setDoOutput( true);
conn.setRequestProperty( "User-Agent", USER_AGENT);
conn.setInstanceFollowRedirects( false);
conn.conn ect();

Clasa AttemptLogin extinde clasa AsyncTask, clasă ce este necesară pentru că ea rulează pe
firul de execuție grafic și poate fi apelată din interiorul codului pentru butonul Login. Aceasta face
posibil transferul de informație de la aplicație la server și primirea răspunsul ui referitor la autentificare.
Metoda doInBackground este specifică clasei AsyncTask și ea realizează conexiunea server și
apelarea funcției ,,login.php”. Se declară USER_AGENT, variabilă ce este folosită pentru ca aplicația
să fie văzută ca un browser de pe un calculator obișnuit și serverul astfel ne trimite versiunea normală a
paginii web. În caz contrar ar trebui definită o versiune specifică telefoanelor sau dispozitivelor mobile.
Se cr eează adresa ce trebuie apelată, se setează conexiunea HTTP și este setată transmiterea informației
prin intermediul metodei GET. Valoarea ,,xxx.xxx.xxx.xxx” reprezintă adresa IP a unui server privat.
Redirecționarea nu este dorită, deoarece ea este realizată atunci când clientul nu a completat toată
cererea, în cazul nos tru, sunt prezente toate informațiile necesare. În final se realizează conexiunea.
Având în vedere c ă serverul are certificatele SSL expirate, este necesară o funcție care să permită
validarea l or, pentru ca aplicația să funcționeze cu protocolul HTTP secu rizat. Metoda care realizează
acest lucru este ,,trustAllCertificates” [17]. În cazul unui server web ce conține certificate valide, se
poate folosi protocolul HTTPS și această metodă nu va fi necesară.

Capitolul 3: Sistemul de localizare
43
BufferedReader inBuff = new BufferedReader( new
InputStreamReader(conn.getInputStream()) );
StringBuilder raspuns = new StringBuilder();
String line;
while ((line = inBuff.readLine()) != null) {
raspuns.append(line).append( '\n');
}
String valoare = raspuns.toString();
valoare =valoare.replaceAll( "\\s","");
Login.m= Integer. parseInt (valoare);

Se crează un buffer pentru a primi informația de la server urmând apoi ca ea să fie citită linie cu
linie și să fie salvată în variabila line. Din cauza funcțiilor PHP care transmit informația cu linii goale și
spații variabile, f iecare linie ce conține informație este reținută în variabila raspuns . Valoarea raspuns
este apoi salvată pentru prelucrări ulterioare.

protected void onProgressUpdate(Void… progress) { }

protected int onPostExecute(String result) {
return Login.m;
}

În final, răspunsul la apelul funcț iei PHP este salvat în variabila m și trimis către clasa Login
prin intermediul metodei onPostExecute. În acest caz nu este necesară informarea utilizatorului de
progresul pe care metoda doInBackground îl face așa că metoda onProgressUpdate va rămâne
nefolosită.

2) Activitatea Logout

Similar activității precedente, Lo gout conține și ea două clase: Logout și AttemptLogout.
Această activitate este apelată prin intermediul butonului aflat în activitatea Meniu.

public class Logout extends Activity {

public static boolean connexOK ;
public static String passLogout ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_logout );

În clasa Logout este inițializată variabila passLogout , ce primește în momentul autentificării
parola introdusă în clasa Login urmat apoi de declararea metodei onCreate în care se setează fișierul
grafic.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
44
final Button button2 = (Button) findViewById(R.id. buttonxx );//Logout button,
trimite la Login
button2.setOnClickListener( new View.OnClickListener() {
public void onClick(View v) {
new AttemptLogout().execute();
Toast.makeText (getApplicationContext(), "You succesfully logged
out", Toast. LENGTH_SHORT ).show();
Intent c = new Intent(Logout. this, Login. class);
startActivity(c);
finish();
}
});
}
public void onBackPressed()
{ }

Se definesc două butoane, primul fiind butonul Cancel (anexa 1.2) . Atunci când este apăsat
trimite la activitatea Meniu prin apelarea clasei cu același nume, apoi închide și eliberează memoria
ocupată de activitatea Logout. Al doilea buton este cel numit Logout în care se apelează clasa
AttemptLogout, clasă ce lucrează pe firul de execuți e al interfeței grafice la fel ca în cazul activității
Login . Se afișează un mesaj pe ecran și se pornește clasa Login , urmând ca apoi activitatea Logout să
se oprească. Este necesar ca butonul Back să fie dezactivat pentru a menține navigarea corectă a
activităților ca și în cazul precedent.
Clasa AttemptLogout realizează deconectarea unui utilizator. Ea extinde clasa AsyncTask și
conține aceleași metode care sunt implementate automat odată cu extinderea clasei AttemptLogin. Este
pornită prin apelarea în c adrul butonului Logout și funcționează pe firul de execuție al interfeței
grafice.

class AttemptLogout extends AsyncTask<Object, Object, String>
{
protected String doInBackground(Object… urls) {
String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36" ;
try {
if(Login.pass!=null)
{Logout. passLogout =Login.pass;}
else{Logout. passLogout =Register. passRegister ;}
trustAllCertificates ();
String strg = "https:// xxx.xxx.xxx.xxx/FF/logout.php?id=" +
MainActivity. iD + "&pass=" + Logout. passLogout ;
URL obj = new URL(strg);
HttpsURLConnection con = (HttpsURLConnection)
obj.openConnection();
con.setRequestMethod( "GET");
con.setDoOutput( true);
con.setRequestProperty( "User-Agent", USER_AGENT);
con.connect();
Logout.connexOK =con.getResponseMessage().equals( "OK");
} catch (Exception e) {
e.printStackTrace();
Log.i("Logout" ,"stacktrace" + Arrays. toString (e.getStackTrace()));
}
return "ok";
}

Capitolul 3: Sistemul de localizare
45 Metoda doInBackground conține conexiunea la baza de date și apelarea funcției ,,logout.php”.
Se crează USER_AGENT ca și în cazul precedent. Se generează adresa ce trebuie apelată utilizând
toate variabilele necesare transmiterii către server . Se seteză apoi conexiunea HTTP , ca și în cazul
activității precedente și este verificată realizarea acesteia. În cazul unei excepții se creează o
înregis trare. În cazul unei funcționări normale, clasa întoarce un mesaj ce arată că procesul s -a realizat
cu succes.

3) Activitatea Register

Activitatea Register conține și ea două clase numite Register și AttemptRegister. Ea este apelată
prin butonul Register existent în ecranul activității Login și este utilizată pentru crearea unui cont nou.
În clasa Register sunt declarate 2 variabile de tip șir de caractere împreună cu 4 editoare de text
în care utilizatorul să își introducă datele personale.
În continuare este definită metoda onCreate, metodă care este implicit prima apelată atunci când
s-a făcut trimiterea către o activitate.

final Button button = (Button) findViewById(R.id. button1);
button.setOnClickListener( new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
MainActivity. iD = edtxt1.getText().toString();
passRegister = edtxt2.getText().toString();
pass2 = edtxt3.getText().toString();
MainActivity. name = edtxt4.getText().toString();

if (passRegister .equals( pass2) == true) {
Logout.passLogout =passRegister ;

new AttemptRegister().execute();
/// nu raspunde nimic daca nu exista; raspunde cu string "exista"
daca contul exista

if (AttemptRegister. val =="" )
{
Toast.makeText (getApplicationContext(), "You succesfully
registered. Please Login" , Toast. LENGTH_SHORT ).show();
Intent a = new Intent(Register. this, Login. class);
startActivity(a);
finish();
}else{
Toast.makeText (getApplicationContext() , "The account exists
already" , Toast. LENGTH_SHORT ).show();
}
}
}
});

Se definește fișierul grafic și se setează elementele grafice care urmează să preia informațiile
introduse de client . Aceste elemente se pot vizualiza în anexa 1.3 . Se setează butonul Register și atunci
când este apăsat, valorile introduse în editoarele de text sunt salvate în variabile. În continuare se face o
verificare ca cele 2 parole să fie identice și se pornește clasa AttemptLogin. Variabila val este întoarsă
apoi pentru a face o ultimă decizie. Dacă ea este nulă, se afișează un mesaj pe ecran și se apelează clasa

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
46 Login pentru autentificare după crearea contului, urmând ca activitatea curentă, și anume Register, să
se închidă. În cazul contrar, se afișează pe ecran un mesaj ce indică existența unui cont cu același ID în
baza de date ( subcapitolul 3.1, fișierul Register) și se așteaptă introducerea unui ID diferit.
Clasa AttemptRegister extinde clasa AsyncTask și rulează pe firul de execuție al interfeței
grafice . Aceasta întoarce prin intermediul funcțiilor specific e, valoarea ,,exista” sau null . Acest e valori
depind de baza de date și mai exact, dacă există deja o înregistrare în DB cu același ID. Modul cum se
face această verificare este prezentat în subcapitolul 3.2 fișierul Register.
public static String val;

Se declară variabila val ce va memora răspunsul serverului și va fi valoarea întoarsă de clasa
doInBackground.

protected String doInBackground(Object… urls) {
String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36" ;
try {
trustAllCertificates ();
String strg = "https://xxx.xxx.xxx.xxx /FF/register.php?id=" +
MainActivity. iD +"&n="+ MainActivity. name+"&pass=" + Register. passRegister ;
URL obj = new URL(strg);
HttpsURLConnection conn = (HttpsURLConnection) obj.openConnection();
conn.setRequestMethod( "GET");
conn.setDoOutput( true);
conn.setRequestProperty( "User-Agent", USER_AGENT);
conn.connect();
connexOK =conn.getResponseMessage().equals( "OK");
if (connexOK ) {
BufferedReader inBuff = new BufferedReader( new
InputStreamReader(conn.getInputStream()));
StringBuilder raspuns = new StringBuilder();
/// nu raspunde nimic daca nu exista; raspunde cu string "exista" daca contul
exista
String line;
while ((line = inBuff.readLine()) != null) {
raspuns.append(line).append( '\n');
}
val = raspuns.toString();
val = val.replaceAll( "\\s", "");
}
} catch (Exception e) {
e.printStackTrace ();
}
return val;
}

Simila r se declară variabila USER _AGENT ce urmează a fi utilizată în realizarea conexiunii
prin protocolul HTTP. Se generează URL -ul nec esar introducerii în baza de date a valorilor introduse
în editoarele de text , din clasa Register, urmând ca apoi să se realizeze conexiunea.
În cazul în care conexiunea s -a realizat corect, se creează un buffer pentru memorarea
răspunsului primit de la se rver. Se realizează prelucrarea șirului de caractere primit, șir ce poate conține
un număr de linii și spații albe. În final se salvează informația și este trimisă către onPostExecute
pentru a putea să fie întoarsă firului de execuție principal .

Capitolul 3: Sistemul de localizare
47 4) Activitate a Meniu

Activitatea Meniu este cea care realizează legătura între cele 3 moduri de funcționare a
sistemului și în același timp conține butonul pentru deconectarea utilizatorului. Ea conține o singură
clasă spre deosebire de cele 3 activități precedente av ând numele Meniu.

final Button buttonA = (Button) findViewById(R.id. buttonA); // FF
buttonA.setOnClickListener( new View.OnClickListener() {
public void onClick(View v) {

Toast.makeText (getApplicationContext(), "FF…",Toast.LENGTH_SHORT ).show();
Intent a= new Intent(Meniu. this, GetID. class);
startActivity(a);
finish();
}
});

În metoda onCreate sunt definite 4 butoane către activitățile principale ale sistemului, trecând în
cazul lui MainActivity și FindLoc prin unele intermediare. Butonul prezentat mai sus este numit FF și
trimite către clasa GetID, unde se poate alege un client al sistemului pentru a fi localizat. Se afișează un
mesaj pe ecran și se oprește activitatea.
Similar se realizează și în cazul celorlalte 3 butoane. Trimiterea către clasa InsertCoord se face
prin i ntermediul butonului FL pentru a accesa modul secundar de funcționare și anume obținerea
direcției către o locație fixă. Apelarea hărților GoogleMaps se face prin butonul cu același nume și
pentru deconectarea utilizatorului se apasă pe ultimul buton numit Logout ce trimite la clasa Logout.

5) Activitatea GetID

Această activitate este apelată prin apăsarea butonului FL din clasa Meniu. Ea are ca scop
conexiunea la baza de date pentru a furniza o listă completă cu toate I D-urile și numele fiecărui
utilizator. Prin aceasta se selectează persoana ce se dorește a fi localizată.
Clasa GetID declară un editor de text și 2 chenare text urmând ca metoda onCreate să le lege de
elementele grafice propriu zise. Conținutul integral al metodei se poate găsi în anexa 1.5
getID();
final Button buttonID = (Button) findViewById(R.id. buttonID );
buttonID.setOnClickListener( new View.OnClickListener() {
public void onClick(View v) {
MainActivity. partneriD =id.getText().toString();
Intent i= new Intent(GetID. this, MainActivity. class);
startActivity(i);
finish();
}
});

Se apelează metoda getID și se creează în interfața grafică un buton care odată apăsat, salvează
valoarea primită de la utilizator prin intermediul editorului de text în variabila parteneriD din
activitatea MainAc tivity. Apoi se apelează activitatea principală pentru a începe localizarea.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
48
String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36" ;
trustAllCertificates ();
String st = "https://xxx.xxx.xxx.xxx /FF/getIDs.php" ;

t1.setText( "connecting" );
URL obj = new URL(st);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
con.setRequestMethod( "GET");
con.setDoOutput( true);
con.setRequestProperty( "User-Agent", USER_AGENT);
con.connect();
t1.setText( "GetID: " + con.getResponseMessage()); ///verif cconexiunii

Metoda getID crează adres a URL ce conține funcția ,,getID” , urmat apoi de setarea parametrilor
și a metodei HTTP folosite pentru a deschide conex iunea și se afișează un mesaj pe ecran ce indică
starea acesteia.

BufferedReader in = new BufferedReader( new
InputStreamReader(con.getInputStream()) ); //buffer pt a salva stream -ul

StringBuilder total = new StringBuilder();
String line;

while ((line = in.readLine()) != null) {
total.append(line).append( '\n');
}
String sirrr = total.toString();
sirrr =sirrr.replaceAll( "\\n","&");
sirrr =sirrr.replaceAll( "\\s","");
sirrr =sirrr.replaceAll( "&&&&","\n");
sirrr =sirrr.replaceAll( "&","");
String s= sirrr.replaceAll( ","," ") ;
t2.setText(s);

Se defineș te un buffer ce are ca scop preluarea informației de la server, urmând apoi ca prin
metodele de prelucrare a șirurilor de caractere să se afișeze pe ecran pe linii, ID -urile și Nickname -urile
respectivilor utilizator i pentru a putea selecta o persoană .

6) Activitatea MainActivity

MainActivity este modul principal de lucru al sistemului, el bazându -se pe ID -ul furnizat de
activita tea Ge tID și alte clase proprii. R ealizează localizarea unui client prin dispozitivul său inteligent
indiferent dacă acesta este static sau în mișcare. El implementează interfața SensorEventListner, ce
permite accesarea senzorilor dispozitivului mobil. ID-ul pro priu este salvat și transmis către această
clasă în timpul activității Login. Se dorește ca această activitate să arate direcția de urmat către găsirea
telefonului partener și afișarea unor informații despre acesta. Ea conține 3 clase, în 3 fișiere diferit e:
MainActivity , GetPos și MyLocationListener.

Capitolul 3: Sistemul de localizare
49 Clasa MainActivity extinde clasa Activity și în același timp implementează interfața
SensorEventListener (anexa 1.6) . În rea lizarea acestei activități s -a plecat de la codul sursă a unei
aplicații Android de t ip ,,open -source” ce are ca scop implementarea un compas [16].

public static int myStatus =0;
public static String iD ;
public static String partneriD ;

public static String name ;
public static float bearing = 0; ///// metoda onSensorChanged – calculul
rotatiei

Următoarele variabile reprezintă disponibilitatea proprie care este setată implicit ca invizibil
lăsând , clientul să o schimbe atunci când dorește să fie localizat. Valoarea iD este cea introdusă în
timpul activității Login, în timp ce parteneriD este introdusă în timpul activității GetID. Numele este
setat în momentul creării unui cont nou, iar variabila bearing este necesară calcului direcției.

setContentView(R.layout. activity_main );
mSensorManager = (SensorManager) getSystemService( SENSOR_SERVICE );
mAccelerometer = mSensorManager .getDefaultSensor(Sensor. TYPE_ACCELEROMETER );
mMagnetometer = mSensorManager .getDefaultSensor(Sensor. TYPE_MAGNETIC_FIELD );
mPointer = (ImageView) findViewById(R.id. pointer);

Metoda onCreate începe prin stabilirea fișierul grafic. Se crează dependențele pentru senzorul
magnetic și accelerometrul și se stabilește legătura cu imaginea numită ,,pointer” ce a rată punctul
cardinal nord [ 16].

mPointer2 = (ImageView) findViewById(R.id. pointer2 );

S-a adăugat ulterior aplicației de compas încă o imagine având ca scop afișarea direcției de
mers . Folosind valo area calculat ă de aplicația inițială pentru a arăta nordul , această nouă imagine, va
reprezenta direcția de mers .

Switch mainSwitch= (Switch) findViewById(R.id. switch1);// seteaza dinamic
valoarea status
mainSwitch.setChecked( false);
mainSwitch.setOnCheckedChangeListener( new
CompoundButton.OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean
isChecked) {

if(isChecked){
myStatus =1;// Status este Visible
}else{
//Status este Invisible
myStatus =0;
}
}
});

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
50 Se definește un comutator pentru a seta dinamic variabila disponibilității myStatus . Se creează
legătura cu interfața grafică și se setează implicit comutatorul ca opr it. În cazul în care el este apăsat , se
verifică starea lui și dacă el este oprit disponibilitatea este setată în modul invizibil, respectiv dacă este
pornit, disponibilitatea este setată în modul vizibil.

LocationManager locationManager = (LocationManager)
getSystemService( LOCATION_SERVICE );

if (locationManager.isProviderEnabled(LocationManager. GPS_PROVIDER )) {
Toast.makeText (this, "GPS is Enabled in your device" ,
Toast.LENGTH_LONG ).show();
} else {
Toast.makeText (this, "GPS is Disabled in your device" ,
Toast.LENGTH_LONG ).show();
}

Se verifică dacă sistemul GPS este pornit sau nu și în funcție de acest lucru se afișează
clientului un mesaj.

runThread(); /// fir de executie pentrut apelarea GetPosition si PutPosition

LocationManager mlocManager = null;
LocationListener mlocListener;
mlocManager = (LocationManage r) getSystemService(Context. LOCATION_SERVICE );
mlocListener = new MyLocationListener();

Se apelează firul de execuție runThread ce realizează actualizarea celor 2 clase care transm it
către serverul web poziția proprie și interoghează DB pentru poziția geograf ică a partenerului. Se
definesc clasele și interfețele ce au rolul de a furniza locația GPS a dispozitivului.

if (ActivityCompat. checkSelfPermission (this,
Manifest.permission. ACCESS_FINE_LOCATION ) !=
PackageManager. PERMISSION_GRANTED && ActivityCompat. checkSelfPermission (this,
Manifest.permission. ACCESS_COARSE_LOCATION ) !=
PackageManager. PERMISSION_GRANTED ) {

return;
}
mlocManager.requestLocationUpdates(LocationManager. GPS_PROVIDER , 1000, 0,
mlocListener);

Se verifică dacă aplicația a primit permisiunea de a accesa lo cația dispozitivului. Este definit
apoi ca accesarea sistemului GPS pentru furnizarea locației să se desfășoare o data la o s ecundă și să se
salveze această valoare chiar dacă utilizatorul nu a parcurs nici un metru.

Capitolul 3: Sistemul de localizare
51
protected void onResume()
{
super.onResume();
mSensorManager .registerListener( this, mAccelerometer ,
SensorManager. SENSOR_DELAY_GAME );
mSensorManager .registerListener( this, mMagnetometer ,
SensorManager. SENSOR_DELAY_GAME );
}

protected void onPause()
{
super.onPause() ;
mSensorManager .unregisterListener( this, mAccelerometer );
mSensorManager .unregisterListener( this, mMagnetometer );
}
Metoda onResume este accesată atunci când activitatea interacționează cu utilizatorul și setează
ce senzor și la ce frecvență să eșantioneze, în timp ce metoda onPause oprește senzorii atunci când
activitatea nu mai este folosită. Metoda onPause este ultima meto dă apelată înainte să se treacă la o altă
activitate. Aceste 2 metode sunt metode ce au fost preluate din aplicația compas [ 16].
Metoda onSensorChanged este o metodă a interf eței SensorEventListener și este apelată atunci
când se citește o valoare la unui dintre senzori.

if (event.sensor == mAccelerometer )
{
System.arraycopy (event.values, 0, mLastAccelerometer , 0,
event.values.length);
mLastAccelerometerSet = true;
}
else if (event.sensor == mMagnetometer )
{
System.arraycopy (event.values, 0, mLastMagnetometer , 0,
event.values.length);
mLastMagnetometerSet = true;
}

În funcție de tipul de senzor matricea care salvează valorile primite are lungime și conținut
diferit. Accelerometrul și senzoru l magnetic oferă 3 valori măsurate pe axele de coordonate [9]. În
situația în care valorile citite sunt de la accelerometru, ele sunt salvate într -o matrice. În situația ca
valorile citite sunt de la senzorul magnetic, se salvează acestea în altă matrice [ 16].

if (mLastAccelerometerSet && mLastMagnetometerSet )
{
SensorManager. getRotationMatrix (mR, null, mLastAccelerometer ,
mLastMagnetometer );
SensorManager. getOrientation (mR, mOrientation );
float azimuthInRadians = mOrientation [0];
float azimuthInDegrees =
(float)(Math.toDegrees (azimuthInRadians)+ 360)%360; //limitează valoarea la
intervalul [0,360]

În cazul în care atât senzorul magnetic cât și accelerometrul au furnizat valori, metoda
getRo tationMatrix calculează pe baza acestora , direcția nordului din sistemul de coordonate proprii

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
52 telefonului , în sistemul de coordonate geografice. Metoda getOrientation calculează pe baza matrice
mR primită ca parametru orientarea dispozitivului inteligent față de nordul magnetic, întorcând pe
prima poziție a matrice mOrientation unghiul azimutal dintre nordul magnetic și axa ordonatelor a
telefonului mobil. Valoarea este apoi modificată din radiani în grade și se fac prelucrări matematice
pentru a limita intervalul de valori între 0 și 360 de grade [ 16].

//// aceasta animatie indica nordul
RotateAnimation ra1 = new RotateAnimation(
mCurrentDegree2 ,-azimuthInDegrees,
Animation. RELATIVE_TO_SELF , 0.5f,
Animation. RELATIVE_TO_SELF , 0.5f);

ra1.setDuration( 250);
ra1.setFillAfter( true);

mPointer2 .startAnimation(ra1);
mCurrentDegree2 = -azimuthInDegrees;

Se creea ză o animație care rotește figura plecând de la valoarea calculată a unghiului azimutal și
rotind în sens ul invers trigonometric săgeata în jurul propriilor axe. Se setează durata de 250 de
milisecunde și se setează ca animația să rămână schimbată după ce s-a executat. Se pornește animația și
se actualizează noua poziție [ 16].

bearing=GetPos. retBearing ();
//bearing = GetPos.bearinggg(loc1, loc2); //calcul alternativ de bearing

MainActivity. t1.setText( "bearing:" +String. valueOf(bearing));

float heading = azimuthInDegrees – bearing; //directia de mers /// e necesar
"-" pt corectia sensului de rotire

Se salvează valoarea calculată în interiorul clasei GetPos și se afișează pe ecran. Variabila
heading este direcția de parcurs, fiind determinată pe baza unghiului azimutal calculat mai devreme și
valoarea bearing , ce reprezintă unghiul între nordul magnetic și poziția telefonului partener.

if(GetPos. hisStatus !=0) {
if (GetPos. retDistance () < 1000) {
t5.setText( "distanta:" + String. valueOf(GetPos. retDistance ()) + "m");
} else {
t5.setText( "distanta:" + String. valueOf(GetPos. retDistance () / 1000)
+ "km");
}
}else{
t5.setText( "distanta:Invisible" );
}

Se prezintă decizia afiș ării distanței între cei 2 utilizatori, acest lucru fiind condiționat de
disponibilitatea partenerului ce se dorește a fi localizat.

Capitolul 3: Sistemul de localizare
53
//animatia indica direactia de parcu rs /// animatia se roteste trigonometric
RotateAnimation ra = new RotateAnimation(
mCurrentDegree ,-heading,
Animation. RELATIVE_TO_SELF , 0.5f,
Animation. RELATIVE_TO_SELF , 0.5f);

ra.setDuration( 250);
ra.setFillAfter( true);

mPointer .startAnimation(ra);
mCurrentDegree = -heading;

Se creează o a doua animație ce va arăta direcția către telefonul partenerului. Această animație
este similară cu cea prezentată mai sus , cu diferența modificării valorii unghiului reprezentat de
variabila heading [16].

@Override
public void onBackPressed()
{
Intent a= new Intent(MainActivity. this, Meniu. class);
startActivity(a);
finish();
return;
}

Se suprascrie butonul Back al telefonului mobil , astfel încât atunci când este apăsat să
pornească activitatea Meniu.

private void runThread() {

new Thread() {
public void run() {
while (true) {
try {
runOnUiThread( new Runnable() {

@Override
public v oid run() {
MyLocationListener. updateMyPos (loc1);
GetPos.updateHisPos (loc2);
}
});
Thread.sleep(2000);
} catch (Interrup tedException e) {
e.printStackTrace();
}
}
}
}.start();
}

Apelul metodelor updateMyPos din clasa MyLocationListener și metoda updateHisPos din
clasa GetPos se face odată la 2 secunde și pentru că acestea fac modificări pe interfața grafică, este
necesar ca ele să fie apelate din firul de execuție al interfeței grafice.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
54 În continuare se va prezenta clasa MyLocationListener, clasă ce implementează interfața
LocationListener și care are rolul de a prelua poziția GPS a dispozitivului inteligent (anexa 1.6) . Una
din metodele conținute de această clasă este updateMyPos ce primește de la firul de execuție din
MainActivity va riabila loc și în care salvează locația. Este afișată pe ecran locația cu un număr redus de
zecimale, calculele ce urmează însă vor folosi valoarea exactă.

String st = "https:// xxx.xxx.xxx.xxx /FF/putPosition.php?id=" +
MainActivity. iD + "&n=" + MainActivity. name + "&La=" + loc.getLatitude() +
"&Lg=" + loc.getLongitude()+ "&st="+ MainActivity. myStatus ;

URL obj = new URL(st);
HttpsURLConnection con = ( HttpsURLConnection) obj.openConnection();
con.setRequestMethod( "GET");
con.setDoOutput( true);
con.setRequestProperty( "User-Agent", USER_AGENT);
con.connect();

Se formează adresa URL a sistemului introducând toate datele necesare și se afișează pe ecran
un mesaj pentru o realizare corectă a conexiunii similar ca și în cazurile precedente (anexa 1.6) .

@Override
public void onLocationChanged(Location loc)
{
latitude = loc.getLatitude();
longitude = loc.getLongitude();
MyLocationListener. updateMyPos (loc);
}

În momentul schimbării poziției geografice se salvează această poziție și se apelează metoda
updateMyPos pentru a fi transmisă către DB.
Clasa GetPos obține poziți a geografic ă a dispozitivului inteligent partener prin interogarea DB .
În continuare vom prezen ta modul de funcționare a acestei clase începând cu metoda updateHisPos.

String st = "https:// xxx.xxx.xxx.xxx /FF/getPosition.php?id=" +
MainActivity. partneriD ;

Metoda începe prin realizarea conex iunii HTTPS , prin formarea adres ei URL a sistemului ,
introducând toate datele necesare și se afișează pe ecran un mesaj pentru o realizare corectă .

BufferedReader in = new BufferedReader( new
InputStreamReader(con.getInputStream()) ); //buffer pt a salva stream -ul

StringBuilder sir = new StringBuil der();
String line;
while ((line = in.readLine()) != null) {
sir.append(line).append( '\n');
}
String coordonatePartener = sir.toString(); // sir se foloseste fara sa fie
de tip String, dar coordonatePartener este String
coordonatePartener =coordonatePartener.replaceAll( "\\s","");/// eliminare
spatii albe din string, spati i ce provin de la functia php

Capitolul 3: Sistemul de localizare
55 Se definește un buffer pentru preluarea datelor provenite de la server în scopul de a fi
prelucrate. Se prelucrează șirul de caractere și se obțin toate valorile de interes despărțite prin virgulă.
Dacă șirul de caractere nu conține informație, înseamnă că ori a existat o problemă cu
conexiunea HTTP , ori informația nu există pe server, ori a existat o eroare în apelarea funcției PHP și
metoda trebuie să își încheie execuția. În caz con trar, în urma informației primite este necesar ca
aceasta să fie descompusă în valorile c e o compun. În acest moment, în variabila coordonatePartener ,
există latitudinea, longitudinea, status, data și ora. Toate aceste valori despărțite prin virgulă.

hisStatus =Integer. parseInt (coordonatePartener.split( ",")[2]);//selectie
status partener

Se selectează a treia valoare din șirul de caractere ( numărătoarea începe de la 0 ) și este salvată
în variabila hisStatus.

if (hisStatus !=0) {
Location loc2 = new Location( ""); //loc2=locatie telefon partener
loc2.setLatitude(Double. parseDouble (coordonatePartener.split( ",")[0]));
loc2.setLongitude(Double. parseDouble (coordonatePartener.split( ",")[1]));
float lati = ( float)
Double.parseDouble (coordonatePartener.split( ",")[0]);// trunchiere
float longi = ( float)
Double.parseDouble (coordonatePartener.split( ",")[1]);

dataOra = coordonatePartener.split( ",")[3];
String data, ora;
data = dataOra.substring( 0, 9);
ora = dataOra.substring( 10);
dataOra = data + " " + ora;

MainActivity. t2.setText( "El "+ lati + " " + longi);
MainActivity. t6.setText( "HisID: " +MainActivity. partneriD +" st:"+
GetPos.hisStatus +" ActiveAt: " + GetPos. getDataOra ());
loc1.setLatitude(MyLocationListener. latitude );
loc1.setLongitude(MyLocationListener. longitude );
x = loc1.bearingTo(loc2); //salvez bearingul ce ia val intre [ -180,180]

if (x < 0) {
x = x + 360;
} // corectia valorii bearing
y = MainActivity. loc.distanceTo(loc2); //distanta intre locatii
}else{
onStatusChanged ();
}

Dacă variabila hisStatus are valoarea diferită de ,,0”, atunci se salvează latitudinea și
longitudinea în variabila loc2. Se prelucrează ultimul termen din șirul inițial pentru a se afișa ora
ultimei înregistrări a dispozitivului partener. Se afișează trunchiat coordonatele și inf ormațiile
referitoare la iD-ul partener, disponibilitatea, data și ora ultimei înregistrări. Se realizează apoi calculul
unghiului între nordul magnetic și poziția telefonului partener și distanța între cele 2 poziții.
În cazul în care hisStatus are valoa rea ,,0” se apelează metoda onStatusChanged care
maschează afișarea coordonatelor și setează valoarea distanței și a unghiului bearing cu ,,0”. Astfel
imaginea va arăta nordul magnetic.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
56
public static void onStatusChanged()
{
MainActivity. t6.setText( "HisID: " +MainActivity. partneriD + " st:"+
hisStatus +" ActiveAt: Invisible" );
MainActivity. t2.setText( "Invisible" );
x=0; //bearing
y=0; //distanta
}
Metodele care întorc distanța, unghiu l, data și ora, sunt utilizate pentru a face citirea codului
mai ușoară.

public static float retBearing()
{return x;}

public static float retDistance()
{return y;}

public static String getDataOra()
{return dataOra;}

7) Activitatea InsertCoord

Această activitate are rolul de oferi utilizatorului posibilitatea de a introduce coordonatele unei
locați i fixe pentru a realiza navigarea către aceasta .

edt1 = (EditText)findViewById(R.id. editTextX );
edt2 = (EditText)findViewById(R.id. editTextY );

final Button button = (Button) findViewById(R.id. button1);
button.setOnClickListener( new View.OnClickListener() {
public void onClick(View v) {
LocLat1=edt1.getText().toString();
LocLong1 = edt2.getText().toString();

Toast.makeText (getApplicationContext(), "FindLoc" ,Toast.LENGTH_SHORT ).show();
Intent m= new Intent(InsertCoord. this, FindLoc. class);
startActivity (m);
finish();
}
});

În metoda onCreate se creează un buton și două editoare de text. În momentul apăsării pe buton,
latitudinea și longitudinea sunt memorate și transmise către clasa FindLoc. Se porn ește apoi activitatea
FindLoc prin apelarea clasei cu același nume (anexa 1.7). De asemenea, butonul Back al dispozitivului
inteligent , este suprascris să apeleze activitatea Meniu.

Capitolul 3: Sistemul de localizare
57 8) Activitatea FindLoc

Activitatea FindLoc funcționează similar ca și a ctivitatea MainActivity. Diferențele între cele
două sunt mici, una dintre ele fiind salvarea coordonatelor primite în activitatea InsertCoord. Această
operație se realizează în metoda onCreate. O altă diferență este calculul distanței și a valorii bearing ce
se calculează între poziția telefonului inteligent și coordonatele introduse în activitatea precedentă,
calcule ce se realizează în interiorul metodei onSensorChanged (anexa 1.8) . Se determină apoi variabila
heading , care este utilizată în animația ce arată direcția către locația selectată. Valorile sunt apoi afișate
pe ecran.
bearingFL = locEu.bearingTo( locDest);
distanceFL = locEu.distanceTo( locDest);

if(bearingFL <0)
{bearingFL =bearingFL +360;}
t1.setText( "bearing:" + String. valueOf(bearingFL ) );
float heading = azimuthInDegrees – bearingFL ; //directia de mers /// e
necesar "-" pt corectia sensului de rotire
if(distanceFL <1000) {
t3.setText( "distanta:" + String. valueOf(distanceFL ) + "m");
}else{t3.setText( "distanta:" + String. valueOf(distanceFL /1000) + "km");}

O altă diferență este dispariția variabilelor de disponibilitate, atât a telefonului curent cât
și a telefonului partener, care în această activit ate nu există. Tot din acest motiv, comutatorul nu mai
este utilizat.
locEu.setLatitude(MyLocationListener. latitude );
locEu.setLongitude(MyLocationListener. longitude );
FindLoc. t.setText( "Eu"+String. valueOf((float)locEu.getLatitude())+ "
"+String. valueOf((float)locEu.getLongitude()));

Diferența principală este conținutul firului de execuție care în acest caz apelează numai
activitatea MyLocationListener de unde setează valoarea locație i proprii, locație care este afișată și pe
ecran. Clasa GetPos nu este apelată deoarece nu mai există telefon partener în această activitate.
Metoda onBackPressed suprascrie butonul Back al dispozitivului și trimite către clasa Meniu.

9) Activitatea MapsActivity

Această activitate este apelată din butonul numit GoogleMaps ce se găsește în Meniu. Această
activitate folosește un API oferit de Google pentru a permite utilizarea hărților Google Maps [18]
(anexa 1.9) . După ce s -a rezervat un API și acesta este introdus în fișierul AndroidManifest.xml se
poate vizualiza harta (anexa 1.10) .â
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng Eu = new LatLng(MyLocationListener. latitude ,
MyLocationListener. longitude );
LatLng El = new LatLng(GetPos. longit1, GetPos. latit1);
mMap.addMarker( new MarkerOptions().position(Eu).title( "Eu"));
mMap.moveCamera(CameraUpdateFactory. newLatLng (Eu));
mMap.addMarker( new MarkerOptions().position(El).title( "El"));
mMap.moveCamera(CameraUpdateFactory. newLatLng (El));
}

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
58 Activitatea conține configurarea implicită, iar în metoda onMapReady s -au creat apoi 2
marcatori ce indică pozițiile celor două di spozitive inteligente. Valorile pentru locații sunt preluate din
clasa MyLocationListener pentru poziția proprie și din clasa GetPos pentru poziția telefonului partener.
Se setează numele celor 2 marcatori și se afișează pe hartă. Ca și în cazul activități i precedente ,
apăsarea butonului Back a dispozitivului apelează clasa Meniu.

3.3 Interfața grafică

Interfața grafică este construită pe baza fișierelor XML asociate fiecărei activități prezentate
anterior în subcapitolul 3.2.
În realizarea unui fișier XML se creează o ierarhie a obiectelor. A stfel se specifică atributele
generale ale fișierului și apoi se introduc diferitele obiecte grafice , precum: editorul de text, chenarele
text, butoanele, comutatorul și imagini cu atribute le lor specifice.
De exemplu, pentru activitatea Login , atributele generale sunt următoarele:

<RelativeLayout xmlns:android = "http://schemas .android.com/apk/res/android"
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width= "match_parent"
android:layout_height = "match_parent"
android:paddingLeft= "@dimen/activity_horizontal_margin"
android:paddingRight = "@dimen/activity_horizontal_margin"
android:paddingTop = "@dimen/activity_vertical_margin"
android:paddingBottom = "@dimen/activity_vertical_margin"
tools:context = ".Login" >

Se definește eticheta rădăcină și anume RelativeLayout și se asigură că fișierul XML recunoa ște
etichetele și atributele folos ite, ele fiind găsite la URL -ul specificat urmând ca apoi să se definească
atributele generale ale fișierului [8]. Se specifică marginea ecranului și contextul în care acest fișier este
apelat.
Modul prin care se specifică proprietățile fiecărui element g rafic este prin atributu l ce primește
valoarea dorită . Fiecare tip de element grafic este asociat cu o etichetă unică și sub această etichetă sunt
enumerate atributele. De exemplu , mai jos , se arată modul în care un chenar text este definit în fișierul
XML al activității Login (anexa 2.1) .

<TextView android:text = "Login"
android:layout_width= "wrap_content "
android:layout_height = "wrap_content"
android:id = "@+id/textview"
android:textSize = "34dp"
android:layout_alignParentTop= "true"
android:layout_centerHorizontal= "true" />

Pe lângă aceste atribute se mai pot adăuga și altele care ar schimba modul în care chenarul text
este afișat. În cazul unui buton și anume în cazul butonului Register se procedează astfel (anexa 2.3) :

Capitolul 3: Sistemul de localizare
59
<Button
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text="Register"
android:id="@+id/button3"
android:layout_marginTop= "28dp"
android:layout_below= "@+id/button"
android:layout_centerHorizontal= "true" />

Prin wrap _content se înțelege că dimensiunea este minimul necesar după ce a fost inclus
conținutul în interiorul elementu lui grafic , în timp ce prin match_parent se dorește ca acel element să ia
aceleași valori ca și p ărintele.

<EditText
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:inputType= "textPassword"
android:id="@+id/editText2"
android:layout_below= "@+id/editText"
android:layout_alignParentLeft= "true"
android:layout_alignParentStart= "true"
android:layout_alignRight= "@+id/editText"
android:layout_alignEnd= "@+id/editText"
android:textColorHint= "#78b7ac"
android:hint="Enter Password" />

Se prezintă editorul de text unde se introduce parola din activitatea Login. Se alege tipul
textului ca textPassword, ceea ce maschează caracterele ce sunt introduse. În figura 3. 3 se prezintă
interfața grafică pentru clasa Login unde se pot observa editoarele de text, chenarele text și butoanele.
Fișierele grafice XML se pot găsi integral în anexa 2 .

Figu ra 3.3: Interfața grafică a activității Login

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
60 Prin apăsarea butonului Register, se apelează activitatea cu același nume și aceasta se poate
observa în figura 3. 4. În cazul în care contul deja există se poate observa mesajul apărut pe ecran.

Figura 3 .4: Interfața grafică a activității Register

În figura 3. 5 se poate observa interfața grafică a activității Meniu, ceea care face p osibilă
tranziția între cele 3 moduri de funcționare a sistemului de localizare.

Figura 3 .5: Interfața grafică a activității Meniu

Capitolul 3: Sistemul de localizare
61 În cazul a ctivității MapsActivity, a fost folosită interfața implicit ă oferit ă, unde au fost adăugați
marcatorii pentru locațiile celor dou ă poziții așa cum se observă în figura 3. 6.

Figura 3 .6: Interfața grafică a activității MapsActivity

În cazul activităților MainActivity și FindLoc este necesar să se introducă ID-ul partenerului,
respectiv coordonatele locației căutate. În figura 3.7 sunt prezentate interfețele grafice pentru
activitățile InsertCoord și GetID ce fac posibil acest lucru.

Figura 3. 7: Interfața grafică a activităților InsertCoord și GetID

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
62 În interfața graf ică a activității MainActivity, figura 3. 8, se poate observa cele două direcții
arătate de săgeți, una pentru nord și una pentru telefonul partener.

Figura 3 .8: Interfața grafică a activității MainActivity
În figura 3. 9 este prezentat un exemplu al activității FindLoc unde s -a setat latitudinea cu
valoare ,,44.263 ” și longitudinea cu valoarea ,,26.325 ”.

Figura 3 .9: Interfața grafică a activității FindLoc

Capitolul 3: Sistemul de localizare
63 3.4 Elemente de securitate

Prin crearea funcțiilor PHP clientului i se oferă anumite funcții și opțiuni de a selecta și de a
actualiza informați a în baza de date . El poate să acceseze și să modifice numai datele ce corespund
contului său, cu excepția funcției ,,getIDs.php”, unde prin simpla accesare se furnizează o listă cu toți
utilizatorii.
Informațiile de autentificare sunt trimise către server unde se face autor izarea către cont prin
intermediul protocolului HTTPS . El oferă protecție suplimentară asupra informației ce este criptată și
oferă garanția că nu există o terță entitate ce interceptează informațiile și le poate folosi . Acest lucru
este făcut posibil de către certificatele SSL.
În acest moment, serverul web care conține baza de date și funcțiile PHP este utilizat de mult
timp și are certificatul SSL expirat. Pentru realizarea conexiunii HTTPS din aplicația Android, este
necesar în acest caz de o metodă ca re să accepte toate certificatele, indiferent de starea lor. Acest lucru
oferă o slăbiciune în securitate deoarece deși se realizează criptarea datelor, clientul nu cunoaște dacă
serverul web este cel corect. Există astfel posibilitatea unei intercepții a datelor. Cu toate acestea
nivelul de securitate este mai ridicat decât dacă s -ar folosi protocolul HTTP. Aceasta este o soluție
temporară și se dorește ca acea metodă să rămână în uz numai pentru a arăta funcționalitatea sistemului
până în momentul reînnoi rii certificatului SSL. În momentul reînnoirii certificatului SSL, sistemul va
putea funcționa normal și cu toate beneficiile pe care protocolul HTTPS le oferă.
Sistemul de control al accesului utilizatorilor și autorizarea lor presupune implementarea
funcțiilor ,,login.php”, ,,register.php” și ,,logout.php”, ce sunt salvate pe serverul web, dar și
corespondentul lor în aplicația Android prin fișierele ,,Login.java”, ,,Register.java” și ,,Logout.java” .
Acestea lucrează împreună în realizarea autentificării și autorizării, dar și a controlului informației ce
este introdusă în baza de date.
Cu ajutorul funcției ,,register.php” se salvează toate informațiile necesare pentru crearea unui
cont nou . Posesorul noului cont este definit implicit ca deconectat urmând să se autentifice pentru a
folosi sistemul. Prin intermediul funcțiil or ,,login.php” și ,,logout.php” se stabilește activitatea unui
client și anume dacă el este autentificat la un moment dat sau nu prin câmpul Login din DB.
Câmpul Login este urmărit ca o funcție de securitate ce va permite introducerea de coordonate
în tabela poziții numai dacă el ne indică valoarea ,,1”. În caz contrar nu se realizează actualizarea.
Acest lucru este necesar pentru protejarea integrității bazei de date, deoa rece abia după apelul funcției
,,login.php”, utilizatorul este autentificat și se cunoaște înregistrarea ce trebuie actualizată cu poziția
respectivului.
Una dintre cele mai uzuale metode prin care se încearcă să se obțină drepturi mai mari asupra
bazelor de date este ce a de injectare de comenzi SQL. Un atacator încearcă diferite combinații de
comenzi inteligent alese pe care le introduce în căsuțele text destinate introducerii de informații în baza
de date. Prin aceste comenzi se poate forța afișarea unui utilizator conținut , ce în mod normal ar fi setat
ca nepermis de administratorul bazei de date. În funcțiile PHP prezentate anterior ex istă o matrice ce
conține comenzile SQL . Înainte de a se formula o cerere , variabila după care se face acea interogare, se
supune unui test în care , dacă există comenzi ce se găsesc în matrice, acestea sunt eliminate.
În cazul funcției ,,register.php” sele cția înregistrărilor se face după ID și nu este necesar să se
testeze celelalte valori ce sunt transmise prin URL. Dacă se încearcă injectarea unor comenzi prin

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
64 Nickname sau prin parola Pass ¸ atunci acestea vor fi introduse ca atare în baza de date sau cel mai
probabil vor furniza o eroare și funcția nu va funcționa.
Pentru funcția ,,logout.php” se utilizează atât ID cât și parola Pass . În cazul în care s -ar proceda
diferit, un utilizator ar putea să utilizeze funcția ,,getIDs.php” și ,,logout.php” pentru a afla ID-ul
tuturor și apoi să îi deconecteze pe to ți. Utilizarea acestor două valori este ascunsă de utilizator.
Sistemul oferă posibilitatea clienților de a își exprima disponibilitatea prin valoarea Status ,
valoare ce se poate modifica din aplicația And roid și care oferă două posibilități: disponibil prin
valoarea ,,1” și indisponibil prin valoarea ,,0”. Prin disponibil, clientul lasă posibilitatea de a fi localizat
de alți utilizatori, iar dacă selectează opțiunea de indisponibil, acesta va continua să transmită date către
baza de date, dar ceilalți utilizatori nu vor putea să îi citească poziția. În cazuri de urgență este posibil
ca utilizatorul sistemului să uite să activeze comutatorul Status și atunci dacă dispozitivul lui mobil nu
ar trimite poziția către DB când modul indisponibil este selectat, ar putea exista implicații dezastruoase.
Din acest motiv s -a decis transmisia a poziției indiferent de disponibilitatea clientului. Accesul la
poziția unui utilizator ce are selectat modul indisponibil poate fi făcută numai de administratorul bazei
de date, păstrând securitatea locației.
În cadrul aplicației Android, sup rascrierea butonului Back, în unele cazuri poate fi o măsura de
siguranță a datelor , deoarece în cazul în care un utilizator se deconectează și dorește s ă introducă alte
informații de autentificare, o apăsa re pe acest buton ar trimite la ecranul precedent sau alte activități ce
au fost utilizate înainte existând cazul ca să se introducă în baza de date informații eronate.

65 Concluzii

S-a abordat această temă deoarece nu există implementat în momentul actual un sistem ce oferă
acelea și funcționalităti. În acest moment există pe piață multe soluții pentru a localiza un telefon și de a
șterge informațiile de pe el , în cazul unui furt/pierdere, însă exist ă puține aplicații care urmăresc găsirea
unui dispozitiv mobil cu ajutorul unui alt terminal. Un mare avantaj al acestui sistem este că nu necesită
un alt dispozitiv ceea ce ar aduce costuri suplimentare (dispozitivul hardware și eventuale servicii, spre
exemplu internet) pentru a localiza un alt utilizator. Atâta timp cât respectivul are aplicația pornită și
dorește să fie localizat, acest lucru se poate realiza foarte u șor.
Tema elaborată poate să fie dezvoltată în continuare, prin implementarea unor algor itmi care să
elimi ne zgomotul și valorilor eronate ce provin de la transmițătoarele GPS și de la senzori . Se dorește
implementarea unor funcții ce afișează și diferența de altitudine. Se propune cartografierea obstacolelor
dintre cele 2 locații ale dispozi tivelor mobile și crearea unor funcții ce permit calculul unei rute optime
evitând obstacolele între cele dou ă terminale. Se dorește implementarea sistemului pe scară largă .
S-a proiectat și implementat o aplicație de monitorizare a poziției GPS pentru ter minale mobile
inteligente, cu sistem de operare Android, pe baza unei arhitecturi client -server. Aplicația permite
monitorizarea poziției GPS a terminalului mobil cu ajutorul unui API HTTP securizat, precum și
navigarea către alte dispozitive mobile aflate în sistem, dar și către destinații fixe prestabilite,
respectând intimitatea utilizatorilor și a condițiilor de securitate a conturilor acestora.
S-a implementat modelul LAMP pe un server web prin instalarea componentelor acestuia. S-a
realizat baza de date utilizând phpMyAdmin și s-au creat funcțiile PHP ce stau la baza serviciului web
REST . S-au implementat elemente de control și securitate pentru protecția informațiilor și a conturilor
utilizatorilor . S-a realizat sistemul de control al accesului utilizatorilor, autorizarea lor și deconectare a.
S-a dezvoltat aplicația Android ce rulează pe terminalul clientului. Aplicația Android a fost
implementată pornind de la o aplicație compas ce a fost modificată pentru a realiza achiziția locaț iei de
la sistemul GPS, comunicația între utilizatori prin recepționarea și transmiterea poziției GPS,
prelucrarea informației recepționate de la serverul web, calculul direcției de mers și a distanței bazate
pe pozițiile GPS ale celor două telefoane, implementarea elementelor de securitate pe dispozitivul
clientului, localizarea pe hărțile Google Maps, interfețele grafice prin care se afișează elementele grafice
de orientare și navigare a utilizatorului, interfețe grafice cu scopul de a introduce și afișa i nformații,
interfețele grafice ale activităților de legătură și interfețele grafice pentru sistemul de control al
accesului utilizatorilor.
Se va cerceta posibilitatea de implementare a sistemului în interiorul clădirilor și în spațiile
unde semnalul GPS nu ajunge prin triangularea semnalului de la diferite puncte de acces Wi -FI, dar și
prin utilizarea unor dispozitive Bluetooth ce vor interacționa cu dispozitivul mobil.
Se dorește dezvoltarea unui dispozitiv de dimensiuni reduse care să includă toate comp onentele
hardware , ce ar face posibil rularea sistemului de localizare la capacități maxime. Dispozitiv poate fi
atașat diverselor obiecte care se pot pierde ușor precum cheile și portofelul.
Se propune dezvoltarea în continuare a acestei aplicații pe sist emul de operare Android, dar și
implementarea pe alte sisteme de operare ca IOS sau Windows Phone.

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
66 Sistemul asistă persoanele care doresc să se întâlnească și care nu cunosc locația în care se află,
furnizând navigarea reciproc ă a unuia către celălalt.
O altă utilizare a aplicației este atunci când cele două persoane se găsesc într -o zonă aglomerată,
moment în care mișcarea continuă cât și lipsa unor repere relevante fac imposibilă întâlnirea.
În cazul unui accident, fie c ă se petrece în zone de șes sau î n zone montane greu accesibile, în
baza de date va fi memorată ultima locație a telefonului, locație ce va ajuta echipaje le de salvare într -o
situație extremă. De asemenea , în cazul unor activități periculoase precum : drumețiile, alpinismul, etc. ,
sistemul poate fi utilizat ca metod ă de precauție și prevenire. Se poate utiliza sistemul și în domeniul
medical și social, pentru persoane bolnave de diabet, boli de inima, Alzheimer, etc ce necesită
supraveghere permanentă, dar și în cazurile sociale ca: localizarea copiilor în diferite situații ,
dezorientarea bătrânilor etc, atâta timp cât presupune existența unui telefon mobil asupra lor.
O altă utilizare este atunci când se pleacă în grup spre o anumită destinație fie cu mașina sau pe
jos. În cazul în care se folosesc mașinile, în zonele urbane, este dificil ca un sofer să se țină unul după
altul. Astfel, șoferii și-ar dori să știe unde anume sunt restul persoanelor /mașinilor din grup , aplicația
venind în ajutorul lor . Dacă un grup de oameni, de exemplu turiști, se plimbă într -o zonă aglomerată se
pot pierde persoane de grup, situație în care utilizând sistemul de localizare , acestea se pot reîntâlni.
Sensibilitatea cu care se găsesc cele două telefoane pereche depind e de performan ța sistemului
de locali zare a terminalelor (modului GPS) cât și a senzorului magnetic. C âmpuri le magnetice perturbă
puternic senzorul magnetic și în unele situații este necesară recalibrarea senzorului.
Sistemul GPS ajută la micșorarea distanței între cele două terminale, însă din cauza zgomotului,
la distanțe mici, el este ineficient. În funcție de obstacolele din mediu, sistemul poate avea într -un caz
favorabil o precizie de până la 2-10 metri. Într -un caz defavorabil precizia poate să scadă și până la 40 –
100 de metri. Se dorește creșterea în viitor a preciziei în proximitate prin tehnologia bluetooth.
Schimbul de informații cu serverul are dimensiuni reduse și astfel s e utilizează trafic mobil
puțin, co nsumând puțin din datele mobile. În utilizarea sistemului este necesar activarea sistemului
GPS și a datelor mobile, amândouă funcțiile consumând multă putere. Din acest motiv sistemul nu
poate funcționa pe perioade lungi de timp.
Se dorește optimizarea ap licației Android pentru a reduce și mai mult consumul de dat e mobile,
schimbul de informații cu serverul, fiind făcut mai rar. Aplicația Android este încă în sta diu de
dezvoltare și conține erori ce apar în momentul utilizării ei.

67 Bibliografie

[1] Documentația oficiala Android , accesat la data 15.03.2017
<< https://developer.android.com/about/android.html >>

[2] Bolcaș Radu Daniel , ”Sistem de localizare în timp real a dispozitivelor inteligente bazate pe
platforma Android și asistență la navigare către destinații fixe sau în mișcare ”, UPB, Sesiunea de
Comunicări Științifice 201 7 (uz intern) .

[3] Documentația oficială Android, ” Introduction to Android ”, accesat la dat a 15.06.2017
<< https://developer.android.com/guide/index.html >>

[4] Documentația oficială Android, ”Application Fundaments ”, accesat la data 16.06.2017
<< https://developer.android.com/guide/components/fundamentals.html >>

[5] Documentația oficială Android, ” Platform Architecture ”, accesat la data 15.06.2017
<< https://developer.android.com/guide/platform/index.html >>

[6] Reto Meier , ”Professional Android 4 Application Development ”, John Wi ley & Sons, Inc.,
Indianapolis, 2012, ISBN: 978 -1-118-10227 -5, pp. 481 -483

[7] Kevin Grant, Chris Haseman , ”Beginning Android Programming: Develop and Design ”,
Peachpit Press, 2014 , ISBN -13: 978 -0321956569 , pp. 89

[8] Wallace Jackson , ”Pro Android UI ”, Apress, 2014, ISBN -13 (electronic): 978 -1-4302 -4987 -0,
pp.30 -32
<< http://pdf.th7.cn/down/files/1508/Pro%20Android%20UI.pdf >> accesat la data 20.06.2017

[9] Documentația oficială Android, ”UI Overview ”, accesat la data 20.06.2017
<< https://developer.android.com/guide/topics/ui/overview.html >>

[10] Wei-Meng Lee , ”Begin ning Android 4 Application Development ”, John Wiley & Sons, Inc. ,
Indiana, 2012, ISBN: 978 -1-118-19954 -1, pp. 395

[11] Fielding Roy Thomas , Tim Berners -Lee, et al. , ” HTTP/1.1, RFC 2616 ”, 1999 , secțiunea 9.3 -9.5
<< https://www.rfc -editor.org/rfc/rfc2616.txt >> accesat la data 21.06.2017

[12] Mark Mass é, ”REST API Design Rulebook ”, O’Reilly Media , Inc., 2012, ISBN: 978 -1-449-
31050 -9, pp.2-6,11

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
68 [13] Documentația oficială PHP, ”Ce este PHP? ”, accesat la data 20.06.2017
<< http://php.net/manual/ro/intro -whatis.php >>

[14]Manualul oficial MySQL, ”MySQL and PHP ”, accesat la data 09.04.2017 , pp. 1 -4
<< https://downloads.mysql.com/docs/apis -php-en.pdf >>

[15] Documentația oficială PHP, ” Injectarea SQL ”, accesat la data 15.06.2017
<< http://php.net/manual/ro/security.database.sql -injection.php >>

[16] William J. Francis , ”Pro tip: Cre ate your own magnetic compass using Android's internal
sensors ”, articol în Techrepublic , accesat la data: 02. 11.2016
<<http://www .techrepublic.com/article/pro -tip-create -your-own-magnetic -compass -using –
androids -internal -sensors/ >>

[17] Nilanchala , ”How to Trust All Certificates for HttpURLConnection in Android ”, articol în
Stacktips , accesat la data: 26.05.2017
<< https://stacktips.com/snippet/how -to-trust-all-certificates -for-httpurlconnection -in-android >>

[18] Documentația oficială GoogleMap, accesat la data 06.05.2017
<<https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap >>

Anexe
69 Anexe 1: Activitățiile aplicației Android și AndroidManifest

În continuare fragmentele de cod ce sunt de culoare gri sunt preluate din aplicația compas ,,open source” [16], sau
este cazul metodei trustAllCertificates() ce permite funcți onarea protocolului HTTPS [ 17].

1.1 Activitatea Login

public class Login extends Activity {

Button bt1, bt2, bt3;
EditText edt1, edt2;
public static String pass;
public static int m;
static TextView txt1, txt2, txt3;
int k = 4; //numara incercarile de
autentificare

@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout. activity_login );

bt1 = (Button)
findViewById(R.id. button); //Login button
edt1 = (EditText)
findViewById(R.id. editText ); ///username
edt2 = (EditText)
findViewById(R.id. editText2 ); ///password

bt2 = (Button)
findViewById(R.id. button2); //Cancel Button
bt3 = (Button)
findViewById(R.id. button3); //Register button

txt1 = (TextView)
findViewById(R.id. textView3 );
txt2 = (TextView)
findViewById(R.id. textView1 );
txt3 = (TextView)
findViewById(R.id. textView2 );
txt1.setVisibility(View. GONE);

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

MainActivity. iD =
edt1.getText().toString();
pass =
edt2.getText().toSt ring();
Logout.passLogout =pass;

Log.i("Login", "inainte de
async");
new AttemptLogin().execute();
Log.i("login", "Attempt login
finished" );
//int j = retRasp();
Log.i("login", "m " + m);

if (m == 1) {

Toast.makeText (getApplicationContext(),
"Redirecting…" , Toast. LENGTH_SHORT ).show();
Intent i = new
Intent(Login. this, Meniu. class);
startActivity(i);
finish();

} else {

Toast.makeText (getApplicationContext(), "Wrong
ID/Password" , Toast. LENGTH_SHORT ).show();

txt1.setVisibility(View. VISIBLE);

txt1.setBackgroundColor(Color. RED);
k–;

txt1.setText(Integer. toString (k));

if (k == 0) {
bt1.setEnabled( false);
}
}
}
});

bt2.setOnClickListener( new
View.OnClickListener() { //butonul Cancel
@Override
public void onClick(View v) {
finish();
}
});

bt3.setOnClickListener( new
View.OnClickListener() { //butonul Register
public void onClick(View v) {
pass = null;
Intent n = new
Intent(Login. this, Register. class);
startActivity(n);
finish();
}
});
}

@Override
public void onBackPressed()

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
70 {
}
}

class AttemptLogin extends AsyncTask<Object,
Object, Integer>
{

protected Integer doInBackground(Object…
urls) {
String USER_AGENT = "Mozilla/5.0
(Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/50.0.2661.87 Safari/537.36" ;

try {
trustAllCertificates ();
String str =
"https://xxx .xxx.xxx.xxx/FF/login.php?id=" +
MainActivity. iD + "&pass=" + Login. pass;

//MainActivity.t1.setText("connecting");
// MainActivity.t2.setText(st);
//testare string st
Log.i("Login","str:"+ str);
URL obj = new URL(str);
Log.i("Login","obj: "+ obj);
HttpsURLConnection conn =
(HttpsURLConnection) obj.openConnection();
Log.i("Login","con: "+ conn);
conn.setRequestMethod( "GET");
Log.i("Login","get: ");
conn.setDoOutput( true);
Log.i("Login","doOutput: " );
conn.setRequestProperty( "User-
Agent", USER_AGENT);

Log.i("Login","req ");

conn.setInstanceFollowRedirects( false);
conn.connect();
Log.i("Login","connect: " );
Log.i("Login","ok? ");

int responseCode =
conn.getResponseCode();
Log.i("Login","response code?
"+responseCode);

BufferedReader inBuff = new
BufferedReader( new
InputStreamReader(conn.getInputStream()) );
Log.i("Login","in"+ inBuff);
StringBuilder raspuns = new
StringBuilder();
String line;
while ((line = inBuff.readLine())
!= null) {

raspuns.append(line).append( '\n');
}
String valoare =
raspuns.toString();
valoare
=valoare.replaceAll( "\\s",""); Login.m=
Integer. parseInt (valoare);
Log.i("Login","valoare" + Login. m);

//MainActivity.t4.setText("putPos:
" + con.getResponseMes sage()); ///verif
cconexiunii

} catch (Exception e) {
// tx2.setText("err Login");
Log.i("Login", "exceptie:
"+e.getCause());

//tx2.setText(e.getLocalizedMessage());
e.printStackTrace();
}

return Login.m;
}
protected void onProgressUpdate(Void…
progress) {

}

protected int onPostExecute(String result)
{
return Login.m;
}
public static void trustAllCertificates()
{
try {
TrustManager[] trustAllCerts = new
TrustManager[]{
new X509TrustManager() {
public
X509Certificate[] getAcceptedIssuers() {
X509Certificate[]
myTrustedAnchors = new X509Certificate[0];
return
myTrustedAnchors;
}

@Override
public void
checkClientTrusted(X509Certificate[] certs,
String authType) {
}

@Override
public void
checkServerTrusted(X509Certificate[] certs,
String authType) {
}
}
};

SSLContext sc =
SSLContext. getInstance ("SSL");
sc.init( null, trustAllCerts, new
SecureRandom());

HttpsURLConnection. setDefaultSSLSocketFactory (
sc.getSocketFactory());

HttpsURLConnection. setDefaultHostnameVerifier (
new HostnameVerifier() {

Anexe
71 @Override
public boolean verify(String
arg0, SSLSession arg1) {
return true ;
}
});
} catch (Exception e) {
}
}

}
1.2 Activitatea Logout

public class Logout extends Activity {

public static boolean connexOK ;
public static String passLogout ;
@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout. activity_logout );

final Button button = (Button)
findViewById(R.id. buttonyy );////Cancel button
trimite la Meniu
button.setOnClickListener( new
View.OnClickListener() {
public void onClick(View v) {

Intent b = new
Intent(Logout. this, Meniu. class);
startActivity(b);
finish();

}
});

final Button button2 = (Button)
findViewById(R.id. buttonxx );////Logout button
trimite la Login
button2.setOnClickListener( new
View.OnClickListener() {
public void onClick(View v) {

Log.i("Logout" , "user");
Log.i("Logout" , "pass");

new AttemptLogout().execute();

Toast.makeText (getApplicationContext(), "You
succesfully logged out ",
Toast.LENGTH_SHORT ).show();

Intent c = new
Intent(Logout. this, Login. class);
startActivity(c);
finish();
}

});

} @Override
public void onBackPressed()
{
}

}
class AttemptLogout extends AsyncTask<Object,
Object, String>
{

protected String doInBackground(Object…
urls) {
String USER_AGENT = "Mozilla/5.0
(Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/50.0.2661.87 Safari/ 537.36";

try {
if(Login.pass!=null)
{Logout. passLogout =Login.pass;}

else{Logout. passLogout =Register. passRegister ;}

trustAllCertificates ();
String strg =
"https:// xxx.xxx.xxx.xxx /FF/logout.php?id=" +
MainActivity. iD + "&pass=" +
Logout.passLogout ;

Log.i("Logout" , "str:" + strg);
URL obj = new URL(strg);
Log.i("Logout" , "obj: " + obj);
HttpsURLConnection con =
(HttpsURLConnection) ob j.openConnection();
Log.i("Logout" , "con: " + con);
con.setRequestMethod( "GET");
Log.i("Logout" , "get: ");
con.setDoOutput( true);
Log.i("Logout" , "doOutput: " );
con.setRequestProperty( "User-
Agent", USER_AGENT);
Log.i("Logout" , "req ");
con.connect();
Log.i("Logout" , "connect: " );
Log.i("Logout" , "ok? " +
con.getResponseMessage());

//Logout.connexOK=con.getResponseMessage().equ
als("OK");

} catch (Exception e) {
// tx2.setText("err Logout");

//tx2.setText(e.getLocalizedMessage());
e.printStackTrace();
Log.i("Logout" ,"stacktrace" +
Arrays.toString (e.getStackTrace()));

}

return "ok";
}
protected void onProgressUpdate(Void…
progress) {

}

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
72
protected String onPostExecute(Void
result)
{
return "deconectare reusita" ;
}
public static void trustAllCertificates()
{
try {
TrustManager[] trustAllCerts = new
TrustManager[]{
new X509TrustManager() {
public
X509Certificate[] getAcceptedIssuers() {
X509Certificate[]
myTrustedAnchors = new X509Certificate[0];
return
myTrustedAnchors;
}

@Override
public void
checkClientTrusted(X509Certificate[] certs,
String authType) {
}

@Override
public void
checkServerTrusted(X509Certificate[] certs,
String authType) {
}
}
};

SSLContext sc =
SSLContext. getInstance ("SSL");
sc.init( null, trustAllCerts, new
SecureRandom());

HttpsURLConnection. setDefaultSSLSocketFactory (
sc.getSocketFactory());

HttpsURLConnection. setDefaultHostnameVerifier (
new HostnameVerifier() {
@Override
public boolean verify(String
arg0, SSLSession arg1) {
return true ;
}
});
} catch (Exception e) {
}
}

}
1.3 Activitatea Register

public class Register extends Activity {
EditText edtxt1, edtxt2, edtxt3, edtxt4;
public static String passRegister , pass2;

@Override
protected void onCreate(Bundle
savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout. activity_register );

edtxt1 = (EditText)
findViewById(R.id. editTexta );
edtxt2 = (EditText)
findViewById(R.id. editTextb );
edtxt3 = (EditText)
findViewById(R.id. editTextc );
edtxt4 = (EditText)
findViewById(R.id. editTextd );

final Button button = (Button)
findViewById(R.id. button1);
button.setOnClickListener( new
View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
MainActivity. iD =
edtxt1.getText().toSt ring();
passRegister =
edtxt2.getText().toString();
pass2 =
edtxt3.getText().toString();
MainActivity. name =
edtxt4.getText().toString();

Log.i("register" , "user:" +
edtxt1.getText().toString()); //id
Log.i("register" , "pass:" +
passRegister );
Log.i("register" , "pass2:" +
pass2);

if (passRegister .equals( pass2)
) {

Logout.passLogout =passRegister ;

Log.i("register" , "inainte
de async" );
new
AttemptRegister().execute();

Log.i("Register" , "valoare
dupa async" + AttemptRegister. val);/// nu
raspunde nimic daca nu exista; raspunde cu
string "ex ista" daca contul e in DB

if
(AttemptRegister. val.equals( "" ))
{

Toast.makeText (getApplicationContext(), "You
succesfully registered. Please Login" ,
Toast.LENGTH_SHORT ).show();
Intent a = new
Intent(Register. this, Login. class);
startActivity(a);
finish();
}else{

Toast.makeText (getApplicationContext(), "The
account e xists already" ,

Anexe
73 Toast.LENGTH_SHORT ).show();
}
}
}
});
}

}
class AttemptRegister extends
AsyncTask<Object, Object, String>
{

public static String val;
public static boolean connexOK;

protected String
doInBackground(Object… urls) {
String USER_AGENT = "Mozilla/5.0
(Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/50.0.2661.87 Safari/537.36" ;

try {
trustAllCertificate s();
String strg =
"https:// xxx.xxx.xxx.xxx /FF/register.php?id="
+ MainActivity. iD +"&n="+
MainActivity. name+"&pass=" +
Register. passRegister ;

//MainActivity.t1.setText("connecting");
// MainActivity.t2.setText(st);
//testare string st
Log.i("register" ,
"str:" + strg);
URL obj = new URL(strg);
Log.i("register" ,
"obj: " + obj);
HttpsURLConnection conn =
(HttpsURLConnection) obj.openConnection();
Log.i("register" ,
"con: " + conn);
conn.setRequestMethod( "GET");
Log.i("register" ,
"get: ");
conn.setDo Output(true);
Log.i("register" ,
"doOutput: " );
conn.setRequestProperty( "User-
Agent", USER_AGENT);
Log.i("register" , "req
");
conn.connect();
Log.i("register" ,
"connect: " );
Log.i("register" , "ok?
" + conn.getResponseMessage());

connexOK =conn.getResponseMessage().equals( "OK"
);
//MainActivity.t4.setText("putPos:
" + con.getResponseMessage()); ///verif
cconexiunii

if (connexOK ) { BufferedReader inBuff = new
BufferedReader( new
InputStreamReader(conn.getInputStream()));
Log.i("Register" , "in" +
inBuff);
StringBuilder raspuns = new
StringBuilder();
Log.i("Register" , "in" +
raspuns); /// nu raspunde nimic daca nu exista;
raspunde cu string "exista" daca contul e in
DB

String line;
while ((line =
inBuff.readLine()) != null) {

raspuns.append(line).append( '\n');
}
val = raspuns.toString();
val = val.replaceAll( "\\s",
"");
Log.i("Register" , "valoare" +
val);/// nu raspunde nimic daca nu exista;
raspunde cu string "exista" daca contul e in
DB

}
} catch (Exception e) {
// tx2.setText("err Logout");

//tx2.setText(e.getLocalizedMessage());
e.printStackTrace ();
}

return val;
}
protected void
onProgressUpdate(Void… progress) {

}

protected String onPostExecute(Void
result)
{
return val;
}

public static void
trustAllCertificates() {
try {
TrustManager[] trustAllCerts =
new TrustManager[]{
new X509TrustManager()
{
public
X509Certificate[] getAcceptedIssuers() {

X509Certificat e[] myTrustedAnchors = new
X509Certificate[0];
return
myTrustedAnchors;
}

@Override
public void
checkClientTrusted(X509Certificate[] certs,

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
74 String authType) {
}

@Override
public void
checkServerTrusted(X509Certificate[] certs,
String authType) {
}
}
};

SSLContext sc =
SSLContext. getInstance ("SSL");
sc.init( null, trustAllCerts,
new SecureRandom());

HttpsURLConnection. setDefaultSSLSocketFactory (
sc.getSocketFactory());

HttpsURLConne ction.setDefaultHostnameVerifier (
new HostnameVerifier() {
@Override
public boolean
verify(String arg0, SSLSession arg1) {
return true ;
}
});
} catch (Exception e) {
}
}
}

1.4 Activitatea Meniu
public class Meniu extends Activity {

@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout. activity_meniu );

final Button buttonA = (Button)
findViewById(R.id. buttonA); // FF
buttonA.setOnClickListener( new
View.OnClickListener() {
public void onClick(View v) {

Toast.makeText (getApplicationC ontext(), "FF…"
,Toast.LENGTH_SHORT ).show();
Intent a= new
Intent(Meniu. this, GetID. class);
startActivity(a);
finish();
}
});

final Button buttonB = (Button)
findViewById(R.id. buttonB); //GoogleMaps
buttonB.setOnClickListener( new
View.OnClickListener() {
public void onClick(View v) {

Toast.makeText (getApplicationContext(), "Maps..
.",Toast.LENGTH_SHORT ).show();
Intent e= new
Intent(Meniu. this, MapsActivity. class);
startActivity(e);
finish();
}
});

/*pt locatie fixaaaa*/
final Button button C = (Button)
findViewById(R.id. buttonC); //FL
buttonC.setOnClickListener( new
View.OnClickListener() {
public void onClick(View v) {
// Perform action on click

Toast.makeText (getApplicationContext(), "FL…"
,Toast.LENGTH_SHORT ).show();

Intent i= new
Intent(Meniu. this, InsertCoord. class);
startActivity(i);
finish();

}
});
final Button buttonD = (Button)
findViewById(R.id. buttonD); //Logout
buttonD.setOnClickListener( new
View.OnClickListener() {
public void onClick(View v) {
// Perform action on click

Intent o= new
Intent(Meniu. this, Logout.class);
startActivity(o);
finish();

}
});

}

@Override
public void onBackPressed()
{
Intent x= new Intent(Meniu. this,
Logout.class);
startActivity(x);
finish();
return;
}
}
1.5 Activitatea GetID

public class GetID extends Activity {
EditText id;
public static TextView t1, t2;
@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);

Anexe
75
setContentView(R.layout. activity_get_id );
t1 = new TextView( this);
t1 = (TextView)
findViewById(R.id. textView6 );
t2 = new TextView( this);
t2 = (TextView)
findViewById(R.id. textView7 );

id =
(EditText)findViewById(R.id. editTextid );
getID();

final Button buttonID = (Button)
findViewById(R.id. buttonID );
buttonID.setOnClickListener( new
View.OnClickListener() {
public void onClick(View v) {
// Perform action on click

MainActivity. partneriD =id.getText().toString()
;
Intent i= new
Intent(GetID. this, MainActivity. class);
startActivity(i);

finish();
}
});
}

public static void getID()
{
String USER_AGENT = "Mozilla/5.0
(Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/50.0.2661.87 Safari/537.36" ;
Log.i("GetID","coord: 11" );

try {
trustAllCertificates ();

String st =
"https:// xxx.xxx.xxx.xxx /FF/getIDs.php" ;
Log.i("GetID","st: "+ st);

t1.setText( "connecting" );
t2.setText(st); //testare string
st
URL obj = new URL(st);
Log.i("GetID","obj: "+ obj);
HttpsURLConnection con =
(HttpsURLConnection) obj.openConnection();
Log.i("GetID","con: "+ con);
con.setRequestMethod( "GET");
Log.i("GetID","get: ");
con.setDoOutput( true);
Log.i("GetID","doOutput: " );
con.setRequestProperty( "User-
Agent", USER_AGENT);
Log.i("GetID","req ");
con.connect();
Log.i("GetID","connect: " );
Log.i("GetID","ok?
"+con.getResponseMessage()); t1.setText( "GetID: " +
con.getResponseMessage()); ///verif
cconexiunii

BufferedReader in = new
BufferedReader( new
InputStreamReader(con.getInputStream()) );
//buffer pt a salva stream -ul
Log.i("GetID","in: "+ in);

StringBuilder total = new
StringBuilder();
String line;

while ((line = in.readLine()) !=
null) {

total.append(line).append( '\n');
}
Log.i("GetID","total: " + total);
String sirrr = total.toString();
sirrr
=sirrr.replaceAll( "\\n","&");
sirrr =sirrr.replaceAll( "\\s","");
sirrr
=sirrr.replaceAll( "&&&&","\n");
sirrr =sirrr.replaceAll( "&","");
Log.i("GetID","sirrr:" + sirrr);

String s= sirrr.replaceAll( ",","
") ;
t2.setText(s);
Log.i("GetID","s"+ s);

} catch (Exception e) {

t2.setText(e.getLocalizedMessage());
e.printStackTrace();
}
}

@Override
public void onBackPressed()
{
Intent y= new Intent(GetID. this,
Meniu.class);
startActivity(y);
finish();
return;
}

public static void trustAllCe rtificates()
{
try {
TrustManager[] trustAllCerts = new
TrustManager[]{
new X509TrustManager() {
public
X509Certificate[] getAcceptedIssuers() {
X509Certificate[]
myTrustedAnchors = new X509Certificate[0];
return
myTrustedAnchors;
}

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
76 @Override
public void
checkClientTrusted(X509Certificate[] certs,
String authType) {
}

@Override
public void
checkServerTrusted(X509Certificate[] certs,
String authType) {
}
}
};

SSLContext sc =
SSLContext.getInstance ("SSL");
sc.init( null, trustAllCerts, new
SecureRandom());

HttpsURLConnection. setDefaultSSLSocketFactory (
sc.getSocketFactory());

HttpsURLConnection. setDefaultHostnameVerifier (
new HostnameVerifier() {
@Override
public boolean verify(String
arg0, SSLSession arg1) {
return true ;
}
});
} catch (Exception e) {
}
}

}

1.6 Activitatea MainActivity
Clasa MainAc tivity :
public class MainActivity extends Activity
implements SensorEventListener {

public static TextView t;
public static TextView t1;
public static TextView t2;
public static TextView t3;
public static TextView t4;
public static TextView t5;
public static TextView t6;

private ImageView mPointer ;
private ImageView mPointer2 ;
private SensorManager mSensorManager ;
private Sensor mAccelerometer ;
private Sensor mMagnetometer ;
private float [] mLastAccelerometer = new
float[3];
private float [] mLastMagnetometer = new
float[3];
private boolean mLastAccelerometerSet =
false;
private boolean mLastMagnetometerSet =
false;
private float [] mR = new float [9]; private float [] mOrientation = new
float[3];
private float mCurrentDegree = 0f;
private float mCurrentDegree2 = 0f;

public static Location loc = null;
public static int myStatus =0;
public static String iD ;
public static String partneriD ;

public static String name ;
public static float bearing = 0; /////
metoda onSensorChanged – calculul rotatiei

public static Location loc2 = new
Location( ""); //loc2=locatie telefonul
partener
public static Location loc1 = new
Location( ""); //loc1=locatie telefonul meu

@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);

StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().
build();
StrictMode. setThreadPolicy (policy);

setContentView(R.layout. activity_main );
mSensorManager = (SensorManager)
getSystemService( SENSOR_SERVICE );
mAccelerometer =
mSensorManager .getDefaultSensor(Sensor. TYPE_AC
CELEROMETER );
mMagnetometer =
mSensorManager .getDefaultSensor(Sensor. TYPE_MA
GNETIC_FIELD );
mPointer = (ImageView)
findViewById(R.id. pointer);
mPointer2 = (ImageView)
findViewById(R.id. pointer2 );

Switch mainSwitch= (Switch)
findViewById(R.id. switch1); // seteaza dinamic
val status
mainSwitch.setChecked( false);

mainSwitch.setOnCheckedChangeListener( new
CompoundButton.OnCheckedChangeListener() {

@Override
public void
onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {

if(isChecked){
myStatus =1;// Status is
Visible
}else{
//Status is Invisible

Anexe
77 myStatus =0;
}
}
});

t = new TextView( this); ///locatia
mea
t = (TextView)
findViewById(R.id. textView );
t1 = new TextView( this);//// bearing
t1 = (TextView)
findViewById(R.id. textView1 );
t2 = new TextView( this); // locatie
partener
t2 = (TextView)
findViewById(R.id. textView2 );
t3 = new TextView( this); //// verif
getPos
t3 = (TextView)
findViewById(R.id. textView3 );
t4 = new TextView( this);//// verif
putPos
t4 = (TextView)
findViewById(R.id. textView4 );
t5 = new TextView( this); //// distanta
t5 = (TextView)
findViewById(R.id. textView5 );
t6 = new TextView( this); //// info
t6 = (TextView)
findViewById(R.id. textView6 );

//////////////////////////////////////////
verif conexiune gps
LocationManager locationManager =
(LocationManager)
getSystemService( LOCATION_SERVICE );

if
(locationManager.isProviderEnabled(LocationMan
ager.GPS_PROVIDER )) {
Toast.makeText (this, "GPS is
Enabled in your device" ,
Toast.LENGTH_LONG ).show();
} else {
Toast.makeText (this, "GPS is
Disabled in your device" ,
Toast.LENGTH_LONG ).show();
}

//////////////////////////////////////////////
///////

loc1.setLatitude( 2.0);
loc1.setLongitude( 2.0);

runThread(); /// thread pt actualizare
GetPosition si PutPosition

LocationManager mlocManager = null;
LocationListener mlocListener;
mlocManager = (LocationManager)
getSystemService(Context. LOCATION_SERVICE );
mlocListener = new
MyLocationListener();
if
(ActivityCompat. checkSelfPermission (this,
Manifest.permission. ACCESS_FIN E_LOCATION ) !=
PackageManager. PERMISSION_GRANTED &&
ActivityCompat. checkSelfPermission (this,
Manifest.permission. ACCESS_COARSE_LOCATION ) !=
PackageManager. PERMISSION_GRANTED ) {

return;
}

mlocManager.requestLocationUpdates(LocationMan
ager.GPS_PROVIDER , 1000, 0, mlocListener);

}

protected void onResume()
{
super.onResume();
mSensorManager .registerListener( this,
mAccelerometer ,
SensorManager. SENSOR_DELAY_GAME );
mSensorManager .registerListener( this,
mMagnetometer ,
SensorManager. SENSOR_DELAY_GAME );
}

protected void onPause()
{
super.onPause();

mSensorManager .unregisterListener( this,
mAccelerometer );

mSensorManager .unregisterListener( this,
mMagnetometer );
}

@Override
public void onSensorChanged(SensorEvent
event)
{
if (event.sensor == mAccelerometer )
{
System.arraycopy (event.values, 0,
mLastAccelerometer , 0, event. values.length);
mLastAccelerometerSet = true;
}
else if (event.sensor ==
mMagnetometer )
{
System.arraycopy (event.values, 0,
mLastMagnetometer , 0, event. values.length);
mLastMagne tometerSet = true;
}

if (mLastAccelerometerSet &&
mLastMagnetometerSet )
{

SensorManager. getRotationMatrix (mR, null,
mLastAccelerometer , mLastMagnetometer );
SensorManager. getOrientation (mR,
mOrientation );
float azimuthInRadians =
mOrientation [0];

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
78 float azimuthInDegrees =
(float)(Math.toDegrees (azimuthInRadians)+360)%
360; //limitează valoarea la intervalul
[0,360]

Log.i("Main
Activity" ,"azimuth" +azimuthInDegrees);

//// aceasta animatie indica
nordul
RotateAnimation ra1 = new
RotateAnimation(
mCurrentDegree2 ,-
azimuthInDegrees,

Animation. RELATIVE_TO_SELF , 0.5f,

Animation. RELATIVE_TO_SELF , 0.5f);

ra1.setDuration(250);
ra1.setFillAfter( true);

mPointer2 .startAnimation(ra1);
mCurrentDegree2 = –
azimuthInDegrees;
////////////////////////////////

bearing=GetPos.retBearing ();
//bearing = GetPos.bearinggg(loc1,
loc2); //calcul alternativ de bearing

MainActivity. t1.setText( "bearing:" +String. valu
eOf(bearing));
Log.i("Main
Activity" ,"bearing" +bearing);
float heading = azimuthInDegrees –
bearing; //directia de mers /// e necesar " -"
pt corectia sensului de rotire

Log.i("Main
Activity" ,"heading" +heading);
if(GetPos. hisStatus !=0) {
if (GetPos. retDistance () <
1000) {
t5.setText( "distanta:" +
String.valueOf(GetPos. retDistance ()) + "m");
} else {
t5.setText( "distanta:" +
String.valueOf(GetPos. retDistance () / 1000) +
"km");
}
}else{

t5.setText( "distanta:Invisible" );
}
//animatia indica direactia de
parcurs /// animatia se roteste trigonometric
RotateAnimation ra = new
RotateAnimation(
mCurrentDegree ,-heading,

Animation. RELATIVE_TO_SELF , 0.5f,

Animation. RELATIVE_TO_SELF , 0.5f);

ra.setDuration( 250); ra.setFillAfter( true);

mPointer .startAnimation(ra);
mCurrentDegree = -heading;
}
}

@Override
public void onAccuracyChanged(Sensor
sensor, int accuracy) {

}

@Override
public void onBackPressed()
{
Intent a= new Intent(MainActivity. this,
Meniu.class);
startActivity(a);
finish();
return;
}

private void runThread() {

new Thread() {
public void run() {
while (true) {
try {
runOnUiThread( new
Runnable() {

@Override
public void run()
{

MyLocationListener. updateMyPos (loc1);

GetPos.updateHisPos (loc2);
}
});
Thread.sleep(2000);
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

}
Clasa GetPos:
public class GetPos {

public static float x,y; // x-bearing//y –
distanta
public static String dataOra;
public static int hisStatus ;
public static double latit1, longit1;

public static void updateHisPos(Location
loc){
loc1 = loc;

Anexe
79
String USER_AGENT = "Mozilla/5.0
(Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/50.0.2661.87 Safari/537.36" ;

try {
trustAllCertificates ();

String st =
"https:// xxx.xxx.xxx.xxx /FF/getPosition.php?id
="+ MainActivity. partneriD ;
// MainActivity.t3.setText(st);
//verif string
URL obj = new URL(st);
HttpsURLConnection con =
(HttpsURLConnection) obj.openConnection();
con.setRequestMethod ("GET");
con.setDoOutput( true);
con.setRequestProperty( "User-
Agent", USER_AGENT);
con.connect();
MainActivity. t3.setText( "getPos: "
+ con.getResponseMessage()); //verificarea
conexiunii //functioneaza

BufferedReader in = new
BufferedReader( new
InputStreamReader(con.getInputStream()) );
//buffer pt a salva stream -ul

StringBuilder sir = new
StringBuilder();
String line;
while ((line = in.readLine()) !=
null) {
sir.append(line).append( '\n');
}
String coordonatePartener =
sir.toString(); // si se foloseste fara sa fie
de tip String, dar coordonatePartener trebuie
sa fie

Log.i("UpdateHisPosition" ,"coordpartener1:" +
coordonatePartener);
coordonatePartener
=coordonatePartener.replaceAll( "\\s","");///
eliminare spatii albe din string, spatii ce
provin de la functia php
//

Log.i("UpdateHisPosition" ,"coordpartener2:" +
coordonatePartene r);
//
MainActivity.t2.setText(coordonatePartener);//
/coordonatePartener = tot ce s -a primit de la
server prin putPosition – lati, long, dataOra

if (coordonatePartener != null)
{

hisStatus =Integer. parseInt (coordonatePartener.
split(",")[2]); //selectie status partener
if (hisStatus !=0) {

Location loc2 = new Location( ""); //loc2=locatie telefon partener

loc2.setLatitude(Double. parseDouble (coordonate
Partener.split( ",")[0]));//// incarca in loc2
coordonatele din stringul coordonatePartener

loc2.setLongitude(Double. parseDouble (coordonat
ePartener.split( ",")[1]));//

latit1 =
Double.parseDouble (coordonatePartener.split( ",
")[0]); ///pt google maps
longit1 =
Double.parseDouble (coordonatePartener.split( ",
")[1]);///pt google maps

float lati = ( float)
Double.parseDouble (coordonatePartener.split( ",
")[0]); ///trunchiere latitudine partener
float longi = ( float)
Double.parseDouble (coordonatePartener.split( ",
")[1]); ///trunchiere longitudine partener

dataOra =
coordonatePartener.split( ",")[3];
Log.i("UpdateHisPosition" ,
"coordpart split3 " + dataOra);
String data, ora;
data =
dataOra.substring( 0, 9);
ora =
dataOra.substring( 10);
dataOra = data + " " +
ora;
Log.i("UpdateHisPosition" ,
"dataOra" + dataOra);

//MainActivity.t2.setText(Double.parseDouble(c
oordonatePartener.split(",")[0])+ " " +
Double.parseDouble(coordonatePartener.split(",
")[1]));

MainActivity. t2.setText("El "+ lati + " " +
longi);
MainActivity. t6.setText(
"HisID: " +MainActivity. partneriD + " st:"+
GetPos.hisStatus +" ActiveAt: " +
GetPos.getDataOra ());

loc1.setLatitude(MyLocationListener. latitude );

loc1.setLongitude(MyLocationListener. longitude
);
Log.i("UpdateHisPosition" ,
"coord mele" + loc1);
x = loc1.bearingTo(loc2);
//salvez bearingul ce ia val intre [ –
180,180]grade
Log.i("UpdateHisPosition" ,
"coord mele" + MyLocationListener. latitude + "
" + MyLocationListener. longitude );
Log.i("UpdateHisPosition" ,
"coord lui" + loc2);

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
80 //MainActivity.t3.setText(String.valueOf(MyLoc
ationListener.latitude+ "
"+MyLocationListener.longitude));
////////////

if (x < 0) {
x = x + 360;
} // corectia valorii
bearing
///////////////
y =
MainActivity. loc.distanceTo(loc2); //distanta
intre locatii
}else{
onStatusChanged ();
}
}

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

//MainActivity.t2.setText(e.getLocalizedMessag
e());
MainActivity. t2.setText( "err
getPosition" );

Log.d("UpdateHisPOsition" ,"exceptie
getPosition" , e);
}
}

public static void onStatusChanged()
{
MainActivity. t6.setText( "HisID:
"+MainActivity. partneriD + " st:"+ hisStatus +"
ActiveAt: Invisible" );
MainActivity. t2.setText( "Invisible" );
x=0; //bearing
y=0; //distanta
}

public static float retBearing()
{return x;}

public static float retDistance()
{return y;}

public static String getDataOra()
{return dataOra;}

public static void trustAllCertificates()
{
try {
TrustManager[] trustAllCerts = new
TrustManager[]{
new X509TrustManager() {
public
X509Certificate[] getAcceptedIssuers() {
X509Certificate[]
myTrustedAnchors = new X509Certificate[0];
return
myTrustedAnchors;
}

@Override public void
checkClientTrusted(X509Certificate[] certs,
String authType) {
}

@Override
public void
checkServerTrusted(X509Certificate[] certs,
String authType) {
}
}
};

SSLContext sc =
SSLContext. getInstance ("SSL");
sc.init( null, trustAllCerts, new
SecureRandom());

HttpsURLConnection. setDefaultSSLSocketFactory (
sc.getSocketFactory());

HttpsURLConnection. setDefaultHostnameVerifier (
new HostnameVerifier() {
@Override
public boolean verify(String
arg0, SSLSession arg1) {
return true ;
}
});
} catch (Exception e) {
}
}

}
Clasa MyLocationListener:
public class MyLocationListener implements
LocationListener {

public static double latitude ;
public static double longitude ;

public static void updateMyPos(Location
loc){
MainActivity. loc = loc;

/// pt afisarea trunchiata a
coordonatelor proprii

MainActivity. t.setText( "Eu"+(float)loc.getLati
tude() + " " + (float)loc.getLongitude());
String USER_AGENT = "Mozilla/5.0
(Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/50.0.2661.87 Safari/537.36" ;

try {
trustAllCertificates ();
String st =
"https:// xxx.xxx.xxx.xxx /FF/putPosition.php?id
=" + MainActivity. iD + "&n=" +
MainActivity. name + "&La=" + loc.getLatitude()
+ "&Lg=" + loc.getLongitude()+ "&st="+
MainActivity. myStatus ;

Anexe
81 URL obj = new URL(st);
HttpsURLConnection con =
(HttpsURLConnection) obj.openConnection();
con.setRequestMethod( "GET");
con.setDoOutput( true);
con.setRequestProperty( "User-
Agent", USER_AGENT);
con.connect();

MainActivity. t4.setText( "putPos: "
+ con.getResponseMessage()); ///verif
cconexiunii

} catch (Exception e) {

MainActivity. t3.setText(e.getLocalizedMessage(
));
e.printStackTrace();
}
}

@Override
public void onLocationChanged(Location
loc)
{
latitude = loc.getLatitude();
longitude = loc.getLongitude();
MyLocationListener. updateMyPos (loc);
}

@Override
public void onProviderDisabled(String
provider)
{
//Toast.makeText(this, "Gps turned off ",
Toast.LENGTH_LONG).show();
//print "Currently GPS is Disabled";
}
@Override
public void onProviderEnabled(String
provider)
{
// Toast.makeText(this, "Gps turned on ",
Toast.LENGTH_L ONG).show();
//print "GPS got Enabled";
}
@Override
public void onStatusChanged(String
provider, int status, Bundle extras)
{
}
public static void trustAllCertificates()
{
try {
TrustManager[] trustAllCerts = new
TrustManager[]{
new X509TrustManager() {
public
X509Certificate[] getAcceptedIssuers() {
X509Certificate[]
myTrustedAnchors = new X509Certificate[0];
return
myTrustedAnchors;
}

@Override public void
checkClientTrusted(X509Certificate[] certs,
String authType) {
}

@Override
public void
checkServerTrusted(X509Certificate[] certs,
String authType) {
}
}
};

SSLContext sc =
SSLContext. getInstance ("SSL");
sc.init( null, trustAllCerts, new
SecureRandom());

HttpsURLConnection. setDefaultSSLSocketFactory (
sc.getSocketFactory());

HttpsURLConnection. setDefaultHostnameVerifier (
new HostnameVerifier() {
@Override
public boolean verify(String
arg0, SSLSession arg1) {
return true ;
}
});
} catch (Exception e) {
}
}

}
1.7 Activitatea InsertCoord
public class InsertCoord extends Activity {

EditText edt1,edt2;
public static String LocLong1 , LocLat1;

@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout. activity_insert_coord )
;

edt1 =
(EditText)findViewById(R.id. editTextX );
edt2 =
(EditText)findViewById(R.id. editTextY );

final Button button = (Button)
findViewById(R.id. button1);
button.setOnClickListener( new
View.OnClickListener() {
public void onClick(View v) {
// Perform action on click

LocLat1=edt1.getText().toString();
LocLong1 =
edt2.getText().toString();
Log.i("Insert coord:" ,

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
82 "LocLat" +LocLat1);
Log.i("Insert coo rd:",
"LocLong" +LocLong1 );

Toast.makeText (getApplicationContext(), "FindLo
c",Toast.LENGTH_SHORT ).show();

Intent m= new
Intent(InsertCoord. this, FindLoc. class);
startActivity(m);
finish();
}
});
}

@Override
public void onBackPressed()
{
Intent a= new Intent(InsertCoord. this,
Meniu.class);
startActivity(a);
finish();
return;
}

}

1.8 Activitatea FindLoc

public class FindLoc extends Activity
implements SensorEventListener {
public static TextView t;
public static TextView t1;
public static TextView t2;
public static TextView t3;
public static TextView t4;
public static TextView t5;

private ImageView mPointer ;
private ImageView mPointer2 ;
private SensorManager mSensorManager ;
private Sensor mAccelerometer ;
private Sensor mMagnetometer ;
private float [] mLastAccelerometer = new
float[3];
private float [] mLastMagnetometer = new
float[3];
private boolean mLastAccelerometerSet =
false;
private boolean mLastMagnetometerSet =
false;
private float [] mR = new float [9];
private float [] mOrientation = new
float[3];
private float mCurrentDegree = 0f;
private float mCurrentDegree2 = 0f;
public static Location loc = null;

public static float bearingFL = 0; ///// e
nevoie pt onSensorChanged pt calculul rotatiei
pt cazul FL public static float distanceFL ;

public static Location locEu = new
Location( ""); //locEu=locatie telefonul meu
public static Location locDest = new
Location( ""); //locDest=destinatiee

@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout. activity_find_loc );
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().
build();
StrictMode. setThreadPolicy (policy);

mSensorManager = (SensorManager)
getSystemService( SENSOR_SERVICE );
mAccelerometer =
mSensorManager .getDefaultSensor(Sensor. TYPE_AC
CELEROMETER );
mMagnetometer =
mSensorManager .getDefaultSensor(Sensor. TYPE_MA
GNETIC_FIELD );
mPointer = (ImageView)
findViewById(R.id. pointer);
mPointer2 = (ImageView)
findViewById(R.id. pointer2 );

t = new TextView( this);
t = (TextView)
findViewById(R.id. textView );
t1 = new TextView( this);
t1 = (TextView)
findViewById(R.id. textView1 );
t2 = new TextView( this);
t2 = (TextView)
findViewById(R.id. textView2 );
t3 = new TextView( this);
t3 = (TextView)
findViewById(R.id. textView3 );
t4 = new TextView( this);
t4 = (TextView)
findViewById(R.id. textView4 );
t5 = new TextView( this);
t5 = (TextView)
findViewById(R.id. textView5 );

//////////////////////////////////////////
verif conexiune gps
LocationManager locationManager =
(LocationManager)
getSystemService( LOCATION_SERVICE );

if
(locationManager.isProviderEnabled(LocationMan
ager.GPS_PROVIDER )) {
Toast.makeText (this, "GPS is
Enabled in your device" ,
Toast.LENGTH_LONG ).show();
} else {

Anexe
83 Toast.makeText (this, "GPS is
Disabled in your device" ,
Toast.LENGTH_LONG).show();
}

//////////////////////////////////////////////
///////

locEu.setLatitude( 2.0);
locEu.setLongitude( 2.0);

Log.i("FindLoc:" ,
"LocLong" +InsertCoord. LocLong1 );
Log.i("FindLoc" ,
"LocLat" +InsertCoord. LocLat1);

runThread2(); /// thread

locDest.setLongitude(Double. parseDouble (Insert
Coord.LocLong1 ));

locDest.setLatitude(Double. parseDouble (InsertC
oord.LocLat1));
FindLoc. t2.setText( "Dest
"+String. valueOf(locDest.getLatitude())+ "
"+String. valueOf(locDest.getLongitude()) );
Log.i("FindLoc:" ,
"LocDest" +locDest.getLatitude()+ "
"+locDest.getLongitude());

LocationManager mlocManager = null;
LocationListener mlocListener;
mlocManager = (LocationManager)
getSystemService(Context. LOCATION_SERVICE );
mlocListener = new
MyLocationListener();

if
(ActivityCompat. checkSelfPermission (this,
Manifest.permission. ACCESS_FINE_LOCATION ) !=
PackageManager. PERMISSION_GRANTED &&
ActivityCompat. checkSelfPermission (this,
Manifest.permission. ACCESS_COARSE_LOCATION ) !=
PackageManager. PERMISSION_GRANTED ) {

return;
}

mlocManager.requestLocationUpdates(LocationMan
ager.GPS_PROVIDER , 1000, 0, mlocListener);

}

protected void onResume() {
super.onResume();
mSensorManager .registerListener( this,
mAccelerometer ,
SensorManager. SENSOR_DELAY_GAME );
mSensorManager .registerListener( this,
mMagnetometer ,
SensorManager. SENSOR_DELAY_GAME );
}

protected void onPause() {
super.onPause();
mSensorManager .unregisterListener( this, mAccelerometer );

mSensorManager .unregisterListener( this,
mMagnetometer );
}
@Override
public void onSensorChanged(SensorEvent
event) {
if (event.sensor == mAccelerometer ) {
System.arraycopy (event.values, 0,
mLastAccelerometer , 0, event. values.length);
mLastAccelerometerSet = true;
} else if (event.sensor ==
mMagnetometer ) {
System.arraycopy (event.values, 0,
mLastMagnetometer , 0, event. values.length);
mLastMagnetometerSet = true;
}

if (mLastAccelerometerSet &&
mLastMagnetometerSet ) {

SensorManager. getRotationMatrix (mR, null,
mLastAccelerometer , mLastMagnetometer );
SensorManager. getOrientation (mR,
mOrientation );
float azimuthInRadians =
mOrientation [0];
float azimuthInDegrees = ( float)
(Math.toDegrees (azimuthInRadians) + 360) %
360;

RotateAnimation ra1 = new
RotateAnimation(
mCurrentDegree2 , –
azimuthInDegrees,

Animation. RELATIVE_TO_SELF , 0.5f,

Animation. RELATIVE_TO_SELF , 0.5f);

ra1.setDuration(250);
ra1.setFillAfter( true);

mPointer2 .startAnimation(ra1);
mCurrentDegree2 = –
azimuthInDegrees;

bearingFL =
locEu.bearingTo( locDest);
distanceFL =
locEu.distanceTo( locDest);

if(bearingFL <0)
{bearingFL =bearingFL +360;}

t1.setText( "bearing:" +
String.valueOf(bearingFL ) );

float heading = azimuthInDegrees –
bearingFL ; //directia de mers /// e necesar " –
" pt corectia sensului de rotire

// t5.setText("distanta:" +
String.valueOf(distanceFL) + "m");

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
84 if(distanceFL <1000) {
t3.setText( "distanta:" +
String.valueOf(distanceFL ) + "m");
}else{t3.setText( "distanta:" +
String.valueOf(distanceFL /1000) + "km");}

//partea de animatie /// animatia
se roteste trigonometric
RotateAnimation ra = new
RotateAnimation(
mCurrentDegree , -heading,

Animation. RELATIVE_TO_SELF , 0.5f,

Animation. RELATIVE_TO_SELF , 0.5f);

ra.setDuration( 250);
ra.setFillAfter( true);

mPointer .startAnimation(ra);
mCurrentDegree = -heading;
}

}

@Override
public void onAccuracyChanged(Sensor
sensor, int accuracy) {

}

private void runThread2() {

new Thread() {
public void run() {
while (true) {
try {
runOnUiThread( new
Runnable() {

@Override
public void run()
{

locEu.setLatitude(MyLocationListener. latitude )
;

locEu.setLongitude(MyLocationListener. longitud
e);
//

FindLoc.t.setText( "Eu"+String. valueOf((float)l
ocEu.getLatitude())+ "
"+String. valueOf((float)locEu.getLongitude()))
;

}
});
Thread.sleep(2000);
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
} }.start();
}

@Override
public void onBackPressed()
{
Intent a= new Intent(FindLoc. this,
Meniu.class);
startActivity(a);
finish();
return;
}
}

1.9 Activitatea MapsActivity
public class MapsActivity extends
FragmentActivity implements OnMapReadyCallback
{

private GoogleMap mMap;

@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout. activity_maps );
SupportMapFragment mapFragment =
(SupportMapFragment)
getSupportFragmentManager()
.findFragmentById(R.id. map);
mapFragment.getMapAsync( this);
}

@Override
public void onMapReady(GoogleMap
googleMap) {
mMap = googleMap;

LatLng Eu = new
LatLng(MyLocationListener. latitude ,
MyLocationListener. longitude );
LatLng El = new LatLng(GetPos. longit1,
GetPos.latit1);

mMap.addMarker( new
MarkerOptions().position(Eu).title( "Eu"));

mMap.moveCamera(CameraUpdateFactory. newLatLng (
Eu));

mMap.addMarker( new
MarkerOptions().position(El).title( "El"));

mMap.moveCamera(CameraUpdateFactory. newLatLng (
El));
}

@Override
public void onBackPressed()
{
Intent y= new Intent(MapsActivity. this,
Meniu.class);

Anexe
85 startActivity(y);
finish();
return;
}
}

1.10 Fișierul AndroidManifest.xml
<?xml version= "1.0" encoding= "utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/an
droid"
package= "com.example.radu.sistemgps" >

<uses-sdk
android:minSdkVersion= "14"
android:targetSdkVersion= "23" />
<!– android:versionCode="1" –>
<!– android:versionName="1.0" –>
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATIO
N" />
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCAT
ION" />
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STAT
E" />
<uses-permission
android:name="com.google.android.providers.gsf.permi
ssions.READ_GSERVICES" />

<uses-feature
android:glEsVersion= "0x00020000"
android:require d="true" />

<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.READ_CONTACTS" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STOR
AGE" />
<uses-permission
android:name="android.permission.READ_PHONE_STATE"
/>
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORA
GE" />

<application
android:allowBackup= "true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:screenOrientation= "portrait" />

<meta-data

android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key"
/>

<activity
android:name=".MapsActivity"
android:label="@string/app_name" />
<activity
android:name=".Login"
android:label="@string/app_na me">
<intent-filter> <action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity >
<activity android:name=".InsertCoord" />
<activity android:name=".Meniu" />
<activity android:name=".FindLoc" />
<activity android:name=".GetID" />
<activity android:name=".Register" />
<activity android:name=".Logout" ></activity >
</application >

</manifest >

Anexe
87 Anexa 2 : Interfața grafică

2.1 Activitatea Login
<?xml version= "1.0" encoding= "utf-8"?>
<RelativeLayout xmlns:android =
"http://schemas.android.com/apk/res/android"
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width= "match_parent"
android:layout_height = "match_parent"
android:paddingLeft=
"@dimen/activity_horizontal_margin"
android:paddingRight =
"@dimen/activity_horizontal_margin"
android:paddingTop =
"@dimen/activity_vertical_margin"
android:paddingBottom =
"@dimen/activity_vertical_margin"
tools:context = ".Login" >

<EditText
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:inputType= "textPassword"
android:ems="10"
android:id="@+id/editText2"
android:layout_below= "@+id/editText"
android:layout_alignParentLeft= "true"
android:layout_alignParentStart ="true"
android:layout_alignRight= "@+id/editText"
android:layout_alignEnd= "@+id/editText"
android:textColorHint= "#78b7ac"
android:hint="Enter Password" />

<TextView
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text=""
android:id="@+id/textView3"
android:layout_alignTop= "@+id/textView2"
android:layout_alignParentRight= "true"
android:layout_alignParentEnd= "true"
android:layout_alignBottom= "@+id/textView2"
android:layout_toEndOf= "@+id/textview"
android:textSize= "24dp"
android:layout_toRightOf= "@+id/textview" />

<Button
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text="Cancel"
android:id="@+id/button2"
android:layout_below= "@+id/textView2"
android:layout_toLeftOf= "@+id/button3"
android:layout_toStartOf= "@+id/button3"
android:layout_marginRight= "13dp"
android:layout_marginEnd= "13dp"
android:layout_marginTop= "56dp" />

<Button
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text="Login"
android:id="@+id/button"
android:textSize= "20dp"
android:layout_alignBaseline= "@+id/button2"
android:layout_alignBottom= "@+id/button2"
android:layout_toRightOf= "@+id/button3"
android:layout_toEndOf= "@+id/button3" android:layout_marginLeft= "25dp"
android:layout_marginStart= "25dp" />

<Button
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text="Register"
android:id="@+id/button3"
android:layout_marginTop= "28dp"
android:layout_below= "@+id/button"
android:layout_centerHorizontal= "true" />

<TextView
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text="Attempts Left:"
android:id="@+id/textView2"
android:textSize= "24dp"
android:layout_marginTop= "54dp"
android:layout_below= "@+id/editText2"
android:layout_alignParentLeft= "true"
android:layout_alignParentStart ="true" />

<EditText
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:id = "@+id/editText"
android:hint = "Enter ID"
android:focusable = "true"
android:textColorHighlight = "#cb7c114c"
android:textColorHint = "#78b7ac"
android:layout_marginTop = "24dp"
android:layout_below= "@+id/textview"
android:layout_alignParentLeft= "true"
android:layout_alignParentStart ="true"
android:layout_alignParentRight= "true"
android:layout_alignParentEnd= "true" />

<TextView android:text = "Login"
android:layout_width= "wrap_content"
android:layout_height = "wrap_content"
android:id = "@+id/textview"
android:textSize = "34dp"
android:layout_alignParentTop= "true"
android:layout_centerHorizontal= "true" />

</RelativeLayout >

2.2 Activitatea Logout
<?xml version= "1.0" encoding= "utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/an
droid"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_logout"
android:layout_width= "match_parent"
android:layout_height= "match_parent"

android:paddingBottom= "@dimen/activity_vertical_marg
in"

android:paddingLeft= "@dimen/acti vity_horizontal_marg
in"

android:paddingRight= "@dimen/activity_horizontal_mar

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
88 gin"

android:paddingTop= "@dimen/activity_vertical_margin"

tools:context= "com.example.radu.sistemgps.Logout" >

<Button
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text="Logout?"
android:id="@+id/buttonxx"
android:layout_marginTop= "36dp"
android:layout_centerHorizontal ="true" />

<Button
android:layout_width= "wrap_content "
android:layout_height= "wrap_content"
android:text="Cancel"
android:id="@+id/buttonyy"
android:layout_marginTop= "61dp"
android:layout_below= "@+id/buttonxx"
android:layout_centerHorizontal ="true" />

</RelativeLayout >

2.3 Activitatea Register
<?xml version= "1.0" encoding= "utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/an
droid"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_register"
android:layout_width= "match_parent"
android:layout_height= "match_parent"

android:paddingBottom= "@dimen/activity_vertical_marg
in"

android:paddingLeft= "@dimen/activity_horizontal_marg
in"

android:paddingRight= "@dimen/activity_horizontal_mar
gin"

android:paddingTop= "@dimen/activity_vertical_margin"

tools:context= "com.example.radu.sistemgps.Register" >

<EditText
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:inputType= "text"
android:ems="10"
android:id="@+id/editTexta"
android:hint="Enter username"
android:layout_below= "@+id/editText"
android:layout_alignParentLeft= "true"
android:layout_alignParentRight = "true"
android:layout_alignParentStart= "true"
android:textColorHint= "#78b7ac"
/>

<EditText
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:id = "@+id/editTextb"
android:hint = "Enter password"
android:focusable = "true"
android:textColorHighlight = "#cb7c114c" android:textColorHint = "#78b7ac"
android:inputType= "textPassword"
android:layout_marginTop = "46dp"
android:layout_alignParentLeft = "true"
android:layout_alignParentStart = "true"
android:layout_alignParentRight = "true"
android:layout_alignParentEnd = "true" />

<EditText
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:id = "@+id/editTextc"
android:hint = "Enter password again"
android:focusable = "true"
android:textColorHighlight = "#cb7c114c"
android:textColorHint = "#78b7ac"
android:inputType= "textPassword"
android:layout_marginTop = "12dp"
android:layout_below= "@+id/editTextb"
android:layout_alignParentLeft= "true"
android:layout_alignParentStart= "true"
android:layout_alignParentRight= "true"
android:layout_alignParentEnd= "true" />

<Button
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text="Create account"
android:id="@+id/button1"
android:layout_marginTop= "149dp"
android:layout_below= "@+id/editTextb"
android:layout_centerHorizontal= "true" />

<EditText
android:layout_width = "wrap_content"
android:layout_height = "wrap_content "
android:id = "@+id/editTextd"
android:hint = "Enter name"
android:focusable = "true"
android:textColorHighlight = "#cb7c114c"
android:textColorHint = "#78b7ac"
android:inputType= "text"
android:layout_marginTop = "17dp"
android:layout_below= "@+id/editTextc"
android:layout_alignParentLeft= "true"
android:layout_alignParentStart= "true"
android:layout_alignParentRight= "true"
android:layout_alignParentEnd= "true" />

</RelativeLayout >

2.4 Activitatea Meniu
<?xml version= "1.0" encoding= "utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/an
droid"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_meniu"
android:layout_width= "match_parent"
android:layout_height= "match_parent"

android:paddingBottom= "@dimen/activity_vertical_marg
in"

android:paddingLeft= "@dimen/activity_horizontal_marg
in"

android:paddingRight= "@dimen/activity_horizontal_mar
gin"

Anexe
89 android:paddingTop= "@dimen/activity_vertical_margin"

tools:context= "com.example.radu.sistemgps.Meniu" >

<Button
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text="FF"
android:id="@+id/buttonA"
android:layout_centerHorizontal= "true"
android:layout_marginBottom ="51dp" />

<Button
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text="FL"
android:id="@+id/buttonC"
android:layout_below= "@+id/buttonA"
android:layout_alignLeft= "@+id/buttonA"
android:layout_alignStart= "@+id/buttonA" />

<Button
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text="Google maps"
android:id="@+id/buttonB"
android:layout_marginTop= "56dp"
android:layout_below= "@+id/buttonC"
android:layout_centerHorizontal= "true" />
<Button
android:layout_wid th="wrap_content"
android:layout_height= "wrap_content"
android:text="Logout"
android:id="@+id/buttonD"
android:layout_marginTop= "56dp"
android:layout_below= "@+id/buttonB"
android:layout_centerHorizontal= "true" />

</RelativeLayout >

2.5 Activitatea GetID
<?xml version= "1.0" encoding= "utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/an
droid"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_get_id"
android:layout_width= "match_parent"
android:layout_height= "match_parent"

android:paddingBottom= "@dimen/activity_vertical_marg
in"

android:paddingLeft= "@dimen/activity_horizontal_marg
in"

android:paddingRight= "@dimen/activity_horizontal_mar
gin"

android:paddingTop= "@dimen/activity_vertical_margin"

tools:context= "com.example.radu.sistemgps.GetID" >

<TextView
android:text="TextView"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_alignParentTop= "true"
android:layout_centerHorizontal ="true"
android:layout_marginTop= "57dp"
android:id="@+id/textView6" />
<TextView
android:text="TextView"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_below= "@+id/textView6"
android:layout_alignRight= "@+id/textView6"
android:layout_alignEnd= "@+id/textView6"
android:layout_marginTop= "43dp"
android:id="@+id/textView7" />

<EditText
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"

android:inputType= "numberDecimal|numberSigned"
android:ems="10"
android:id="@+id/editTextid"
android:hint="partener ID:"
android:layout_below= "@+id/editText"
android:layout_alignParentLeft= "true"
android:layout_alignParentRight = "true"
android:layout_alignParentStart= "true"
android:textColorHint= "#78b7ac"
/>

<Button
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text="Go"
android:id="@+id/buttonID"
android:layout_marginBottom= "48dp"
android:layout_alignParentBottom= "true"
android:layout_toRightOf= "@+id/textView7"
android:layout_toEndOf= "@+id/textView7" />
</RelativeLayout >

2.6 Activitatea MainActivity
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/an
droid"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width= "match_parent"
android:layout_height= "match_parent"

android:paddingBottom= "@dimen/activity_vertical_marg
in"

android:paddingLeft= "@dimen/activity_horizontal_marg
in"

android:paddingRight= "@dimen/activity_horizontal_mar
gin"

android:paddingTop= "@dimen/activity_vertical_margin"

tools:context= "com.example.radu.sistemgps.MainActivi
ty" >

<TextView
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text=""
android:id="@+id/textView1"
android:layout_alignParentBottom= "true"
android:layout_marginBottom= "28dp"
android:layout_alignLeft= "@+id/switch1"
android:layout_alignStart= "@+id/switch1" />

<TextView

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
90 android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text=""
android:id="@+id/textView"
android:layout_alignBaseline= "@+id/textView1"
android:layout_alignBottom ="@+id/textView1"
android:layout_toRightOf= "@+id/pointer"
android:layout_toEndOf= "@+id/pointer" />

<ImageView
android:id="@+id/pointer"
android:layout_width= "150dp"
android:layout_height= "150dp"
android:src="@drawable/pointer2"
android:layout_marginBottom= "51dp"
android:layout_above= "@+id/textView1"
android:layout_centerHorizontal= "true" />

<ImageView
android:id="@+id/pointer2"
android:layout_width= "wrap_content"
android:layout_h eight="wrap_content"
android:src="@drawable/busola3"
android:layout_marginBottom= "20dp"
android:layout_above= "@+id/pointer"
android:layout_centerHorizontal= "true" />

<TextView
android:text=""
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_alignParentBottom= "true"
android:layout_centerHorizontal= "true"
android:id="@+id/textView2" />

<TextView
android:text=""
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:id="@+id/textView6"
android:layout_below= "@+id/textView5"
android:layout_alignLeft= "@+id/textView4"
android:layout_alignStart= "@+id/textView4"
/>

<TextView
android:text=""
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:id="@+id/textView4"
android:layout_below= "@+id/textView3"
android:layout_ali gnLeft="@+id/textView3"
/>

<TextView
android:text=""
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:id="@+id/textView5"
android:layout_below= "@+id/textView4"
android:layout_alignLeft= "@+id/textView4"
android:layout_alignStart= "@+id/textView4"
/>

<TextView
android:text=""
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_marginTop= "47dp"
android:id="@+id/textView3"
android:layout_alignParentTop= "true"
android:layout_alignLeft= "@+id/switch1"
android:layout_alignStart= "@+id/switch1" />
<Switch
android:text="Status"
android:layout_wi dth="wrap_content"
android:layout_height= "wrap_content"
android:id="@+id/switch1"
android:layout_alignParentTop= "true"
android:layout_centerHorizontal= "true"
android:textOn= "Visible"
android:textOff= "Invisible" />

</RelativeLayout >

2.7 Activitatea InsertCoord
<?xml version= "1.0" encoding= "utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/an
droid"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_insert_coord"
android:layout_width= "match_parent"
android:layout_height= "match_parent"

android:paddingBottom= "@dimen/activity_vertical_marg
in"

android:paddingLeft= "@dimen/activity_horizontal_marg
in"

android:paddingRight= "@dimen/activity_horizontal_mar
gin"

android:paddingTop= "@dimen/activity_vertical_margin"

tools:context= "com.example.radu.sistemgps.InsertCoor
d">

<EditText
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:id = "@+id/editTextY"
android:hint = "Enter Long (+forE/ -forW)"
android:focusable = "true"
android:textColorHighlight = "#cb7c114c"
android:textColorHint = "#78b7ac"

android:inputType= "numberDecimal|numberSigned"
android:layout_marginTop = "46dp"
android:layout_alignParentLeft = "true"
android:layout_alignParentStart = "true"
android:layout_alignParentRight = "true"
android:layout_alignParentEnd = "true" />

<EditText
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"

android:inputType= "numberDecimal|numberSigned"
android:ems="10"
android:id="@+id/editTextX"
android:hint="Enter Lat (+forN/ -forS)"
android:layout_below= "@+id/editText"
android:layout_alignParentLeft= "true"
android:layout_alignParentRight = "true"
android:layout_alignParentStart= "true"
android:textColorHint= "#78b7ac"
/>

<Button
android:layout_width= "wrap_content"

Anexe
91 android:layout_height= "wrap_content"
android:text="FindLocation"
android:id="@+id/button1"
android:layout_marginTop= "36dp"
android:layout_below= "@+id/editTextY"
android:layout_centerHorizontal= "true" />

</RelativeLayout >

2.8 Activitatea FindLoc
<?xml version= "1.0" encoding= "utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/an
droid"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_find_loc"
android:layout_width= "match_parent"
android:layout_height= "match_parent"

android:paddingBottom= "@dimen/activity_vertical_marg
in"

android:paddingLeft= "@dimen/activity _horizontal_marg
in"

android:paddingRight= "@dimen/activity_horizontal_mar
gin"

android:paddingTop= "@dimen/activity_vertical_margin"

tools:context= "com.example.radu.sistemgps.FindLoc" >

<TextView
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text=""
android:id="@+id/textView1"
android:layout_alignParentBottom= "true"
android:layout_alignLeft= "@+id/pointer"
android:layout_alignStart= "@+id/pointer"
android:layout_marginBottom= "28dp" />

<TextView
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text=""
android:id="@+id/textView"

android:layout_alignBaseline= "@+id/textView1"
android:layout_alignBottom= "@+id/textView1"
android:layout_toRightOf= "@+id/pointer"
android:layout_toEndOf= "@+id/pointer" />

<TextView
android:text=""
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_alignParentBottom= "true"
android:layout_centerHorizontal= "true"
android:id="@+id/textView2" />

<TextView
android:text=""
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_alignParentTop= "true"
android:layout_centerHorizontal= "true"
android:layout_marginTop= "10dp"
android:id="@+id/textView3" />
<TextView
android:text=""
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_below= "@+id/textView3"
android:layout_alignLeft= "@+id/textView3"
android:layout_marginTop= "10dp"
android:id="@+id/textView4" />

<TextView
android:text=""
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_below= "@+id/textView4"
android:layout_alignLeft= "@+id/textView4"
android:layout_marginTop= "10dp"
android:id="@+id/textView5" />

<ImageView
android:id="@+id/pointer"
android:layout_width= "150dp"
android:layout_height= "150dp"
android:src="@drawable/pointer2"
android:layout_marginBottom= "71dp"
android:layout_above= "@+id/textView"
android:layout_centerHorizontal= "true" />

<ImageView
android:id="@+id/pointer2"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:src="@drawab le/busola3"
android:layout_below= "@+id/textView5"
android:layout_centerHorizontal= "true"
android:layout_marginTop= "28dp" />

</RelativeLayout >

2.9 Activitatea MapsActivity
<fragment
xmlns:android="http://schemas.android.com/apk/res/an
droid"
xmlns:map="http://schemas.android.com/apk/res –
auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"

android:name="com.google.android.gms.maps.SupportMap
Fragment"
android:layout_width= "match_parent"
android:layout_height= "match_parent"

tools:context= "com.example.radu.sistemgps.MapsActivi
ty"

/>

Anexe
93 Anexa 3: Fișierele PHP

3.1 Fișierul datacon
<?
include("settings.php");
$dblink=MYSQL_CONNECT($MySqlHostname,
$MySqlUsername, $MySqlPassword) OR DIE("Unable to
connect to database");

@mysql_select_db("$db") or die( "Unable to
select database");
?>

3.2 Fișierul settings
<?
$MySqlHostname = "localhost";
$MySqlUsername = " ******** ";
$MySqlPassword = " ******** ";
$db = "localizare";

// Row Colors
$row1BgColor = "#FFFFFF";
$row2BgColor = "#C0C0C0";
$dbConnectionFile =
"include( \"datacon.php \");";

?>
3.3 Fișierul Login
<?
include("head.php");
include("datacon.php");
?>

<?
$cuvant=$_GET['id'];
$pass=$_GET['pass'];

// verificare impotriva SQL injection

$banlist = array
(
"insert", "select", "update", "delete",
"distinct", "having", "truncate", "replace",
"handler", "like", "as", "or",
"procedure", "limit", "order by", "group by",
"asc", "desc"
);

if ( eregi ( "[a -zA-Z0-9]+", $cuvant ) )
{
$cuvant = trim ( str_replace (
$banlist, '', strtolower ( $cuvant ) ) );
}
else
{
$cuvant = NULL;
}

$queryselect = "select * from utilizatori where
ID=$cuvant AND pass='$pass'";

$resultselect = MYSQL_QUERY($queryselect);
$numbersearchselect =
mysql_Numrows($resultselect);
if ($numbersearchs elect>0) {

$querysearch = "update utilizatori set login=1
where ID=$cuvant";

$resultsearch = MYSQL_QUERY($querysearch);
echo("1");
}
else
{
echo("0");
}

?>
3.4 Fișierul Logout
<?
include("head.php");
include("datacon.php");
?>

<?
$cuvant=$_GET['id'];
$pass=$_GET['pass'];

// verificare impotriva SQL injection

$banlist = array
(
"insert", "select", "update", "delete",
"distinct", "having", "truncate", "replace",
"handler", "like", "as", "or",
"procedure", "limit", "order by", "g roup by",
"asc", "desc"
);

if ( eregi ( "[a -zA-Z0-9]+", $cuvant ) )
{
$cuvant = trim ( str_replace (
$banlist, '', strtolower ( $cuvant ) ) );
}
else
{
$cuvant = NULL;
}

$queryselect = "select * from utilizatori where
ID=$cuvant AND pass='$pass '";

$resultselect = MYSQL_QUERY($queryselect);
$numbersearchselect =
mysql_Numrows($resultselect);

if ($numbersearchselect>0) {

$querysearch = "update utilizatori set login=0
where ID=$cuvant";

$resultsearch = MYSQL_QUERY($querysearch);
}
else
{
}

Sistem de localizare în timp real a dispozitivelor intelige nte bazate pe platforma Android
94 ?>
3.5 Fișierul Register
<?
include("head.php");
include("datacon.php");
?>

<?
$cuvant=$_GET['id'];
$nick=$_GET['n'];
$pass=$_GET['pass'];

// verificare impotriva SQL injection

$banlist = array
(
"insert", "select", "update", "delete",
"distinct", "having", "truncate", "replace",
"handler", "like", "as", "or",
"procedure", "limit", "order by", "group by",
"asc", "desc"
);

if ( eregi ( "[a -zA-Z0-9]+", $cuvant ) )
{
$cuvant = trim ( str_replace (
$banlist, '', strtolower ( $cuvant ) ) );
}
else
{
$cuvant = NULL;
}

$queryselect = "select * from utilizatori where
ID=$cuvant";

$resultselect = MYSQL_QUERY($queryselect);
$numbersearchselect =
mysql_Numrows($resultselect);

if ($numbersearchselect>0) {
echo("exista");
}
else
{
$querysearch = " insert into utilizatori
(ID,NickName,pass,login) VALUES ($cuvant,'$nick',
'$pass',0)";

$resultsearch = MYSQL_QUERY($querysearch);
}
?>
3.6 Fișierul putPosition
<?
include("head.php");
include("datacon.php");
?>
<?
$cuvant=$_GET['id'];
$nick=$_GET['n'];
$lat=$_GET['La'];
$lon=$_GET['Lg'];
$st=$_GET['st'];

// verificare impotriva SQL injection

$banlist = array
( "insert", "select", "update", "delete",
"distinct", "having", "truncate", "replace",
"handler", "like", "as", "or",
"procedure", "limit", "o rder by", "group by",
"asc", "desc"
);

if ( eregi ( "[a -zA-Z0-9]+", $cuvant ) )
{
$cuvant = trim ( str_replace (
$banlist, '', strtolower ( $cuvant ) ) );
}
else
{
$cuvant = NULL;
}

$query = "select login from utilizatori where
ID=$cuvant";

$result = MYSQL_QUERY($query);

if($result==1)
{

$queryselect = "select * from pozitii where
ID=$cuvant";

$resultselect = MYSQL_QUERY($queryselect);
$numbersearchselect =
mysql_Numrows($resultselect);

if ($numbersearchselect>0) {

$querysearch = "updat e pozitii set
DataTimp=now(),Latitudine=$lat, Longitudine=$lon,
Status=$st where ID=$cuvant";
$resultsearch = MYSQL_QUERY($querysearch);
}
else
{
$querysearch = "insert into pozitii
(DataTimp,ID,NickName,Latitudine,Longitudine,Statu
s) VALUES (now(),$cuvant ,'$nick', $lat,
$lon,$st)";

$resultsearch = MYSQL_QUERY($querysearch);
}
}
?>
3.7 Fișierul getPosition
<?
include("head.php");
include("datacon.php");
?>

<?
$cuvant=$_GET['id'];

// verificare impotriva SQL injection

$banlist = array
(
"insert", "select", "update", "delete",
"distinct", "having", "truncate", "replace",
"handler", "like", "as", "or",
"procedure", "limit", "order by", "group by",
"asc", "desc"
);

if ( eregi ( "[a -zA-Z0-9]+", $cuvant ) )
{

Anexe
95 $cuvant = trim ( str_replace (
$banlist, '', strtolower ( $cuvant ) ) );
}
else
{
$cuvant = NULL;
}

$querysearch = "select
Latitudine,Longitudine,Status, MAX(DataTimp) from
pozitii where ID=$cuvant";

$resultsearch = MYSQL_QUERY($querysearch);
$numbersearch = mysql_Numrows($resultsearch);

if ($numbersearch>0) {

$x=0;

?>
<?
while ($x<$numbersearch)
{
?> <?
$rom=mysql_result($resultsearch,$x,"Latitudine");
?>
<? echo $rom; ?>,
<?
$eng=mysql_result($resultsearch,$x,"Longitudine");
?>
<? echo $eng; ?>,
<?
$st=mysql_result($resultsearch,$x,"Status"); ?>
<? echo $st; ?>,

<?
$dt=mysql_result($resultsearch,$x,3);
?>
<? echo $dt; ?>
<?
$x++;
} // end while
?>
<?
$exista='D';
} // end if
else
{
$exista='N';
}

mysql_free_result($resultsearch);

?>
3.8 Fișierul GetIDs
<?
include("head.php");
include("datacon.php");
?>

<?

$querysearch = "select distinct ID,NickName from
pozitii";

$resultsearch = MYSQL_QUERY($querysearch);
$numbersearch = mysql_Numrows($resultsearch);

if ($numbersearch>0) {

$x=0;
?><?
while ($x<$numbersearch)
{
?>
<?
$rom=mysql_result($resultsearch,$x,"ID"); ?>
<? echo $rom; echo ", "?>
<?
$eng=mysql_result($resultsearch,$x,"NickName"); ?>
<? echo $eng; ?>

<?
$x++;
} // end while
?>
<?
$exista='D';
} // end if
else
{
$exista='N';
}
mysql_free_result($resultsearch);

?>

Anexe
97 Anexa 4: Structura bazei de date

– phpMyAdmin SQL Dump
– version 3.1.0
– http://www.phpmyadmin.net

– Host: localhost
– Generation Time: Jun 22, 2017 at 11:08 AM
– Server version: 5.0.88
– PHP Version: 5.2.9

SET SQ L_MODE="NO_AUTO_VALUE_ON_ZERO";

– Database: `localizare`

4.1 Structura tabelei poziții

– Table structure for table `pozitii`

CREATE TABLE IF NOT EXISTS `pozitii` (
`DataTimp` datetime NOT NULL,
`ID` varchar(20) NOT NULL,
`NickName` varchar(30) NOT NULL,
`Latitudine` double NOT NULL,
`Longitudine` double NOT NULL,
`Status` int(11) NOT NULL,
FULLTEXT KEY `ID` (`ID`),
FULLTEXT KEY `ID_2` (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

4.2 Structura tabelei utilizatori


– Table structure for table `utilizatori`

CREATE TABLE IF NOT EXISTS `utilizatori` (
`ID` varchar(20) NOT NULL,
`NickName` varchar(30) NOT NULL,
`pass` varchar(30) NO T NULL,
`login` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Similar Posts