Programul de studiu Informatică [622765]

Universitatea TRANSILVANIA din Brașov
Facultatea de Matematicǎ și Informatică
Programul de studiu Informatică

Lucrare de licență

Autor: Ene Victor – Ștefăniță
Coordonator științific: Conf. univ. dr. Deaconu Adrian

Brașov,2017

BIKEAPP – APLICAȚIE MOBILĂ DE
SOCIALIZARE FOLOSIND GOOGLE MAPS

1 Introducere ………………………….. ………………………….. ………………………….. ………………………….. 1
2 Baze de date ………………………….. ………………………….. ………………………….. …………………………. 3
Noțiuni generale ………………………….. ………………………….. ………………………….. ……………….. 3
Clasificarea sistemelor de baze de date ………………………….. ………………………….. ………….. 4
Clasificare după modelul de date ………………………….. ………………………….. …………. 4
Clasificare după numărul de utilizatori ………………………….. ………………………….. … 4
Clasificare după numărul de dispozitive pe care este reținută baza de date ……. 5
Construirea schemelor relație ………………………….. ………………………….. ……………………….. 5
Relația ”1 -1” ………………………….. ………………………….. ………………………….. …………… 5
Relația ”1 -N” ………………………….. ………………………….. ………………………….. ………….. 5
Relația ”M -N” ………………………….. ………………………….. ………………………….. ………… 6
Relația unară ………………………….. ………………………….. ………………………….. ………….. 6
Normalizarea bazelor de date ………………………….. ………………………….. ………………………… 7
Forma normală unu ………………………….. ………………………….. ………………………….. … 7
Forma normală doi ………………………….. ………………………….. ………………………….. …. 8
Forma normală trei ………………………….. ………………………….. ………………………….. … 9
Forma normală Boyce -Codd ………………………….. ………………………….. ………………. 10
Demonstrare FN3 pentru BikeApp ………………………….. ………………………….. …….. 10
Baza de date a aplicației BikeApp ………………………….. ………………………….. ………………… 11
MySQL ………………………….. ………………………….. ………………………….. …………………. 11
PHP ………………………….. ………………………….. ………………………….. ……………………… 12
JSON ………………………….. ………………………….. ………………………….. ……………………. 12
Legătura înt re Android, PHP și MySQL ………………………….. …………………………. 13
3 Android ………………………….. ………………………….. ………………………….. ………………………….. …. 17
Platforma hardware Android ………………………….. ………………………….. ………………………. 17
Procesorul ………………………….. ………………………….. ………………………….. …………….. 18
Memoria ………………………….. ………………………….. ………………………….. ……………….. 18
Sistem de poziționare globală ………………………….. ………………………….. …………….. 19

Rețele fără fir ………………………….. ………………………….. ………………………….. ……….. 19
Card SD ………………………….. ………………………….. ………………………….. ……………….. 20
Ecranul ………………………….. ………………………….. ………………………….. …………………. 20
Camera de fotografiat ………………………….. ………………………….. ……………………….. 21
Bateria ………………………….. ………………………….. ………………………….. ………………….. 21
Senzori de mișcare ………………………….. ………………………….. ………………………….. … 21
Platforma software Android ………………………….. ………………………….. ………………………… 22
Arhitectura sistemului de operare Android ………………………….. …………………….. 22
Componentele unei aplicații Android ………………………….. ………………………….. …. 26
Fișierul Manifest ………………………….. ………………………….. ………………………….. …… 28
4 Instrumente externe ………………………….. ………………………….. ………………………….. …………… 31
Google Maps v2 ………………………….. ………………………….. ………………………….. ………………. 31
Caracteristici pentru dezvoltatori. ………………………….. ………………………….. ……… 31
Funcționalitate în BikeApp ………………………….. ………………………….. ………………… 35
Exemple de aplicații care folosesc GoogleMaps V2 ………………………….. ………….. 35
Firebase ………………………….. ………………………….. ………………………….. …………………………. 35
5 Prezentarea aplicației ………………………….. ………………………….. ………………………….. …………. 40
Cerințe non -funcționale ………………………….. ………………………….. ………………………….. ….. 40
Clase ………………………….. ………………………….. ………………………….. ………………………….. ….. 40
Pachetul Engine ………………………….. ………………………….. ………………………….. …….. 40
Pachetul UI ………………………….. ………………………….. ………………………….. …………… 42
Pachetul Utils ………………………….. ………………………….. ………………………….. ………… 44
Prezentarea funcționalității aplicației ………………………….. ………………………….. …………… 46
Înregistrarea utilizatorului ………………………….. ………………………….. ………………… 46
Autentificarea utilizatorului ………………………….. ………………………….. ………………. 47
Ecranul principal ………………………….. ………………………….. ………………………….. ….. 50
6 Concluzii ………………………….. ………………………….. ………………………….. ………………………….. .. 61
Bibliografie ………………………….. ………………………….. ………………………….. ………………………….. …. 62

1
1 Introducere

Un telefon mobil reprezintă un dispozitiv electronic transportabil care se conectează cu
alte telefoane cu ajutorul rețelelor GSM1 sau CDMA2.
Primul telefon mobil a apărut în anul 1973, atunci când Martin Cooper , care la acel
moment era manager general la firma Motorola , efectua prima convorbire telefonică în timp ce
mergea pe stradă, însă a fost nevoie de 10 ani de teste pentru a fi comercializat sub numele
Motorola DynaTAC 8000x și devenea primul telefon care a fost recunoscut și acce ptat de
autoritățile competente , cântărind 900g și având 25cm lungime. [1]
Odată cu trecerea timpului , telefonul a suferit multe î mbunătățiri , transformându -se
dintru -un simplu dispozitiv de comunicare , într -un aparat electronic intelige nt care ajută
utilizatorii s ă își satisfacă ș i alte nevoi cum ar fi: divertisment, împărtășirea documentelor sau
a lucrurilor personale, înregistrarea momentelor importante, folosirea aplicațiilor pentru a ușura
acțiunile fiecărui utilizator etc. Toate aceste nevoi au devenit posibil e odată cu apariția
telefoanelor inteligente.
Primul telefon intelig ent a fost Simon care a apărut î n anul 1992, produs de compania
IBM . De atunci au inceput să apară nenumărate modele de telefoane cu diferite siste me de
operare precum: Android, i OS, Windows mobile etc.
Aplicaț ia pe care am ales să o prezint este dezvoltată pentru sistemul de ope rare Android
și se numește BikeA pp.
Modelarea aplicației s -a realizat în mediul de dezvoltare Android Studio, care a fost
realizat și este sprijinit de compani a americană Google.
Bikeapp este o aplicație destinată bicicliștilor, cu ajutorul căreia utilizatorii pot efectua
acțiuni precum: înregistrarea traseelor, trimiterea de mesaje, împărtăsirea traseelor, capturarea
momentelor importante cu ajutorul camerei de fotografiat și desenarea pe hartă a traseelor.
Printre tehnologiile folosite la realizarea acestei aplicații se numără: Google M aps,
Firebase, Java, PHP, MySQL.

1 Sistem global pentru comunicații mobile.
2 Canal de acces multiplu.

2
Motivul pentru care am ales să dezvolt și să prezint aceasta a plicație este că din
observați ile mele, nu am descoperit prea multe aplicații de acest gen pentru bicicliș ti, iar cele
care sunt deja prezente în magazinele de pe internet , nu pun a ccentul pe socializare, acest lucru
diferă in principal între aplicația BikeA pp și celelalte aplicații ex istente.

3
2 Baze de date

Noțiuni generale
O bază de date poate fi definită ca o reuniune de date , creată ș i menținută sub controlul
computerului pentru a face posibilă prelucrarea datelor. [2]
Prelucrarea constă în următoarele operații : inserarea datelor, citirea datelor, actualizarea
datelor și ș tergerea datelor.
Spre deosebire de metodele vechi de înregistrare a datelor pentru diferite activități
precum documentele scrise sau fișiere le text pe disc, sistemele de baze de date oferă avantaje
majore cum ar fi :
 Viteză mare de găsire a datelor;
 Volumul redus al datelo r în comparație cu d ocumentele scrise;
 Scăderea redundanței pentru datele folosite în comun de mai mulți utilizatori și
mai multe aplicații . De exemplu într -o firmă pentru gestionarea salariilor
angajaților și orelor lucrate a angajaților se va folosi o s ingură bază de date;
 Controlul datelor se face de către o singură persoa nă desemnată pentru acest
lucru;
 Flexibilitate ce înseamna posibilitatea schimbă rii bazei de date fără alterarea ei.

Figura 2.1 Conexiune la baza de date.

4

Clasificarea sistemelor de baze de date

Bazele de date pot fi clasificate după mai multe criterii cum ar fi: după modelul de da te,
după numărul de utilizatori și după numărul de dispozitive pe c are este reținută baza de date.

Clasificare după modelul de date

O mare parte din sistemele de baze de date la momentul actual sunt create î n modelul
de date relațional sau în modelul de date orientat pe obiect. Datorită dezvoltării continue a
acestor modele s -a realizat o nouă categorie de baze de date numită obiect -relaționale care
îmbina caracteristicile celorlalte două modele. [3]
Modelul de date re lațional (Relat ional Model) este bazat pe noțiunea de relație și are o
reprezentare simplă formată dintr -un tabel bidimensional cu linii și co loane.
Modelul de date orientat pe obiect (Object Model) este un concept important în
informatică. Sistemele de baze de date care folosesc acest model se folosesc în principal de
limbajele de programare obiect orientate.
Modelul de date obiect -relațional (Object -Relational Model) este o îmbinare a
modelului de date relațional cu mod elul de date orientat pe obiect, pentru a putea realiza baze
de date complexe.

Clasificare după numărul de utilizatori

Sistemel e de baze de date se împart în două categorii:
 multiutilizator ;
 monoutilizator .
Cele mai utilizate sisteme de baze de date sunt cele multiutilizator, ele permit accesul
în același timp a mai multor utilizatori la aceeași bază de date spre deosebire de cele
monoutilizator care permit suportul unui sing ur utilizator.

5

Clasificare după numărul de dispozitive pe care este reținută baza de
date

În această clasificare distingem două sisteme de baze de date:
 distribuite ;
 centralizate .
Un sistem de baze de date distribuit poate avea datele pe mai multe calculatoare
conectate între ele cu ajutorul unei rețele.
Un sistem de baze de date centralizat are datele salvate pe un singur calculator.

Construirea schemelor relație

O relaț ie reprezintă o corespondența î ntre entități din ace eași mulțime sau din mai multe
mulțimi. [4]

Relația ”1-1”

Reprezintă relația în care un ui element al primei mulțimi îi corespunde un singur
element din a doua mulțime și invers.

Relația ”1-N”
Reprezintă relația în care unui element al primei mulțimi îi corespund mai multe
elemente din a doua mulț ime, dar nu și invers.

Figura 2 .2 Relatia “1 -1”

6

Relația ”M-N”

Reprezintă relația în care unui element al primei mulțimi îi corespund mai multe
elemente din a doua mulțime și reciproc.

Relația unară

Până acum , toate relațiile prezentate mai su s sunt binare și au două relații implicate insă,
relația unară, folosește o singură relație aceasta fiind asociată cu ea însăși.

Figura 2.3 Relaț ia “1 -N”

Figura 2 .4 Relația “M -N”

7

Normalizare a bazelor de date

Procesul de normalizare a fost introdus de E dgar Frank Codd în anul 1972. La început
au fost propuse trei forme normale 1NF, 2NF, 3NF. [3] Ulterior, prin enunțarea unei definiții
mai puternice a formei normale trei, s -a obținut forma Boyce -Codd, purtând numele celor care
au descoperit ac eastă formă normală: Raymond Boyce și Edgar Frank Codd. Toate aceste forme
normale se bazează pe dependențele funcționale stabilite între atributele unei relații.
Cele mai utilizate forme normale sunt: forma normală 3 și forma normală Boyce -Codd
dar există și forme normale mai puternice precum forma normală 4 și forma normală 5 însă nu
sunt prea des întâlnite.
Normalizarea se realizează trecând prin toate formele normale, pâna la forma dorită.
Pentru ca o bază de date să fie normalizată este indicat să se ajungă cel puțin până la forma
normală trei.

Forma normală unu

Considerăm că o relație se află in forma normală unu dacă nu există atribute compuse
sau repetitive .
Pentru a înțelege mai bine forma normală unu exemplificăm normalizarea următorului
tabel:

Figura 2 .5 Relație unară

8

Id materie Denumire An NumeProfesor
1 Programare obiect
orientată I A.Băicoianu,
A.Deaconu

Transformarea tabelului în formă normală unu prin eliminarea setului de valori din
dreptul atributului NumeProfesor și considerând două materii diferite.
Id materie Denumire An NumeProfesor
1 Programare obiect
orientată I A.Băicoianu
2 Programare obiect
orientată I A.Deaconu

Forma normală doi

Forma normală doi este realizată atunci când fiecare atribut care nu aparține cheii
primare, este dependent de cheia primară și indeplinește condițiile pentru a fi în forma normală
unu.
Pentru a exemplifica form a normală doi, considerăm tabelul de la forma normală unu
unde adăugăm și alte câmpuri cum ar fi: NumeStudent și Notă.

Id materie Denumire An Nume Profesor Nume
Std. Notă
1 Programare obiect
orientată I A.Băicoianu Mihai 8
2 Programare obiect
orientată I A.Deaconu Mihai 9

9
Tabelul de de mai sus nu este în formă normală doi. Pentru a -l aduce la forma normală
doi vom împărți tabelul în trei , și o să avem tabelele Studenți, Materii, Note.
Tabelul Studenți va avea următoarea structură:
Id student Nume
1 Mihai

Tabelul Materii va avea următoarea structură:
Id materie Denumire An Nume Profesor
1 Programare obiect
orientată I A.Băicoianu
2 Programare obiect
orientată I A.Deaconu

Tabelul Note va avea următoarea structură:
Notă Id student Id materie
8 1 1
9 1 2

Forma normală trei

Pentru ca un tabel să fie in forma normală trei, în primul rând trebuie să îndeplinească
condițiile de la forma normală unu și doi i ar în al doilea rând trebuie ca toate câmpurile non –
primare să depindă numai de câmpuri primare.
Nu face parte din normalizare dar este indicat să nu se treacă în tabel câmpuri care se
pot deduce din alte câmpuri spre exemp lu dacă avem în tabelul Student câmpul dată naștere, nu
este recomandabil să avem câmpuri care se pot ded uce cum ar fi vârsta.

10

Forma normală Boyce -Codd

Forma normală Boyce -Codd este obținuta prin utilizarea cheilor candidat din relație. O
relație în formă normală trei cu o singură cheie candidat es te și în forma normală Boyce -Codd .
Dacă orice determinant din relație este cheie candidat atunci se consideră că o relație
este în forma normală Boyce -Codd.
În cele mai multe cazuri este destul de greu să ajugem la forma normală Boyce -Codd,
pentru aceste cazuri este recomandabil să se rămână la forma normală trei.

Demonstrare FN3 pentru BikeApp

În aplicația BikeApp avem următoarele tabele: Coordinates, User, Route,
Images .
În cadrul bazei de date avem u rmătoarele relatii:
 între tabelul User ș i tabelul Route avem rel ația ”1-N”;
 între tabelul Route și tabelul Coordinates avem relația ”1-N”;
 între tabelul Coordinates și tabelul Image avem relația ”1-N”.

Figura 2 .6: Baza de date a aplicației Bike -App

11
Pentru ca o bază de date să fie in formă normală trei, trebuie mai întâi să fie în formă
normală unu și în formă normală doi, prin urmare se demonstrează, pe rând că baza de date
aparține formei normale unu si doi.
Deoarece în baza de date nu se găsesc atribute compuse sau combinații ale lor , se
demonstrează apartenența bazei de date la forma normală unu.
Odată ce se demonstrază că baza de date îndeplinește condițiile pentru a fi în formă
normală unu, se îndeplinește si prima regulă pentru a fi în formă normală doi. A doua regulă
pentru a fi în formă normală doi este îndeplinită prin faptul că tabelele conțin doar atribute care
dau informații despre cheia tabelului. Din aceste două reguli r ezultă că baza de date este în
formă normală doi.
Întrucât, baza de date satisface regulile pentru a fi în formă normală unu și doi, și pentru
că toate câmpurile non -primare depind numai de câmpuri primare , se demonstrează că baza de
date a aplicației Bike App se află în formă normală trei.
Datorită demonstrării că baza de date se află în formă normală trei , se demonstrează și
faptul că baza de date este proiectată corect si se poate folosi pentru a stoca informațiile
înregistrate de aplicație.

Baza de date a aplicației BikeApp

Baza de date a aplicației BikeApp a fost creată cu ajutorul sistemului de gestiune a
bazelor de date MySQL. Pentru conectarea si trimiterea de cereri către baza de date s-au folosit
scripturi PHP , iar datele sunt primite de către di spozitivul mobil în format JSON.

MySQL

MySQL reprezintă un sistem de gestiune a bazelor de date open -source3 și este susținut
de compania Oracle. La ora actuală este cel mai popular sistem de gestiune a bazelor de date și
deobicei este în strânsă legătu ră cu limbajul de programare PHP .
Chiar dacă deobicei MySQL este folosit cu limbajul PHP, se pot crea aplicații în orice
limbaj cunoscut precum: C, C++, C#, Java.

3 gratuit, fara licența

12
Administrarea bazei de date MySQL se poate face folosind diferite aplicații precum
MySQL Ad ministrator, MySQL Query Browser, MySQL Workbench, phpMyAdmin etc. sau
prin linie de comandă.
Ultima versiune de MySQL este 5.7.18.

PHP

PHP reprezintă un limbaj de programare folosit , de cele mai multe ori pentru crearea
paginilor web dinamice si a aplicațiilor web.
În genereal , se folosește introdus în codul HTML4, însă se poate folosi și pentru crearea
aplicațiilor independente , începand cu versiunea 4.3.0. Face parte din categoria celor mai
folosite limbaje de programare w eb, permițând conexiunea client -server.
Este open -source și inițial a fost dezvoltat de Rasmus Lerdorf , dar după ce numărul de
utilizatori a crescut , a fost preluat de asociația The PHP Group.
Una din cele mai importante facilități cu care PHP -ul a impresionat este că se poate
conecta cu aproape toate bazele de date relaționale.
Ultima versiune de PHP apărută este 7.1.

JSON

JSON5 reprezintă un tip de formatare a datelor în aplicații informatice . Este un forma t
text ușor de înteles de către oameni , prin care se pot reprezenta obiecte sau alte structuri de date
și este folosit în general pentru a transmite datele prin rețea .
Formatul JSON a fost creat de Douglas Crockford și în zilele noastre se bucură de o
popu laritate foarte mare în rândul programatorilor , fiind printre cele mai folosite moduri de
formatare a datelor.

4 HyperText Markup Language
5 JavaScript Object Notation

13

Legătura între Android, PHP și MySQL

Datorită nevoii de folosire a aplicației în același timp de către mai mulți utilizatori, a
trebuit să creez un server web și apoi cu ajutorul limbajului de programare PHP și a sistemului
de gestiune a bazelor de date MySQL , să pot transmite date de la dispozitiv către baza de date
și invers , sub format JSON.
Pentru a da posibiltatea transmiterii datelor am folosit urmatoarele scripturi:
 Script pentru realiz area conexiunii la baza de date;
 Script pentru metodele CRUD6 ale ut ilizatorului;
 Script pentru metodele CRUD ale rutelor ;
 Script pentru metodele CRUD ale coordonatelor .
În continuare voi prezenta scripturile enumerate anterior.
1. Script pentru realizarea conexiunii la baza de date.

6 Create Read Update Delete
Figura 2 .7 Exemplu de formatare JSON

//Defining Constants
define('HOST','localhost');
define('USER','id652270_victor');
define('PASS','victor');
define('DB','id652270_bikeapp');
//Connecting to Database
$con = mysqli_connect(HOST,USER,PASS,DB) or die('Unable
to Connect');

14
În cadrul acestui script , cu ajutorul cuvântului cheie define am definit toate datele
folosite la conectarea cu baza de date a aplicației și cu ajutorul funcției mysqli_connect() se
deschide o nouă conexiune la serverul MySQL. În cazul în care nu se poate deschide conexiunea
la server, se apelează funcția die(message) care afișează mesajul primit ca parametru. Variabila
$con va reține conexiunea la baza de date.

2. Script pentru metodele CRUD ale utilizatorului

Prin utilizarea acestui script se face adăugarea unui utilizator în baza de date. Cu ajutorul
instrucțiunii if($_SERVER[ ”REQUEST METHOD”]==’POST’ ) se verifică dacă scriptul
primește un vector de obiecte cheie -valoare, și ulterior se asignează fiecare variabilă cu o
valoarea asociată acelei chei , se execută fraza SQL și se adaugă user -ul în baza de date. if($_SERVER['REQUEST_METHOD']=='POST'){
//Getting values
$firstName = $_POST['firstName'];
$lastName = $_POST['lastName'];
$eMail = $_POST['eMail'];
$adress = $_POST['adress'];
$birthDate = $_POST['birthDate'];
$userName = $_POST['userName'];
$password = $_POST['password'];

//Creating an sql query
$sql = "INSERT INTO user
(firstName,lastName,eMail,adress,birthDate,userName,password) VALUES
('$firstName','$lastName','$eMail','$adress','$birthDate','$userName','$password')";

//Importing our db connection script
require_once('dbConnect.php');

//Executing query to database
if(mysqli_query($con,$sql)){
echo 'User Added Successfully';
}else{
echo 'Could Not Add User';
}

//Closing the database s$sql = "INSERT INTO user
(firstName,lastName ,eMail,adress,birthDate,userName,passw
ord) VALUES
('$firstName','$lastName','$eMail','$adress','$birthDate'
,'$userName','$password')";
}

15
Se procedează in mod similar pentru citirea din baza de date a unui utilizator, numai că ,
în acest caz , nu o să mai folosim variabila globală $_POST . În cazul în care se face o extrager e
din baza de date , este recomandabil să folosim variabila globală $_GE T.

if(isset($_GET['userName'])){ $name = $_GET['userName'];
}
//Importing database
require_once('dbConnect.php');
//Creating sql query with where clause to get an specific
employee
$sql = "SELECT * FROM user WHERE userName='$name'";
//getting resu lt
$r = mysqli_query($con,$sql);
//pushing result to an array
$result = array();
$row = mysqli_fetch_array($r);
array_push($result,array(
"idUser"=>$row['idUser'],
"firstName"=>$row['firstName'],
"lastName"=>$row['lastName'],
"eMail"=>$row['eMai l'],
"adress"=>$row['adress'],
"birthDate"=>$row['birthDate'],
"userName"=>$row['userName'],
"password"=>$row['password']
));

//displaying in json format
echo json_encode(array('result'=>$result));

mysqli_close($con);

16
Observăm din cod faptul că folosim următoarele metode și variabile specifice limbajului PHP:
 isset($_GET) care returnează adevărat dacă variabila $_GET este diferită de
null și fals dacă este null;
 require_once() include și evaluează un fișier dat ca parametru, în acest caz
scriptul cu ajutorul căruia deschidem conexiunea la baza de date;
 mysqli_query() realizează o interogare la baza de date;
 mysqli_fetch_array() reține intr -un vector datele primite de la baza de date;
 array_push() tratează vectorul c a o stivă și adaugă e lemente la sfârșitul
vectorului;
 json_encode() returnează un string care reprezintă un format JSON pentru o
valoare dată și în caz de eroare returnează fals;
 mysqli_close() realizează inchiderea conex iunii la baza de date.

Operațiile de actualizare si ștergere se realizeaza similar cu cele de adăugare și citire ,
avănd diferite in principal doar frazele SQL.

3. Script p entru metodele CRUD ale traseelor
Acest script ajută la adăugarea, citirea, actualizarea și ștergerea unui traseu
la cererea unui utilizator. Se realizează analog ca în cazul utilizatorilor având diferit doar
numărul de parametrii primiți de către script.

4. Script pentru metodele CRUD ale coordonatelor
Acest script pune la dispoziție utilizatorului operațiile de adăugare,
ștergere, citire a unei coordonate. După cum se poate observa lipsește operația de actualizare ,
datorită nefolosirii ei în aplicația BikeApp.
Operațiile sunt scrise în mod similar cu cele prezentate anterior.

17
3 Android

Android reprezintă un sistem de o perar e pentru telefoanele mobile
moderne și este bazat pe nucleul Linux 2.6. [5]
La început, mai exact în anul 2005 , Android care pe acea vreme era o firmă care dezvolta
aplicații pentru telefoane mobile , a fost cumpărată de către compania americană Google.
La data de 5 noiembrie 2007 a fost făcut public anunțul creării unei alianțe cu numele
Open Handset Alliance, având ca membrii companii cunoscute la acel moment precum: HTC,
Intel, Motorola etc. având c a scop dezvoltarea dispozitivelor mobile. Până la acest moment
sistemul de operare a cunoscut mai multe versiuni, ultima versiune la momentul actual fiind
Android 7.0 Nougat.
Primu l telefon cu sistem de operare A ndroid a apărut în anul 2008 și a fost numit Google
1.
Statisticile arată că 1 din 5 persoane folosesc un dispozitiv android , și în prezent peste
1.4 miliarde de persoane folosesc un astfel de dispozitiv.

Platforma hardware Android

O caracteristică importantă a platformei A ndroid este faptul ca suportă o gamă largă de
componente hardware, acest lucru fiind posibil datorită nucleului Linux care a evoluat de –
alungul timpului. Această caracteristică este benefică producătorilor deoarece pot alege
componentele dorite pentru dispozitivul pe care vor sa îl dezvolte.
Sistemul de operare A ndroid a fost dezvoltat pentru a suporta un număr mare de
dispozitive și producători, printre care unele sunt depășite înainte de a se afla de ele, însă câteva
componente sunt foarte importante și este necesar să fie pr ezentate in continuare , deoarece ele
reprezintă nucleul unui dispozitiv android .
Cele mai importante componente hardware a unui dispozitiv android sunt:
 Procesorul (CPU) ;
 Memoria ;
 Sistem de poziționare globală ;
 Rețele făra fir ;
 Card SD ;
 Ecran ;

18
 Camera de fotografiat ;
 Bateria ;
 Senzori de mișcare.

Procesorul

Procesorul joacă un rol important in funcționarea dispozitivelor mobile și nu avea cum
să lipsească de pe dispozitivele Android. El se ocupă în principal cu partea de rulare a sistemului
de operar e și a codului aplicațiilor, însă tot de el depinde controlul celorlalte funcționalități
precum: afișare, stocare, rețeaua etc.
Tipurile de procesoare adăugate în mare parte pe dispozitivele android începând cu
primele modele au fost procesoarele ARM, ace st tip de procesoare aveau destulă putere pentru
dispozitivele android și foloseau puțină energie, acest aspect fiind foarte bun pentru a
îmbunătăți durata de viață a bateriei. Cu toate că aceste tipuri de procesoare erau bune,
dezvoltatorii din domeniul d ispozitivelor android au ales să folosească și alte procesoare, spre
exemplu firma Intel a propus tipul de procesor Atom. [6]

Memoria

Datorită faptului că dispozitivele android se aseamană în mare parte cu computerele,
prezintă necesitate de memorie.
Două dintre cele mai importante tipuri de memorie prezente pe dispozitive le android
sunt:
 Memoria volatilă RAM7;
 Memoria nevolatilă NAND.
Memoria RAM este folosită pentru încărcarea și executarea funcțiilor importante a
sistemului de operare dar și pentru aplicații si alte date. Este o memorie de tip volatilă, ceea ce
înseamnă că nu păstrează datele la stingerea dispozitivului sau la rămânerea fara energie.
Memoria NAND este folosită pentru a păstra sistemul de operare și datele utilizatorului.
Este o memorie de tip nevolatilă care dă posibilitatea utilizatorilor să păstreze datele si după
stingerea dispozitivului.

7 Memorie cu acces aleator

19
Datorită spațiului restrâns, plasarea componentelor hardware în interiorul
dispozitivului, de c ele mai multe ori este dificilă, de aceea de cele mai multe ori memoria RAM
și memoria NAND sunt asamblate intr -o componentă numită MCP8.

Sistem de poziționare globală

Una dintre cele mai importante descoperiri pentru dispozitivele mobile a fost integrarea
poziționării globale. Această îmbunătațire are rolul de a identifica telefonul prin satelit și este
folosită pentru mai multe scopuri , spre exemplu: aplicații de navi garea, aplicații de urmarire
etc.
Sistemul de poziționare globală este folosit și în aplicația BikeApp, cu ajutorul acestuia
traseele sunt înregistrate.

Rețele fără fir

Introducerea utilizării rețelelor fără fir a fost un factor important în dezvoltarea continuă
a aplicațiilor.

8 Multichip package
Figura 3.1 Arhitectura MCP

20
Cele mai importante rețele fara fir sunt:
 Wi-Fi
 Bluetooth
Tehnologia Wi -Fi permite conexiunea la internet cu o viteză mai mare decât conexiunea
mobilă de internet, aceasta fiind foarte utilă p entru descărcarea de aplicații, navigarea pe
internet etc.
Tehnologia Bluetooth este deasemenea foarte importantă la conectarea dispozitivului
cu alte dispozitive fără fir cum ar fi: căști, imprimante etc. Această tehnologie este utilă si la
împărtășirea d atelor cu alte dispozitive.

Card SD

Datorită memoriei limitate, majoritatea telefoanelor mobile au fost construite cu
opțiunea de a adăuga memorie suplimentară cu ajutorul unui astfel de card digital.
Cardul SD funcționează similar cu memoria NAND, adi ca este tot memorie nevolatilă
în care sunt păstrate informațiile și după inchiderea telefonului sau după extragerea cardului.
Acest dispozitiv poate fi folosit și ca dispozitiv de transmitere a datelor.

Ecran ul

Ecranul pe dispozitivele android este de asemenea o component ă importantă. El
reprezinta o parte importantă în utilizarea telefonului prin afișarea informațiilor și răspunsul la
atingeri.
În ultimii ani ecranele au suferit o dezvoltare continuă, pornind de la ecrane mici și cu
un timp de reacție lent și ajungânduse la ecrane de dimensiuni mari, cu un timp de reacție foarte
rapid și o sensibilitate la atingeri foarte bună.
Ecranele de tip touch -screen9 sunt formate din două părți, prima parte fiind afișajul,
utilizânduse cristale lichide și a doua parte este responsabilă cu detectarea atingerilor
utilizatorului.
În dezvoltarea ecranelor se pune accent pe următoarele îmbunătățiri: rezoluție,
coloristică , îmbunătățirea sensibilității la atingere, reduc erea consumului de energie etc.

9 Ecran tactil

21

Camera de fotografiat

Inițial pe dispozitivele mobile a fost adăugată o cameră situată în partea opusă a
ecranului, pentru a permite utilizatorului să fotografieze. Camerel e de fotografiat puse la
început pe dispozitivele android, realizau fotografii la o rezoluție foarte slabă, insă odată cu
trecerea timpului ele au fost perfecționate ajungând să fotografieze și să filmeze la o rezoluție
foarte mare și cu o claritate foarte buna, depășind multe aparate de fotografiat.
În ultimii ani de fabricație, dispozitivele au fost îmbunătățite, trecând de la o singură
camera de fotografiat la două camere de fotogr afiat, una frontală si cea de pe spatele telefonului,
producătorii motivâ nd că această îmbunătățire este benefică la realizarea de apeluri video.
Un exemplu important de mentionat pentru utilizarea camerei, înafară de fotografiere
este citirea codurilor QR, funcție care ajută la trimiterea către anumite site -uri doar scanând
aceste coduri.

Bateria

O preocupare foarte importantă a dezvoltatorilor de dispozitive android a reprezentat -o
mereu durata de viață a bateriei.
Odată cu aducerea îmbunătățirilor pe partea hardware s -a constatat și o nevoie de
consum mai mare a energiei datorită funcționalității lor, de aceea la ora actuală toți producătorii
de telefoane pun o importanță deosebită pe baterie.
Mulți dintre utilizatorii actuali de telefoane inteligente își încarcă bateria dispozitivului
în fiecare zi sau chiar de mai multe ori pe zi, de aceea un aspect important în cumpărarea unui
telefon e ste durata de viață a bateriei.

Senzori de mișcare

Multe dispozitive mobile au încorporate senzori de mișcare. Senzorii de mișcare
detectează rotirea ecranului și scuturarea lui, a ceste mișcări fiind frecvent folosite în dezvoltarea
jocurilor și schimbarea ecranului din modul portret în modul landscape și invers.

22

Platforma software Android
Sistemul de operare Android este unul dintre cele mai folosite sisteme de operare la
acest m oment. Sistemul de operare Android este bazat pe nucleul Linux kernel 2.6 și este
dezvoltat de compania Google , în general , pentru tablete și telefoane mobile. Din momentul în
care Android a devenit open -source a suferit o creștere rapidă în topul celor ma i utilizate sisteme
de operare și datorită acestui lucru a devenit favorit pentru mai mulți consumatori și
dezvoltatori. Utilizatorii Android au posibilitatea de a descărca foarte multe aplicații din
magazinul Google Play.
Pentru a ajuta dezvoltatorii la producerea softurilor de calitate, Android pune la
dispoziție pachetul Android SDK10.
Părțile componente ale Android SDK:
 Debugger;
 Biblioteci ;
 Un emulator de telefon mobil;
 Documentație;
 Tutoriale.
Android SDK se bazează in principal pe limbajul de programare Java, însă suportă si
limbajul C++ .

Arhitectura sistemului de operare Android

Sistemul de operare Android funcționează precum o stivă de componente software [7].
Principalele componente ale arhitecturii sistemului de operare Android sunt:
 Linux kernel;
 Biblioteci native;
 Android Runtime;
 Cadrul pentru aplicații ;
 Aplicații.

10 Software Development Kit

23

Linux Kernel
Este situat în partea de jos a stivei de softuri. Sistemul de operare Android este construit
pe acest nivel cu multe schimbări aduse de Goog le. La fel ca toate sistemele de operare, acesta
produce următoarele funcționalități:
 Administrarea proceselor;
 Administrarea memoriei;
 Administrarea dispozitivelor (cameră, ecran, tastatură etc.)
Sistemul de operare Android interacționează cu partea hardware a dispozitivului cu
ajutorul acestui nivel al stivei.
Acest nivel al stivei conține multe drivere de dispozitive hardware.
Linux K ernel este responsabil cu: adm inistrarea, memoria virtuală, rețeaua, driverele și
administrarea energiei.

Figura 3 .2 Arhitectura sistemului de operare Android

24
Biblioteci native
Deasupra nivelului de Linux K ernel în stiva de softuri se află nivelul bibliotecilor native
Android. Aces nivel permite dispozitivului să gestioneze diferite tipuri de date. Toate aceste
biblioteci sunt scrise în limabjele de programare C și C++ și sunt apelate cu ajutorul intefeței
Java.
Cele mai importante bibliote ci native sunt:
 Managerul de suprafață;
 SQLite;
 WebKit;
 Media framework;
 Free Type ;
 LibC.

Managerul de suprafață este folosit pentru a administra ecranul dispozitivului și pentru
a compune ferestrele din ecranul dispozitivului.
SQLite este folosit pentru a stoca datele pe dispozitivul android.
WebKit stă la baza navigatorului și se ocupă cu afisarea conținutului HTML.
Media framework este folosit în redarea și inregistrarea conținutului audio, video și foto.
Free Type pentru interpretare de fonturi si pentru redarea de conținut grafic 2D sau 3D
pe ecran.
LibC conține librarii de sistem scrise în limbajul C.

Android Runtime
Android Runtime este alcătuit din mașina virtuală Dalvik și biblioteci de nucleu J ava.
Este plasat pe același nivel cu bibliotecile native.
Mașina virtuală Dalvik este un tip al mașinii virtuale Java folosită pentru a rula aplicații
pe dispozitivele android. Ea permite unei aplicații Android să ruleze în propriul proces, cu
propria instanță a m așinii virtuale Dalvik. Mașina virtuală Dalvik poate crea mai multe instanțe
în același timp, prin această metodă asigurându -se: securitate, izolare, administrare de memorie
și suport pentru fire de execuție. Spre deosebire de mașina virtuală Java care e b azată pe un
singur proces, mașina virtuală Dalvik e bazat pe un singur registru. Mașina virtuală Dalvik
execută fisiere cu extensia .dex, care su nt obținute din fișierul .class prin instrumentul dx care
este inclus în Android SDK.

25
Mașina virtuala Dalvik e ste optimizată pentru o putere de procesare mică și pentru
memorie redusă. Ea a fost dezvoltată de Dan Bornstein de la compania Google.

Cadrul pentru aplicații
Nivelul cadrului de aplicații, din stiva de softuri a arhitecturii sistemului de operare pune
la dispoziție o multitudine de servicii și API -uri pent ru aplicații în formă de clase J ava.
Dezvoltatorii de aplicații Android, au dreptul să utilizeze aceste servicii în aplicațiile lor.
Acestea sunt blocuri funcționale cu care dezvoltatorul interacționează direct.
Cele mai importante blocuri funcționale sunt:
 Furnizori de conținut – este folosit pentru schimbul de date între aplicații și în
gestiunea modului de accesare a dat elor d in alte aplicații;
 Managerul de telefonie – gestionează toate funcționalităț ile ce țin de apelurile
vocale;
 Managerul locației – este folosit pentru gestionarea locației, utilizând semnal
GPS;
 Managerul de resurse – gestionează resursele folosite în aplic ație;
 Managerul de activități – gestionează ciclul de viață a unei aplicații.

Figur a 3.3 Transformare fișier java î n fisier dex.

26

Aplicații
Nivelul de aplicații se află in vârful stivei de programe al arhitecturii sistemului de
operare Android.
Câteva aplicații care vin preinstalate pe dispozitivele android sunt: aplicația pentru
mesaje SMS, aplicația pentru apeluri, navigator web și administratorul de contacte.
Dezvoltatorul poate realiza propria aplicație și poate înlocui fie care dintre aplicațiile
existente.

Componentele unei aplicații Android

În acest sucapitol se vor preze nta componentele, ce duc la formarea unei aplicații
Android.
Componentele unei aplicații Android sunt blocurile funcționale de creare a unei
aplicații, fiecare componentă reprezentând un punct de intrare , prin ajutorul căruia sistemul sau
un utilizator poate introduce a aplicați a. În general unele componente depind de altele.

Figur a 3.4 Ciclul de viață al unei activități.

27
Există patru tipuri diferite de componente ale aplicației:
 Activități;
 Servicii;
 Consumatori de intenții difuzate (Broadcast receivers) ;
 Furnizori de conținut.

Activități
Activitatea reprezintă punctul de in trare pentru intereacțiunea cu utilizatorul. Ea
reprezintă un singur ecran cu o interfața pentru utilizator. Spre exemplu aplicația BikeApp are
o activitate care afișează rutele, o activitate pentru inregistrarea unui utilizator etc. Deși
activitățile corelează în aplicație, fiecare acțiune a utilizatorului este reprezentată de o activitate.
În genera l, o aplicație android are mai mult de o activitate, însă î n fiecare aplicație există
o activitate principală , restul fiind activități de tip copii.
Activitățile funcționează ca o stivă, atunci când o activitate este deschisă, cealaltă , din
care a fos t dec lanșată activitatea secundară este pusă in fundal și la deschiderea noii activități,
vechea activitate se oprește. În momentul când butonul „înapoi ” este apăsat, vechea activitate
este repornită iar activitatea curentă distrusă.

Servicii
O altă component ă importantă a unei aplicații android, o reprezintă serviciul . Nu oferă
interfață cu utilizatorul și face operațiuni de lungă durată în fundal.
Un serviciu nu se termină în momentul în care componenta aplicației care a inițializat
serviciul s -a terminat s au s-a schimbat, el functionând în fundal până în momentul în care este
oprit.
Un exemplu de aplicație care folosește servicii poate fi o aplicație de descărcare sau de
încărcare.

Consumatori de intentii difuzate
Un co nsumator de intenț ii difuzate (Broadcast Receiver) reprezintă o componentă a unei
aplicații android care ascultă evenimente sau intenții la nivel de sistem. El nu conține nici o
interfață de utilizator.
În momentul în care se înregistrează un consumator de intenții difuzate, aplicația
așteaptă criteriul specificat și răspunde.

28
Exemple de intenții difuzate de sistem:
 android.intent.action.BATTERY_LOW – indică b ateria scăzută a
dispozitivului;
 android.intent.action.CALL – se folosește pentru a ef ectua apelul către cineva
anume;
 android.intent.action.DATE_ CHANGED – data a fost schimbată;
 android.net.conn.CONNECTIVITY_CHANGE – indică faptul că rețeaua
mobilă sau conexiunea fără fir a fost schimbată.

Furnizori de conținut
Un furnizor de conținut gestionează date pentru aplicații s i permite păstrarea lor intr -o
bază de date, într -un fisier sau prin oricare metodă de persistență , pentru a avea acces din cadrul
a mai multor aplicații.
Furnizorii de conținu t se comportă ca o bază de date. P e un furnizor de conținut se pot
realiza oper ațiile de adăugare, interogare, editare și ștergere prin metodele insert(), query(),
edit(), delete().
În cele mai multe cazuri aceste date sunt stocate sub forma unei baze de date SQLite.

Fișierul Manifest

În fiecare aplicație este obligatoriu să existe un fișier AndroidManifest.xml în calea
aplicației.
Fisierul manifest conține informații legat e de aplicația care se dezvoltă, inform ații pe
care sistemul trebuie să le aibe , pentru a putea executa codul aplicației [8].
Fișierul manifest conține noduri pentru fiecare dintre componentele aplicației android
prezentate mai sus, acestea fiind: activități, servicii, consumatori de intenții difuzate și furnizări
de conținut.
Manifestul începe prin tagul <manifest> , și conține atributele xmlns:android,
android:package. Prin atributul xmlns:android se specifiă regulile de securitate din fișier și prin
atributul android:package se specifică pachetul aplicației.
În continuare voi explica toate nodurile prezente in fișierul manifes t din BikeApp:

29
 <uses -feature> – declară o singură componentă de tip hardware sau software
utilizată de aplicație.

Aplicația BikeApp folosește OpenGL deoarece este necesar pe ntru a folosi API -ul
GoogleMaps și camera care este necesară in realizarea pozelor.
 <uses -permission> – solicită permisiunea folosirii unor fu ncționalități. La
versiunile android mai vechi decât 5.1 permisiunile sunt cerute de către aplicație
la instalare și la versiunile mai noi decât 5.1 permisiunile sunt cerute la utilizare.

Aplicația BikeApp solicită permisiuni pentru urmatoarele funcționalități: locație,
conexiune fără fir, internet, citire și scriere pe sursă externă.
 <application> – reprezintă declarația aplicației și are ca parametri componente
a aplicației.

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

android:name="android.hardware.camera"
android:required= "false" />

<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"
/>
<uses-permission
android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permis sion.ACCESS_NETWORK_STATE" />
<uses-permission
android:name="com.google.android.providers.gsf.permission.
READ_GSERVICES" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl= "true"
android:theme="@style/AppTheme" >

30
Pentru aplicație se setează următoarele declarații: copie de rezervă, icoana aplicației,
numele, tema.
 <activity> – declară o activitate ce reprezintă o interfața grafică cu utilizatorul.
Toate activitățile trebuiesc menționate în această secțiune.

În această secțiune sunt trecute toate ferestrele din aplicația BikeApp.
 <service> – declară toate serviciile folosite în aplicație.

Singurul serviciu folosit în BikeApp este LocationService, care ajută la determinarea
poziției utilizatorului.
 <meta -data> o pereche nume -valoare pentru un element extern.

În această secțiune, în fisierul aplicației BikeApp setăm versiunea pentru s erviciile
Google -Play si cheia pentru funcționarea API -ului Google Maps.

<activity
android:name=".UI.Login"
android:label="@string/app_name" >
<intent-filter>
<action
android:name="android.intent.action.MAIN" />

<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity >
<activity
android:name=".UI.MainActivity"
android:label="@string/app_name"
android:screenOrientation= "portrait"
android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".UI.RouteOperations" />
<activity android:name=".UI.Chat" />
<activity android:name=".UI.Users" ></activity >
<activity android:name=".UI.SignUp" />

<service android:name=".Utils.LocationService " />

<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"
/>
<meta-data
android:name="com.google.android.geo.API_KEY"

android:value="AIzaSyCFgvLGDfzV9MxYDTsyTLdhSw4Rb8YZ4hU" />

31

4 Instrumente externe

Google Maps v2 și Firebase sunt două API11-uri folosite în dezvoltarea aplicației
BikeApp și în continuare le voi prezenta pe fiecare pe rând.

Google Maps v2

Google Maps v2 este disponibil pe platformele Android, iOS, Web [9].
API-ul este distribuit ca parte a Google Play SDK, care poate fi descărcat în Android
Studio, din secțiunea Android SDK Manager.
Google Maps API V2 include com.google.android.gms.maps și clasele
com.google.android.gms.maps.model. Clasele din acest pachet permite descărcarea, afișarea și
salvarea bucaților din hartă și o mulțime variată de opțiuni de afișare si control. [10]
Clasa cheie în pachetul de la Google este com.google.android.gms.maps.GoogleMap.
Această clasă ajută la obținerea hărții de la serviciile Google Maps.
Atunci când harta se încarcă , permite folosirea gest urilor pentru a putea realiza
operațiile de apropiere, depărtare, cererea de bucăți noi , rotire etc.
Pentru a putea folosi API -ul de la Google trebuie obținută cheia intrând pe site -ul oficial
al API -ului și trebuie făcut cont.
Caracteristici pentru dezvoltatori.
Hărți
Cu ajutorul API -ului Google Maps putem selecta modul de afișare a hărții din
următoarele 4 opțiuni:
 Hartă în modul normal;
 Hartă în modul teren;
 Hartă în modul satelit;
 Hartă in modul hibrid.
Harta în modul normal, reprezintă tipul clasic de hartă cu numele străzilor.

11 Application program interface.

32

Harta în modul teren, reprezintă harta clasică cu date de elevație, unde formele de relief
sunt diferențiate, reprezintă o abordare 3D.

Figura 4.1 Harta în mod normal

Figura 4 .2 Harta în modul teren

33
Harta în modul satelit, reprezintă harta formată din imagini din satelit, cu o rezoluție
foarte bună, singurul minus fiind lipsa numelor străzilor.

Harta în modul hibrid, reprezintă o combinație între harta în modul normal și în modul
satelit, de aici si numele de hibrid.

Figura 4 .3 Harta în modul satelit.

Figura 4.4 Harta în modul hibrid

34
Personalizarea hărții
Utilizator ul API -ului de la Google Maps îș i poate personaliza harta prin adăugarea de
semne pe hartă pentru a adăuga puncte de interes. Semnele se pot personaliza , permițând
modificarea structurii si culorii lor.
O altă funcționalitate foarte importantă este desenarea poliliniilor si poligoanelor pentru
a determina trasee sau zone.

Controlul vizual
Utilizatorul poate controla partea vizuală a hărții cu ajutorul urmatoarelor funcții:
 rotire;
 apropiere;
 înclinare;
 mutare.
Datorită acestor funcții utilizatorul primeș te acces complet asupra hărții.

Figura 4 .5 Semn pe hartă

35

Funcționalitate în BikeApp

În dezvoltarea aplicației BikeApp, am folosit API -ul Google Maps V2 și s -a dovedit
foarte utilă.
Cu ajutorul acestui API , BikeApp oferă următoarele funcționalități:
 Schimba rea modului de afișare a hărții;
 Desenarea traseelor.

Exemple de aplicații care folosesc GoogleMaps V2

În acest subcapitol voi prezenta două aplicații populare, care utilizează API -ul Google
Maps.

Uber
Uber este o companie americană care a fost dezvoltată cu scopul ca utiliz atorii să poată
comanda din aplicație un taxiu, cu ajutorul semnalului GPS și rețelei de internet.
Compania lucrează doar cu șoferi individuali și nu acceptă colaborări cu alte firme de
taxi.

Hărți și navigare Google
Este o aplicație de navigare dezvolta tă de compania americană Google. C u ajutorul ei
putem afla locații exacte din 220 de țări, putem seta și urmări trasee în funcție de preferințele
noastre.
Aplicația permite navigarea pentru bicicliști, pietoni și conducători auto.

Firebase

Firebase este o platformă de dezvoltare a aplicațiilor web și mobil. Compania a fost
înființată în anul 2011, de către Andrew Lee și James Tamplin având sediul în Sa n Francisco.
Inițial Firebase a pornit ca fiind un API care permitea utilizatorilor să sto cheze date,
care puteau fi sincronizate în timp real. [11]

36

În anul 2014 compania Google a cumpărat platforma Firebase și a adus un număr mare
de servicii precum:
 mesagerie în cloud ;
 autorizare ;
 bază de date în timp real ;
 spațiu de stocare ;
 găzduire web;
 raportare de incidente;
 testare .

Mesagerie în cloud
Firebase Cloud Messaging(Mesagerie în cloud) este o platformă pentru trimiterea de
notificări pentru dispozitivele android.
În prezent FCM12 poate fi folosit fără plată suplimentară.

Autorizare
Autorizarea reprezintă un sistem de autentificare pentru utilizatorii care folosesc
aplicația. Această platform permite și autentificarea prin rețelele sociale: Facebook, Twitter și
Google.
În plus această platformă oferă un sistem de gestionare a utilizatorior , pe care
dezvoltatorii îl pot folosi la conectarea utilizatorilor în aplicația lor.

12 Firebase Cloud Messaging mAuth.createUserWithEmailAndPassword(eMail_, password_)
.addOnCompleteListener( this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete( @NonNull Task<AuthResult> task) {
if (task.isSuccessful( )) {
Log.d("CU", "createUserWithEmail:onComplete:" +
task.isSuccessful());
AddUser ae = new AddUser();
ae.execute();
} else if (!task.isSuccessful()) {
Toast.makeText (SignUp. this,
task.getException().getMessage(),
Toast.LENGTH_SHORT ).show();
}

}
});

37

Pentru a adăuga un utilizator în sistemul de gestionare din platforma Firebase, se
folosește interfața statica FirebaseAuth.getInstance() , iar din această interfață se folosește
metoda createUserWithEmailAndPassword(string email, string password), care primește doi
parametri , aceștia fiind emailul utilizatorului și parola.
Metoda poate returna tipuri de erori în functie de parametri primiți și anume: email
invalid, parola prea scurtă, a dresa de email este înregistrată deja etc.

Bază de date în timp real
Firebase oferă un serviciul prin care dezvoltatorii pot stoca pe site -ul API -ului o bază
de date , care permite sincronizare în rândul utilizatorilor.
Baza de date este stocată în cloud sub forma de stringuri JSON, acest lucru fiind benefic
în sincronizarea mai multor platforme de de zvoltare cum ar fi iOS, Android și JavaScript pentru
a accesa baza de date de pe mai multe dispozitive.
În aplicația BikeApp, baza de date prezentă pe site -ul Firebase se ocupă cu stocarea
mesajelor transmise între utilizatori.

Utilizatorii sunt înregistrați în nodul users, iar conversațiile sunt salvate sub formă de
noduri nume utilizator1_ nume utilizator2.

Figura 4 .6 Baza de date din Firebase a aplicației BikeApp

38

Spațiu de stocare
Spațiul de stocare Firebase permite dezvoltatorului să includă opțiunea de salvare
online , pentru a fi reținute pozele, video -urile și fișierelor proprii într -un mod sigur.
În aplicația BikeApp se folosește pentru a stoca imaginile realizate la un anumit moment
pe parcursul traseelor.

Găzduire web
Firebase permite si găzduirea site -urilor web formate din HTML, CSS și JavaScript,
acest beneficiul venind în urma cererilor efectuate de către clienți.

Raportare de incidente
Un serviciu foarte important și benefic adăugat de platforma Firebase este acela de
raportare a incidentelor.
Raportarea incidentelor se salvează precum o stivă, iar erorile sunt transmise
utilizatorului pe email -ul dezvoltatorul ui sau le poate accesa din consola proprie. În opinia mea
este unul dintre cele mai importante și benefice sisteme integrate în platforma Firebase.

Figura 4 .7 Exemplu de email primit în urma unei erori

39

Testare
Un alt servicu oferit de platforma Firebase este reprezentat de posibilitatea de testare
automată a aplicației. Platforma Firebase oferă posibilitatea încărcării fișierului .apk, și testarea
lui pe o gamă variată de dispozitive.
Dezvoltatorul poate defini singur testele pe ca re dorește să le efectueze pe aplicație sau
poate lăsa platforma să caute erori a leator.

Exemple de aplicații care utilizează Firebase
Conform cu site -ul13 oficial se folosesc de această platformă următoarele aplicații
cunoscute:
 Shazam – aplicație pentru înregistrare si recunoastere conținut audio.
 Trivago – aplicație pentru căutare de hoteluri și pensiuni.
 Duolingo – aplicație care ajută la învățarea de limbi străine.

13 https://firebase.google.com/

40

5 Prezentarea aplicației

Pentru dezvoltarea aplicației s -a folosit mediul de dezvoltare Android Studio 2.3.2,
utilizând limbajul de programare Java.

Cerințe non -funcționale

Pentru ca aplicația BikeApp să funcționeze sunt necesare următoarele componente:
 dispozitiv android;
 versiunea sistemului de operare să fie mai nouă decât Android 4.4 Kitkat;
 conexiune la internet – pentru realizarea autentificării în aplicație ;

Clase
În acest subcapitol sunt prezentate clasele realizate, pentru a face posibilă
funcționalitatea aplicației.

Pachetul Engine
În acest pachet se află clasele folosite de partea logică al aplicației și nu au nici o legătura
cu interfața grafică.

Coordinate
Clasa Coordinate conține următoarele atribute:
 idCoordinate – reprezintă id -ul coordonatei din baza de date și este de tip Integer;
 latitude – reprezintă latitudinea coordonatei și este de tip Double;
 longitude – reprezintă longitudinea coordonatei și este de tip Double;
 idRoute – reprezintă id -ul traseului din care face parte co ordonata și este de tip
Integer.
Clasa conține pe lângă atributel e enumerate și un constructor cu parametri i, getteri
și setteri.

41

Route
Clasa Route conține următoarele atribute:
 idRoute – reprezintă id -ul traseului din baza de date și este de tip Integer;
 nameRoute – reprezintă numele traseului și este de tip String;
 _public – este setat cu 1 dacă traseul este public și cu 0 dacă traseul este privat
și este de tip Integer.
Clasa conține , pe lângă atributele enumerate anterior , doi constru ctori ( unul fără
parametrii și unul cu parametrii) getteri și setteri.

User
Clasa User conține următoarele atribute:
 idUser – reprezintă id -ul utilizatorului din baza de date și este de tip Integer;
 firstName – reprezintă prenumele utilizatorului și este de tip String;
 lastName – reprezintă numele utilizatorului și este de tip String;
 eMail – reprezintă numele utilizatorului și este de tip String;
 adress – reprezintă adresa utilizatorului și este de tip String;
 birthDate – reprezintă data de naștere a utilizatorului și este de tip String;
 userName – reprezintă numele de utiliza tor și este de tip String;
 password – reprezintă parola utili zatorului și este de tip String.
Clasa conține pe lângă atributele enumerate anterior doi constructori ( unul cu
parametrii și unul fără parametrii ), getteri și setteri.

UserDetails
Clasa UserDetails este folosită la legătura formată de conversația dintre doi utilizatori
și conține următoarele atribute statice:
 username – reprezintă numele utilizatorului care pornește conversația și este de
tip String;
 password – reprezintă parola utilizatorului care pornește co nversația și este de
tip String;
 chatWith – reprezintă numele de utilizator al celui cu care ponește conversația.

42

Pachetul UI

În acest pachet avem clasele care se ocupă cu interfața grafică, cele numite în Android
activit ăți.

Login
În această clasă se află partea de autentificare a aplicației și are următoarele componente
grafice:
 username – reprezintă locul unde utilizatorul adaugă numele de utilizator și este
de tip text editabil;
 password – reprezintă locul unde util izatorul adaugă parola necesară
autentificării și este de tip text editabil;
 sign_in_button – reprezintă butonul pe care utilizatorul apasă pentru a se
autentifica în aplicație și este de tip buton.
În cadrul acestei clase se realizează conexiunea bazei de date cu dispozitivul și se
verifica existența utilizatorului.

SignUp
În această clasă se află partea de înregistrare în aplicație și are următoarele componente
grafice:
 firstName – reprezintă locul unde utilizatorul își adaugă prenumele și este de tip
text editabil;
 lastName – reprezintă locul unde utilizatorul își adaugă numele și este de tip
text editabil;
 eMail – reprezintă locul unde utilizatorul îș i adaugă emailul și este de tip text
editabil;
 adress – reprezintă locul unde utilizatorul îș i adaugă adresa și este de tip text
editabil;
 birthDate – reprezintă locul unde utilizatorul îș i adaugă data de naștere și este
de tip text editabil;

43
 userName – reprezintă locul unde utilizatorul îș i adaugă numele de utilizator
și este de tip text editabil;
 passw ord – reprezintă locul unde utilizatorul își adaugă parola și este de tip
text editabil;
 signUp – reprezintă locul unde utilizatorul apasă pentru a trimite toate aceste
date către baza de date și este de tip button.
În această activitate datele despre ut ilizator sunt extrase din interfața grafică și sunt
trimise către baza de date pentru a se poate face crearea contului.

Chat
În această clasă se află partea de comunicare între utilizatori și are următoarele
componente grafice:
 sendButton – reprezintă lo cul unde utilizatorul apasă pentru a putea trimite
mesajul și este de tip ImageView;
 messageArea – reprezintă locul unde utilizatorul scrie mesajul pe care dorește
să îl trimită și este de tip text editabil.
În cadrul acestei activități se realizează transmiterea de mesaje între doi utilizatori.
MainActivity
Această clasă reprezintă fe reastra principală a aplicației. D in ea se pot accesa toate
funcționalitățile aplicației.
Conține o fereastră de tipul SupportMapFragment cu ajutorul căreia este desena tă harta
de la google.
Activitatea conține pe lângă fereastra în care este afișată harta și un meniu din care
putem selecta următoarele opțiuni:
 Redesenare hartă – reprezintă locul unde utilizatorul apasă pentru a șterge toate
traseele desenate pe hartă;
 Afișare traseu – reprezintă locul unde utilizatorul apasă pentru a afișa un traseu
din baza de date;
 Ștergere traseu – reprezintă locul unde utilizatorul apasă pentru a șt erge din baza
de date un traseu;
 Oprire înregistrare – reprezintă locul unde utilizatorul apasă pentru a opri
înregistrarea unui traseu;

44
 Pornire înregistrare – reprezintă locul unde utilizatorul apas ă pentru a înregistra
un traseu;
 Încarcă traseul – reprezintă locul unde utilizatorul apasă pentru a în cărca un
traseu în baza de date;
 Fotografiază – reprezintă locul unde utilizatoru l apasă pentru a realiza o poză;
 Mesagerie – reprezintă locul unde utilizatorul apasă pentru a trimite un mesaj.
Această activitate reprezintă nucleul principal al a plicației , din e a putându -se apela
celelalte activități.

Route operations
Această clasă reprezintă fereastra generică, în care sunt executate operațiile cu trasee.
Operațiile cu trasee pe care le efectuăm în cadrul acestei activități sunt: vizualizare,
ștergere, încărcare.
Componentele grafice ale acestei activități sunt:
 RoutesSpinner – reprezintă locul unde utilizatorul are posibilitatea de a alege
un traseu.
 btnShow – reprezintă locul unde apasă pentru a executa o anumită operație
prezentată mai sus.

Pachetul Utils

În acest pachet se află clasele utile pentru realizarea aplicației BikeApp, și sunt utilizate
pe tot parcursul rulării aplicației.

AddCoordinateThread
În cadrul acestei clase se pornește un fir de execuție separat pentru încărcarea
coordonatelor, în spatele procesului principal.
Un traseu poate avea un număr mare de coordonate, de aceea este necesar să fie pornit
un fir de execuție, pentru a nu bloca firul de execuție principal.

45
Config
În cadrul acestei clase sunt definite ca și atribute statice toate linkurile către scripturile
de php aflate pe serverul de hosting cât și numele parametrilor primiți în scripturile de php.

CoordinateDB
În cadrul acestei clase sunt definite metodele de inserare, citire, actualizare și ștergere a
unei coordonate.
GraphicsUtil s
Cu ajutorul acestei clase se desenează un traseu pe hartă, metoda statică
RenderCoordinates() primește ca parametri o listă de coordonate, pe care le afișează pe rând pe
hartă.
LocationService
În această clasă este defini t serviciul, cu ajutorul căruia telefonul înregistrează locația
de la satelit sau de la rețelele mobile.
Atriubutele acestei clase sunt:
 locationManager – este de tipul LocationManager;
 listener – este de tipul MyLocationListener;
 previousBestLocation – este de tipul Location.
Datorită acestei clase, telefonul poate înregistra locația curentă pe fundal.

LoggedUser
Această clasă reprezintă un șablon singleton, datorită acestei clase se poate salva
utilizatorul de la autentificare, fiind accesibil pe tot parcursul execuției aplicații.

Request Handler
În această clasă sunt definite metode, pentru a trimite cereri de tip POST și GET către
serverul de baze de date prin scrip turile php.

RouteDB
În această clasă se află operațiile de inserare, ștergere, citire și actualizare pentru un
traseu.

46

Prezentarea funcționalității aplicației

În continuare este prezentată funcționalitatea aplicației BikeApp.

Înregistrarea utilizatorului

Utilizatorul se înregistrează în aplicație completând un formular cu datele personale.

În momentul în care utilizatorul aplicației apasă butonul ÎNREGISTRARE , datele sunt
trimise către baza de date și astfel utilizatorul este înre gistrat în baza de date.

Figura 5.1 Formular de înregistrare a utilizatorului

47

Autentificarea utilizatorului
Utilizatorul se autentifică cu numele de utilizator si parola, iar datele introduse sunt
verificate în baza de date. Î n caz de succes utilizatorul este autentificat în aplicație iar în caz
contrar primește un mesaj de eroare.
La primirea mesajului de eroare utilizatorul are posibi litatea de a merge direct la pagina
de înregistrare .
În cazul în care la momentul autentificării nu există conexiune la internet va apărea u n
mesaj de eroare în partea de jos a paginii. signUP.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
addUser();
}
});
private void addUser() {

if (!checkRegistration()) {
return;
}

final String firstName_ = firstName .getText().toString().trim();
final String lastName_ = lastName .getText().toString().trim();
final String eMail_ = eMail.getText().toString().trim();
final String adress_ = adress.getText(). toString().trim();
final String birthdate_ = birthDate .getText().toString().trim();
final String userName_ = userName .getText().toString().trim();
final String password_ = password .getText().toString().trim();
class AddUser extends AsyncTask<Void,Void,String> {…}

mAuth.createUserWithEmailAndPassword(eMail_, password_)
.addOnCompleteListener( this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete( @NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d("CU", "createUserWithEmail:onComplete:" +
task.isSuccessful());
AddUser ae = new AddUser();
ae.execute();
} else if (!task.isSuccessful()) {
Toast.makeText (SignUp. this,
task.getException().getMessage(),
Toast.LENGTH_SHORT ).show();
}

}
});

Figura 5 .2 Acțiunea executată în momentul apăsă rii pe butonul ÎNREGISTRARE.

48

Figura 5.4 Mesaj de eroare în cazul autentifică rii eș uate

Figura 5.3 Pagina de autentificare în aplicație .

49

final Button mUserNameSignInButton = (Button)
findViewById(R.id. sign_in_button );
mUserNameSignInButton.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View view) {

attemptLogin();

}
});
private void attemptLogin() {

// Reset errors.
mUsernameView .setError( null);
mPasswordView .setError( null);

// Store values at the time of the login attempt.
String userName = mUsernameView .getText().toString();
String password = mPasswordView .getText().toString();

boolean cancel = false;

// Check for a valid password, if the user entered one.
if (TextUtils. isEmpty(password)) {
mPasswordView .setError(getString(R.string. error_invalid_password ));
cancel = true;
}

// Check for a valid username.
if (TextUtils. isEmpty(userName)) {
mUsernameView .setError(getString(R.string. error_field_required ));
cancel = true;
}

if (!cancel) {
//hide keyboard
InputMethodManager imm = (InputMethodManager)
getSystemService( INPUT_METHOD_SERVICE );
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);

if (!Utils. isNetworkConnected (this)) {
Snackbar snackbar = Snackbar
.make(linearLayout , "No internet connection!" ,
Snackbar. LENGTH_SHORT );
View sbView = snackbar.getView();
sbView.setBackgroundColor(Color. rgb(196, 81, 44));
TextView textView = (TextView)
sbView.findViewById(android.support.design.R.id. snackbar_text );
textView.setTextColor(Color. WHITE);
snackbar.show();
} else
getUser();

}
}

Figura 5.5 Codul scris pentru acțiune a de apăsare a butonului AUTENTIFICARE .

50

Ecranul principal

Din ecranul principal al aplicației utilizatorul are posibilitatea de a efectu a toate acțiunile
posibile în aplicația BikeApp.

Redesenare hartă
Oferă posibilitatea ștergerii traseelor desenate pe hartă.

Afișare traseu
La apăsarea butonulu i de afisare a unui traseu , apare o fereastră care permite
utilizatorului să selecteze următoarele surse de trasee:
 Telefon – afișează utilizatorului traseele salvate local pe disp ozitiv;
 Server – afișează utilizatorului traseele salvate în baza de date .

Figura 5.6 Meniul principal al aplicației .

51

Figura 5.7 Fereastra în care utilizatorul selectează sursa de trasee.

Figura 5.8 Fereastra în care utilizatorul selectează traseul pentru a -l
afisa.

52

if (mode.compareToIgnoreCase( "DB") == 0) {
RDB = new RouteDB(RouteOperations. this, RouteOperations. this);
RDB.getRoutesByIdUsr(mUser.getIdUser());
btnShow.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mOperation ==null) {
Intent intent = new Intent(getApplicationContext(),
MainActivity. class);
String nameRoute = (String) RoutesSpinner .getSelectedItem();
intent.putExtra( "routeName" , nameRoute);
setResult( 1, intent);
finish();
}
else if (mode.compareToIgnoreCase( "local") == 0)
{
List<String>mList=Utils. readFromFile (this,Config. nonUploadedRoutes );
List<String> names= new ArrayList<>();

for(String name : mList)
{
String parts[];
parts = name.split( ";");
names.add(parts[ 1]);
}

adapter = new ArrayAdapter<String>(getApplicationContext(),
android.R.layout. simple_spinner_item , names);

adapter.setDropDownViewResource(android.R.layout. simple_spinner_dropdown_item );
RoutesSpinner .setAdapter( adapter);
btnShow.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mOperation ==null) {
Intent intent = new Intent(getApplicationContext(),
MainActivity. class);
String nameRoute = (String) RoutesSpinner .getSelectedItem();
intent.putExtra( "routeName" , nameRoute);
setResult( 3, intent);
finish();
}

// Următorul cod se află în ecranul principal

if (requestCode == Config. SHOWDBRECORD ) {
if (null != data) {
String nameRoute = data.getStringExtra( "routeName" );
if (nameRoute != null) {
mCurrentRoute = new Route();
mCurrentRoute .setNameRoute(nameRoute);
mRdb.getRoute(nameRoute);
mRender = true;
} else
Toast.makeText (this, "You can't show an inexistent route!" ,
Toast.LENGTH_SHORT ).show();

}
}

53

Ștergere traseu
La apăsarea butonului Ș terge re traseu se deschide o fereastră identică cu cea de la afișare
traseu , unde se selectează sursa de unde se va șterge traseul.

Figura 5.10 Fereastra de ștergere a unei rute .

if (requestCode == Config. SHOWLOCALRECORD ) {
if (data != null) {
String nameRoute = data.getStringExtra( "routeName" );
if (nameRoute != null) {
List<String> mDFromFile = Utils. readFromFile (this, nameRoute);
List<LatLng> listToBeRender =
Utils.getCoordinatesFromArrayList (mDFromFile);
if (listToBeRender.size() > 0) {
CameraUpdate center =
CameraUpdateFactory. newLatLng (listToBeRender.get( 0));
CameraUpdate zoom = CameraUpdateFactory. zoomTo(18);
mMap.moveCamera(center);
mMap.animateCamera(zoom);
mMap.addPolyline( new Utils(). drawPolyLine (listToBeRender));

Marker start_marker = mMap.addMarker( new MarkerOptions()
.position(li stToBeRender.get( 0))

.icon(BitmapDescriptorFactory. defaultMarker (BitmapDescriptorFactory. HUE_GREEN ))
.title("Start")
.snippet( "Route " + nameRoute));

Marker stop_marker = mMap.addMarker( new MarkerOptions()
.position(listToBeRender.get(listToBeRender.size() – 1))
.title("Stop")
.snippet( "Route " + nameRoute));
}
} else
Toast.makeText (this, "You can't show an inexistent route!" ,
Toast.LENGTH_SHORT ).show();

}
}

Figura 5.9 Codul care permite afișarea unui traseu din ambele surse.

54

Oprire înregistrare
La apăsarea acestui buton se oprește serviciul care înregistează traseul.
Pornire înregistrare
La apăsarea acestui buton se deschide o fereastră unde , utiliza torul setează numele
traseului ș i proprietatea ca traseul să fie public sau privat.
După completarea câmpurilor se lansează în execuție un serviciu , care realizează
localizarea în fundal.
Acest serviciu se oprește doar atunci când utilizato rul decide să oprească traseul sau în
momentul în care aplicația este distrusă în rest ea putând înregistra coordonatele și în fundal.

if (requestCode == Config. DELETEROUTE ) {
if (data != null) {
String mode = data.getStringExtra( "Mode");
if (mode.compareToIgnoreCase( "local") == 0) {
String routeName = data.getStringExtra( "routeName" );
if (routeName != null) {
int index = -1;
List<String> list = Utils. readFromFile (this,
Config.nonUploadedRoutes );
for (int i = 0; i < list.size(); i++) {
if (list.get(i).compareToIgnoreCase(routeName) == 0) {
index = i;
}
}
list.remove(index);
Utils.deleteFile (this, Config. nonUploadedRoutes );
try {
Utils.WriteToNonUploadedFile (list, this);
} catch (IOException e) {
e.printStackTrace();
}
} else
Toast.makeText (this, "You can't delete an inexistent route!" ,
Toast.LENGTH_SHORT ).show();

} else if (mode.compareToIgnoreCase( "DB") == 0) {
if (data.getStringExtra( "routeName" ) != null)
mRdb.deleteRoute(data.getStringExtra( "routeName" ));
else
Toast.makeText (this, "You can't delete an inexistent route!" ,
Toast.LENGTH_SHORT ).show();

}
}
}
Figura 5.11 Codul care permite ștergerea unui traseu.

55

Figura 5.12 Fereastra pentru începerea înregistrării
unui traseu.
//Start record route
if (mRouteUtil .nOfRoute == null) {
AlertDialog.Builder builder = new AlertDialog.Builder( this);
builder.setTitle( "Record Route" );
// Set up the input
final LinearLayout mLinLay = new LinearLayout( this);
final EditText mText = new EditText( this);
final RadioGroup rGroup = new RadioGroup( this);
final RadioButton mRbtn = new RadioButton( this);
final RadioButton nRbtn = new RadioButton( this);
mRbtn.setText( "Public" );
nRbtn.setText( "Private" );
mText.setHint( "Route name" );
// Specify the type of input expected; this, for example, sets the input as a
password, and will mask the text
mText.setInputType(InputType. TYPE_CLASS_TEXT |
InputType. TYPE_TEXT_VARIATION_NORMAL );
rGroup.addView(mRbtn, 0);
rGroup.addView(nRbtn, 1);
rGroup.check(mRbtn.getId());
mLinLay.a ddView(mText, 0);
mLinLay.addView(rGroup, 1);
builder.setView(mLinLay);
// Set up the buttons
builder.setPositiveButton( "OK", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mText.getText().toString().length() > 3) {
int _public = 0;
if (mRbtn.isChecked()) {
_public = 1;
} else _public = 0;
mRouteUtil .ctx = MainActivity. this;
mRouteUtil .nOfRoute = mText.getText().toString();
mRouteUtil .recordRoute();
mRouteUtil ._public = _public
}
});
builder.setNegativeButton( "Cancel" , new DialogInterface.OnClickListener() {
@Override
public void onClick (DialogInterface dialog , int which) {
dialog.cancel() ;
}
});

56

} else
Toast.makeText (MainActivity. this, "Name of Route must be at
least 3 characters" , Toast. LENGTH_LONG ).show();
}
});
builder.setNegativeButton( "Cancel" , new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});

builder.show();
} else
Toast.makeText (MainActivity. this, "You already record a route!" ,
Toast.LENGTH_LONG ).show();

//RouteUtil class

public void recordRoute() {
if (intent == null) {
Toast.makeText (ctx, "Start recording!" , Toast. LENGTH_LONG ).show();
intent = new Intent(ctx, LocationService. class);
intent.putExtra( "routeName" ,nOfRoute );
ctx.startService( intent);
} else {
Toast.makeText (ctx, "You already record one Route!" ,
Toast.LENGTH_LONG ).show();
}
}

//Location service class
public void onLocationChanged( final Location loc) {
Log.i("***************" , "Location changed" );
double distance = 4;
if ((loc != null) && (previousBestLocation != null))
distance = previousBestLocation .distanceTo(loc);

if ((loc != previousBestLocation ) && (distance >= 3))
if (isBetterLocation(loc, previousBestLocation ) &&
(nOfRoute .compareToIgnoreCase( "") != 0)) {

new Utils(). writeToFile (loc.getLatitude() + "-" +
loc.getLongitude(), getApplicationContex t(), nOfRoute );
Toast.makeText (getApplicationContext(), "Latitude" +
loc.getLatitude() + "\nLongitude" + loc.getLongitude() +
"\nroute" + nOfRoute , Toast. LENGTH_LONG ).show();
previousBestLocation = loc;

CameraUpdate center =
CameraUpdateFactory. newLatLng (new LatLng(loc.getLatitude(),
loc.getLongitude()));
CameraUpdate zoom = CameraUpdateFactory. zoomTo(17);
MainActivity. mMap.moveCamera(center);
MainActivity. mMap.animateCamera(zoom);
}
}
Figura 5.13 Codul care permite începerea înregistrării unui traseu.

57
Încarcă traseul
Toate traseele se înregistrează prima dată local , într-un fișier , pentru a permite
utilizatorului să înregistreze și atunci când nu există conexiune la internet. U lterior el poate să
încarce traseul în baza de date , în momentul când acesta deține conexiune la internet.

Figura 5.14 Fereastra care permite încărcarea
unui traseu.

btnShow.setText( "Upload" );

adapter = new ArrayAdapter<>(getApplicationContext(),
android.R.layout. simple_spinner_item , mListWithRoutes);
adapter.setDropDownViewResource(android.R.layout. simple_spinner_dropdown_item );
RoutesSpinner .setAdapter( adapter);
btnShow.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), MainActivity. class);
String nameRoute = (String) RoutesSpinner .getSelectedItem();
int index=RoutesSpinner .getSelectedItemPosition();
List<String> updatedList = new Utils(). readFromFile (RouteOperations. this,
Config.nonUploadedRoutes );
updatedList.remove(index);
Utils.deleteFi le(RouteOperations. this,Config. nonUploadedRoutes );
try {
Utils.WriteToNonUploadedFile (updatedList,RouteOperations. this);
} catch (IOException e) {
e.printStackTrace();
}
intent.putExtra( "routeName" , nameRoute);
setResult( 2, intent);
finish();
}
});
Figura 5.15 Codul care ajută la încărcarea unui traseu.

58
Fotografiază
Acest buton deschide o fereastră utilizatorului, care îi permite să realizeze o fotografie
la o anumită coordonată și să o deseneze pe traseu .
Mesagerie
Acest buton duce către o fereastră unde se află toți utilizatori și permite utilizatorului
curent să pornească o discuție privată cu unul dintre ei.
Serviciul de mesagerie pe care îl pune la dispoziție aplicația BikeApp este în timp real,
și este realizat cu ajutorul platformei Firebase.

Figura 5.16 Fereastra care afișează lista de utilizatori

59

Figura 5 .17 Fereastra care permite scrierea unui mesaj

// Main activity login firebase part

UserDetails. username = LoggedUser. getInstance ().getUser().getUserName();
UserDetails. password = LoggedUser. getInstance ().getUser().getPassword();
//Log in in firebase
mAuth.signInWithEmailAndPassword(LoggedUser. getInstance ().getUser().geteMail(),
LoggedUser. getInstance ().getUser().getPassword())
.addOnCompleteListener( this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete( @NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
Log.w("Sign in" , "signInWithEmail" , task.getException());
Toast.makeText (MainActivity. this, "Authentication failed." ,
Toast.LENGTH_SHORT ).show();
return;
}
Log.d("Sign in" , "signInWithEmail:onComplete:" +
task.isSuccessful());
Toast.makeText (MainActivity. this, "Authentification
succesfu lly.",
Toast.LENGTH_SHORT ).show();

FirebaseDatabase. getInstance ().getReference().push().setValue( "ASD",mAuth.getCu
rrentUser().getDisplayName());

}
});
startActivity( new Intent(MainActivity. this, Users.class));

60

//Users rendering part

usersList .setOnItemClickListener( new AdapterView.OnItemClickListener() {
@Override
public void onItemClick (AdapterView<?> parent, View view, int position, long
id) {
UserDetails. chatWith = al.get(position);
startActivity( new Intent(Users. this, Chat.class));
}
});
//Chat class part
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_chat );
layout = (LinearLayout) findViewById(R.id. layout1);
sendButton = (ImageView) findViewById(R.id. sendButton );
messageArea = (EditText) findViewById(R.id. messageArea );
scrollView = (ScrollView) findViewById(R.id. scrollView );
reference1 = mDBConn + UserDetails. username + "_" + UserDetails. chatWith ;
reference2 = mDBConn + UserDetails. chatWith + "_" + UserDetails. username ;
sendButton .setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
String messageText = messageArea .getText().toString();

if (!messageText.equals( "")) {
Map<String, String> map = new HashMap<String, String>();
map.put( "message" , messageText);
map.put( "user", UserDetails. username );

FirebaseDatabase. getInstance ().getReferenceFromUrl( reference1 ).push().setValue(m
ap);

FirebaseDatabase. getInstance ().getReferenceFromUrl( reference2 ).push().setValue(m
ap);
messageArea .setText( "");
}
}
});

public void addMessageBox(String message, int type) {
TextView textView = new TextView(Chat. this);
textView.setText(message);
textView.setTextColor(Color. BLACK);
LinearLayout.LayoutParams lp = new
LinearLayout.LayoutParams(ViewGroup.LayoutParams. MATCH_PARENT ,
ViewGroup.LayoutParams. WRAP_CONTENT );
lp.setMargins( 0, 0, 0, 10);
textView.setLayoutParams(lp);

if (type == 1) {
textView.setBackgroundResource(R.drawable. rounded_corner1 );
} else {
textView.setBackgroundResource(R.drawable. rounded_corner2 );
}

layout.addView(textView);
scrollView .fullScroll(View. FOCUS_DOWN );
}
Figura 5.18 Codul care a jută la transmiterea de mesaje

61
6 Concluzii

Datorită inmulțirii autoveh iculelor, transportul în unele momente a devenit un calvar, în
cazul acesta din ce în ce mai mulți oameni aleg transportul pe bicicleta în locul transportului cu
autovehiculele .
Aplicația BikeApp oferă o soluție pentru bicicliști de a împărtăși traseele lor proprii cu
toți oamenii care folosesc aplicația, prin acest mod utilizatorii pot descoperi trasee noi și
implicit locuri noi de relax are. Ea este benefică si pentru cei care căl ătoresc rar și nu cunosc
trasee, deoarece prin opț iunea de înregistrare trasee fiecare utilizator se poate întoarce pe același
drum urmărind ruta de pe dispozitiv.
În continuare aș dori sa dezvolt o funcționalita te pentru a da posibilitatea tuturor
utilizatorilor să voteze traseele și să existe un clasament al utilizatorilor cu cele mai multe trasee
încărcate.

62

Bibliogra fie

[1] "Telefon mobil," [Online]. Available:
https://ro.wikipedia.org/wiki/T elefon_mobil.
[2] "Bază de date," [Online]. Available:
https://ro.wikipedia.org/wiki/Baz%C4%83_de_date.
[3] S. B. N. Ramez Elmasri, Fundamentals of Database Systems.
[4] R. J. Robbins, Database Fundamentals, 1995.
[5] "Android(sistem de operare)," [Online]. Available:
https://ro.wikipedia.org/wiki/Android_(sistem_de_operare).
[6] A. Hoog, Android Forensics, 2011.
[7] R. Singh, "An Overview of Android Operating System and Its
Security Features," in ISSN : 2248 -9622 , 2014.
[8] M. L. Murphy, The Busy Coder's Guide to Android.
[9] "Google Maps API," Google, [Online]. Available:
https://developers.google.com/maps/android/.
[10] "Developer Android," [Online]. Available:
https://developer.android.com/.
[11] "Firebase," [Online]. Available:
https://en.wikipedia.org/wiki/Firebase.
[12] "Firebase," [Online]. Available: https://firebase.google.com/.

Similar Posts