.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
să
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
să
î
ș
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
să
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
că
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
să
pot
organiza
pe
cont
propriu
ș
i
în
detaliu
vacan
ț
ele,
însă
de
multe
ori
trebuie
să
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
să
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
să
î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
să
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
să
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
să
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
să
facem
cast
din
tipul
de
dată
respectiv
în
clasa
care
este
defapt
reprezentată.
Pentru
a
putea
face
opera
ț
iile
de
mai
sus
trebuie
să
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
că
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
să
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
că
pentru
exersarea
dezvoltării
de
aplica
ț
ii
folosind
API-uri
din
platformă
nu
vom
ajunge
efectiv
să
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
să
avem
instalată
extensia
(Plug-in)
Google
Play
Services,
iar
mai
apoi
fiecare
serviciu
în
parte.
Versiunile
de
servicii
ș
i
Google
Play
trebuie
să
corespundă
între
ele,
dar
nu
trebuie
să
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
să
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
să
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
să
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
că
oferă
o
interfa
ț
ă
mai
prietenoasă cu utilizatorul pentru folosirea sistemelor distribuite de control al versiunilor.
Pentru
a
putea
folosi
GitHub
trebuie
să
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
să
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
să
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
că
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
să
coincidă.
De
exemplu,
pentru
biblioteca
folosită
pentru
componenta
RecyclerView
trebuie
să
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
că
î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
că
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
să
folosim
bine-cunoscutele
breakpoint-uri
ș
i
trebuie
să
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
să
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
să
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
să
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
să
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
că
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
să
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
că
dore
ș
te
să
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
să
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
că
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
că
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
că
î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
să
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
să
încerce
să
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
să
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”
să
se
deschidă
o
galerie
cu
poze.
Acest
lucru
este
posibil
prin
deschiderea
unui
ecran
nou
care
să
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
că
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
că
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
să
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
că
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
să
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
că
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
să
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
să
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
să
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
să
intre
pe
adresa
de
email
introdusă
ș
i
să
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
că
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
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: .l. Dr. Ing. Raul ROBU [610718] (ID: 610718)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
