.l. Dr. Ing. Raul ROBU [610718]

UNIVERSITATEA POLITEHNICA TIMI
Ș
OARA

FACULTATEA DE AUTOMATICĂ
Ș
I CALCULATOARE

AUTOMATICĂ
Ș
I INFORMATIC Ă APLICATĂ

Aplica
ț
ie And roid pentru administrarea serviciilor de

cazare pe cont propriu

PROIECT DE DIPLOMĂ

Profesor coordonator:
Autor:

Ș
.l. Dr. Ing. Raul ROBU

Cosmin-Ionu
ț
CÎRLEA

TIMI
Ș
OARA

2019

1. INTRODUCERE
4

1.1. Contextul de realizare
4

1.2. Tema aplica
ț
iei
4

1.3. Aplica
ț
ii similare în raport cu aplica
ț
ia dezvoltată
5

2. FUNDAMENTARE TEORETICĂ
6

2.1. Java
6

2.2. Firebase
6

2.2.1. Platforma Firebase
6

2.2.2. Consola Firebase
7

2.2.3. Autentificare
8

2.2.4. Realtime Database
9

2.2.5. NoSQL
11

2.2.6. Firebase Storage
12

2.3. Google API
14

2.4. GitHub
16

2.5. GitKraken
17

2.6. Android Studio
19

2.6.1. Informa
ț
ii generale
19

2.6.2. Manifest, Gradle
20

2.6.3. Activită
ț
i
ș
i fragmente
20

2.6.4. Emulatorul
21

2.6.5. Debug
ș
i Instant Run
22

3. IMPLEMENTAREA APLICA
Ț
IEI
24

3.1. Arhitectura aplica
ț
iei
24

3.2. Schemă bloc func
ț
ională
24

3.3. Utilizarea limbajului Java
26

3.4. Elemente XML
ș
i resurse
27

3.5. Activită
ț
i Androi d
29

3.6. Biblioteci utilizate
50

3.7. Bază de date
52

3.8. Testarea aplica
ț
iei
55

4. UTILIZAREA APLICA
Ț
IEI
56

4.1. Cerin
ț
e de sistem
56

4.2. Pornirea aplica
ț
iei
56

4.3. Autentificare
ș
i înregistrare
57

4.4. Adăugare date în profil
58

4.4.1. Adăugare poză
58

2

4.4.2. Adăugare servicii
58

4.4.3.
Ș
tergere sau ie
ș
ire din cont
60

4.5. Căutare
ș
i filtrare
60

4.6. Vizualizarea serviciului în detaliu
62

4.7. Achizi
ț
ionarea un ui serviciu
62

4.8. Starea unei rezervări
63

6. CONCLUZII
65

7. BIBLIOGRAFIE
66

3

1. INTRODUCERE

1.1. Contextul de realizare

Trăim
în
secolul
vitezei,
acesta
este
un
lucru
cert.
Această
viteză
se
răsfrânge
asupra

vie
ț
ii
noastre
ș
i
în
mod
direct,
dar
ș
i
în
mod
indirect.
Ritmul
de
zi
cu
zi
devine
tot
mai
alerg
ș
i

avem
nevoie
de
un
mod
de
a
ț
ine
pasul
cu
el
ș
i
de
a
îi
face
fa
ț
ă.
Dorim

facem
tot
mai
multe

lucruri,
iar
timpul
parcă
devine
tot
mai
pu
ț
in.
Una
dintre
metodele
preferate
de
relaxare
o

reprezintă
călătoria
:
un
weekend
într-un
ora
ș
,
o
săptămână
la
munte
sau
mare
sau
chiar
ș
i
mai

mult într-o loca
ț
ie exotică .

Conform
unui
raport
al
organiza
ț
iei
pentru
turism
din
cadrul
Na
ț
iunilor
Unite
peste
1300

de
milioane
de
călători
au
cheltuit
peste
1300
de
miliarde
de
dolari
doar
în
2017,
reprezentând

10% din produsul intern brut la nivel global.

Fig. 1: Statistici UNWTO pentru turism, 2017[1]

Cum
această
viteză
se
reflectă
ș
i
la
internet,
iar
online
se
găsesc
tot
mai
multe
informa
ț
ii,

este
de
a
ș
teptat
ca
o
bună
parte
din
oameni

î
ș
i
organizeze
singuri
vacan
ț
ele
cu
un
simplu

telefon
ș
i mai multe site-u ri sau aplica
ț
ii.

1.2. Tema aplica
ț
iei

Cum
ar
fi
ca
o
singură
aplica
ț
ie

fie
suficientă
pentru
toate
serviciile
necesare
unei

vacan
ț
e
reu
ș
ite?
O
singură
aplica
ț
ie
înseamnă
timp
salvat,
date
personale
ș
i
bancare

introduse
într-un
singur
loc,
sigur,
toate
informa
ț
iile
la
un
singur
click
distan
ț
ă.
Este
ca
ș
i
cum

ai
avea
propriul
tău
administrator
de
vacan
ț
ă
ș
i
în
care
ai
puterea
de
a
decide
amănun
ț
it
cum

vrei să arate vacan
ț
a ta.

Această
solu
ț
ie
este
dezvoltată
în
cadrul
lucrării,
o
aplica
ț
ie
Android
pentru

administrarea
serviciilor
de
vacan
ț
ă
pe
cont
propriu,
WorldApp.
Numele
aplica
ț
ie
sugerează

4

faptul

se
poate
vizita
întreaga
lume
(cuvântul
“World”
din
limba
engleză
care
se
poate

traduce
ca
lume
sau
planetă)
prin
intermediul
unei
aplica
ț
ii
(cuvântul
“App”
fiind

prescurtarea de la “Application”).

Personal
sunt
un
fan
al
călătoriilor
ș
i
îmi
place

pot
organiza
pe
cont
propriu
ș
i
în

detaliu
vacan
ț
ele,
însă
de
multe
ori
trebuie

consult
o
mul
ț
ime
de
site-uri
pentru
a
găsi
o

combina
ț
ie
convenabilă.
A
ș
a
a
venit
ideea
de
a
pune
serviciile
necesare
unei
vacan
ț
e
reu
ș
ite

într-o singură aplica
ț
ie : c azare, parcare, ghid turistic, administrator de rezervări.

1.3. Aplica
ț
ii similare în raport cu aplica
ț
ia dezvoltată

Vom
compara
aplica
ț
ia
WorldApp
cu
două
aplica
ț
ii
bine-cunoscute
:
AirBnb
ș
i
Visit
a

city.
AirBnb
a
început
ca
o
aplica
ț
ie
care
permitea
oricărei
persoane

găzduiască
călători

din
toată
lumea,
contra-cost,
iar
acum
are
ș
i
oferte
pentru
diferite
experien
ț
e,
inclusiv
ghid

turistic,
dar
ș
i
recomandă ri
de
restaurante.
Visit
a
city
este
o
aplica
ț
ie
care
se
ocupă
exclusiv

de oferte de tururi prin diferite ora
ș
e
ș
i are milioane de utilizatori .

Caracteristici

WorldApp

AirBnb

Visit a city

Op
ț
iuni de cazare

Da

Da

Nu

Op
ț
iuni de parcare

Da

Nu

Nu

Op
ț
iuni de tur ghidat

Da

Da

Da

Recenzii

Nu

Da

Da

Încărcare servicii ca

persoană fizică

Da

Da

Da

Galerie foto

Da

Da

Da

Hartă interactivă

Da

Da

Nu

Filtrare intuitivă

Da

Da

Nu

Recomandări

Nu

Da

Da

Necesită

autentificare

Da

Da

Nu

Tabel 1 : WorldApp în compara
ț
ie cu AirBnb
ș
i Visitacity

După
cum
observăm
în
tabelul
de
mai
sus
punctul
forte
al
aplica
ț
iei
WorldApp
este

reprezentat
de
op
ț
iunea
de
a
închiria
un
loc
de
parcare.
Acest
serviciu
reprezintă
oportunitatea

de
intrare
pe
o
pia
ț
ă
ultra-competitivă
ș
i
cu
jucători
foarte
mari
în
domeniu.
Deoarece
foarte

multe
persoane
călătoresc
sau
fac
naveta
cu
ma
ș
ina
locurile
de
parcare
reprezintă
o
problemă

în
toate
ora
ș
ele
mari.
Un
eventual
succes
al
serviciului
de
parcare
ar
aduce
utilizatori
care

încerce
ș
i celelalte servic ii ale aplica
ț
iei.

5

2. FUNDAMENTARE TEORETICĂ

2.1. Java

Este un limbaj orientat pe obiecte care face parte din familia C, alături de C, C++
ș
i C#.

De
ș
i
este
un
program
cu
o
vechime
considerabilă
pentru
domeniul
IT
&
C,
a
rezistat
alături
de

limbajele
mai
noi
ș
i
mai
dinamice,
el
fiind
de
asemenea
îmbunătă
ț
it
constant.
Are
aplica
ț
ii
în
toate

subdomeniile
industriei,
cel
mai
des
fiind
întâlnit
în
domeniul
aplica
ț
iilor
mobile,
fiind
limbajul
de

bază
pentru
sistemul
de
operare
Android.
Pe
lângă
acestea
mai
este
folosit
în
web
sau
embedded.

Datorită
ma
ș
inii
sale
virtua le
(JVM)
este
folosit
pentru
back-end
de
majoritatea
companiilor
din

Top 500.

Conform
unor
statistici
efectuate
de
ș
i
pe
platforma
GitHub
în
2018,
Java
se
află
pe
locul
3
în

topul preferin
ț
elor pentru de zvoltarea de aplica
ț
ii.

Fig. 2 : Topul limbajelor populare în 2018 întocmit de GitHub[2]

2.2. Firebase

2.2.1. Platforma Firebase

6

Firebase
face
parte
din
categoria
Backend-as-a-Service
(BaaS)
ș
i
este
o
platformă
ce

înglobează
o
multitudine
de
func
ț
iuni.
Aceasta
a
apărut
initi
ț
ial
sub
formă
de
start-up,
iar
datorită

poten
ț
ialul
ș
i utilită
ț
ii uria
ș
e a trecut sub tutela Google.

2.2.2. Consola Firebase

Consola

este
centrul
prin
care
se
controlează
toate
serviciile
Firebase
ale
tuturor
proiectelor

înregistrate
pe
platformă.
Func
ț
ionează
ca
un
super
administrator
al
serviciilor
ș
i
necesită

autentificare.
După
autentificare
se
selectează
un
proiect
existent
sau
se
adaugă
unul
nou.
De

asemenea,
aici
ne
este
oferită
o
privire
de
ansamblu
asupra
problemelor
din
aplica
ț
ie
prin

Crashalytics
sau
statistici
privind
utilizatorii
aplica
ț
iei
precum
numărul
de
instalări,
instalări
active

sau
utilizatori
activi
într-o
perioadă
de
timp.
Tot
aici
putem
vedea
fluxul
de
date
din
aplica
ț
ie,

download-uri sau upload-uri în kilobi
ț
i.

Prin
intermediul
consolei
putem
observa
ș
i
reten
ț
ia
utilizatorilor
într-o
anumită
perioadă
sau

putem face profit de pe urma anun
ț
urilor sau reclamelor în aplica
ț
ie prin intermediul AdMob.

Fig. 3 : Firebase analytics
ș
i AdMob

7

BaaS

permite
dezvoltatorilor

se
concentreze
pe
experien
ț
a
utilizatorilor
eliminând
partea

de server, partea de API-uri sau de stocare.

Fig. 4: O parte dintre serviciile oferite de Firebase

Serviciile
Firebase
folosite
în
cadrul
aplica
ț
iei
:
bază
de
date
în
timp
real,
Autentificare,

depozitare Cloud.

2.2.3. Autentificare

Permite
conectarea
la
o
aplica
ț
ie
prin
intermediul
mai
multor
metode
securizate.
Metoda
de

autentificare
aleasă
pentru
aplica
ț
ie
este
cea
cu
email
ș
i
parolă
,
accesul
la
date
fiind
permis
doar

până la un anumit nivel fără un cont valabil.

Firebase
Auth
are
un
sistem
foarte
avansat
când
vine
vorba
de
fiabilitate
pe
dispozitive

mobile.
O
dată
ce
un
utilizator
s-a
autentificat
de
pe
un
dispozitiv
acesta
rămâne
autentificat
până
la

ș
tergerea aplica
ț
iei sau ie
ș
irea din cont.

8

Fig.5 : Consola pentru modurile de autentificare în aplica
ț
ie

Activarea
sau
dezactivarea
unor
servicii
de
autentificare
(sign-in)
se
face
printr-un
simplu

buton
în
consola
Firebase
aferentă
aplica
ț
iei.
În
partea
de
cod
aplica
ț
iei
lucrurile
sunt
asemănătoare

indiferent
de
metoda
de
autentificare
dorită
:
se
apelează
serviciul
(API-ul)
de
autentificare
cu

creden
ț
ialele
introduse,
iar
mai
apoi
este
verificată
autenticitatea
datelor
cu
serverul.
Datele

esen
ț
iale
sunt
trecute
prin
o
func
ț
ie
hash
ș
i
sunt
criptate,
astfel
încât
nivelul
de
siguran
ț
ă
privind

datele
cre
ș
te
exponen
ț
ial.
Atât
emailul,
cât
ș
i
hash-ul
parolei
pot
fi
văzute
în
cadrul
consolei
de

administrator.

Pentru
evitarea
aglomerării
aplica
ț
iei
cu
conturi
false
sau
nefolosite,
dar
ș
i
pentru
evitarea

anun
ț
urilor
false
create
de
bo
ț
i,
la
crearea
unui
cont
trebuie
confirm ată
adresa
de
email,
acest
lucru

fiind posibil tot prin cadrul serviciului de autentificare amintit mai sus, oferit de Firebase.

2.2.4. Realtime Database

Este
vorba
despre
baza
de
date
a
prezentului
ș
i
viitorului,
baza
de
date
în
timp
real.
Spre

deosebire
de
bazele
de
date
clasice
în
care
se
fac
apeluri
pentru
sincronizarea
datelor,
această
bază

de
date
trimite
datele
către
aplica
ț
ie
în
momentul
în
care
se
înregistrează
schimbări
în
interiorul

nodurilor sale.

Principiile
acestei
baze
de
date
sunt
diferite
de
cele
ale
unei
baze
de
date
clasice
:
datele
sunt

stocate sub formă de noduri
ș
i copii în diverse tabele.

9

Fig.6 : Exemplu tabelă în Firebase, cea care se vede în detaliu fiind cea cu utilizatori

După
cum
putem
observa
în
baza
de
date
avem
mai
multe
tabele,
iar
fiecare
tabelă
are
mai

multe
noduri,
numite
copii.
Luăm
ca
exemplu
tabela
de
utilizatori
“users”
din
imagine
ș
i

exemplificăm
modul
de
lucru
cu
Firebase
Realtime
Database.
În
primul
rând
trebuie

stabilim

accesul la datele dinăuntrul tabelelor, acest lucru se face din consolă.

Fig.7 : Consola permisiunilor de acces la baza de date

În
partea
de
cod
trebuie

ob
ț
inem
o
referin
ț
ă
către
baza
de
date,
iar
de
acolo
totul
se

desfă
ș
oară
sistematic
:
este
accesat
fiecare
nod
în
parte,
de
la
nodul
mare
(tabela)
“users”,
mai
apoi

la
ID-ul
următoarei
intrări
ș
i
implicit
ID-ul
unui
utilizator,
iar
la
final
putem
accesa
nodul

mBookingManager.
Acest
lucru
se
face
foarte
u
ș
or
adăugând

.child()

de
câte
ori
este
nevoie
la
o

referin
ț
ă către o bază de date .

După
ce
am
stabilit
comunicarea
cu
un
nod
/
copil
al
tabelei
putem
accesa
fiecare
element
/

nod
al
său
în
parte
cu
un
for
each.
Se
face
o
snaphshot
(poză)
bazei
de
date
ș
i
se
accesează
ia
fiecare

10

nod
al
snapshot-ului
ob
ț
inut
în
parte.
Deoarece
în
aplica
ț
ie
lucrăm
cu
clase
ș
i
obiecte,
iar
din

Firebase
datele
vin
sub
alte
forme
trebuie

facem
cast
din
tipul
de
dată
respectiv
în
clasa
care
este

defapt
reprezentată.
Pentru
a
putea
face
opera
ț
iile
de
mai
sus
trebuie

ata
ș
ăm
un
“data
listener”
pe

referin
ț
a
tabelei
dorite.
Există
trei
tipuri
de
“listeners”,
în
func
ț
ie
de
modul
în
care
acestea
se

activează
:
doar
atunci
când
se
adaugă
un
nou
nod
în
tabelă,
o
singură
dată
(ca
un
request
/
querry

clasic),
iar
al
3

lea
nod
este
cel
care
aduce
elementul
de
noutate
în
func
ț
ionalitate
ș
i
utilitate

cel

care
se
activează
de
fiecare
dată
când
există
o
schimbare
la
oricare
din
datele
existente
în
tabelă

(adăugare,
ș
tergere, modific are).

Pentru
cel
din
urmă
se
folosesc
două
metode
care
ajută
la
prelucrarea
datelor:

onDataChanged()

pentru
atunci
când
se
modifică
datele,
onCancelled()

folosită
de
obicei
atunci

când nu se poate accesa baza de date (răspuns de la server) din diverse motive.

Fig. 8 : Exemplificare prelucrare de date din Firebase

Acestă
tehnologie
avansată
este
posibilă
ș
i
cu
ajutorul
WebSocket-urilor.
În
timp
ce
în

majoritatea
cazurilor
în
lucrul
cu
baze
de
date
se
folose
ș
te
protocolul
de
comunicare
HTTP,

Firebase
folose
ș
te
WebSock et-urile
pentru
faptul

acestea
sunt
cu
mult
mai
rapide
ș
i
mai
u
ș
or
de

între
ț
inut
deoarece
la
un
singur
socket
se
pot
conecta
o
mul
ț
ime
de
endpoint-uri.
Toate
datele
se

sincronizează
automat
înăuntrul
unei
conexiuni
de
tipul
celei
amintite
mai
sus
ș
i
viteza
cu
care
se

întâmplă depinde doar de viteza internetului.

2.2.5. NoSQL

Firebase
folose
ș
te
pentru
bazele
sale
de
date
o
tehnologie
nouă,
diferită
de
stilul
clasic
SQL,

numită
NoSQL.
Toate
datele
sunt
stocate
sub
formă
de
JSON.
Putem
oricând
importa
sau
exporta

datele sub formatul amintit mai devreme,

Bazele
de
date
SQL
sunt
foarte
puternice
ș
i
versatile,
folosite
mai
ales
la
interogări
complexe.

Ele
sunt
însă
destul
de
restrictive
necesitând
ca
toate
datele
salvate

urmeze
o
anumită
schemă,

ceea ce se traduce prin multă planificare în prealabil
ș
i o mare dificultate la modificare.

11

Pe
de
altă
parte
bazele
de
date
NoSQL
(non-SQL
sau
not-only-SQL)
sunt
mult
mai
flexibile,

ele
având
posibilitatea
stocării
datelor
în
multe
variante:
bazate
pe
coloane,
de
tipul
cheie-valoare,

documente,
graph-uri.
Nu
necesită
o
planificare
amănun
ț
ită
în
prealabil
ș
i
se
pot
adăuga
tipuri
de

date
pe
parcurs.
Acest
tip
de
baze
de
date
este
folosit
în
aplica
ț
ia
WorldApp.
În
imaginea
următoare

avem o ilustrare a diferen
ț
elor dintre cele două variante de baze de date.

Fig. 9 : Compara
ț
ie între SQL
ș
i NoSQL

2.2.6. Firebase Storage

Este
o
modalitate
foarte
simplă
de
a
salva
fi
ș
iere
binare,
cele
mai
uzuale
fiind
imaginile.
În

aplica
ț
ia
dezvoltată
pentru
licen
ț
ă
am
folosit
acestă
facilitate
de
stocare
de
fi
ș
iere
(file
storage)

pentru
imaginile
de
profil,
ale
tururilor
ș
i
oportunită
ț
ilor
de
cazare.
Pentru
a
vedea
mai
multe
detalii

despre
un
fi
ș
ier
se
poate
da
click
pe
el
ș
i
în
partea
dreaptă
vor
fi
afi
ș
ate.
Printre
aceste
detalii

regăsim
ș
i link-ul de downlo ad care este folosit mai apoi la afi
ș
area imaginii în aplica
ț
ie.

În
momentul
în
care
se
adaugă
o
imagine
nouă
în
serviciul
de
stocare
Firebase
facem
un
apel

pentru
a
ob
ț
ine
URL-ul
imaginii
ș
i
pentru
a-l
salva
în
nodul
coresp unzător.
Pentru
a
afi
ș
a
mai
apoi

imaginea
respectivă
se
încarcă
URL-ul
salvat
într-o
componentă
de
afi
ș
are
imagini
(ImageView).

Pentru
a
asigura
unicitatea
numelui
unui
fi
ș
ier
folosim
func
ț
ia
de
ob
ț
inere
a
timpului
în
milisecunde

din Java.

12

Fig. 10 : Datele unui fi
ș
ier stocat în serviciul de File Storage al Firebase

Fig. 11 : Exemplificare de stocare a unei imagini în FileStorage
ș
i Realtime Database

13

2.3. Google API

Pe
lângă
platforma
Firebase
mai
există
o
multitudine
de
servicii
oferite
de
Google.
Dintre

acestea,
în
aplica
ț
ie
am
folosit
Maps
SDK
pentru
Android,
adică
Google
Maps
pentru
platforma

Android
ș
i Geolocation API .

Pentru
a
putea
folosi
serviciile
mai
sus
amintite
este
nevoie
de
crearea
unui
cont
de

dezvoltator
pe
Google
Cloud
Platform.
Această
platformă
este
asemănătoare
ș
i
conectată
cu

Platforma
Firebase.
Cele
două
sunt
entită
ț
i
separe
ș
i
împart
informa
ț
ii
până
la
un
anumit
punct,

nefiind posibile totalitatea opera
ț
iilor Firebase din Cloud Platform
ș
i invers.

În
timp
ce
Firebase
este
Backed-as-a-Service
(BaaS),
Cloud
Platform
este
furnizor
de
servicii

de
tipul
Infrastructure-as-a-Service
(IaaS),
Platform-as-a-Service,
servicii
de
tipul
“serverless

computing”.
De
asemenea,
este
o
platformă
pentru
dezvoltare
ș
i
găzduire
de
Aplica
ț
ii
Web,

Internetul Lucrurilor (IoT), are func
ț
ii variate de analiză
ș
i ramifica
ț
ii în multe alte arii
ș
i domenii.

Fig. 12 : Privire de ansamblu asupra platformei Google Cloud

A
ș
a
cum
am
men
ț
ionat
mai
sus,
este
nevoie
de
un
cont
de
dezvoltator
pentru
a
putea
folosi

platforma,
dar
nu
este
suficient
pentru
a
putea
folosi
o
gamă
largă
de
produse,
printre
care
ș
i
Maps

SDK
sau
Geolocation,
prezente
în
aplica
ț
ie.
Pentru
a
putea
fi
folosite
toate
serviciile
este
necesară

introducerea
unui
cont
sau
card
bancar
valabil,
cu
toate

pentru
exersarea
dezvoltării
de
aplica
ț
ii

folosind
API-uri
din
platformă
nu
vom
ajunge
efectiv

plătim
în
primul
an
sau
până
la
o
anumită

mărime de date.

Pentru
a
putea
folosi
un
serviciu
în
aplica
ț
ia
din
Android
Studio
(sau
orice
alt
mediu
de

dezvoltare)
trebuie

avem
instalată
extensia
(Plug-in)
Google
Play
Services,
iar
mai
apoi
fiecare

serviciu
în
parte.
Versiunile
de
servicii
ș
i
Google
Play
trebuie

corespundă
între
ele,
dar
nu
trebuie


fie
neapărat
aduse
“la
zi”
dacă
nu
dorim
schimbările
din
noile
versiuni.
După
ce
adăugăm

serviciile
în
mediul
de
dezvoltare
trebuie

creăm
un
proiect
în
Cloud
Platform.
În
acest
proiect

14

vom
avea
toate
serviciile
folosite
în
cadrul
proiectului,
pentru
fiecare
proiect
în
parte
fiind
necesară

activarea
individuală
a
serviciilor
ș
i
implicit
introducerea
unui
nou
cont
bancar,
fapt
care
u
ș
urează

munca dezvoltatorilor per ansamblu.

Odată
ce
avem
serviciile
instalate
ș
i
activate
va
trebui

ob
ț
inem
datele
de
identificare
pentru

servicii
ș
i
proiect
:
în
Andr oid
Studio
sunt
trecute
cheile
primite
de
la
Cloud
Platform
ș
i
care
vor

permite
accesarea
API-urilor,
iar
în
Cloud
Platform
sunt
trecute
date
despre
proiect
pentru
a
nu

permite altor proiecte să solicite datele în numele nostru.

Google
Maps
API
(Maps
for
Android
SDK)

este
unul
dintre
serviciile
disponibile
pe

Google
Cloud
Platform
ș
i
utilizate
în
cadrul
aplica
ț
iei.
Pentru
simpla
afi
ș
are
a
unei
hăr
ț
i
este
nevoie

de
cheia
de
autentificare
amintită
mai
sus,
iar
apelurile
către
server
ș
i
respectiv,
costurile,
se
pot

vedea
în
panoul
principal
al
Consolei
la
sec
ț
iunea
Google
Maps.
Pe
lângă
afi
ș
area
hăr
ț
ii
prin

intermediul
API-ului
putem
pune
marcaje
pe
hartă
ș
i
putem
ob
ț
ine
direc
ț
ii
către
acel
marcaj
prin
2

atingeri.

Fig. 13 : Privire de ansamblu asupra Serviciului Maps Android SDK din platformă

Geolocation
API

este
un
serviciu
care
vine
în
completarea
celui
mai
sus
amintit,
dar
poate
fi

folosit
ș
i
separat.
Prin
interm ediul
acestuia
putem
afla
loca
ț
ia
dispozitivului
sau
putem
extra
date
de

pe
hartă.
De
exemplu,
la
plasarea
unui
marcaj
(pin)
pe
hartă
putem
ob
ț
ine
ț
ara,
regiunea,
localitatea,

adresa exactă, codul po
ș
tal
ș
i alte date de la acea pozi
ț
ie.

Legătura
dintre
Firebase
ș
i
Cloud
Platform
este
foarte
strânsă,
ambele
fiind
servicii
oferite
de

către
Google
:
proiectele
dintr-o
consolă
se
regăsesc
ș
i
în
cealaltă
atâta
timp
cât
pe
ambele
console

este autentificat un singur utilizator.

15

2.4. GitHub

Git

reprezintă
un
sistem
distribuit
de
control
al
versiunilor
diferite
de
cod,
adică
de
detectare
a

schimbărilor
din
codul
sursă
de
la
o
variantă
(versiune)
la
alta.
Este
folosit
peste
tot
unde
se

efectuează
ac
ț
iuni
de
dezvo ltare
de
cod
ș
i
scopul
său
este
acela
de
a
u
ș
ura
munca
dezvoltatorilor
de

cod,
dar
ș
i
aceea
de
a
coord ona
mai
bine
munca
în
echipă
asupra
unui
produs.
Nu
doar
fi
ș
ierele
cu

cod pot fi trecute printr-un sistem de genul celui amintit, ci orice tip de fi
ș
iere.

Printre
calită
ț
ile
Git
se
enumeră
viteza,
integritatea
datelor
ș
i
ajutorul
în
munca
care
nu
este

liniară
ș
i
care
necesită
îmbinarea
mai
multor
caracteristici
diferite.
De
exemplu,
în
cadrul
unei

aplica
ț
ii
se
poate
lucra
în
paralel
la
autentificare
ș
i
înregistrare,
iar
mai
apoi
codul
este
pus
împreună

ș
i
adus
la
o
formă
comună
care

permită
rularea
sa
în
condi
ț
ii
optime.
De
asemenea,
datorită

sistemului
distribuit
de
control
ar
versiunilor
putem
reveni
oricând
la
o
variantă
anterioară
celei

curente dacă este nevoie.

Git este creat de către Linus Torvalds, tatăl sistemului de operare Linux
ș
i este open-source.

GitHub

este
o
aplica
ț
ie
web
pentru
găzduirea
unui
sistem
de
control
al
versiunilor

Git.
Este

o
subsidiară
a
celebrei
companii
Microsoft
ș
i
oferă
ș
i
servicii
de
identificare
a
problemelor
din
cod

(bug-uri),
cerere
de
noi
caracteristici
al
sistemului
dezvoltat,
administrarea
sarcinilor
de
lucru
ș
i

altele.
Probabil
cel
mai
mare
avantaj
oferit
însă
de
acest
software
este
faptul

oferă
o
interfa
ț
ă
mai

prietenoasă cu utilizatorul pentru folosirea sistemelor distribuite de control al versiunilor.

Pentru
a
putea
folosi
GitHub
trebuie

avem
un
cont,
iar
în
cadrul
unui
cont
putem
avea
mai

multe
proiecte,
numite
în
limbaj
de
specialitate
“repository”
sau
pe
română

depozit.
Aceste

depozite
sunt
publice
în
op
ț
iunea
gratuită
a
aplica
ț
iei,
adică
orice
are
acces
la
ele,
însă
nu
pot

adăuga
sau
modifica,
ci
doar
vizualiza.
Pentru
a
putea
adăuga
cod
este
nevoie
de
acces
ș
i
de
a

ini
ț
ializa repository-ul pe co mputerul dezvoltatorului care dore
ș
te să contribuie.

De
obicei
la
un
proiect
mare
contribuie
multe
persoane
ș
i
acest
lucru
se
poate
vedea.
Este

foarte
folositor
deoarece
a
ș
a
se
în
ț
elege
mai
bine
cum
s-a
ajuns
la
un
produs
final
ș
i
cine
a
avut
o

anumită contribu
ț
ie.

Pentru
o
utilizare
mai
facilă
a
sistemului
de
control
al
versiunilor
putem
folosi
diferite

programe
care
au
o
interfa
ț
ă
prietenoasă
cu
utilizatorul
privind
opera
ț
iile
posibile
sau
necesare
:

ini
ț
ializare
depozit
(reposito ry),
creare
de
noi
ramuri
(branch-uri),
aducerea
codului
de
pe
o
ramură

la
zi
ș
i
altele
pe
care
le
vom
discuta
în
continuare.
Pentru
acest
proiect
eu
am
ales

folosesc

aplica
ț
ia

GitKraken

.

16

Fig. 14 : Exemplu de depozit (repository) pe GitHub

2.5. GitKraken

Acest
software
este
gratuit
dacă
nu
este
folosit
în
scop
comercial
ș
i
este
foarte
intuitiv
de

folosit.

Opera
ț
iile
folosite
în
GitKraken
pentru
dezvoltarea
aplica
ț
iei
:
ini
ț
ializare
repository,
creare

de
ramură
nouă,
aducerea
la
zi
a
codului
de
pe
ramura
deviată
din
ramura
principală,
îmbinarea
unei

ramuri derivate cu ramura principală, revenirea la o versiune anterioară.

În
figura
de
mai
jos
avem
un
exemplu
de
unire
a
unei
ramuri
derivate
din
ramura
“master”
cu

fiecare “commit” (adăugare de versiune nouă, vizibilă doar local)
ș
i data la care a fost efectuat.

În
momentul
în
care
selectăm
una
dintre
versiuni
vom
putea
vedea
toate
modificările
care
au

avut loc fa
ț
ă de versiunea pr ecedentă : adăugare, modificare sau
ș
tergere.

Pentru
a
reveni
la
o
versiune
anterioară
se
apasă
click
dreapta
pe
versiunea
dorită
ș
i
se
face
o

opera
ț
iune de inversare (der ulare înapoi) a schimbărilor efectuate.

17

Fig.15 : Fereastra principală din GitKraken

18

Fig. 16 : Exemplu de modificări asupra unei versiuni de cod

În
cazul
în
care
ne
dorim
ca
schimbările

ajungă
ș
i
pe
server,
adică
toată
lumea
care

participă la proiect să le poată vedea trebuie să trimitem aceste modificări folosind op
ț
iunea “push”.

Pentru
fiecare
nouă
func
ț
ionalitate
am
creat
o
nouă
ramură,
derivată
din
ramura
principală,
iar

la
final
am
unit
ramura
nouă
cu
cea
din
care
a
fost
derivată,
adăugând
noile
func
ț
ionalită
ț
i
la
cele

existente.

2.6. Android Studio

2.6.1. Informa
ț
ii gen erale

Este
mediul
de
dezvoltare
oficial
al
sistemului
de
operare
Android,
oferit
de
Google.
Construit

pe
ideea
celor
de
la
JetBrains

IntelliJ
IDEA,
a
oferit
o
alternativă
mult
mai
bună
la
dezvoltarea

aplica
ț
iilor
mobile
în
Eclips e.
Limbajele
acceptate
sunt
Java
ș
i
Kotlin

noul
limbaj
dezvoltat
de
cei

de la Google.

Fiind
un
produs
dezvoltat
de
Google
folosirea
Firebase
ș
i
Cloud
Platform
în
cadrul
IDE-ului

nu
doar

este
facilă,
dar
este
chiar
integrată
prin
diferite
opera
ț
iuni
de
ajutor.
Avem
parte
de
un

asistent
pentru
Firebase
care
ne
ajută
atât
cu
documenta
ț
ie
pentru
serviciile
oferite
direct
în

aplica
ț
ie, cât
ș
i cu bucă
ț
i de cod suficiente
ș
i necesare pentru conectarea la un serviciu anume.

19

Fig.17 : Asistentul Firebase pentru Android Studio
ș
i o parte de cod

2.6.2. Manifest, Gradle

Fi
ș
ierul
Manifest
este
specific
unui
proiect
nativ
Android
ș
i
con
ț
ine
informa
ț
ii
despre
numele

proiectului,
activită
ț
ile
(ecranele)
din
cadrul
proiectului,
dar
ș
i
permisiunile
de
care
are
nevoie

aplica
ț
ia
pentru
a
func
ț
iona
a
ș
a
cum
este
inten
ț
ionat
:
acces
la
loca
ț
ia
dispozitivului,
acces
la

internet, acces la stocare internă pentru scriere
ș
i citire.

În
fi
ș
ierul
Gradle.app
sunt
importate
biblioteci
sau
proiecte
care
vin
în
ajutorul
sau
în

completarea
serviciilor
existente
deja
în
Android
Studio,
sau
chiar
func
ț
ionalită
ț
i
complet
noi.

Aceste
biblioteci
trebuie
administrate
cu
grijă
deoarece
multe
sunt
interconectate
ș
i
au
diferite

versiuni,
iar
pentru
o
func
ț
ionare
corectă
versiunile
trebuie

coincidă.
De
exemplu,
pentru

biblioteca
folosită
pentru
componenta

RecyclerView
trebuie

avem
importată
ș
i
biblioteca

support:appcompat-v7.

Tot
în
cadrul
fi
ș
ierulu i
Gradle
avem
trecute
ș
i
versiunile
de
Android
ț
intă
ș
i
minime,
dar
ș
i

versiunea de Google Play Store a aplica
ț
iei.

2.6.3. Activită
ț
i
ș
i fragmente

O
activitate
reprezintă
un
ecran
într-o
aplica
ț
ie
Android,
în
timp
ce
un
fragment
reprezintă
o

por
ț
iune de ecran. Mai multe fragmente pot face parte din aceea
ș
i activitate.

O
activitate
este
formată
dintr-un
fi
ș
ier
Java
în
care
este
trecută
partea
de
cod
ș
i
un
fi
ș
ier
XML

unde
sunt
trecute
componentele
care
sunt
afi
ș
ate
pe
ecran
:
butoane,
casete
de
text,
afi
ș
are
de

imagini,
desfă
ș
urare
de
liste
ș
i
multe
alte
componente.
Cele
două
sunt
legate
între
ele,
iar
pentru
a

avea
acces
la
componentele
XML
în
fi
ș
ierul
Java
acestea
trebuie
declarate,
iar
mai
apoi
identificate

20

după
ID.
De
ș
i
aproape
toate
proprietă
ț
ile
componentelor
de
interfa
ț
ă
pot
fi
setate
atât
programatic,

cât
ș
i în fi
ș
ierul XML, unele sunt obligatoriu completate în cel din u rmă amintit.

Pentru
exemplificarea
folosirii
fragmentelor
în
cadrul
unei
activită
ț
i
vom
lua
activitatea
de

bază
a
aplica
ț
iei
WorldApp
în
care
avem
4
fragmente
diferite,
schimbate
între
ele
prin
intermediul

componentei
Bottom
Navigation
care
se
află
în
fi
ș
ierul
XML
aferent
activită
ț
ii
principale.
Pe
lângă

această
componentă,
în
activitatea
principală
folosim
un
element
de
tipul
FrameLayout
ca
element

de
afi
ș
are
al
celor
4
fragme nte.
Prin
apăsarea
unui
buton
din
cele
4
de
jos,
în
FrameLayout
este

încărcat un fi
ș
ier XML afere nt fragmentului conectat la buton.

În
imaginea
de
mai
jos
se
poate
observa
faptul

în
interiorul
layout-ului
principal
există
cele

două componente amintite care schimbă fragmentele între ele pe ecranul principal.

Fig. 18 : Fi
ș
ierul XML aferent activită
ț
ii pri ncipale

2.6.4. Emulatorul

Android
Studio
beneficiază
de
un
simulator
de
dispozitive
fizice
numit
emulator.
Pe
acesta
de

pot
testa
aplica
ț
iile
fără
a
fi
nevoie
de
un
dispozitiv
fizic,
dispunând
de
o
mare
varietate
de

dimensiuni
ș
i
versiuni
ale
sistemului
de
operare.
Însă,
partea
cea
mai
folosită
de
către
dezvoltatori

din
acest
emulator
o
reprezintă
previzualizarea
ecranelor.
Această
func
ț
ionalitate
este
prezentă
în

ecranul
de
editare
al
fi
ș
ierelor
XML
ș
i
este
de
foarte
mare
ajutor
deoarece
ne
arată
aspectul

activită
ț
ii în timp real.

21

În
imaginea
de
mai
jos
putem
observa
faptul

am
ales
ca
dispozitiv
pentru
emulator
un

telefon
Galaxy
Nexus
6P
care
este
foarte
similar
ca
dimensiune
cu
dispozitivul
fizic
pe
care
s-au

efectuat
testele.
De
ș
i
un
emulator
este
folositor,
dezvoltarea
profesionistă
se
face
defapt
folosind

dispozitive fizice, acestea fiind mai rapide
ș
i având mai multe capacită
ț
i tehnologice.

Fig. 19 : Previzualizarea unui ecran în timpul dezvoltării ecranului

2.6.5. Debug
ș
i Inst ant Run

Android
Studio
are
posibilită
ț
i
de
depanare
a
aplica
ț
ie,
fie
ea
instalată
pe
un
dispozitiv
fizic

sau
unul
virtual,
cu
ajutorul
emulatorului.
Pentru
a
opri
execu
ț
ia
în
anumite
puncte
sau
pentru
a

vedea
valoarea
unor
variabile
trebuie

folosim
bine-cunoscutele
breakpoint-uri
ș
i
trebuie

activăm modul “Debug” din aplica
ț
ie.

Pentru
mai
multe
detalii
asupra
execu
ț
iei
programului
sau
a
erorilor
apărute
avem
la
dispozi
ț
ie

ferestrele
Logcat,
Debug
sau
Run
unde
vedem
detaliat
ce
se
întâmplă.
Mai
există
ș
i
posibilitatea

captării
ș
i tratării de eroare î n timp real folosind instruc
ț
iunile Try
ș
i Catch.

O
caracteristică
foarte
folositoare
a
op
ț
iunii
de
depanare
din
cadrul
Android
Studio
este

afi
ș
area valorilor tuturor var iabilelor care fac subiectul execu
ț
iei la momentul depanării, pe ecran.

22

Fig. 20 : Android Studio în modul Debug

Func
ț
ia
de
Instant
Run
a
mediului
de
dezvoltare
permite
încărcarea
schimbărilor
foarte
rapid,

economisind
foarte
mult
timp,
această
func
ț
ie
nefiind
prezentă
în
multe
alte
medii
asemănătoare.

Este
o
practică
de
dezvoltare
incrementală
ș
i
înseamnă
defapt
încărcarea
schimbărilor
în
loc
de

reîncărcarea
întregii
aplica
ț
ie,
proces
care
de
obicei
poate
dura
ș
i
minute
bune,
se
transformă
în

cateva secunde.

Fig. 21 : Modul de operare al func
ț
iei Instant Run [3]

23

3. IMPLEMENTAREA APLICA
Ț
IEI

3.1. Arhitectura aplica
ț
iei

Software-ul are două mari module : aplica
ț
ia mobilă
ș
i baza de date Firebase. Prin

intermediul aplica
ț
iei mo bile sunt introduse
ș
i prelucrate date, ele fiind scrise
ș
i citite din

baza de date. Prin intermediul Firebase se asigură nu doar baza de date, ci
ș
i serviciile de

autentificare
ș
i înregistrar e.

În WorldApp un utilizator cu un cont valabil poate fi în acela
ș
i timp călător
ș
i gazdă. Din

ecranele de listare servicii poate alege ceea ce al
ț
i utilizatori oferă, iar din ecranul Profile

poate alege să vadă serviciile oferite de către el, respectiv să adauge unele noi.

Fig. 22 : Arhitectura aplica
ț
iei

3.2. Schemă bloc func
ț
ională

În
figura
23
este
prezentată
schema
bloc
func
ț
ională
pentru
opera
ț
iunea
de
rezervarea
a

unui
serviciu
existent
în
cadrul
aplica
ț
iei.
Pentru
rezervarea
unui
serviciu
este
nevoie
de

autentificare.

24

Fig. 23 : Schema bloc func
ț
ională pentru o rezervare

25

3.3. Utilizarea limbajului Java

Un
proiect
în
Android
Studio
con
ț
ine
o
mul
ț
ime
de
fi
ș
iere,
dar
cele
cu
care
lucrăm
în
mod

direct sunt cele Java
ș
i XM L. În acest paragraf vom discuta despre fi
ș
ierele Java.

Orice
activitate
(ecran)
al
aplica
ț
iei
este
o
combina
ț
ie
între
un
fi
ș
ier
Java
în
care
este
trecută

partea
de
cod
ș
i
un
fi
ș
ier
XML
unde
sunt
trecute
componentele
de
interfa
ț
ă.
Legătură
dintre
ele

se
face
din
ambele
fi
ș
ierele,
în
cel
Java
declarându-se
fi
ș
ierul
XML
care
con
ț
ine
layout-ul
dorit,

iar în celălalt fi
ș
ier este d eclarată clasa care reprezintă defapt activitatea.

Fig. 24 : Declararea fi
ș
ierului XML în clasa aferentă unei activită
ț
i

Fig.25 : Declararea clasei în fi
ș
ierul XML

Pe
lângă
activită
ț
i
(ecrane)
fi
ș
ierele
Java
reprezintă
clase le
care
abstractizează
nevoile

aplica
ț
iei,
numite
modele ,
clase
de
ajutor
pentru
conectare
la
baze
de
date,
conversii
între
tipuri

de date, clase de ajutor pentru rezervare sau înregistrare.

26

3.4. Elemente XML
ș
i resurse

Pentru
fi
ș
ierele
de
genul
există
un
folder
separat
denumit

res
în
cadrul
unui
proiect
în
Android

Studio. În cadrul acestui folder există sub-folderele : drawable, layout, menu, mipmap, values.

Fig. 26 : Folderul res

În
folderul
mipmap
se
găsesc
fi
ș
iere
de
acela
ș
i
tip
cu
numele
folderului,
de
obicei
create
în

interiorul proiectului
ș
i reprezintă imagini.

În
interiorul
folderului
values
sunt
salvate
fi
ș
iere
XML
cu
date
despre
stiluri,
culori,
texte

implicite,
dar
ș
i
create
de
către
dezvoltator.
În
cadrul
aplica
ț
iei
am
folosit
mai
multe
stiluri

personalizate
pentru
a
reduce
timpul
de
dezvoltare
prin
eliminarea
liniilor
de
cod
repetitive,
dar

ș
i deoarece pentru unele e lemente de UI, de exemplu butonul rotund, era nevoie de un stil nou.

Fig. 27 : Exemplu de stil din fi
ș
ierul styles.xml

Un
alt
exemplu
foarte
folositor
în
reprezintă
fi
ș
ierul
strings.xml
în
care
se
salvează
cuvinte

sau
fraze
care
nu
se
modifică
pe
parcursul
rulării
fiind
posibilă
refolosirea
acestora
prin
referirea

loca
ț
iei
si
numelui

@strings/save_text,
spre
exemplu.
O
altă
misiune
a
fi
ș
ierului
este
aceeea
de

a
facilita
traducerea
aplica
ț
iei
în
mai
multe
limbi
deoarece
acelea
ș
i
cuvinte
în
limbi
diferite
vor

avea acela
ș
i ID.

27

În folderul home se află doar layout-ul pentru meniul din josul ecranului principal.

Folderul
în
care
se
află
toate
fi
ș
ierele
XML
care
reprezintă
layout-urile
aferente
ecranelor
este

folderul
layout.
Aceste
fi
ș
iere
XML
reprezintă
atât
ecranul
întreg,
cât
ș
i
componente
separate

cum ar fi
ș
abloanele pent ru RecyclerView, diferitele tipuri de bări de navigare sau fragmente.

Un
fi
ș
ier
layout
are
la
bază
un
“container”,
un
view
părinte
care

con
ț
ină
toate
celelalte

view-uri
prezente
în
fi
ș
ier.
Un
view
reprezintă
un
element
de
UI.
Există
ș
i
view-uri
care
sunt

formate din alăturarea mai multor view-uri, de exemplu ScrollGalleryView.

Fig.28 : Exemplu de ecran în XML

În
ecranul
de
mai
sus
este
folosit
un
RelativeLayout
ca
view
principal,
iar
view-urile

copil
sunt
bara
de
navigare,
un
ImageView
folosit
pentru
afi
ș
area
de
imagini,
3
casete
text
ș
i
un

buton.
Bara
de
navigare
este
un
layout
separat,
un
fi
ș
ier
XML
separat,
iar
pentru
a
fi
folosit
ne

ajutăm
de
expresia
<include
layout=”@layout/numele_fi
ș
ierului_xml_dorit”/>
care
selectează

fi
ș
ierul
denumit
ș
i
îl
introduce
în
layout-ul
curent.
Astfel
cre
ș
te
foarte
mult
re-utilizabilitatea

componentelor
ș
i se face depanarea mult mai u
ș
oară
ș
i dezvoltarea mai rapidă.

Fig. 29 : Fi
ș
ierul XML care con
ț
ine bara de navigare

28

Un
element
de
UI
are
mai
multe
atribute
care
pot
fi
setate
pentru
a
determina
diferite

caracteristici, cele mai importante fiind lă
ț
ime, lungime
ș
i pozi
ț
ia în pagină.

Fig.30 : Exemplu de view -casetă text, cu diferite atribute

Folderul drawable con
ț
ine imagini, clip art-uri (icoane) create în cadrul Android Studio, dar
ș
i

diferite fi
ș
iere XML care con
ț
in stiluri pentru butoane sau pentru BottomNavigation. În principiu

aici sunt stocate fi
ș
iere ce
ț
in de aspect, UI diferite de layout-uri s au stiluri.

Fig. 31 : Trei tipuri diferite de fi
ș
iere în folderul drawable

3.5. Activită
ț
i Android

În
cadrul
unei
clase
aferente
unei

activită
ț
i
sunt
declarate
toate
elementele
de
UI
(User

Interface

interfa
ț
a
cu
utilizatorul)
care
fac
subiectul
unor
schimbări
sau
a
unor
valori
care
sunt

dinamice,
adică
sunt
schimbate
programatic.
Ele
se
identifică
după
un
nume
(ID)
care
trebuie

fie
unic,
iar
pentru
a
putea
accesa
un
element
acesta
trebuie
declarat
ș
i
găsit
prin
metoda

findViewById() care are ca parametru numele.

O
clasă
care
define
ș
te
o
activitate
trebuie

mo
ș
tenească
o
clasă
oferită
de
către
IDE,
ș
i

anume
AppCompatActivity.
În
interiorul
acestei
clase
există
mai
multe
metode
care
gestionează

ciclul de via
ț
ă al unui ecr an :


onCreate()


onStart()

29


onResume()


onPause()


onStop()


onDestroy()


onRestart()

Fig. 32 : Ciclul de via
ț
ă al unei activită
ț
i [4]

În
mod
obi
ș
nuit
declar a
ț
iile
de
componente
XML
se
efectueaz ă
în
metoda
onCreate()
care
este

suprascrisă
din
clasa
de
bază
amintită
mai
sus.
În
momentul
în
care
dorim

efectuăm
opera
ț
ii

pe una dintre metodele din cadrul ciclului de via
ț
ă al unei activită
ț
i trebuie să supra-scriem

În
cadrul
aplica
ț
iei
am
creat
o
nouă
activitate
de
bază
care
mo
ș
tene
ș
te
AppCompatActivity
ș
i

care
reprezintă
scheletul
pe
care
sunt
construite
majoritatea
activită
ț
ilor.
Această
clasă
se

nume
ș
te
BaseAppCompa t
ș
i
aduce
în
plus
fa
ț
ă
de
cea
amintită
mai
sus
un
“toolbar”,
o
bară
de

naviga
ț
ie,
cu
un
buton
care
ne
întoarce
la
ecranul
precedent
ș
i
cu
o
metodă
care
ne
oferă

posibilitatea
de
a
seta
un
titlu
pentru
această
bară,
dacă
dorim.
Acest
lucru
u
ș
urează
munca
ș
i

scade
din
timpul
efectiv
de
dezvoltare.
Ne
oferă
ș
i
o
flexibilitate
prin
faptul

putem
alege
ce

metode să folosim în fiecare situa
ț
ie.

30

Fig. 33 : Clasa de bază pentru majoritatea ecranelor din aplica
ț
ie

Pe
lângă
elementele
de
UI
ș
i
opera
ț
iile
asupra
lor,
într-o
activ itate
mai
sunt
declarate
opera
ț
ii

de prelucrare a datelor, de primire sau de trimitere a lor către server sau utilizatori.

Activită
ț
ile de autent ificare
ș
i înregistrare

În
cadrul
activită
ț
ii
de
autentificare
utilizatorul
introduce
datele
de
autentificare,
iar
la

apăsarea
butonului
“Log
In”
se
efectuează
autentificare
prin
serviciul
de
autentificare
al
Firebase.
În

imaginea de mai jos observăm posibilitatea de înregistrare în cazul în care nu avem un cont valabil.

Fig. 34 : Ecranul de autentificare

31

Datele
introduse
în
casetele
pentru
numele
de
utilizator
ș
i
parolă
sunt
preluate
ș
i
apelează

metoda
de
autentificare
cu
email
ș
i
parolă
din
Firebase,
care
are
ș
i
un
“listener”
care
anun
ț
ă

aplica
ț
ia
când
datele
au
fost
verificate
cu
cele
din
baza
de
date,
iar
în
cazul
în
care
opera
ț
ia
a
avut

succes
se
va
continua
opera
ț
ia
de
autentificare.
Un
ultim
pas
pentru
această
opera
ț
ie
este
verificarea

email-ului
la
momentul
înregistrării
unui
cont
nou
prin
func
ț
ia
isEmailVerified().
Acest
email
se

trimite
automat
ș
i
contul
trebuie
confirmat
o
singură
dată.
Măsura
a
fost
luată
pentru
prevenirea

creări de conturi false sau a spam-ului.

Fig.35 : Opera
ț
iile de autentificare din clasa LogInActivity

Înregistrarea
unui
cont
nou
se
face
din
activitatea
RegisterActivity,
la
care
se
ajunge
prin

activitatea
LogIn.
Sunt
necesare
doar
câteva
informa
ț
ii
de
bază,
fără
de
care
sistemul
gândit
nu
ar

putea func
ț
iona, dar care să nu fie prea în detaliu
ș
i oamenii să abandoneze înscrierea în aplica
ț
ie.

Fig.36 : Ecranul de înregistrare

32

La
fel
ca
la
procesul
de
autentificare
ș
i
în
procesul
de
înregistrare
avem
func
ț
ii
ș
i
“listeners”

din
cadrul
Firebase,
acesta
fiind
unul
dintre
motivele
pentru
care
am
ales
această
platformă
pentru

dezvoltarea
software-ului.
Două
dintre
func
ț
iile
oferite
de
serviciul
de
înregistrare
mai
importante,

apelate,
sunt
createUserWithEmailAndPassword()
unde
trimitem
ca
parametrii
numele
de
utilizator

ș
i
parola
introduse
de
utilizator
ș
i
sendEmailVerification()
care
trimite
un
mail
de
verificare
a

contului către email-ul introdus.

Fig. 37 : Cod pentru înregistrarea în Firebase

Splash
Activity


este
activitatea
care
încarcă
principalele
date
din
baza
de
date
în
memoria

telefonului.
Este
afi
ș
ată
înaintea
activită
ț
ii
principale
pe
durata
efectuării
opera
ț
iilor
de
verificare
ș
i

preluare de date.

Home
Activity


activitatea
principală,
afi
ș
ată
la
intrarea
în
aplica
ț
ie,
după
preluarea
datelor

necesare.
Această
activitate
este
compusă
din
4
fragmente
:
Home,
Trips,
Inbox,
Profile,
care
sunt

încărcate în func
ț
ie de buton ul apăsat în josul ecranului.

Pentru
bara
de
jos
am
folosit
un
element
numit
BottomNavigationView
care
con
ț
ine
4

elemente,
fiecare
cu
un
ID
propriu.
În
func
ț
ie
de
ID-ul
selectat
se
va
încărca
un
fragment
diferit
în

ecranul
principal.
Toate
fragmentele
sunt
declarate
la
ini
ț
ializarea
ecranului
Home
pentru

optimizare.

Home
Fragment

sunt
afi
ș
ate
op
ț
iunile
de
vizualizare
a
tururilor
ghidate,
oportunită
ț
ilor
de

cazare, locurilor de parcare sau a statisticilor.

Pentru
afi
ș
area
op
ț
iunilor
am
folosit
elementul
de
UI
numi t
CardView
ș
i
am
setat
pentru

fiecare
dintre
ele
metoda
onClick()
pentru
a
ne
duce
la
ecranul
aferent
informa
ț
iei
afi
ș
ate.
CardView

oferă un aspect mai plăcut el fiind creat pentru astfel de expunere de informa
ț
ii.

Trips
Fragment
(fig.39)

are
două
func
ț
ionalită
ț
i:
afi
ș
area
tuturor
serviciilor
pe
care
le-am

contractat
sau
am
încercat

le
contractăm
sub
denumirea
de
“Your
bookings”,
iar
sub
denumirea

de
“Your
guests”
sunt
afi
ș
ate
toate
serviciile
oferite
de
către
utilizatorul
curent
care
au
fost

contractate
ș
i
acceptate.
Cea
din
urmă
are
scopul
de
a
ajuta
în
administrarea
afacerii
din
punctul
de

vedere al unei gazde.

33

Fig. 38 : Încărcarea diferitelor fragmente în func
ț
ie de op
ț
iunea selectată

Fig. 39 : Ecranul pentru fragmentul Trips

34

Inbox
Fragment

sunt
afi
ș
ate
toate
serviciile
noastre
contractate
în
diferite
perioade
de
către

alte
persoane.
Există
op
ț
iunea
de
acceptare
sau
respingere,
se
pot
vedea
aproximativ
acelea
ș
i
detalii

despre rezervare ca în fragmentul Trips.

Fig. 40 : Ecranul pentru fragmentul Inbox

Dacă
în
ecranul
Inbox
vedem
banii
încasa
ț
i
de
către
proprietar,
în
ecranul
Trips
vedem
banii

plăti
ț
i de către client.

Profile
Fragment

în
cazul
în
care
nu
suntem
autentifica
ț
i
va
apărea
un
buton
care
ne
va
duce

la
ecranul
de
autentificare.
De
asemenea,
în
acest
caz
sunt
permise
toate
opera
ț
iile,
mai
pu
ț
in
cele
de

rezervare servicii, iar ecranele Trips
ș
i Inbox vor fi goale.

În
cazul
în
care
există
un
utilizator
autentificat,
atunci
vor
apărea
serviciile
propuse
de
acesta

într-un
meniu
care
mai
are
op
ț
iunile
deconectare
de
la
cont,
ș
tergere
cont
ș
i
altele
clasice.
În
plus
va

mai
apărea
în
partea
de
sus
o
bară
cu
numele
ș
i
poza
utilizatorului
curent.
Poza
se
poate
schimba

oricând prin simpla apăsare în locul unde este localizată aceasta.

35

Fig. 41 : Ecranul pentru profil

La
apăsarea
op
ț
iunii
de
ș
tergere
cont
va
apărea
un
dialog
care
va
întreba
utilizatorul
dacă
este

sigur

dore
ș
te

facă
acest
lucru.
În
cazul
unui
răspuns
afirmativ
atunci
datele
utilizatorului
din

aplica
ț
ie vor fi
ș
terse.

Cele
trei
activită
ț
i
pentru
afi
ș
area
serviciilor
oferite
de
utilizator:
Accommodation,
Tour
ș
i

Parkings
listings
sunt
foarte
asemănătoare,
ele
având
în
spate
aceea
ș
i
logică,
dar
tabele
(date)
ș
i

adaptor pentru componenta RecyclerView diferit.

RecyclerView

este
o
componentă
asemănătoare
unei
liste,
mult
mai
capabilă
însă
:
se
poate

actualiza
în
timp
real,
afi
ș
ează
oricâte
obiecte,
calculează
singură
dimensiunile
de
care
are
nevoie,

se
poate
personaliza
ș
i
adap ta
u
ș
or.
În
fi
ș
ierul
XML
se
declară
ca
o
componentă
obi
ș
nuită,
este
însă

nevoie
de
o
bibliotecă
separată
care
se
importă
în
fi
ș
ierul
Gradle
-mai
multe
detalii
despre
acest

lucru în sub-capitolul dedicat.

Fig. 42 : RecyclerView în fi
ș
ierul XML

36

În
fi
ș
ierul
Java
se
declară
ca
un
element
obi
ș
nuit
XML,
dar
pentru
a
func
ț
iona
trebuie

se

seteze
un
adaptor
ș
i
eventua l
un
Layout
Manager.
De
fiecare
dată
când
setăm
adaptorul
se
apelează

metoda setAdapter()
ș
i se pa sează ca argument tipul de adaptor.

Pentru
fiecare
listă
în
parte
se
poate
crea
un
adaptor
separat
dacă
modul
în
care
sunt
afi
ș
ate

datele
din
listă
este
diferit.
În
solu
ț
ia
prezentată
un
adaptor
are
în
constructor
doi
parametrii
:

contextul (activitatea) de unde este apelat
ș
i lista de obiecte care trebuie afi
ș
ată.

În

adaptor

setăm
layout-ul
pentru
obiectele
din
listă
,
luăm
valorile
din
listă
ș
i
le
atribuim

elementelor
de
UI.
Mai
exact
în
metoda
onCreateViewHolder()
se
setează
ș
ablonul
pentru
afi
ș
are,

în
metoda
onBindViewHolder()
se
ia
fiecare
obiect
în
parte
folosind
metoda
get()
ș
i
parametrul

position
din
metoda
amintită
pentru
a
determina
obiectul
în
cauză.
Tot
în
cadrul
metodei
de
“bind”

se
setează
ș
i
ac
ț
iunea
care
corespunde
unui
click
pe
celulă,
deoarece
e
nevoie
de
parametrul
position

mai sus amintit pentru a determina care celulă a fost selectată.

Fig. 43 : onBindViewHolder() exemplu

Pentru
exemplificarea
unui
ecran
în
care
sunt
listate
servicii
oferite
de
către
utilizator
vom

folosi op
ț
iunea “Tour listing s” din meniul ecranului “Profile”, amintit mai sus.

37

Fig. 44 : Ecranul Tour Listings
ș
i exemplu de folosire a RecyclerView

Tot
în
cadrul
acestui
ecran
este
folosit
ș
i
Floating
Action
Button,
în
josul
ecranului
în
partea

dreaptă.
Este
un
element
relativ
nou
ș
i
un
acord
nescris
legat
de
el
este
acela

se
folose
ș
te
la

adăugare.
În
cazul
acesta
îl
folosim
pentru
adăugarea
unui
tur
nou,
iar
în
celelalte
activită
ț
i
la

adăugare
de
cazare,
respectiv
parcare.
Particularitatea
sa
este

tot
timpul
se
află
deasupra

celorlalte elemente de UI, în rest el fiind declarat
ș
i folosit ca un buton obi
ș
nuit.

Dacă
apăsăm
pe
o
pe
o
celulă
se
va
deschide
o
nouă
activitate,
în
care
este
desfă
ș
urat
un
tur,
o

cazare
sau
o
parcare.
Fiecare
dintre
cele
3
ecrane
sunt
diferite,
având
nevoie
de
detalii
ș
i
mod
de

expunere
diferite.
La
apăsarea
unei
celule
toate
datele
sale
vor
fi
serializate
în
format
JSON,
iar
în

următoarea
activitate
se
de-serializează
folosind,
schimbul
de
date
are
loc
cu
ajutorul
unei
chei
de

identificare a valorii, un dic
ț
ionar.

Pentru
exemplificarea
unui
ecran
care
arată
detaliile
unui
serviciu
vom
folosi
un
serviciu
de

cazare,
fiind
cel
mai
amplu
având,
printre
altele
:
Google
Maps
unde
avem
loca
ț
ia
clădirii
ș
i
o

galerie de poze.

38

Fig. 45 : Ecran al unei unită
ț
i de cazare

Pentru
galeria
de
poze
s-a
folosit
o
bibliotecă
externă
[]
ș
i
s-a
adaptat
la
cerin
ț
ele
aplica
ț
iei.
Pe

fundal
gri
sunt
expuse
de
la
stânga
la
dreapta
:
numărul
maxim
de
persoane
acceptate,
numărul
de

camere,
numărul
de
paturi,
iar
la
final
avem
numărul
de
băi.
În
fig.
45
se
observă
faptul

în

captura
de
ecran
este
surprinsă
tranzi
ț
ia
între
două
imagini
care
fac
parte
din
galerie.
De
asemenea,

toate
imaginile
din
galerie
sunt
vizibile
în
format
de
miniatură
în
partea
de
jos
a
imaginilor
mari
din

galerie.

În
figura
următoare
pe
fundal
gri
este
trecut
proprietarul
serviciului,
iar
sub
harta
care
arată

locul de cazare este trecută loca
ț
ia exactă.

39

Fig. 46 : Partea de jos al unui ecran aferent unei unită
ț
i de cazare

Harta

este
interactivă
ș
i
se
poate
mi
ș
ca
pentru
a
vedea
ce
este
în
jur,
sau
se
poate
apăsa
pe

pin-ul
ro
ș
u
ș
i
vor
apărea
cele
2
op
ț
iuni
din
partea
dreaptă
a
ecranului
:
amândouă
reprezintă
direc
ț
ii

de la loca
ț
ia curentă la loca
ț
ia de pe hartă.

Ac
ț
ionarea
butonul
de
cumpărare
“Book”
func
ț
ionează
doar
dacă
există
un
utilizator

autentificat
ș
i
a
selectat
o
perioadă
pentru
rezervare.
Dacă
aceste
condi
ț
ii
sunt
îndeplinite
atunci

vom ajunge la ecranul de plată.

Payment
Activity


în
această
activitate
se
introduc
datele
finale
pentru
efectuarea
unei

rezervări
ș
i este afi
ș
ată suma care trebuie plătită.

Pentru
verificarea
datelor
este
folosită
o
func
ț
ie
care
asigură
un
minim
de
ajutor
ș
i
care

verifică
lungimea
caracterelor
introduse
în
casetele
corespunzătoare
numărului
de
pe
card,
a

CVV-ului sau a datei de expirare.

Sumele
din
partea
de
jos
a
paginii
sunt
preluate
cu
ajutorul
unui
BookingManager,
nefiind

nevoie să memorăm obiecte extra sau mai mari, salvând memorie
ș
i timp.

40

Fig. 47 : Ecranul pentru efectuarea plă
ț
ii
ș
i finalizarea rezervării

Administrarea rezervărilor

Este
făcută
cu
ceea
ce
am
denumit
ca
fiind
BookingManager,
un
model
care
re
ț
ine
datele

esen
ț
iale pentru afi
ș
area
ș
i gestionarea unei rezervări.

Fig.48 : Clasa BookingManager

41

Sunt
trecute
mai
multe
date
decât
sunt
necesare
unui
tip
de
rezervare
deoarece
acest
manager

este
folosit
pentru
toate
tipurile.
Acest
obiect
se
construie
ș
te
treptat,
adăugând
date
pe
măsură
ce

avansăm în aplica
ț
ie.

Fig. 49 : Exemplu de folosire a unui BookingManager

Există
o
tabelă
în
baza
de
date
pentru
BookingManager
în
care
se
scrie
de
fiecare
dată
când
se

efectuează
o
opera
ț
ie
de
rezervare.
Mai
apoi
se
cite
ș
te
când
este
nevoie

se
afi
ș
eze
o
cerere
de

rezervare pentru un serviciu sau când trebuie afi
ș
ată starea unei rezervări – ecranele Trips
ș
i Inbox.

Pentru
schimbarea
stării
unei
rezervări
se
modifică
valoarea
variabilei
mStatus
din
nodul

aferent ID-ului rezervării prin metoda updateChildren() din biblioteca Firebase.

Listarea
tuturor
parcărilor,
tururilor
sau
a
locurilor
de
cazare
se
face
în
cadrul
a
trei
activită
ț
i

foarte
asemănătoare,
dar
cu
adaptor
diferit,
care
se
accesează
prin
intermediul
CardView-urilor
din

activitatea principală, Home. Luăm ca exemplu listarea
ș
i filtrarea tururilor.

O
primă
filtrare
se
face
după
ID-ul
proprietarului,
fiind
ilogic
ca
cineva

încerce

cumpere

propriul
tur
ghidat.
Pentru
prevenirea
erorilor
s-au
acoperit
ș
i
cazurile
în
care
nu
există
un
utilizator

autentificat,
iar
acesta
va
vedea
toate
tururile
ș
i
va
putea
folosi
ș
i
filtrele,
dar
nu
va
putea
cumpăra

până după autentificare.

Pentru
ecranele
de
listare
bara
de
navigare
s-a
schimbat
în
sensul
în
care
apare
ș
i
un
buton

care
va
deschide
activitatea
de
filtrare.
Între
cele
două
activită
ț
i
se
va
face
un
schimb
de
informa
ț
ii,

cele
introduse
în
cea
de
filtrare
vor
determina
care
dintre
tururile
existente
vor
fi
afi
ș
ate,
iar
la
o
altă

apăsare
a
butonului
de
filtrare
se
vor
afi
ș
a
valorile
după
care
s-a
făcut
filtrarea
anterioară
pentru
o

mai bună experien
ț
ă de utiliz are.

42

Fig. 50 : Ecran pentru listarea tururilor disponibile după filtrare

Fig. 51 : Ecran de filtrare pentru tururi

43

Datele pentru filtrare sunt trimise sub forma unui tablou de valori care este desfă
ș
urat
ș
i

interpretat în activitatea de listare. Pentru trimiterea valorilor spre folosire trebuie să apăsăm

butonul din dreapta-jos care are o lupă, pentru a face aplica
ț
ia mai intuitivă,
ș
i care ne va duce la

ecranul de listare cu valorile dorite în tabloul men
ț
ionat. Apăsarea butonului din bara de

naviga
ț
ie nu va însemna o n ouă filtrare.

În bara de navigare se va afi
ș
a tot timpul pasul curent pentru a facilita navigarea prin

aplica
ț
ie.

Din ecranul care listează un tip de servicii oferite de către utilizator prin Floating Action

Buton-ul amintit mai sus se ajunge la o serie de ecrane care permite introducerea de noi

oportunită
ț
i. Desigur, de pe ecranul cu tururi vom putea adăuga noi tururi, de pe ecranul cu

oferte de cazare vom putem pune noi loca
ț
ii, iar din cel de parcări vom adăuga noi locuri de

parcare.

Pentru exemplificare vom lua în calcul adăugarea unei noi loca
ț
ii de cazare, fiind cea mai

amplă opera
ț
iune dintre c ele trei posibile.

Fig. 52 : Primul ecran pentru adăugarea unei case

Toate datele sunt adăugate într-o variabilă statică, foarte asemănătoare cu modelul

obiectului care se vrea a se adăuga. În fiecare ecran se adăugă noi informa
ț
ii, iar dacă se

dore
ș
te să se modifice pe parcurs se poate merge pe ecranele anterioare folosind butonul de

navigare din bara de navigare.

44

Din primul ecran se preia numele anun
ț
ului dintr-o casetă Edit Text, pentru celelalte date

afi
ș
ate pe ecran folosindu -se un element numit “Spinner “care este varianta de casetă de tip

“dropdown” bine-cunoscut în domeniu. Valorile din spinner trebuie ini
ț
ializate cu un

ArrayAdapter<Obiect> unde Obiect reprezintă tipul de date care va apărea în listă, iar pe

lângă această listă în adaptor se declară
ș
i layout-ul, adică modul în care vor fi afi
ș
ate aceste

date.

Fig.53 : Folosirea variabilei statice în al 2-lea ecran de adăugare cazare

45

Fig.54 : Al 2-lea ecran de adăugare cazare

În
cel
de-al
doilea
ecran
de
cazare
se
stabile
ș
te
loca
ț
ia
pe
hartă
printr-o
simplă
apăsare
pe

hartă.
S-a
folosit
un
serviciu
de
stabilire
a
loca
ț
iei,
care
este
vizibil
în
figura
54.
La
fiecare

pozi
ț
ionare
a
pin-ului
pe
hartă,
adică
la
fiecare
apăsare
pe
hartă
se
vor
completa
datele
găsite

în
zonă
:
în
prima
casetă
text
va
fi
trecută
toată
adresa,
în
a
doua
casetă
este
codul
po
ș
tal,
iar

în
ultima,
jude
ț
ul
sau
regiunea
administrativă.
În
cazul
în
care
nu
sunt
corecte
datele
sau
nu

sunt
completate
deoarece
nu
au
fost
găsite
utilizatorul
va
putea

introducă
manual
datele

sau să le modifice pe cele existente.

Acest
mod
interactiv
de
introducere
a
datelor
salvează
timp
semnificativ
în
momentul

adăugării
unui
nou
obiect,
iar
adresa
poate
fi
exactă
având
inclusiv
numărul
ș
i
numele

loca
ț
iei.

46

Fig.55 : Al 3-lea ecran de adăugare cazare

În
cel
de
al
3-lea
ecran
se
salvează
în
2
casete
text,
dintre
care
una
are
proprietatea

inputType="textMultiLine"
pentru
a
permite
o
afi
ș
are
pe
mai
multe
rânduri.
Pentru
a
nu

acoperi
tot
ecranul
se
folose
ș
te
ș
i
proprietatea
“lines”
cu
valoare a
8,
în
eventualitatea
în
care

vor fi mai mult de 8 rânduri introduse atunci se va putea mi
ș
ca caseta text în sus sau în jos.

47

Fig. 56 : Ecran 4 înainte de adăugare poze

În
ultimul
ecran
se
vor
încărca
pozele
în
Firebase
ș
i
vor
fi
afi
ș
ate
pe
ecran
după
încărcarea

lor.
Pentru
acest
lucru
este
necesar
ca
la
apăsarea
butonului
“Upload
photos”

se
deschidă
o

galerie
cu
poze.
Acest
lucru
este
posibil
prin
deschiderea
unui
ecran
nou
care

arate
fi
ș
iere

de
tipul
“image/*”,
adică
orice
tip
de
imagini.
Proprietatea
“extra_allow_multiple”
face

posibilă
selectarea
mai
multor
imagini,
iar
“action_get_content”
specifică
faptul

se
dore
ș
te

să se extragă con
ț
inut din noua activitate.

Fig.56 : Modalitatea de a deschide o galerie
ș
i de a selecta mai multe imagini

O
activitate
de
tipul
celei
de
sus
este
exemplificată
în
următoarea
figură.
Observăm

interfa
ț
a
este
una
prieten oasă
:
în
partea
stângă
este
afi
ș
at
numărul
de
imagini
selectate,
iar
în

dreapta este butonul de salvare.

48

Fig.58 : Activitatea de selectare poze pentru cazare

După
selectarea
imaginilor
se
ob
ț
ine
calea
către
unde
acestea
sunt
salvate
în
telefon
într-un

vector
care
salvează
obiecte
de
tip
“Uri”.
Mai
apoi
se
ia
fiecare
URI
(Uniform
Resource

Identifier)
din
vector
ș
i
se
efectuează
opera
ț
ii
de
urcare
în
servici ul
Firebase
Storage.
Pentru
a

evita
suprascrierea
datelor
la
salvarea
unor
imagini
noi
se
folose
ș
te
aceea
ș
i
metodă
ca
la

salvarea
imaginilor
de
profil
:
pentru
fiecare
fi
ș
ier
local
care
se
dore
ș
te
a
fi
urcat
în
Storage
se

schimbă
numele
curent
cu
data
ș
i
ora
curentă
în
milisecunde
ș
i
se
adăuga
extensia
originală.

Această
metodă
este
folosită
în
multe
aplica
ț
ii
fiind
foarte
greu

se
ob
ț
ină
două
fi
ș
iere
cu

nume
ș
i extensii identice.

Următorul
pas
este
acela
de
a
urca
fiecare
imagine
în
Storage,
iar
mai
apoi
de
a
ob
ț
ine

URL
(Uniform
Resource
Locator)
ș
i
salvarea
sa
în
lista
obiectului
de
cazare.
Fiecare
obiect

are
o
astfel
de
listă
care
memorează
loca
ț
iile
din
Storage
,
prin
link-uri
de
descărcare,
a

imaginilor care apar
ț
in lui.

Un
ultim
pas
pentru
completarea
ecranului
îl
reprezintă
afi
ș
area
imaginilor
după
ce
au
fost

încărcate în serviciul Firebase cu ajutorul unui RecyclerView.

Butonul
“Finish”
va
completa
ultimele
date
necesare
pentru
adăugarea
unui
nou
serviciu

de cazare, va duce utilizatorul la ecranul principal
ș
i va afi
ș
a un mesaj de succes.

49

Fig. 59 : Ecranul 4 după încărcarea pozelor selectate

Noul
obiect
se
poate
vedea
imediat
după
adăugare
în
lista
de
servicii
oferite
sau
în
ecranele

de căutare de astfel de servicii.

3.6. Biblioteci utilizate

Toate biblioteci folosite se găsesc într-un singur fi
ș
ier : build.gradle (modulul aplica
ț
ie).

Fiecare linie înseamnă o nouă bibliotecă, cele subliniate cu galben semnalând faptul că

există noi versiuni disponibile. La trecerea cu mouse-ul peste aceste linii galbene vor fi

afi
ș
ate versiunile mai noi disponibile. Actualizarea se face relativ u
ș
or fiind necesar

schimbarea numărului sau numelui bibliotecii respective, iar apoi se apasă butonul de

sincronizare. Trebuie avut însă grijă la bibliotecile care
ț
in de alte biblioteci sau care au

referin
ț
e în alte biblioteci deoarece versiunile trebuie să fie compatibile.

Orice aplica
ț
ie are câteva biblioteci ini
ț
iale, de bază, fără de care nu poate func
ț
iona, cum

sunt appcompat -v7, support-v4 sau support-compat.

În continuare vom discuta despre bibliotecile care aduc func
ț
ionalită
ț
i extra, fie ele oferite

de furnizori cunoscu
ț
i precum Google sau de diver
ș
i dezvoltatori din mediul online. Astfel de

biblioteci se găsesc sub formă de proiecte în Repository-uri răspândite pe internet sau pe

site-uri oficiale.

50

Fig. 60 : Fi
ș
ierul gradle cu toate bibliotecile folosite

Bibliotecile Firebase : Core, Auth, Database, Storage. De biblioteca Firebase Core este

nevoie în orice aplica
ț
ie care folose
ș
te serviciile platformei cu acela
ș
i nume, indiferent de

serviciu.

Biblioteca Firebase Auth este folosită pentru serviciile de autentificare din platformă
ș
i

con
ț
ine, printre altele, func
ț
iile signInWithEmailAndPassword() pentru autentificare
ș
i pentru

înregistrare,

createUserW ithEmailAndPassword().

Firebase Database oferă accesul la serviciile de bază de date în timp real
ș
i con
ț
ine

func
ț
iile care efectuează o pera
ț
iile. De asemenea, această bibliote că este responsabilă
ș
i

pentru “listeners”, cei care supraveghează tot ce se întâmplă cu baza de date.

Firebase Storage ne permite să operăm cu baza de date de tip blob, destinată stocărilor de

obiecte de dimensiuni mari, de exemplu, poze.

Bibliotecile pentru lucrul cu imaginile sunt Glide
ș
i ScrollGalleryView. Glide este

recunoscută la un nivel mai oficial în timp ce cea de a doua este preluată de pe GitHub
ș
i are

la bază Glide, dar
ș
i alte d ouă biblioteci asemănătoare. Dacă prima dintre cele amintite se

ocupă de o singură imagine, cea de a doua reprezintă o galerie de imagini
ș
i chiar
ș
i video-uri.

Pentru a putea folosi hăr
ț
ile am introdus biblioteca play-services-maps
ș
i un plug-in pentru

Google Services.

Restul bibliotecilor sunt biblioteci comune pentru o aplica
ț
ie Android, inclusiv gson pentru

serializarea
ș
i deserializar ea în format Json.

51

3.7. Bază de date

Baza
de
date
este
făcută
pe
platforma
Firebase,
serviciu
despre
care
am
discutat
mai
la

începutul
lucrării.
Este
un
mijloc
modern
ș
i
practic
de
lucru
pentru
un
volum
mare
de
date
ș
i

de tipuri diferite. Se bazează pe noduri
ș
i fi
ș
iere de tip Json.

JSON
este
un
format
u
ș
or
pentru
schimbul
de
date,
u
ș
or
de
scris
ș
i
de
citit
pentru
oameni.

Este un format foarte răspândit ce se bazează pe cheie-valoare.

Fig. 61 : Exemplu de JSON din baza de date

Ce
este
special
la
această
bază
de
date
este
faptul

modificările
sunt
urmărite
în

permanen
ț
ă
ș
i
atunci
când
are
loc
una
se
modifică
ș
i
în
locurile
unde
e
relevant.
Astfel
se

reu
ș
e
ș
te afi
ș
area ime diată a unor servicii noi adăugate fără interogări asupra bazei de date.

Chiar
ș
i
modul
de
interogare
este
diferit
datorită
nodurilor
:
nu
se
poate
selecta
o
singură

coloană
după
care

se
caute,
ci
se
iau
obiectele
la
rând,
se
transformă
din
format
JSON
în

obiect de tipul căutat
ș
i apoi se fac opera
ț
ii.

Fig. 62 : Tabelele din baza de date

52

Tocmai
faptul

se
bazează
pe
format
JSON
ajută
la
stocarea
datelor
fără
a
se
pune

problema
de
ce
tip
de
date
stocăm,
problemă
care
se
ridică
la
o
bază
de
date
de
tip
SQL.

Toate
datele
sunt
salvate
sub
formă
de
ș
iruri
de
caractere,
iar
mai
apoi,
la
deserializarea
lor

în
cadrul
aplica
ț
iei
ele
sunt
convertite
la
un
obiect
dorit.
În
acel
moment
pot
apărea

probleme în cazul în care căutăm chei, adică nume de coloane, care nu există.

Identificarea în această bază de date se face, de regulă, după o cheie unică, un ID.

Pentru
a
scrie
sau
citi
dintr-o
anumită
tabelă
trebuie

ob
ț
inem
o
referin
ț
ă
către
acea

tabelă,
acest
lucru
îl
putem
face
prin
următoarea
linie
de
cod
în
cadrul
unei
clase
Java
:

FirebaseDatabase.getInstance().getReference().
După
ce
se
ob
ț
ine
referin
ț
a
putem
adresa

diferite
noduri
adăugând
secven
ț
a
.child("Nume
nod")
la
final,
iar
dacă
dorim

ajungem
la

nivel
mai
jos
în
nod
adăugăm
secven
ț
a
.child("Nume
nod")
ori
de
câte
ori
este
nevoie,
până

la
nivel
de
coloană.
Este
o
bază
de
date
în
timp
real
datorită
“listeners”

func
ț
ie
care

observă
ce
se
întâmplă
cu
valorile
din
tabelă
ș
i
trimit
mai
apoi
schimbările
sau
chiar
toată

tabelă, după cum este cazul.

Fig. 63 : Exemplu de folosire a unui listener

Pentru
a
veni
cât
mai
bine
în
întâmpinarea
cerin
ț
elor
unui
dezvoltator
există
trei
tipuri
de

astfel
de
func
ț
ii
:
ValueEventListener

observă
ș
i
trimite
date
la
fiecare
modificare
din

tabelă,
SingleEventListener

preia
ș
i
trimite
datele
o
singură
dată,
ChildEventListener

preia
ș
i trimite date d oar la adăugarea unui nou nod în tabelă.
În
cadrul
aplica
ț
iei
au
fost

folosite primele două.

Preluarea
datelor
se
face
în
metoda
onDataChange(DataSnapshot
dataSnapshot)
unde

DataSnapshot
reprezintă
un
fi
ș
ier
JSON
cu
datele
din
tabelă
la
momentul
interogării.
De

obicei
se
parcurg
toate
obiectele
din
snapshot
ș
i
se
convertesc
la
clasa
dorită
prin
metoda

getValue(Clasa.class), parametrul fiind clasa respectivă.

Pentru
a
scrie
în
baza
de
date
se
memorează
toate
datele
într-un
obiect,
iar
mai
apoi

folosind
func
ț
ia
setValue(),
cu
parametrul
fiind
respectivul
obiect,
pe
o
referin
ț
ă
către
o

tabelă se va crea un nod nou reprezentând obiectul în format JSON.

53

Există
ș
i
variant a
de
modificare
a
unor
date
existente,
acest
lucru
făcându-se
prin

intermediul
func
ț
iei
updateChildren()
care
va
primi
ca
parametru
un
obiect
de
tip
HashMap

care
va
avea
cheia
numele
coloanei,
iar
valoarea
va
fi
cea
pe
care
dorim

o
înlocuim
în

baza de date.

Firebase
Storage
func
ț
ionează
foarte
asemănător
Database,
fiind
ș
i
aici
nevoie
de
o

referin
ț
ă
către
loca
ț
ia
unde
se
salvează
date.
Aici
însă
se
creează
foldere
ș
i
fi
ș
iere,
nu
noduri.

Deoarece
fi
ș
iere
salvate
aici
sunt
considerabil
mai
mari
fa
ț
ă
de
cele
din
baza
de
date
se

folose
ș
te
un
task
de
tipul
StorageTask
specific
Firebase
pentru
a
asigura
integritatea
datelor

ș
i faptul că acestea a jung la destina
ț
ie.

Fig.64 : Modul de organizare în Firebase Storage

Fig. 65 : Exemplu de utilizare a Firebase Storage

54

În
imaginea
de
mai
sus
se
observă
task-ul
despre
care
s-a
discutat
ș
i
clasicul

CompleteListener()
specific
Firebase
care
se
execută
la
încheierea
cu
succes
a
unei
opera
ț
ii

legate de baza de date.

3.8. Testarea aplica
ț
iei

În
dezvoltarea
aplica
ț
iilor
mobile
este
o
bună
practică
testarea
în
timp
real,
pe
dispozitiv

fizic.
Acest
lucru
este
ș
i
foarte
u
ș
or
de
efectuat
fiind
vorba
despre
un
dispozitiv
care
este
tot

timpul la îndemână
ș
i nu despre o antenă radio, de exemplu.

La
fiecare
ecran
nou,
la
fiecare
nouă
func
ț
ionalitate
dezvoltată
sau
la
orice
schimbare
s-a

făcut
testarea
pe
dispozitiv
fizic.
Func
ț
ia
Instant
Run
men
ț
ionată
anterior
este
creată
special

pentru
a
permite
astfel
dezvoltarea
iterativă,
în
care
se
văd
u
ș
or
gre
ș
elile
ș
i
se
corectează

repede.
Erorile
au
fost
eliminate
astfel
imediat
când
au
apărut.
Pentru
fiecare
nouă

func
ț
ionalitate
s-a
creat
o
ramură
nouă
pe
Git,
iar
la
final,
după
dezvoltarea
ș
i
testarea

ecranului s-a unit cu celelalte func
ț
ionalită
ț
i.

Au
fost
efectuate
teste
ș
i
de
către
alte
persoane,
care
nu
erau
familiare
cu
aplica
ț
ia,
iar
în

urma sugestiilor venite din partea lor am îmbunătă
ț
it experien
ț
a utilizatorului.

55

4. UTILIZAREA APLICA
Ț
IEI

4.1. Cerin
ț
e de sistem

Aplica
ț
ia func
ț
ionează doar pe dispozitive mobile care rulează ca sistem de operare

Android. Este necesară o versiune Android 6.0 sau mai nouă
ș
i minim 20MB memorie.

Aceste specifica
ț
ii permit rularea aplica
ț
iei pe cel pu
ț
in 70% dintre dispozitivele ce au acest

sistem de operare.

Fig. 66 : Distribu
ț
ia telefoanelor după versiunea sistemului de operare, mai 2019[5]

Pentru func
ț
ionarea ap lica
ț
iei este nevoie de o conexiune stabi lă la internet.

4.2. Pornirea aplica
ț
iei

Se face clasic prin apăsarea pictogramei corespunzătoare aplica
ț
iei din meniul principal al

telefonului.

Fig. 67 : Pictograma aplica
ț
iei

Primul
ecran
care
se
va
deschide
este
ecranul
principal
ș
i
vor
fi
disponibile
fragmentele

Home,
care
va
permite
căutarea
de
oferte
ș
i
Profile
care
va
avea
un
buton
de
autentificare.

56

Dacă
se
încearcă
rezervarea
utilizatorul
va
fi
redirec
ț
ionat
către
ecranul
de
autentificare
ș
i
se

va afi
ș
a un mesaj.

Fig. 68 : Încercarea de rezervare fără a fi autentificat

După
autentificare
devin
disponibile
fragmentele
Trips,
Inbox,
iar
în
fragmentul
Profile
va

apărea un meniu cu mai multe op
ț
iuni.

4.3. Autentificare
ș
i înregistrare

Pentru
accesul
la
toate
func
ț
ionalită
ț
ile
aplica
ț
iei
se
face
autentificarea
introducând

email-ul
ș
i
parola
cu
care
s-a
creat
contul.
În
cazul
în
care
utilizatorul
nu
are
un
cont
se
poate

înregistra
foarte
simplu
:
din
ecranul
de
autentificare
se
apasă
op
ț
iunea
din
josul
ecranului

“No account? Register here!” care duce către ecranul de înregistrare.

După
completarea
datelor
cerute
în
ecranul
de
înregistrare
utilizatorul
trebuie

intre
pe

adresa
de
email
introdusă
ș
i

a
ș
tepte
un
email
de
confirmare
a
contului
din
partea
aplica
ț
iei


acest
lucru
este
anun
ț
at
printr-un
mesaj
similar
celui
care
informează
utilizatorul

este

necesar să fie autentificat pentru rezervare.

Mesajele
apar
în
partea
de
jos
a
ecranului
ș
i
sunt
acolo
pentru
câteva
secunde,
ele
poartă

denumirea de Toast Messages.

57

Fig. 69 : Mail de confirmare a adresei

Fig. 70 : Mesaj de confirmare email

4.4. Adăugare date în profil

4.4.1. Adăugare poză

Există o poză de profil generică care se poate schimba din ecranul Profile prin simpla

apăsare a imaginii
ș
i selec tarea uneia noi din galeria de imagini a telefonului.

4.4.2. Adăugare servicii

În meniu există trei servicii : tur ghidat, cazare sau loc de parcare
ș
i un utilizator poate

adăuga oricâte servicii o dată ce are un cont valid. Pentru acest lucru trebuie să selecteze din

58

meniu op
ț
iunea de listare a tuturor serviciilor de un anume tip oferite de către el. În acel ecran

va putea de asemenea să adauge un serviciu nou de acela
ș
i tip prin apăsarea butonului din

partea dreapta-jos a ecranului.

Fig. 71 : Butonul pentru adăugare tururi

Apăsarea butonului ne va duce la primul ecran pentru adăugarea unui nou serviciu.

Pentru fiecare serviciu ecranele sunt diferite
ș
i în număr diferit, în func
ț
ie de complexitate.

Fig.72 : Primul ecran la adăugare tur
Fig. 73 : Primul ecran la adăugare

parcări

59

4.4.3.
Ș
tergere sau ie
ș
ire din cont

Tot
în
cadrul
meniului
amintit
mai
sus
există
op
ț
iunile
de
Sign
Out
(ie
ș
ire
din
cont)
ș
i

Delete account –
ș
tergere cont după confirmarea acestui lucru.

Fig.74 : Ecranul de profil cu meniul aferent

4.5. Căutare
ș
i filtrare

Din ecranul principal, în fragmentul Home sunt afi
ș
ate op
ț
iunile de căutare servicii sau

vizualizare statistici. La selectarea unui serviciu de căutare ne vor fi afi
ș
ate o parte dintre

serviciile disponibile spre achizi
ț
ie. Se recomandă folosirea filtrului din partea dreaptă a barei

de navigare pentru ob
ț
inerea unor rezultate mai exacte.

60

Fig.75 : Înainte de filtrare
Fig. 76 : Datele de filtrare

Fig. 77 : După filtrare

61

4.6. Vizualizarea serviciului în detaliu

Pentru a vedea toate detaliile relevante ale unui serviciu se apasă oriunde în interiorul unei

celule din listă.

Fig. 78 : O parte dintre detaliile unei cazări

4.7. Achizi
ț
ionarea unui serviciu

În partea de jos a ecranului cu detalii se află butonul de rezervare, dar în prealabil trebuie

selectate date pentru a se verifica disponibilitatea. Acest lucru se face din activitatea de

filtrare. Ultimul lucru de făcut înainte de finalizarea unei rezervări este introducerea detaliilor

legate de plată.

62

Fig. 79 : Ecranul de plată

4.8. Starea unei rezervări

Pentru a verifica starea unei rezervări există ecranul Trips unde este afi
ș
ată aceasta, care

poate fi “Pending” – în a
ș
teptare, “Denied” – respinsă, ”Accepted” – acceptată ,”Incoming” –

stare disponibilă doar pentru serviciile oferite de către utilizatorul curent care au fost

acceptate
ș
i urmează să v ină. De asemenea, pe acest ecran sunt trecute
ș
i alte date relevante

cum ar fi titlul serviciului, perioada de timp selectată, pre
ț
ul plătit sau suma primită
ș
i

numărul de telefon.

Fig.80 : Ecranul Trips

63

Pe ecranul Inbox se administrează cererile de rezervare pentru serviciile utilizatorului.

Acesta are op
ț
iunile acce ptare
ș
i respingere rezervare, iar celelalt e detalii sunt identice cu cele

de pe ecranul Trips.

Fig.81 : Rezervare în a
ș
teptare

64

6. CONCLUZII

Dezvoltarea acestei aplica
ț
ii s-a dovedit a fi foarte complexă, pe parcursul lucrului la ea

întâmpinând mai multe obstacole, atât tehnice, cât
ș
i din punct de vedere al organizării

datelor. Un software de asemenea dimensiuni are multe func
ț
ionalită
ț
i diferite care pot

determina poten
ț
ialii clien
ț
i să folosească aplica
ț
ia.

Faptul că un utilizator poate fi client
ș
i proprietar cu un singur cont reprezintă un avantaj

din punct de vedere al UX (user experience), tranzi
ț
ia între cele două roluri fiind practic

insesizabilă.

Ideea ini
ț
ială a aplica
ț
iei a fost de a combina serviciile de caza re cu cele de tur ghidat, dar

pe parcurs, după mai multe discu
ț
ii despre aplica
ț
ie cu diverse persoane, am hotărât că un

serviciu de parcare ar fi bine-venit. După alte discu
ț
ii am realizat faptul că acest serviciu de

parcare ar putea reprezenta defapt rampa de lansare a aplica
ț
iei într-o pia
ț
ă foarte dezvoltată

ș
i competitivă cum este c ea a turismului.

În final am realizat o solu
ț
ie completă pentru vacan
ț
e pe cont propriu oferind servicii de

cazare, parcare, ghid turistic
ș
i administrator de rezervări. În continuare se vor dezvolta alte

servicii auxiliare cum ar fi închiriere de ma
ș
ini
ș
i biciclete sau rezervări la diferite

restaurante.

65

7. BIBLIOGRAFIE

[1] –

https://www.e-unwto .org/doi/pdf/10.18111/9789284419876

[2] –

https://hackernoon.com/top-3-most-popular-programming-languages-in-2018-and-their-

annual-salaries-51b4a7354e06

[3] –

https://medium.com/ google-developers/instant-run-how-does-it-work-294a1633367f

[4] –

https://developer.and roid.com/guide/components/activities/activity-lifecycle

[5] –

https://developer.and roid.com/about/dashboards

[6] –

https://developer.android.com/guide/components/activities/intro-activities

[7] –

https://developer.android.com/guide/navigation/navigation-principles

[8] –

https://developer.android.com/guide/components/intents-filters

[9] –

https://developer.android.com/

[10] –

https://firebase.google.com/docs/auth/android/manage-users

[11] –

https://firebase.google.com/docs/database/android/read-and-write

[12] –


Neil Smyth, Androi d Studio 3.0 Development Essentials, 2017

[13] –

https://firebase.google.com/docs/database/admin/retrieve-data

[14] –

https://developers.google.com/maps/documentation/android-sdk/map

[15] –

https://developer.android.com/reference/android/location/Geocoder

[16] – Ian Darwin, Android Cookbook, 2017

[17] – Gerardus Blokdyk, Firebase the ultimate step-by-step guide, 2018

66

Similar Posts