Development of Mobile Applications in Java Android
1.
Dispozitive și Aplicații
Mobile– curs 1
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
2.
Agenda
Obiectivul disciplinei
Prezentare disciplină (fișa disciplinei)
Elemente de conținut (structură curs/seminar)
Modalitatea de evaluare (curs + seminar)
Introducere/Dispozitive mobile
Sisteme de operare pentru dispozitive mobile
Android: concepte de bază
2
3.
Obiectivul disciplinei
Utilizareaeficientă a tehnologiilor mobile în societatea
informațională actuală
Asimilarea conceptelor specifice dezvoltării aplicațiilor
destinate dispozitivelor mobile
Însușirea modelului de programare pentru platforma
Android
Dezvoltarea capacității studenților de rezolvare a
problemelor practice prin dezvoltarea de aplicații
eficiente pentru platforma Android
3
4.
Prezentare disciplină
Site-uldisciplinei este http://pdm.ase.ro. Aici va fi
publicat suportul de curs și informații de interes în zona
Avizier.
Suportul de seminar va fi accesibil prin intermediul
https://github.com/cristianciurea/DAM2022.
4
5.
Elemente de conținut
1. Introducere/Dispozitive mobile; Sisteme de operare pentru dispozitive mobile;
Android: concepte de bază. Structura unui program; activități (1) – ciclul de viață
2. Activități (2), Fragmente, Mesaje (clasa Intent)
3. Structuri de navigare (elemente de design). Interfața grafică (1)
4. Interfața grafică (2) – tratarea evenimentelor, meniuri
5. Interfața grafică (3) – liste cu adaptor personalizat
6. Interfața grafică (4)
7. Operații asincrone și accesul la rețea (1) (HTTP, servicii Web)
8. Accesul la rețea (2): prelucrarea fișierelor XML și JSON
9. Stocarea persistentă a datelor (fișiere și baze de date SQLite/Room) (1)
10. Stocarea persistentă a datelor (fișiere și baze de date SQLite/Room) (2)
11. Baze de date online (Firebase Firestore)
12. Grafică bidimensională
13. Utilizarea Google Maps în aplicații. Servicii. Poziție geografică.
14. Furnizori de conținut. Receptori de mesaje. Testarea și validarea aplicațiilor.
Publicarea aplicațiilor în Google Play. 5
6.
Modalitatea de evaluare
Seminar(50% din nota finală):
Două probe practice, bazate pe materia predată până în acel moment.
Durata probei practice: 60 de minute (30% din nota finală):
Proba practică 1 (15% din nota finală) – săptămâna a 8-a
Proba practică 2 (15% din nota finală) – săptămâna a 12-a
Implicarea la seminar (implementări pe baza unor cerințe specifice
aplicației de la seminar) - 20% din nota finală (minim 2
evaluări/student/semestru)
Curs:
test grilă la calculator (50% din nota finală)
Condiție de intrare în examen:
obținerea a minim 20% din 50% punctaj seminar (echivalent nota 4 din 10
la seminar)
Condiție de promovare:
obținerea punctajului minim de promovare (nota 5) la examen.
6
7.
Abilități necesare
Experiențăde dezvoltare în Java (sau Kotlin)
Experiență de lucru în Android Studio (sau IntelliJ IDEA, sau
Eclipse cu ADT)
7
8.
Introducere/Dispozitive mobile
Telefoanemobile
Smartphone-uri
Tablete
cu/fără suport telefonie
PDA (Personal digital assistant)
fără suport telefonie
Dispozitive portabile (wearable)
cu/fără suport telefonie
8
Introducere/Dispozitive mobile
Arhitectura SoC
Procesor aplicații (CPU)
Interfața cu memoria
Procesor grafic (GPU)
Controlerul USB
Interfața serială
Controlerul Bluetooth
Controlerul WiFi
Interfața camerei foto
14
15.
Introducere/Dispozitive mobile
Procesoare deaplicații
Arhitectură RISC (Reduced Instruction Set Computer)
ARM (Advanced RISC Machine) v7, v8
32/64 biți
Frecvență de lucru: maxim 1.5-2.7 GHz
Unul sau mai multe nuclee
Consum redus de energie
15
Introducere/Dispozitive mobile
Conectivitate WWAN(GSM)
CSD – Circuit-Switched Data
HSCSD – High Speed Circuit-Switched Data
GPRS – General Packet Radio Services
EDGE – Enhanced Data Rates for Global Evolution
UMTS – Universal Mobile Telecommunications System
HSDPA – High Speed Downlink Packet Access
HSUPA – High Speed Uplink Packet Access
LTE – Long Term Evolution (radio frequency up to 6 GHz)
5G - fifth-generation technology standard for broadband cellular
networks (radio frequency 30 to 300 GHz)
22
Sisteme de operarepentru dispozitive mobile
Sisteme de operare proprii
feature phones
platforma de dezvoltare precum Java ME
Sisteme de operare pentru smartphones/tablete/portabile
posibilitatea dezvoltării de aplicații pe baza unui SDK
25
Android (Google)
Bada (Samsung)
Tizen (Tizen Association)
BlackBerry OS (BlackBerry/RIM)
BREW (Qualcomm)
Firefox OS (Mozilla)
iOS (Apple)
Linux Mobile
Palm OS/Garnet OS (Palm)
Symbian (Nokia)
webOS (HP)
Windows Phone/Windows CE/Windows Mobile (Microsoft)
27
Sisteme de operare pentru dispozitive mobile
Sisteme de operarepentru dispozitive mobile
Smartphone (2012 – 2014)
29
At the end of 2016:
• Android market share was 88%
• 99.6% of new smartphones run
Android or iOS
Sisteme de operarepentru dispozitive mobile
Aplicații destinate dispozitivelor mobile
Implementare
Aplicații Native
Aplicații Hibride
Cod binar interpretabil sau compilat JIT
Utilizează un nivel intermediar
Aplicații Web mobile
Cu/fără acces la rețea
33
34.
Sisteme de operarepentru dispozitive mobile
Android:
Proiect inițiat de Google
Nucleul bazat pe Linux 2.6.x/3.x
Aplicații bazate pe Java/Kotlin
Mașină virtuală proprie
Disponibilitate
Telefoane mobile, Tablete, Dispozitive portabile, Televizoare/STB, Auto
Telefoane mobile:
HTC One, Samsung Galaxy, Google Pixel, Huawei
Tablete:
Samsung Galaxy Tab, Google Nexus
34
35.
Sisteme de operarepentru dispozitive mobile
De ce Android?
Numărul mare de instalări existente
Limbajul Java/Kotlin
Posibilitatea de testare a aplicațiilor direct pe telefonul mobil
Varietatea dispozitivelor mobile
Costuri mai mici pentru dezvoltatori
Magazinul virtual Google Play (peste 2.5 mil. aplicații)
35
36.
Sisteme de operarepentru dispozitive mobile
36
Arhitectura platformei Android:
37.
Sisteme de operarepentru dispozitive mobile
37
Operating system API level
Android 2.2 (Froyo) 8
Android 2.3.3 – 2.3.7 (Gingerbread) 10
Android 3.x (Honeycomb) 11-13 (tablets)
Android 4.0.x (Ice Cream Sandwich) 14, 15
Android 4.1, 4.2, 4.3 (Jelly Bean) 16, 17, 18
Android 4.4 (KitKat) 19
Versiuni de Android:
38.
Sisteme de operarepentru dispozitive mobile
38
Operating system API level
Android 4.4W (Wear) 20
Android 5.0, 5.1.x (Lollipop) 21, 22
Android 6.0 (Marshmallow) 23
Android 7.0 (Nougat) 24, 25
Android 8.0 (Oreo) 26, 27
Android 9.0 (Pie) 28
Android 10 (Queen Cake) 29
Android 11 30
Versiuni de Android:
39.
Sisteme de operarepentru dispozitive mobile
39
Operating system API level
Android 12 (Snow Cone) 31, 32
Android 13 (Tiramisu) 33
Versiuni de Android:
Sisteme de operarepentru dispozitive mobile
Versiuni de Android în România (Mai 2019)
Conform StatCounter, sistemul de operare Android este pe primul loc în România,
din Iunie 2017 până în prezent, cu o cotă de piață de 80.26% în Mai 2019.
41
Other; 2,39%; 2%
Pie (API 28); 2,82%; 3%
KitKat (API 19 ); 5,73%; 6%
Lollipop (API 21, 22);
16,07%; 16%
Marshmallow (API 23 );
16,12%; 16%
Oreo (API 26, 27 ); 25,86%;
26%
Nougat (API 24, 25);
31,02%; 31%
Other
Pie (API 28)
KitKat (API 19 )
Lollipop (API 21, 22)
Marshmallow (API 23 )
Oreo (API 26, 27 )
Nougat (API 24, 25)
42.
Sisteme de operarepentru dispozitive mobile
42
Gingerbread (API 10); 0,30%
ICS (API 15); 0,30%
Jelly Bean (API 16, 17 și
18); 3,20%
KitKat (API 19); 6,90%
Lollipop (API 21 si 22);
14,50%
Marshmallow (API 23);
16,90%
Nougat (API 24 și 25);
19,20%
Oreo (API 26 și 27); 28,30%
Pie (API 28); 10,40%
Gingerbread (API 10)
ICS (API 15)
Jelly Bean (API 16, 17 și 18)
KitKat (API 19)
Lollipop (API 21 si 22)
Marshmallow (API 23)
Nougat (API 24 și 25)
Oreo (API 26 și 27)
Pie (API 28)
Versiuni de Android la nivel mondial (Mai 2019)
Sisteme de operarepentru dispozitive mobile
45
Android 12 Highlights
Dynamic Color. Responsive Motion. Conversation Widgets. Accessibility
Improvements. Safe. Mic & Camera Indicators and Toggles. Approximate
Location Permissions. Privacy Dashboard. Private Compute Core. Effortless.
Enhanced Gaming. Scrolling Screenshots.
46.
Sisteme de operarepentru dispozitive mobile
46
Android 13 Highlights
Android 13 features and changes list
•Camera.
•Core functionality.
•Developer productivity and tools.
•Graphics.
•Media.
•Performance and battery.
•Privacy and security.
•Tablets and large screens.
47.
Sisteme de operarepentru dispozitive mobile
Patru motive pentru care Android primește atât de multă
atenție:
Android este disponibil gratuit
Oricine poate obține gratuit instrumente de dezvoltare,
documentația tehnică și codul sursă
Costul instruirii este mic dacă știți Java SE
Este implementat și în alte domenii în afară de
telefoanele mobile (de exemplu, industria auto)
47
48.
Android: concepte debază
Clasificarea aplicațiilor mobile:
în termeni de implementare
bazate pe interfață Web
aplicații independente/client
Native (API specific)
Cod binar interpretabil sau compilat JIT (similar cu Java ME)
în termeni de acces la rețea
Aplicații distribuite
Este necesar accesul la rețea/Internet
Aplicații independente (standalone)
Nu este necesar accesul la rețea/Internet
48
49.
Android: concepte debază
49
Sistem de operare Limbaj de programare
Android Java, Kotlin
iOS Objective-C, C++, Swift
Windows Phone C#/VB.NET (Silverlight and XNA),
C++
Dezvoltarea de aplicaţii mobile:
50.
Android: concepte debază
50
Dezvoltarea de aplicaţii mobile:
Platforma Limbaj/Tehnologii
.NET CF C#, VB.NET
Java ME Java
Web WML/XHTML/HTML5/JavaScript/CSS
Qt C++
51.
Android: concepte debază
Modelul de programare Android:
Nucleul Linux
Biblioteci native C
Limbaje de programare
Java, Kotlin
C/C++ (interfața de programare nativă)
ART – Android RunTime
Mediul de execuție curent al aplicațiilor Android
Începând cu Android 4.4
Compilare înainte de execuție
Mașină virtuală proprie (Dalvik VM)
Cod binar executabil incompatibil Java SE
Fișiere dex
Fiecare aplicație rulează într-un proces separat
Compilarea JIT
51
52.
Android: concepte debază
Facilități de programare:
Interfața utilizator
Baze de date
SQLite, Room
Media API: Audio, Video
Camera
Grafică 2D, Animație
Grafică 3D (OpenGL)
Informații personale
Rețea și comunicații: Socket, HTTP, Bluetooth, NFC
Telefonie
Senzori: GPS, Accelerometru, Giroscop, Busolă
52
53.
Android: concepte debază
Instrumente de dezvoltare:
Software necesar:
Java SE Development Kit (JDK)
Android SDK
Mediu de dezvoltare integrat (IDE):
Android Studio
Mediul oficial începând cu anul 2013
Eclipse
plugin: Android Development Toolkit (ADT)
IntelliJ IDEA, NetBeans (plugin-uri necesare)
53
54.
Android: concepte debază
Instrumente de dezvoltare (dezvoltare multiplatformă):
Visual Studio + Xamarin
Dezvoltare
Multiplatformă
Nativă
Limbaje de programare
C#
F#
Bazat pe biblioteci .Net (Mono) și SDK nativ (Android, iOS etc.)
54
55.
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
55
56.
Dispozitive și Aplicații
Mobile– curs 2
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
57.
Agenda
Structura aplicațiilorAndroid
Activități – ciclul de viață
Resurse
Mesaje (Intent)
Interfața cu utilizatorul
componente vizuale
containere
Interfața grafică în mod declarativ
Interfața grafică în mod procedural
Containere
Tratarea evenimentelor 2
58.
Android: concepte debază
Android SDK:
Biblioteci și resurse specifice fiecărei platforme Android
Resurse și imagini emulatoare
Instrumente pentru compilare și generarea conținutului
binar executabil
Cod sursă
Resurse
3
Android: concepte debază
Dalvik Debug Monitor Server (DDMS):
permite accesul la:
dispozitive virtuale (emulatoare)
dispozitive fizice
vizualizare:
și posibilitatea de a opri procesele
a memoriei
statisticilor privind accesul la rețea
consola de mesaje (LogCat)
acces la sistemul de fișiere
11
67.
Android: concepte debază
Consola de mesaje (LogCat):
Afișează mesaje transmise din aplicații
utilizator
ale sistemului
Mesaje de tip
Avertizare (w)
Depanare (d)
Eroare (e)
Informare (i)
Informare detaliată (v)
Eroare excepțională (wtf) 12
68.
Android: concepte debază
Messages console (LogCat):
Clasa android.util.Log
Metode statice asociate tipurilor de mesaje:
e(), w(), i(), d(), v(), wtf()
Parametri:
Identificator sursă mesaj (String)
Numele clasei, aplicației, activității etc.
Posibilitatea de filtrare
Mesajul care va fi afișat (String)
Metoda statică generală
println()
În plus, primul parametru include tipul mesajului
Log.ASSERT, Log.ERROR, Log.INFO etc.
Exemple:
Log.i("Activity1", "Information message");
println(Log.ASSERT, "Activity 1", "Invalid assertion!"); 13
Structura aplicațiilor Android
Includ una sau mai multe componente
Componentele sunt înregistrate de sistem
Pot fi și componente locale
Componentele pot fi activate
Local, în cadrul aplicației
Global, la nivelul sistemului
15
71.
Structura aplicațiilor Android
Componentelede bază ale aplicațiilor Android:
Activități
Clasa de bază este android.app.Activity
Servicii
Clasa de bază este android.app.Service
Furnizori de conținut
Clasa de bază este android.content.ContentProvider
Receptori de mesaje
Clasa de bază este android.content.BroadcastReceiver
mesaje
Clasa de bază este android.content.Intent 16
Structura aplicațiilor Android
Activitățile:
Asociate ferestrelor aplicației
O aplicație poate avea una sau mai multe activități
O singură activitate principală
Componente vizuale asociate
Derivate din clasa View
18
74.
Structura aplicațiilor Android
Servicii:
Rutine care rulează în paralel cu firul principal
Nu prezintă interfață grafică
Permit derularea unor acțiuni în fundal fără a bloca:
firul principal de execuție
Interacțiunea cu aplicațiile
19
75.
Structura aplicațiilor Android
Furnizoride conținut:
Suport pentru partajarea datelor între aplicații
Datele partajate sunt stocate în diferite surse de date
(fișiere, baze de date etc.)
Pun la dispoziție o modalitatea standard pentru accesul la
date și actualizarea acestora
Accesul se realizează printr-un URI de forma content://
20
76.
Structura aplicațiilor Android
Mesaje(obiecte Intent):
Pentru activarea componentelor se utilizează mesaje asincrone
încapsulate în obiecte de tip Intent
Invocare componente
Deschidere navigator, inițiere aplicație apeluri telefonice,
afișarea hărții la o anumită poziție geografică etc.
Comunicare între componente
21
77.
Structura aplicațiilor Android
Receptoride mesaje:
Aplicațiile pot reacționa la apariția unor evenimente la nivelul
sistemului prin utilizarea claselor derivate din
BroadcastReceiver
Apel telefonic, modificarea nivelului bateriei, recepționarea
unui mesaj, mesaje transmise de alte aplicații etc.
Nu prezintă interfață grafică
O aplicație poate include mai multe componente pentru
recepționarea de evenimente
22
Structura aplicațiilor Android
AndroidManifest.xml:
Componentele aplicației
activități, servicii, furnizori de conținut, receptori de mesaje
denumirile claselor asociate
Proprietăți
Informații pachet: denumire, versiune
Atribute aplicație: denumire, pictograma asociată, tema, opțiuni memorie,
restricții, permisiuni etc.
Filtrele de mesaje
definite în cadrul aplicației/componentelor
Permisiunile de acces
<uses-permission android:name="permisiune"/>
Cerințe hardware și software
<uses-feature android:name="cerință" android:required="true/false"/>
26
82.
Structura aplicațiilor Android
Pentru… este necesară permisiunea
android.permission. …
acces la Internet/rețea INTERNET
scriere și citire date de contact READ_CONTACTS, WRITE_CONTACTS
scriere și citire în Calendar READ_CALENDAR, WRITE_CALENDAR
trimitere SMS-uri, scriere şi citire
SMS-uri
SEND_SMS, READ_SMS, WRITE_SMS
utilizarea telefoniei CALL_PHONE
accesare mediu extern de stocare READ_EXTERNAL_STORAGE,
WRITE_EXTERNAL_STORAGE
identificare poziţie geografică ACCESS_FINE_LOCATION,
ACCESS_COARSE_LOCATION
27
Exemple de permisiuni:
Dacă se utilizează API 23 sau o versiune ulterioară, atunci trebuie să verificați
permisiunile la execuție!
83.
Structura aplicațiilor Android
API 23 (Marshmallow)
Permisiuni normale
Accesul este acordat automat
Exemple: Internet, Bluetooth, NFC, Vibrații etc.
Permisiuni cu risc/periculoase
Accesul este acordat individual de către utilizator
Aplicațiile controlează accesul la execuție
Exemple: Calendar, Camera, Contacts, SMS, Location,
Phone, Storage etc.
28
Structura aplicațiilor Android
Fișierelebinare Android:
Extensia apk (Android Package)
Conțin codul binar și resursele
Resursele pot fi compilate sau nu
Pe lângă resurse poate fi adăugat orice tip de fișier
34
apk
• /META-INF
• /lib
• /res
• /assets
• AndroidManifest.xml
• classes.dex
• resources.arsc
90.
Structura aplicațiilor Android
ClasaContext:
Clasă abstractă definită în pachetul android.content
Asigură accesul la mediul aplicației
Acces la resurse
Lansarea de activități noi
Acces la servicii de sistem
Acces la baze de date și fișiere
35
91.
Structura aplicațiilor Android
ClasaAplicație:
Accesul la setările și metodele ale aplicației
Clasă derivată din Application
Generată implicit
Poate fi creată o clasă utilizator prin derivare
Are un context asociat
Disponibil pe toată durată rulării aplicației
getApplicationContext()
36
92.
Structura aplicațiilor Android
Activități:
Asociate ferestrelor aplicației
O aplicație poate avea una sau mai multe activități
Stiva de activități
Task-uri
Derivate din clasa de bază android.app.Activity
Derivată din clasa Context (în vârful ierarhiei)
Contextul activității = this
Fiecare obiect grafic referă contextul activității din care face
parte
37
93.
Structura aplicațiilor Android
Activități:
Au o fereastră asociată
Reprezentarea interfeței grafice
Dispun de un ciclu de viață
Mai multe stări
Metode cu apel invers
Invocate la trecerea într-o stare
Posibilitatea de salvare a stării activității (conținut,
poziție componente vizuale, proprietăți etc.)
38
Ciclul de viațăal activităților
onCreate() – este apelată la crearea aplicației;
onStart() – apelată înainte de afișarea activității;
onResume() – aceasta se numește atunci când activitatea devine vizibilă
și utilizatorul interacționează cu aceasta;
onPause() – apelată atunci când o nouă activitate este adusă în prim-
plan;
onStop() – apelarea se face atunci când activitatea nu mai este utilizată
și nu este vizibilă;
onRestart() – aceasta se apelează atunci când activitatea revine în prim
plan după ce se apelează metoda onStart();
onDestroy() – este apelată când activitatea este terminată și distrusă
pentru a elibera memoria.
42
Resurse
//preluarea unui sirde caractere
String sir = getResources().getString(R.string.mesaj);
//preluarea unei culori:
int culoare = getResources().getColor(R.color.culoare_fundal);
//initializarea unei liste de valori din resurse
String [] optiuni= getResources().getStringArray(R.array.optiuni);
52
108.
Interfața grafică
Definităprin intermediul componentelor vizuale și a
containerelor
Asociate activităților și altor componente vizuale
Inițializare
Declarativ, prin fișiere XML
Separă codul de interfața grafică
Procedural, prin cod
Componente vizuale (widgets) – controale
Modalităţi de aranjare și structurare (ViewGroup/Layout) –
containere
53
109.
Interfața grafică
View
Utilizată pentru desenarea suprafeței și tratarea evenimentelor
Clasa de bază pentru componente vizuale simple (widgets)
Pachetul android.view
ViewGroup
Derivată din clasa View
Clasă de bază pentru containere și componente vizuale complexe
Pachetul android.view
54
110.
Containere
Definesc structuravizuală a interfeței utilizator
Structurarea conținutului vizual:
Liniară (verticală/orizontală)
Tabelară
Relativă
Clasă de bază în ierarhie: ViewGroup
Definire
Descriptiv
Procedural
55
111.
Containere
LinearLayout
Orizontalsau vertical
TableLayout
Linii si coloane
TableRow
GridLayout
Linii și coloane
Combină TableLayout cu LinearLayout
RelativeLayout
Relativ la alte componente
56
Componente vizuale
Controale
Pachetul android.widget.*;
Incluse
Text static
Text editabil
Butoane
Liste
Bare de progres
etc.
58
114.
Componente vizuale
TextView
Text static
EditText
Introducere text
Suport pentru selecția tipului
de date (inputType)
AutoCompleteTextView
Derivată din EditText
Introducere text
Are asociată o listă de sugestii
Space
Inserarea de spații între componente
59
115.
Componente vizuale
Button
Buton standard
Derivat din TextView
RadioButton
Buton utilizat în selecția exclusivă
Derivat din TextView
uzual, este inclus într-un RadioGroup;
CheckBox
Buton utilizat în selecția multiplă
ToggleButton
Buton cu două stări, starea apăsat fiind marcată prin intermediul unui
indicator
Switch
Buton cu două stări (stânga-dreapta)
60
116.
Componente vizuale
ImageView
Control pentru afișarea de imagini
ImageButton
Buton care permite afișarea unei imagini
Derivat din ImageView
ProgressBar
Bară de progres
Determinată (limita superioară stabilită)
Indeterminată (fără limită superioară, ciclică)
SeekBar
Derivat din ProgressBar,
permite selectarea valorii curente
61
117.
Componente vizuale
AnalogClock
Ceas analogic
TextClock
DigitalClock (depreciată)
Ceas digital
Afișat conform setărilor de sistem
Chronometer
Cronometru
RadioGroup
permite gruparea butoanelor radio
62
118.
Componente vizuale complexe
Spinner
control asemănător unei liste combinate
ListView
listă compusă care afișează elementele
componente pe verticală
GridView
permite poziționarea componentelor
vizuale sub formă de linii și coloane
63
119.
Componente vizuale complexe
ExpandableListView
listă compusă în care elementele
sunt grupate pe categorii
DatePicker
selecția datei
derivat din FrameLayout
TimePicker
selecția orei
derivat din FrameLayout
64
120.
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
65
121.
Dispozitive și Aplicații
Mobile– curs 3
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
122.
Agenda
Interfața cuutilizatorul
componente vizuale
containere
Interfața grafică în mod declarativ
Interfața grafică în mod procedural
Containere
Tratarea evenimentelor
2
123.
Android Support Library
AndroidX (începând cu API 28)
Biblioteci de clase
Asigură compatibilitatea pentru versiunile anterioare Android
Fragmente, bara de acțiune, container tabular, bară de
instrumente etc.
Include componente noi
ViewPager, DrawerLayout
RecyclerView
Snackbar
3
124.
Interfața în moddeclarativ
Fișiere XML
Definire
Elemente interfaţă grafică/elemente vizuale (res/layout)
Meniuri (res/menu)
Posibilitatea de reutilizare (includere)
Resurse referite
Valori constante (res/values)
string
dimen
color
Asocierea componentelor vizuale activităților
metoda setContentView()
4
125.
Fișierele XML (layout)
Descriu structura ecranelor sau a componentelor vizuale
Fiecare componentă inclusă este reprezentată de un element
XML
Denumirile elementelor XML = denumirile claselor asociate
componentelor
Atributele = proprietățile asociate componentelor
5
126.
Proprietăți
android:proprietate
Specificefiecărei componente vizuale
android:layout_proprietate
clasa LayoutParams
Transmise componentei părinte în vederea poziționării și
dimensionării
obligatorii:
android:layout_width și android:layout_height
Valori:
wrap_content sau match_parent sau
mărimi constante
6
Valori constante
px(pixels)
dp (density-independent pixels)
un dp = un pixel pentru o densitate de 160 dpi
mm, in
Raportare la dimensiunea fizică a ecranului
pt (puncte; 1/72 inch)
fonturi
sp (scale-independent pixels)
fonturi
8
129.
Densitatea (PPI/DPI)
Densitatea=
ℎ𝑝2+𝑣𝑝2
𝑑𝑖𝑎𝑔
hp – rezoluția pe orizontală (pixeli)
vp – rezoluția pe verticală (pixeli)
diag – diagonala (inches)
9
130.
Dimensiuni - conversii
Din pixeli în dp
𝑑𝑝 =
𝑝𝑥 ∗160
𝐷𝑃𝐼
Din dp în pixeli
𝑝𝑥 =
𝑑𝑝 ∗𝐷𝑃𝐼
160
10
131.
Dimensiuni – conversii(în cod)
DisplayMetrics dm = getResources().getDisplayMetrics();
//conversie la pixeli
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dp, dm);
//sau
int px = Math.round(dp * dm.density);
11
Referirea componentelor încod
Metoda din clasa Activity:
View findViewById(int idResursa)
<T extends View> T findViewById(int idResursa)
Exemplu
TextView tv = (TextView) findViewById(R.id.textViewTitlul);
tv.setText("text stabilit din cod");
Apelul se realizează după invocarea metodei setContentView()!
17
138.
Interfața în modprocedural
Controalele inițializate din cod
Constructori
Contextul curent
Inițializare proprietăți
Adăugare la containere
Metoda addView()
Anumite dimensiuni trebuie calculate
Asociere conținut în activitate
setContentView()
Poate fi un container sau un control
18
Interfața în modprocedural
//containerul
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
//controlul static
TextView tv = new TextView(this);
tv.setText("Titlul:");
//conversie 20dp la pixeli
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int hPixeli = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20,
displayMetrics);
24
145.
Interfața în modprocedural
//inaltime 20dp, latime WRAP_CONTENT
LayoutParams lpt = new LayoutParams(LayoutParams.WRAP_CONTENT, hPixeli);
tv.setLayoutParams(lpt);
//pentru WRAP_CONTENT la controlul de editare si la buton
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
25
146.
Interfața în modprocedural
//controlul de editare
EditText et = new EditText(this);
et.setText("introduceti titlul" );
et.setEms(10);
et.setLayoutParams(lp);
//butonul
Button buton = new Button(this);
buton.setText("Trimite");
buton.setLayoutParams(lp);
//adaugare la container
layout.addView(tv); layout.addView(et); layout.addView(buton);
//asociere continut
setContentView(layout);
26
147.
LinearLayout
Modul dearanjare a componentelor: android:orientation
horizontal
vertical
27
ConstraintLayout
Ierarhie carenu implică imbricarea controalelor
Asemănător containerului de tip RelativeLayout
Integrat cu editorul vizual din Android Studio
Creșterea performanțelor
dependencies {
implementation 'com.android.support.constraint:constraint-layout:x.x.x'
}
32
153.
ConstraintLayout
Restricții
Puncte deconectare între controale și
alte controale
containerul părinte
puncte de referință
Poziționare relativă
Identificatorii controalelor sau parent
Margini
Inclusiv controlul față de componentele ascunse
Centrare/poziționare proporțională
Înlănțuire
Dimensiuni
Puncte de referință 33
TableLayout
Derivată dinLinearLayout
Linii
TableRow
Coloana asociată
android:layout_column
Întinderea pe mai multe coloane:
android:layout_span
Adaptarea la conținut (pe baza indecșilor coloanelor)
android:shrinkColumns
Eliminarea spațiului liber
android:stretchColumns
Extinderea coloanelor pentru a ocupa spațiul liber
android:collapseColumns
Ascunderea coloanelor
36
GridLayout
Număr coloane
android:columnCount
Întinderea pe mai multe linii:
android:layout_rowSpan
Întinderea pe mai multe coloane:
android:layout_columnSpan
38
FrameLayout
În moduzual, este afișată o singură componentă vizuală
Poziționarea componentelor:
Implicit: colțul stanga-sus
Suprapunere pe niveluri pe axa z
adancime
android:layout_gravity
Suprapunerea componentelor vizuale
40
161.
ScrollView / HorizontalScrollView
Derivată din FrameLayout
Acceptă o singură componentă vizuală;
Afișare bare de defilare
android:scrollbars="vertical"
Ocuparea întregii suprafețe disponibile
android:fillViewport="true"
41
162.
Parametrii containerelor
Clasade bază ViewGroup.LayoutParams
Definită în fiecare clasă de tip container
LinearLayout.LayoutParams, RelativeLayout.LayoutParams
Referire din clasa View
setLayoutParams()
getLayoutParams()
Proprietăți comune
width, height
Proprietăți specifice containerului
gravity, weight
Constructor
width, height
42
163.
Parametrii containerelor
//inaltime 20pixeli
LinearLayout.LayoutParams lp = new
LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, 20);
lp.setMargins(10, 10, 10, 10);//left, top, right, bottom (pixeli)
view.setLayoutParams(lp);
//daca obiectul view este deja atasat la un container
LayoutParams lpb = view.getLayoutParams();
lpb.width = ViewGroup.LayoutParams. MATCH_PARENT;
lpb.height = ViewGroup.LayoutParams.WRAP_CONTENT;
view.setLayoutParams(lpb);
43
164.
Tratarea evenimentelor
Interfețede tip listener
Ex: View.OnClickListener
Metode pentru tratarea evenimentelor
Ex.: onClick()
Înregistrarea evenimentelor
Ex.: setOnClickListener()
44
Tratarea evenimentelor
Implementareainterfeței într-o clasă
dedicată
existentă (clasa de tip activitate etc.)
Implementarea interfeței într-o clasă anonimă
Varianta rapidă pentru evenimentul click:
proprietatea onClick în fișierul XML
metoda de tratare a evenimentului în clasa activitate asociată
46
167.
Tratarea evenimentelor
public classActivitate extends Activity implements
View.OnClickListener {
public void onCreate(Bundle savedInstanceState) {
//înregistrare clasă tratare eveniment pentru Button buton
buton.setOnClickListener(this);
//...
}
//tratare eveniment
public void onClick(View view) {
// Tratarea evenimentului
}
} 47
168.
Tratarea evenimentelor
public classEvenimClick implements View.OnClickListener {
//tratare eveniment
public void onClick(View view) {
// Tratarea evenimentului
}
}
public class Activitate extends Activity {
public void onCreate(Bundle savedInstanceState) {
//înregistrare clasă tratare eveniment pentru Button buton
buton.setOnClickListener(new EvenimClick());
//…
}
}
48
169.
Tratarea evenimentelor
//Înregistrare șiimplementare clasă anonimă
//pentru tratare eveniment pentru controlul
//buton de tip Button. Codul poate fi în onCreate()
buton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Tratarea evenimentului
}
});
49
170.
Tratarea evenimentelor
XML
android:onClick="numeMetoda"
În clasa derivată din Activity:
public void numeMetoda(View view) { … }
Aceeși metodă pentru mai multe controale
Diferența între controale:
view.getId()
50
171.
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
51
172.
Dispozitive și Aplicații
Mobile– curs 4
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
173.
Agenda
Interfața cuutilizatorul
Stiluri și teme
Deserializarea componentelor
Meniuri și bara aplicației
Menu, ActionBar, Toolbar
Fragmente
2
174.
Interfața cu utilizatorul
Blocul de bază pentru interfața cu utilizatorul este un obiect
View care este creat din clasa View, ocupă o zonă
dreptunghiulară pe ecran și este responsabil pentru desen și
gestionarea evenimentelor.
ViewGroup este o subclasă a lui View și oferă un container
invizibil care include alte vizualizări sau alte obiecte ViewGroup
pentru a defini proprietățile legate de aspect.
Un layout (aspect) tipic care definește structura vizuală pentru
o interfață utilizator Android poate fi creat fie în timpul rulării
folosind obiectele View / ViewGroup, fie se declară utilizând
fișierul XML main_layout.xml.
3
Stiluri și teme
Stilurile
descriu proprietățile de formatare pentru diferite elemente de interfață
grafică (controale și containere)
se aplică în mod individual
Temele
stiluri care se aplică la nivelul unei activități/control/container
se utilizează global
Predefinite și utilizator
Resurse utilizator
res/values/styles.xml
Resurse predefinite
R.style
5
Stiluri și teme
Teme
Atributul android:theme la nivelul
Aplicației (toate activitățile)
Unei activități
Unui container/control
AndroidManifest.xml
8
Deserializarea componentelor
Creareade obiecte pe baza unui fișier XML
Clasa
LayoutInflator
Instanțierea obiectelor pentru conversie:
Activity#getLayoutInflater()
Context#getSystemService(String)
LayoutInflater.from(context)
Metoda de conversie:
View inflate(id_resursa, părinte)
11
183.
Meniuri
Meniu principalactivitate
Meniuri contextuale
Apăsarea prelungită pe ecran
Meniuri de tip popup
12
Meniuri
Opțiuni meniu
Identificatorulgrupului din care face parte opțiunea
Identificatorul opțiunii
Ordinea de afișare în meniu
Titlul
Pictograma asociată
Nu este afișată decât în bara aplicației
14
186.
Meniuri
Meniul principal
Pânăla API 11
Un buton dedicat (MENU)
Lansează meniul aplicației
Începând cu API 11
Nu mai este obligatoriu butonul dedicat
Definire
Resurse
Programatic
15
Meniuri
Meniul principal
Metodecu apel invers din clasele derivate din Activity
Creare:
public boolean onCreateOptionsMenu(Menu meniu)
Tratarea evenimentelor:
public boolean onOptionsItemSelected(MenuItem mi)
Modificarea dinamică a conținutului:
public boolean onPrepareOptionsMenu(Menu meniu)
17
Meniuri
Meniul principal– XML
@Override
public boolean onCreateOptionsMenu(
Menu meniu) {
//…
getMenuInflater().inflate(R.menu.main, meniu);
//…
return true;
}
19
R.menu.main
– resursă res/menu/main.xml
191.
Meniuri
Meniul principal– Java
@Override
public boolean onCreateOptionsMenu(
Menu meniu) {
meniu.add(Menu.NONE, MI_INAINTE, 0, "Inainte");
return true;
}
20
MI_INAINTE
– identificator constant pentru opțiune (int)
192.
Meniuri
Meniul principal
publicboolean onOptionsItemSelected(MenuItem mi)
{
//tratarea evenimentelor generate de selecția din meniu
switch (mi.getItemId()) {
case R.id.INAINTE : {
//
break;
}
//...
}
}
21
193.
Meniuri
Meniuri contextuale
InterfațaContextMenu
Inițializare
public void onCreateContextMenu(ContextMenu menu,
View v, ContextMenuInfo menuInfo)
Tratare evenimente
public boolean onContextItemSelected(MenuItem mi)
Asociere control
registerForContextMenu(view)
22
194.
Bara aplicației
Accesrapid la acțiuni și comenzi specifice
Suport pentru navigare în aplicație
Informații cu privire la contextul utilizatorului în cadrul
aplicației
Identitatea aplicației
Comutarea între perspective
23
Bara aplicației
ActionBar
Integrată activității din care face parte
Suport pentru navigare (depreciat începând cu API 21)
Meniu de tip listă (control de tip Spinner);
Control de navigare prin selectori (tab);
Toolbar (API 21, Material Design)
Definită sub format unui control uzual
Poate fi plasată oriunde pe ecran
Flexibilitate ridicată
25
197.
Bara aplicației
Controlde navigare (meniu sau pictogramă săgeată)
Pictograma aplicației/Logo
Titlul aplicației/activității
Subtitlu
Controale utilizator/opțiuni din meniu
Pictograma meniului (overflow icon)
opțiuni din meniu
26
198.
Bara aplicației
Accesla obiectul de tip ActionBar
getActionBar()
Stabilire bară aplicație
setActionBar()
27
199.
Bara aplicației
ActionBar
Ascundere/afișarebară
hide()/show()
Afișare titlu/subtitlu
setTitle()/setSubtitle()
Modificare mod de navigare (depreciat)
setNavigationMode()
NAVIGATION_MODE_STANDARD
NAVIGATION_MODE_LIST
NAVIGATION_MODE_TABS
28
200.
Bara aplicației
Toolbar
Temafără bara de acțiune
Theme.Tema.NoActionBar
sau temă proprie, cu atributele:
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
29
Fragmente
Posibilitatea demodularizare a interfeței
Gestiunea facilă a dimensiunilor diferite
Transmiterea obiectelor între ecranele aplicației
Suport pentru navigare între ecrane
Stiva de fragmente
31
203.
Fragmente
Un FragmentAndroid este parte dintr-o activitate, cunoscut ca și sub-
activitate. Pot fi mai multe fragmente la nivel de activitate.
Fragmentele reprezintă mai multe ecrane în cadrul unei activități.
Clasa FragmentManager este responsabilă pentru interacțiunea dintre
obiectele de tip fragment.
32
Fragmente
Derivate dinclasa Fragment
Asociate activităților
Au un ciclu de viață propriu
Recepționează evenimente
Interfața inițializată din XML sau cod
Static vs. dinamic
Necesită un container
34
Fragmente
Ciclul deviață al fragmentelor Android este afectat de ciclul de viață
al activității, deoarece fragmentele sunt incluse în activitate.
Fiecare fragment are propriile sale metode ale ciclului de viață, care
sunt afectate de ciclul de viață al activității, deoarece fragmentele
sunt încorporate în activitate.
36
Fragmente- XML
Creareclasă de tip fragment, derivată din Fragment
Definire machetă activitate (layout_activitate.xml)
Include elementul fragment
Referă clasa de tip fragment
Clasa de tip activitate referă resursa de tip machetă care
include fragmentul
Definire machetă fragment (layout_fragment.xml)
În clasa de tip fragment:
deserializare machetă fragment (inflate)
metoda onCreateView()
42
214.
Fragmente - XML
publicclass ClasaFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle bundle) {
// macheta asociată fragmentului
return inflater.inflate(R.layout.layout_fragment,
container, false);
}
}
43
215.
Fragmente
Referirea fragmentelor
Inițializareaunui obiect de tip FragmentManager
getFragmentManager() din clasa activitate
Inițializarea unui obiect de tip Fragment definit în layout:
FragmentManager#findFragmentById(id)
FragmentManager#.findFragmentByTag(tag)
44
216.
Fragmente
Fragmente dinamice
Nuse utilizează elementul fragment în fișierele de tip machetă
Se definește un container pentru fragment
uzual un FrameLayout
Clase specializate pentru tranzacții
45
217.
Fragmente
Tranzacții cu fragmente
FragmentManager
Gestionează fragmentele din cadrul activităților
Interacțiunea cu fragmentele în cadrul activităților
FragmentTransaction
Operații cu fragmente
adăugare
ștergere
înlocuire
46
218.
Fragmente
Tranzacții cu fragmente
Inițierea unei tranzacții
apelul metodei beginTransaction() din clasa
FragmentManager
se obține un obiect de tip FragmentTransaction
Operații cu fragmente (FragmentTransaction):
Adăugare – metoda add()
Eliminare –metoda remove()
Înlocuire fragment –metoda replace()
Salvarea operațiilor (FragmentTransaction):
metoda commit()
47
219.
Fragmente
Tranzacții cu fragmente
FragmentManagerfm = getFragmentManager();
FragmentA fragmentA = new FragmentA();
FragmentB fragmentB = new FragmentB();
// adaugare fragment A
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fragId, fragmentA, "fragmentA");
ft.commit();
48
220.
Fragmente
Tranzacții cu fragmente
//înlocuire fragment A cu B
FragmentTransaction ft2 = fm.beginTransaction();
ft2.replace(R.id.fragId, fragmentB, ”fragmentB”);
// adaugare fragment in stiva (revenire cu Back)
ft2.addToBackStack(null);
ft2.commit();
// eliminare fragment B
FragmentTransaction ft3 = fm.beginTransaction();
ft3.remove(fm.findFragmentByTag("fragmentB"));
ft3.commit(); 49
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
51
223.
Dispozitive și Aplicații
Mobile– curs 5
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
224.
Agenda
Componente vizualecomplexe
Liste
Adaptoare
Tratarea selecțiilor
Ferestre de informare
Mesaje (Intent)
2
225.
Componente vizuale complexe
Controale complexe (ViewGroup)
Elemente de tip View
Implementează clasa abstractă AdapterView
Inițializate prin intermediul unui adaptor
Asocierea
metoda setAdapter()
3
Adaptoare
Asigură legăturadintre sursa de date și controale de tip listă de
elemente
Acces la sursa de date
Creează un View pentru fiecare element din sursa de date
5
Resurse predefinite
9
Resursă predefinită
(android.R.layout…)
Descriere
simple_spinner_itemText pe o singură linie
simple_spinner_dropdown_item Text pe o linie care include
suport pentru selecție
simple_list_item_1 Text pe o singură linie
simple_list_item_2 Text pe două linii
simple_list_item_simple_choice Text pe o linie care include
suport pentru selecția
exclusivă
simple_list_item_multiple_choice Text pe o linie care include
suport pentru selecția multiplă
simple_expandable_list_item_1 Text pe o singură linie
simple_expandable_list_item_2 Text pe două linii
ArrayAdapter
Sursa dedate simplă:
ArrayList, Array, etc.
Constructor:
Contextul (activitate)
Identificatorul resursei de tip machetă asociat unui element
din listă
Identificatorul controlului de tip TextView (dacă este cazul)
Lista de șiruri
Pentru un element din sursă:
Apelează metoda toString()
Asociază conținutul unui TextView
12
235.
ArrayAdapter – Exemplu
String[] tari = new String[] {"Romania", "Bulgaria", "Grecia"};
//inițializare listă
ListView lv = findViewById(R.id.lista1);
//initializarea adaptor
ArrayAdapter<String> adaptor = new ArrayAdapter<>(
this,
android.R.layout.simple_list_item_1,
tari);
//asociere adaptor
lv.setAdapter(adaptor);
13
236.
ArrayAdapter – Exemplu
String[] tari = new String[] {"Romania", "Bulgaria", "Grecia"};
//inițializare listă
ListView lv = findViewById(R.id.lista1);
//initializarea adaptor
ArrayAdapter<String> adaptor = new ArrayAdapter<>(
this, R.layout.element_lista,
R.id.textViewTara
tari);
//asociere adaptor
lv.setAdapter(adaptor);
14
237.
ArrayAdapter – Exemplu
classTara {
String nume ;
int populatie;
Bitmap steag;
//metode de acces publice (ex. getNume()/setNume())
public String toString() {
return "Denumire: " + nume + ", populatie: " + populatie;
}
}
15
238.
ArrayAdapter – Exemplu
ArrayList<Tara>listaTari = new ArrayList<>();
//inițializare listă
ListView lv = findViewById(R.id.lista1);
//initializarea adaptor
ArrayAdapter<Tara> adaptor = new ArrayAdapter<>(
this,
android.R.layout.simple_list_item_1,
listaTari);
//asociere adaptor
lv.setAdapter(adaptor);
16
SimpleAdapter
Contextul curent
Lista de obiecte care vor fi afișate în listă
incluse în obiecte de tip Map
cheia este de tip String
cheia identifică numele coloanei ale cărei valori sunt
inițializate
Identificatorul unei resurse de tip machetă
Lista coloanelor ale căror valori vor fi afișate pe fiecare linie din listă
numele coloanelor trebuie identificate în obiectele de tip Map din
lista de date
Lista identificatorilor asociați resurselor de tip TextView utilizate
18
241.
SimpleAdapter – Exemplu
ArrayList<Map<String,String>> tari = new ArrayList<>();
final String NUME = "nume";
final String POPULATIE = "populatie";
//in metoda onCreate()
for (Tara obTara : listaTari) {
HashMap<String, String> tara = new HashMap<String, String>();
tara.put(NUME, obTara.getNume());
tara.put(POPULATIE, obTara.getPopulatie() + " locuitori");
tari.add(tara);
}
19
242.
SimpleAdapter – Exemplu
String[]proprietati = { NUME, POPULATIE };
int[] identificatori = { android.R.id.text1, android.R.id.text2 };
SimpleAdapter adaptor = new SimpleAdapter(
this, // contextul
tari,// lista de obiecte
android.R.layout.simple_list_item_2, // identificatorul machetei
proprietati, // proprietatile utilizate
identificatori);
//activitatea este de tip ListActivity
setListAdapter(adaptor);
20
Adaptor personalizat
Derivaredin clasa BaseAdapter
int getCount( )
returnează numărul de elemente disponibile în sursa de date
object getItem(int pozitie)
returnează elementul de la poziția indicată
long getItemId(int pozitie)
returnează identificatorul înregistrării de la poziția indicată
View getView(int pozitie, View convertView, ViewGroup
parinte)
metoda returnează obiectul de tip View creat și inițializat
pentru afișarea în listă a elementului de la poziția indicată
23
Adaptor personalizat –Exemplu
public class AdaptorTari extends BaseAdapter {
private static class ViewHolder {
public ImageView ivSteag;
public TextView tvNume, tvPopulatie;
}
//…
}
29
252.
Adaptor personalizat –Exemplu
@Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder holder;
if(view == null) {//controlul este afisat pentru prima oara
//initializare obiecte controale
view = layoutInflater.inflate(R.layout.element_lista, parent, false);
holder = new ViewHolder();
holder.ivSteag = view.findViewById(R.id.imageViewSteag);
holder.tvNume = view.findViewById(R.id.textViewNume);
holder.tvPopulatie = view.findViewById(R.id.textViewPopulatie);
convertView.setTag(holder);
}
//else în continuare
30
Notificarea modificărilor
ArrayAdapterinclude metode de gestiune a sursei de date
add(), insert(), remove(), clear()
După fiecare modificare se apelează prin, intermediul
adaptorului, metoda
notifyDataSetChanged()
Recrearea adaptor cu noua listă (nerecomandat)
33
256.
Asociere text listăvidă
Fișier de tip machetă
/res/layout/layout.xml
<ListView />
<TextView android:id="@+id/empty"
…
34
257.
Asociere text listăvidă
Fișier sursă
//inițializare listă
ListView lv = ...
//initalizare control text listă vidă
TextView textViewListaVida =
(TextView)findViewById(R.id.empty);
//asociere text listă vidă
textListaVida.setText(textListaVida);
//asociere control
lv.setEmptyView(textViewListaVida);
35
Ferestre de informare
AlertDialog
Create prin intermediul clasei AlertDialog.Builder
Ferestrele includ:
Titlu (text + pictogramă)
Mesaj/Listă/Opțiuni (exclusive sau multiple)
Butoane (maxim trei)
Creare și afișare: show()
Inchidere: dismiss(), cancel()
41
264.
Ferestre de informare
AlertDialog.Builder
Constructorul: contextul curent
Creare AlertDialog: create()
42
Stabilire Metoda
Mesaj setMessage(mesaj)
Titlu setTitle(titlu)
Buton acțiune pozitivă (OK) setPositiveButton(eticheta,
tratare_actiune)
Buton acțiune negativă (No) setNegativeButton(eticheta,
tratare_actiune)
Buton acțiune neutră (Cancel) setNeutralButton(eticheta,
tratare_actiune)
Pictograma titlu setIcon(idPictograma)
Acțiune tasta Back setCancelable(true/false)
265.
Ferestre de informare
newAlertDialog.Builder(this)
.setTitle("Info")
.setMessage("Exemplu AlertDialog")
.show();
43
266.
Ferestre de informarecu liste
setItems()
Lista elemente
Obiect tratare eveniment selecție
setSingleChoiceItems()
+ element selectat sau -1
setMultipleChoicheItems()
+ lista elemente selectate sau null
44
267.
Ferestre de informare– Exemplu
new AlertDialog.Builder(this)
.setTitle("Font")
.setMultiChoiceItems(optiuni, null, new
DialogInterface.OnMultiChoiceClickListener() {
public void onClick(DialogInterface dialog, int id, boolean isChecked) {
// preluare selectie}})
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//prelucrare confirmare selectie
dialog.dismiss(); }})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//renuntare la selectie
dialog.cancel(); }})
.show()
45
Ferestre de informare
ClasaToast
Afișarea unui mesaj de informare pentru o durată determinată
Inițializare
Constructor
Metoda statică makeText()
Context, text și durată
Durată
Toast.LENGTH_SHORT
Toast.LENGTH_LONG
Afișare
show() 47
270.
Ferestre de informare
Metode:
setText()
setDuration
setGravity()
poziționare pe ecran
Poate fi personalizată
setView()
Toast.makeText(this,
"Fisierul a fost salvat",
Toast.LENGTH_SHORT).show();
48
Mesaje (Intent)
Tipuri demesaje
Explicite
Sunt invocate anumite componente
Necesară cunoașterea numelui componentei
Implicite
Sunt invocate acele componentele care corespund unor
criterii (acțiune, tip date etc.)
Componentele nu sunt cunoscute la apel
51
274.
Mesaje (Intent)
Acțiuni
Definitesub forma unor operații (String)
Operații
Predefinite (sistem)
Definite de programator
Generice sau specializate
VIEW vs. CALL
52
275.
Mesaje (Intent)
Date
Prezentatesub forma unui URI (Uri)
Caracterizate prin tip (formatul MIME)
text/html, text/plain, application/pdf etc.
Date suplimentare (Bundle atașat)
Extras
53
276.
Mesaje (Intent)
Date suplimentare
Obiect de tip Bundle atașat
Container de date
Adăugare date
putExtra(cheie, valoare)
Adăugare conținut container existent de date
putExtras(Bundle)
Preluare date
getTIPExtra(cheie): getFloatExtra(), getStringExtra() etc.
Obținere container date
Bundle getExtras()
54
Mesaje (Intent)
Categorii
Asociatecomponentei care prelucrează mesajul
Informații suplimentare cu privire modalitatea de lansare a
activității destinație
Exemple
CATEGORY_LAUNCHER
CATEGORY_HOME
CATEGORY_PREFERENCE
56
279.
Mesaje (Intent)
Constructori
Mesajegenerice
Fără parametri
Mesaje implicite
Acțiune (String)
Acțiune (String) și date (Uri)
Mesaje explicite
Context și componentă (Class)
Acțiune (String), date (Uri), Context și componentă (Class)
57
Mesaje (Intent)
Transmiterea șifiltrarea mesajelor
Orice componentă Android (activitate, serviciu, receptor) poate
fi informată prin intermediul mesajelor (Intent)
Includerea de filtre (XML și/sau cod)
Filtre
Acțiune: ACTION_VIEW, ACTION_PICK etc.
Categorie (android.intent.category): DEFAULT,
LAUNCHER, TAB etc.
Tip conținut
Protocol: http, content, geo etc.
MIME: text/plain, vnd.android-dir/mms-sms etc.
59
282.
Mesaje (Intent)
Transmiterea șifiltrarea mesajelor
Componentele includ filtre de mesaje
Acțiune, tip date, protocol etc.
După transmiterea unui mesaj
Sistemul identifică acele componente care corespund mesajului
(filtrare)
Dacă există una sau mai multe componente
Sunt invocate direct
Utilizatorul selectează componenta dintr-o listă de
componente
Dacă nu există
Excepție
60
283.
Mesaje (Intent)
Filtrarea mesajelor(XML)
Elementul intent-filter în fișierul manifest
Pot fi mai multe intrări de acest tip
Este asociat unei componente:
<componenta>
<intent-filter>
<action android:name="actiune" />
<category android:name="categorie" />
<data android:scheme="protocol"/>
</intent-filter>
</componenta>
Pot include priorități în tratarea acestora de către componente
(activități/receptori
android:priority 61
Mesaje (Intent)
Lansareaunei activități cu transmitere de date
/*
Din activitatea curentă (referită prin this) este lansată activitatea de tip
ActivitateIntrebari
*/
Intent intent = new Intent(this, ActivitateIntrebari.class);
//se transmite un parametru
intent.putExtra("idTest", 1001);
//se lansează activitatea
startActivity(intent);
64
287.
Mesaje (Intent)
Preluareadatelor în activitatea invocată
@Override
public void onCreate(Bundle stare)
{
super.onCreate(stare);
//obținere container date
Bundle param = getIntent().getExtras();
//se testează în prealabil dacă param este null
int idTest = param.getInt("idTest")
//…SAU
int idTest = getIntent().getIntExtra("idTest", 0);
}
65
288.
Mesaje (Intent)
Mesaje implicite
Pe baza unei acțiuni precizate
Componentele (activități, servicii) se înregistrează pentru
diferite acțiuni
Rezultat
Excepție: Nici o componentă înregistrată
Lansare componentă: există o singură componentă
înregistrată sau implicită
Selecție componentă: mai multe componente înregistrate,
nici una implicită; utilizatorul va opta pentru o componentă
66
289.
Mesaje (Intent)
Mesajeimplicite: Exemplul 1
//Deschiderea navigatorului Web pe baza unui URL:
Intent intent2 = new Intent(Intent.ACTION_VIEW);
intent2.setData(Uri.parse("http://www.ase.ro");
startActivity(intent2);
67
290.
Mesaje (Intent)
Mesajeimplicite: Exemplul 2
//Deschiderea navigatorului Web pe baza unui URL
//cu verificarea existenței unei aplicații înregistrate
Intent intent2 = new Intent(Intent.ACTION_VIEW);
intent2.setData(Uri.parse("http://www.ase.ro");
if (intent2 .resolveActivity(getPackageManager()) != null) {
startActivity(intent2);
}
68
291.
Mesaje (Intent)
Invocarea uneiactivități pentru răspuns
Invocarea unor activități pentru efectuarea unor selecții
imagini
contacte
fotografii
Activitățile invocate: definite de programator sau existente (de sistem sau
terțe)
Mecanism care permite preluarea răspunsurilor
Dacă selecția este acceptată, activitatea invocată încapsulează datele într-un
mesaj (Intent)
Obiect
Referință (Uri)
Activitatea apelantă este notificată prin intermediul unei metode cu apel invers
69
Mesaje (Intent)
Invocareaunei activități pentru răspuns: Exemplul 1
//Selectarea unui imagini din galerie
final int SEL_IMAGINE = 100;
//lansare activitate de selecție imagine din galerie
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, SEL_IMAGINE );
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent intent) {
//după efectuarea selecției sau renunțare
if ((requestCode == SEL_IMAGINE ) && (resultCode == RESULT_OK)) {
Uri uriImagine = intent.getData();
//prelucrare uriImagine
}
74
297.
Mesaje (Intent)
Invocareaunei activități pentru răspuns: Exemplul 2
//Selectarea unui contact
final int SEL_CONTACT = 100;
//lansare activitate de selecție contact
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, SEL_CONTACT);
//după efectuarea selecției sau renunțare
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent intent) {
if ((requestCode == SEL_CONTACT) && (resultCode == RESULT_OK)) {
Uri uriContact= intent.getData();
//prelucrare uriContact cu un furnizor de conținut
}
}
75
298.
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
76
299.
Dispozitive și Aplicații
Mobile– curs 6
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
Accesul la rețea
HTTP/HTTPS:Restricții
Începând cu API 28 (Android 9)
Excepție acces HTTP nesecurizat
Cleartext HTTP traffic to * not permitted
Soluție:
AndroidManifest.xml
<application ...
android:usesCleartextTraffic="true" ...> ...
</application>
9
308.
Accesul la rețea
HTTP: Exemplu
URL url = null;
HttpURLConnection conn = null;
try {
url = new URL("http://pdm.ase.ro");
conn = (HttpURLConnection)url.openConnection();
// preluare raspuns
InputStream is = conn.getInputStream();
/*prelucrare conținut*/
}
catch (Exception e) {/*tratare excepție*/ }
finally {
if (conn != null)
conn.disconnect();
}
10
309.
Accesul la rețea
HTTP: Exemplu
URL url = null;
HttpURLConnection conn = null;
try {
url = new URL("http://pdm.ase.ro");
// preluare raspuns
InputStream is = url.openStream();
/*prelucrare conținut*/
}
catch (Exception e) {/*tratare excepție*/ }
finally {
if (conn != null)
conn.disconnect();
}
11
310.
Accesul la rețea
Prelucrareconținut
Fluxuri de date
Octeți
InputStream
ByteArrayInputStream
Caractere
InputStreamReader
BufferedReader
StringBuilder
StringBuffer
Sincronizat
Tipuri de date
Scanner
12
311.
Accesul la rețea
Descărcareafișierelor
Serviciul de sistem DownloadManager
getSystemService(DOWNLOAD_SERVICE)
Inițiere
enqueue()
Verificare stare transfer
REVENIRE
Servicii, Recepționarea mesajelor (BroadcastReceiver), Cursor
13
312.
Servicii Web
Oferăun mijloc standard de interoperare între aplicațiile software
care rulează pe o varietate de platforme și framework-uri
În mod uzual, clientul și serverul comunică prin HTTP prin intermediul
WWW
Disponibile în rețeaua Internet sau rețele private (intranet)
Nu sunt legate de nici un sistem de operare sau limbaj de programare
Caracteristici: interoperabilitatea și extensibilitatea
14
313.
Servicii Web
SOAP
Mesaje XML
WSDL
REST, RESTful (Representational State Transfer)
XML, JSON, HTML
15
314.
Servicii Web SOAP
Biblioteca kSOAP2
Se creează un mesaj SOAP
clasa SoapSerializationEnvelope
detaliile cererii se adaugă la mesaj prin intermediul clasei
SoapObject;
Clasa HttpTransportSE este utilizată pentru a efectua apelul real al
metodei serviciului Web, mesajul fiind transmis ca parametru.
metoda call()
Rezultatul este preluat de la partea de răspuns a mesajului
getResponse()
16
315.
Servicii Web REST
Acțiunile sunt implementate uzual prin protocolul HTTP
Comenzi (GET, POST, DELETE etc.) asociate acțiunilor
Rezultatul returnat
JSON
XML
17
316.
Operații asincrone
Activitățiconsumatoare de resurse
intrare/ieșire, prelucrări complexe etc.
Se realizează fără a bloca firul principal execuție
Evitarea blocării interfeței aplicației
Pot rula în alt fir de execuție
Transmiterea parametrilor
Problemă: actualizarea componentelor grafice din alt fir de execuție
decât cel în care au fost create
18
Clasa Handler
Transmitereade obiecte de tip Message și Runnable
Recepționarea de obiecte de tip Message
Obiectele sunt transmise între fire de execuție diferite
Fiecare obiect de tip Handler este asociat
unui fir de execuție
unei cozi de mesaje
21
320.
Clasa Handler
Prelucrareamesajelor
metoda cu apel invers handleMessage()
Transmiterea mesajelor
metode de forma sendYYY()
22
321.
Clasa Handler
Obiectede tip Runnable
Transmise către coada de mesaje asociată firului de execuție
Transmiterea obiectelor Runnable
Metode de forma postYYY()
23
Clasa Handler
Inițializare Handler
Constructor fără parametri
Asociat firului curent
Constructor cu un obiect de tip Looper
Clasă care rulează bucla de mesaje a unui fir de execuție
Looper.getMainLooper()
Constructor cu un obiect pentru preluarea apelurilor inverse
Handler.Callback
Constructor cu doi parametri
25
324.
Clasa Handler
Exemplu:Transmitere mesaj din alt fir de execuție
//inițializare mesaj
Message mesaj = new Message();
mesaj.obj = obiectul_de_transmis;
mesaj.what = cod_mesaj;
Handler handler;
//inițializare handler …
//trimire mesaj
handler.sendMessage(mesaj);
26
325.
Clasa Handler
Exemplu:Recepționare mesaj în firul principal
//definire la nivelul activității
Handler handler = new Handler() {
@Override
public void handleMessage(Message mesaj) {
switch (mesaj.what) {
case cod_mesaj:
//prelucrare
break;
}
super.handleMessage(mesaj);
}
};
27
Clasa Handler
Exemplu:Splash Screen
public class SplashScreen extends Activity {
final int DURATA_AFISARE = 3000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setari fereastra (full screen)
setContentView(R.layout.splash_screen);
...
29
328.
Clasa Handler
Exemplu:Splash Screen
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// dupa scurgerea timpului se apeleaza activitatea principala
Intent i = new Intent(SplashScreen.this, ActivityMain.class);
startActivity(i);
// inchiderea activitatii splash
finish();
}//end run
}, DURATA_AFISARE);
}//end onCreate()
}//end Activitate
30
329.
Clasa Handler
Exemplu:Splash Screen
//ascundere titlu requestWindowFeature(Window.FEATURE_NO_TITLE);
//afisare pe tot ecranul
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
);
31
Metode specifice
Exemplu:runOnUiThread()
this.runOnUiThread(new Runnable() {
@Override
public void run() {
editText.setText(text);
}
});
34
333.
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
35
334.
Dispozitive și Aplicații
Mobile– curs 7
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
Accesul la rețea
Mecanismele Android pentru accesarea datelor de rețea se
bazează pe protocoale standardizate pentru accesarea
resurselor online.
Un obiect HttpClient este utilizat pentru acces la distanță prin
intermediul metodelor POST și GET după deschiderea unei
conexiuni cu clasa HttpURLConnection.
Principalul avantaj al acestui mecanism este că poate fi utilizat
pentru orice tip de resurse.
Pentru a efectua operații de rețea utilizând apel asincron, se
poate utiliza clasa AsyncTask și toate procesele sunt
implementate în metoda doInBackground().
3
337.
Accesul la rețea
Metodele de acces la distanță acceptă conexiuni securizate cu
SSL sau TLS prin HTTP și alte proprietăți de conexiune, cum ar
fi streaming, expirări (timeouts) și pooling de conexiuni.
HttpURLConnection presupune utilizarea obiectelor ca fluxuri
de date. Un obiect URL este definit cu adresa către o locație la
distanță ca prim parametru. Pe baza obiectului URL se
definește o conexiune HTTP cu caracteristici precum:
Expirarea timpului de citire;
Expirarea timpului de conectare;
Metoda de solicitare (GET/POST).
4
338.
Accesul la rețea
Pentru ca aplicația Android să poată accesa informații despre rețea
și pentru a utiliza resursele la distanță, trebuie adăugate
permisiunile INTERNET și ACCESS_NETWORK_STATE în
AndroidManifest.xml.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"/>
5
339.
Accesul la rețea
Pentru accesarea datelor de rețea, mai întâi ar trebui să existe
o rețea și dispozitivul să fie conectat la aceasta. După aceea,
operațiunile de rețea trebuie făcute pe un fir separat pentru a
nu interfera cu firul principal de interfață UI și a bloca interfața
din cauza întârzierilor imprevizibile.
Pentru a efectua operațiuni de rețea utilizând un apel asincron,
se poate folosi clasa AsyncTask și implementarea întregului
proces în metoda doInBackground().
6
340.
Accesul la rețea
Pentru a verifica conectivitatea la rețea, un obiect
ConnectivityManager trebuie definit si inițializat cu
Context.CONNECTIVITY_SERVICE prin utilizarea metodei
getSystemService(). Din acest obiect prezența și starea rețelei
pot fi verificate accesând metodele getActiveNetworkInfo() și
isConnected().
7
341.
Accesul la rețea
Pentrua accesa resursele la distanță, clasa care extinde
AsyncTask trebuie să suprascrie trei metode :
onPreExecute() – această metodă este utilizată pentru a
inițializa toate variabilele înainte de a executa cererea;
doInBackground() – aici are loc solicitarea efectivă de date;
onPostExecute() – această metodă implementează logica
aplicației după ce solicitarea web a fost finalizată.
8
Clasa AsyncTask
Clasaabstractă AsyncTask<param, prog, rez>
Metode cu apel invers:
doInBackground(param… pars)
onProgressUpdate(prog…pars)
publishProgress()
onPostExecute(rez par)
onPreExecute()
Lansarea în execuție
metoda execute(param)
10
344.
Clasa AsyncTask
onPreExecute()
Rulată înainte de începerea prelucrărilor
doInBackground()
Execută operația de lungă durată
Rulată în mod asincron
onProgressUpdate()
Se apelează periodic pentru afișarea progresului operației de lungă durată
Invocată după apelurile metodelor de tip publishProgress()
onPostExecute()
Se apelează după încheierea prelucrărilor
Primește ca parametru obiectul rezultat în urma prelucrărilor
11
Exemplu AsyncTask
//Parametrul transmiseste un URL
//Rezultatul este un şir de caractere (String)
//progresul nu este monitorizat (Void)
class PrelAsinc extends AsyncTask<URL, Void, String> {
@Override
protected String doInBackground(URL... url) {
//acces url: url[0]
//conectare la server si preluare continut
return un_string;
}
@Override
protected void onPostExecute(String un_string) {
//actualizare element interfata grafica;
textView.setText(un_string);
}
}
13
347.
Exemplu AsyncTask
//Apelul dinfirul principal
URL url = new URL("http://pdm.ase.ro");
PrelAsinc pa = new PrelAsinc ();
pa.execute(url);
14
348.
Servicii Web
SOAP
Mesaje XML
WSDL
REST, RESTful (Representational State Transfer)
XML, JSON, HTML
15
349.
Servicii Web SOAP
Biblioteca kSOAP2
Se creează un mesaj SOAP
clasa SoapSerializationEnvelope
detaliile cererii se adaugă la mesaj prin intermediul clasei
SoapObject;
Clasa HttpTransportSE este utilizată pentru a efectua apelul real al
metodei serviciului Web, mesajul fiind transmis ca parametru.
metoda call()
Rezultatul este preluat de la partea de răspuns a mesajului
getResponse()
16
350.
Servicii Web SOAP
SOAP sau Simple Object Access Protocol este o specificație de
protocol pentru schimbul de informații structurate. SOAP este
utilizat în implementarea serviciilor web, bazate pe XML,
Extensible Markup Language, pentru a descrie formatul
mesajelor schimbate printr-o conexiune HTTP.
Comparativ cu accesul resurselor la distanță prin intermediul
unui DefaultHttpClient, consumul unui serviciu web .NET nu
poate fi realizat folosind instrumente Android standard.
Bibliotecile externe sunt necesare pentru a formata, serializa,
trimite și primi conținut prin HTTP folosind SOAP. Un astfel de
exemplu de bibliotecă externă este kSOAP, un proiect open
source.
17
351.
Servicii Web SOAP
Pentruutilizarea bibliotecii kSOAP trebuie definită o listă de
atribute care descriu serviciul web .NET care trebuie consumat:
NAMESPACE - o valoare care reprezintă domeniul în care rulează
serviciul web, poate fi specifică organizației;
METHOD_NAME - numele metodei care trebuie consumată;
SERVICE_URL - adresa URL a descrierii serviciului; locația de
unde poate fi accesat serviciul;
SOAP_ACTION - este echivalent cu spațiul de nume concatenat
cu numele metodei;
PARAMETRI - parametrii locali ai metodei.
18
352.
Servicii Web SOAP
Atributele sunt definite ca obiecte de tip String.
Accesul la serviciul web se face pe un fir separat decât firul
principal UI și pentru aceasta trebuie implementat un
mecanism de tip Thread.
//KSOAP call configuration
private static final String NAMESPACE ="http://tempuri.org/";
private static final String METHOD_NAME ="GetNearCinemaList";
private static final String SERVICE_URL ="address to SOAP service";
final String SOAP_ACTION ="http://tempuri.org/GetNearCinemaList";
private static final String ID_MOVIE = "1";
19
353.
Fișiere XML
Noduri/elemente
Un nod rădăcină
Atribute
<?xml version="1.0" encoding="ISO-8859-1"?>
<element_radacina>
<element atribut="val_atribut">
val_element sau alte elemente
</element>
…
</element_radacina>
20
354.
Fișiere XML
<?xml version="1.0"encoding="ISO-8859-1"?>
<biblioteca>
<carte cota="19222">
<autor>
<nume>R. Meier</nume>
</autor>
<titlu> Professional Android Application Development </titlu>
<editura>wiley</editura>
<an>2009</an>
<isbn>1-72-11-2222</isbn>
<pagini>500</pagini>
</carte>
21
355.
Fișiere XML
<carte cota="19223">
<autor>
<nume>S.Hashimi</nume>
<nume> S. Komatineni</nume>
<nume> D. MacLean </nume>
</autor>
<titlu>Pro Android 3</titlu>
<editura>Apress</editura>
<an>2011</an>
<isbn>0-321-15040-6</isbn>
<pagini>336</pagini>
</carte>
</biblioteca>
22
Prelucrare fișiere XML
SAX (Simple API for XML)
org.xml.sax
SAXParserFactory, SAXParser
Parcurgere secvențială a documentului XML
Evenimente – funcții cu apel invers
XML Pull
org.xmlpull.v1
XmlPullParserFactory, XmlPullParser
Parcurgere secvențială a documentului XML
Evenimente – tratate imediat
DOM
org.w3c.dom
DocumentBuilderFactory, DocumentBuilder, Document
Se generează o structură ierarhică în memorie
Nodurile sunt grupate în liste
25
359.
Prelucrare fișiere XML
SAX
SAXParserFactory
utilizată pentru crearea obiectelor de tip SAXParser
SAXParser
responsabilă cu prelucrarea fișierului XML
XMLReader
citirea fișierului XML
metoda parse()
Clasă derivată din DefaultHandler
26
360.
Prelucrare fișiere XML
Clasaderivată din DefaultHandler
Metode apelate în timpul prelucrării
startElement()
apelată la începerea citirii unui nou element;
endElement()
apelată la sfârșitul citirii unui element;
characters()
apelată la apariția unei secvențe de caractere din cadrul unui element
Se asociază la XmlReader
setContentHandler()
Preluare rezultat
27
Prelucrare fișiere XML
XmlPullParser
next() – parcurgerea documentului
Evenimente
Tipuri: START_TAG/END_TAG, TEXT,
START_DOCUMENT/END_DOCUMENT
getEventType()
nextToken() – parcurgerea cu evenimente adiționale
getName() – obținere nume etichetă
getText() – obținere conținut
getAttributeCount() – număr atribute
getAttributeValue() – valoare atribut
30
364.
Prelucrare fișiere XML
staticArrayList<Carte> prelucreazaXML_Pull(InputStream isXML) {
ArrayList<Carte> lista = new ArrayList<Carte>();
Carte carte = null;
int event; String text = null;
try {
// creare parser
XmlPullParser xmlParser = Xml.newPullParser();
xmlParser.setInput(isXML, null);
event = xmlParser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
String name = xmlParser.getName();
//aici este switch-ul de alături -->
event = xmlParser.next();
}
} catch (Exception e) {e.printStackTrace(); }
return lista;}
31
365.
Prelucrare fișiere XML
switch(event) {
case XmlPullParser.START_TAG:
if (name.equals("carte")) {
carte = new Carte();
carte.setCota(xmlParser.getAttributeValue(null,"cota"));
}
break;
case XmlPullParser.TEXT:
text = xmlParser.getText();
break;
case XmlPullParser.END_TAG:
if (name.equals("titlu")) { carte.setTitlu(text); }
if (name.equals("carte")) { lista.add(carte); }
break;
} 32
366.
Prelucrare fișiere XML
DOM
Interfețe
Node
Element (impl. Node)
NodeList
item(poz)
Clasa DocumentBuilder
metoda parse()
InputStream
Clasa Document (impl. Node)
33
367.
Prelucrare fișiere XML
DOM
Document
getElementsByTagName()
NodeList
Element
getAttribute()
Node
getTextContent()
34
368.
Prelucrare fișiere XML
DocumentBuilderFactorydocBuilderFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
//obținerea flux de intrare
InputStream is = getResources().openRawResource(R.raw.biblx);
//creare document
Document docXml = docBuilder.parse(is);
35
369.
Prelucrare fișiere XML
if(docXml != null) {
//obținere listă de noduri de tipul dat
NodeList carti = docXml.getElementsByTagName("carte");
//parcurgere listă
for (int i = 0; i < carti.getLength(); i++) {
//preluare și prelucrare noduri
Node nodCrt = carti.item(i);
if (nodCrt.getNodeType() == Node.ELEMENT_NODE) {
Element obj= (Element) nodCrt;
Carte carte = new Carte();
carte.cota = obj.getAttribute("cota");
carte.titlu = obj.getElementsByTagName("titlu").
item(0).getTextContent();
carte.isbn = obj.getElementsByTagName("isbn").
item(0).getTextContent();
}
}
} 36
Prelucrare fișiere JSON
JSONObjectjObject = new JSONObject(stringJson);
JSONObject joBibl = jObject.getJSONObject("biblioteca");
JSONArray jaCarti = joBibl.getJSONArray("carte");
for (int i = 0; i < jaCarti.length(); i++) {
Carte carte = new Carte();
// preluare carte
JSONObject joCarte = jaCarti.getJSONObject(i);
String titlu = joCarte .getString("titlu");
carte.setTitlu(titlu);
int an = joCarte .getInt("an");
String cota = joCarte.getString("-cota");
….
} 38
372.
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
39
373.
Dispozitive și Aplicații
Mobile– curs 8
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
374.
Agenda
Stocarea persistentăa datelor
Baze de date
SQLite
Room Persistence Library
Stocarea în containerul aplicației
Fișiere de proprietăți
Fișiere interne
Serializarea și deserializarea obiectelor
2
375.
Stocarea persistentă adatelor
Suport
Fișiere
Baze de date SQLite
Disponibilitate
Pachetul aplicației
Extern pachetului aplicației
Acces
Zona privată asociată aplicației
Zona publică
Mediul de stocare
Mediu de stocare intern
Mediul de stocare extern
Modalități structurate de stocare
Fișiere de proprietăți
Baze de date SQLite 3
376.
Stocarea datelor aplicației
Zona privată de date
/data/data/pachet_aplicație
Zona privată de date (mediu extern de stocare)
/dir_ext/Android/data/pachet_aplicație
Subdirectoare
cache
databases
shared_prefs
files
etc.
4
377.
Baze de dateSQLITE
Baze de date
SQLite
Baze de date relaționale
Room
5
378.
Baze de dateSQLITE
SQLite
Tipuri de date suportate
INTEGER
REAL
TEXT
BLOB
Conversii între tipuri (relații de afinitate)
Restricții
nu suportă anumite tipuri de asociere (join)
restricția de referențialitate
nu este activată implicit
nu suportă tranzacții imbricate
6
379.
Baze de dateSQLITE
Pentru a crea o nouă bază de date SQLite, trebuie mai întâi să creăm
o subclasă din SQLiteOpenHelper și să suprascriem metoda
onCreate(), unde putem executa o comandă SQLite pentru a crea
tabele în baza de date.
SQLiteOpenHelper este o clasă abstractă care este utilizată pentru a
implementa modelul pentru crearea, deschiderea și actualizarea
bazelor de date SQLite.
Prin derivarea clasei SQLiteOpenHelper se implementează logica
utilizată pentru a decide dacă o bază de date SQLite trebuie creată
sau actualizată înainte de a fi deschisă.
7
380.
Baze de dateSQLITE
Pentru a scrie și a citi din baza de date, putem apela metodele
getWritableDatabase() și respectiv getReadableDatabase().
Putem executa interogări SQLite folosind metoda query() din clasa
SQLiteDatabase, care acceptă diverși parametri de interogare.
Fiecare interogare SQLite va returna un cursor care indică toate
înregistrările găsite de interogare. Cursorul este mecanismul cu care
putem naviga printre rezultatele dintr-o interogare a bazei de date și
putem parcurge rânduri și coloane.
8
381.
Baze de dateSQLITE – Biblioteca ROOM
Room
Nivel de abstractizare peste SQLite
ORM (Object Relational Mapping)
Dependențe
implementation "androidx.room:room-runtime:2.2.2"
annotationProcessor "androidx.room:room-compiler:2.2.2"
9
382.
Baze de dateSQLITE – Biblioteca ROOM
Obiecte utilizate
Entități
Operații asupra datelor
Baza de date
Adnotări Java
10
383.
Baze de dateSQLITE – Biblioteca ROOM
Entități
Clase Java asociate tabelelor
Datele membre sunt asociate câmpurilor tabelei
Datele membre
Publice
Funcții accesor (set/get)
Pot fi ignorate anumite câmpuri
Nu sunt incluse obiecte
Posibilități de conversie
11
384.
Baze de dateSQLITE – Biblioteca ROOM
Entități
@Entity
clasa Java asociată unei tabele
tableName
Denumirea personalizată a tabelei
@PrimaryKey – câmp de tip cheie primară
autogenerate
@ColumnInfo
name
Denumirea personalizată a câmpului în tabelă
@Ignore – câmpul nu este inclus în tabelă 12
385.
Baze de dateSQLITE – Biblioteca ROOM
Relații între entități
Proprietatea foreignKey din @Entity
Valoarea de tip @ForeignKey
Atribute
entity
Clasa asociată entității părinte
parentColumns
Denumirile coloanelor din tabela părinte
childColumns
Denumirile coloanelor din tabela copil
onDelete , onUpdate
CASCADE
13
386.
Baze de dateSQLITE – Biblioteca ROOM
Relații între entități
Clase non-entitate
@Relation
Listă de obiecte asociate unei entități
parentColumn
entityColumn
entity
@Embedded
Includerea unei entități în cadrul clasei
14
387.
Baze de dateSQLITE – Biblioteca ROOM
Operații asupra datelor
@Dao
Definește interfața pentru operațiile asupra datelor
Include metode de selecție, inserare, modificare
Metodele trebuie adnotate
Operațiile trebuie executate asincron
15
388.
Baze de dateSQLITE – Biblioteca ROOM
Operații asupra datelor
@Query
Metodă de tip interogare
@Insert
Metodă pentru inserare
@Update
Metodă pentru actualizare
@Delete
Metodă pentru ștergere
16
389.
Baze de dateSQLITE – Biblioteca ROOM
Baza de date
Extinde clasa abstractă RoomDatabase
Clasă abstractă
Adnotare @Database
Clasa asociată bazei de date
entities
Clasele asociate entităților
version
Versiunea curentă a bazei de date
Metode care returnează obiectele de tip Dao asociate entităților
Managementul versiunilor (migrare)
17
390.
Baze de dateSQLITE – Biblioteca ROOM
Inițializarea bazei de date
O singură instanță
databaseBuilder(context, clasa_bd, nume_bd)
Metoda statică în clasa Room
Clasa RoomDatabase.Builder
Opțiuni creare
fallbackToDestructiveMigration()
allowMainThreadQueries()
Metoda build()
Returnează obiectul de tip baza de date
18
391.
Baze de dateSQLITE – Biblioteca ROOM
Cursor
android.database
Interfață
permite gestiunea înregistrărilor rezultate în urma interogării
unei baze de date
SQLiteCursor
Implementare pentru baze de date SQLite
19
Baze de dateSQLITE – Biblioteca ROOM
Cursor: Obținerea de informații
Numărul de înregistrări
getCount()
Numele coloanei
getColumnName()
Poziția coloanei
getColumnIndex()
22
395.
Baze de dateSQLITE – Biblioteca ROOM
Adaptoare de tip Cursor
CursorAdapter
Coloana _id
SimpleCursorAdapter
23
396.
Exemplu: SimpleCursorAdapter
SimpleCursorAdapter adapter= new SimpleCursorAdapter(
this, // contextul
android.R.layout.two_line_list_item, //sablonul liniei
cursor, // cursorul
new String[] { … }// lista numelor coloanelor,
new int[] { … } //lista identificatorilor de resurse asociate
);
24
397.
Stocarea în containerulaplicației
Resurse
Directoarele
res/raw – orice tip de fișier
res/xml – fișiere XML compilate
Acces prin intermediul unui identificator de resursă
Directorul assets
Prelucrare fluxuri de date
Structurare directoare și fișiere
25
398.
Stocarea în containerulaplicației
getResources() -> Resources
Fișiere din res/raw
openRawResource() -> InputStream
Fișiere din res/xml
getXml() -> XmlPullParser
26
Fișiere
Pot fisalvate în memoria persistentă
internă
externă
Fişierele salvate în spaţiul de stocare intern sunt accesibile
implicit doar la nivelul aplicaţiei
Vor fi şterse odată cu dezinstalarea acesteia
28
401.
Fișiere
Clasa Environment
Mediulextern amovibil:
isExternalStorageRemovable()
Stare mediu extern stocare
getExternalStorageState()
MEDIA_MOUNTED
MEDIA_MOUNTED_READ_ONLY
MEDIA_UNMOUNTED
MEDIA_REMOVED
29
402.
Fișiere
Directoare speciale
ClasaEnvironment, metode statice, rezultat File
Directorul radăcină
getRootDirectory()
Directorul date utilizator:
getDataDirectory()
Director cache download:
getDownloadCacheDirectory()
Director mediu extern stocare:
getExternalStorageDirectory()
depreciat API 29
30
Fișiere
Directoare speciale
ClasaActivity (Context)
Director date extern aplicației
getExternalFilesDir()
Directoare de date externe aplicației (API 19)
getExternalFilesDirs()
Director date
getFilesDir()
Director cache intern
getCacheDir()
Director cache extern
getExternalCacheDir()
32
405.
Fișiere
Clasa File
Operațiila nivel de fișier și director
Obținere și stabilire proprietăți
Mutare/redenumire
Creare director
Obținere conținut director etc.
33
406.
Fișiere
InputStream șiOutputStream
clase abstracte
suport pentru operaţii cu fluxuri de date
FileInputStream și FileOutputStream
fluxuri de date la nivel de octet utilizate pentru citirea şi
scrierea din fişiere;
FileReader și FileWriter
fluxuri de date la nivel de caracter utilizate pentru citirea şi
scrierea din fişiere;
34
407.
Fișiere
InputStreamReader şiOutputStreamWriter
fluxuri de date la nivel de caracter
derivate din clasele Reader, respectiv Writer
asociate unor obiecte de tip InputStream, respectiv
OutputStream;
operaţiile de intrare-ieşire nu sunt realizate direct din
fişiere
BufferedReader şi BufferedWriter –
asociate unor obiecte de tip Reader, respectiv Writer
permit efectuarea operaţiilor de intrare/ieşire prin
intermediul zonelor de memorie tampon (buffer).
35
Fișiere
Pentru a salvadate într-un fișier intern al aplicației Android, avem
nevoie de unele dintre clasele și metodele din pachetul java.io:
Clasa FileOutputStream creează un flux de ieșire care scrie octeți
într-un fișier; dacă fișierul de ieșire există, acesta poate fi înlocuit sau
adăugat; dacă nu există, va fi creat un nou fișier;
Clasa FileInputStream creează un flux de intrare utilizat pentru a citi
octeți dintr-un fișier;
37
410.
Fișiere
metoda write()din clasa FileOutputStream este echivalentă cu
write(buffer, 0, buffer.length) și scrie într-un buffer intern o matrice
de octeți, începând de la poziția zero până la dimensiunea matricei.
metoda getBytes() disponibilă în toate clasele wrapper returnează o
nouă matrice de octeți care conține caracterele șirului codificat
folosind setul de caractere implicit al sistemului.
metoda close() închide fluxul de date; implementările acestei metode
ar trebui să elibereze orice resurse utilizate de respectivul flux.
38
411.
Fișiere
Clasa Context oferăcâteva metode pentru interacțiunea cu sistemul de
fișiere intern:
metoda openFileOutput() este utilizată pentru a deschide un fișier
privat asociat cu pachetul de aplicații din acest context; metoda
returnează un FileOutputStream și creează fișierul dacă nu există
deja.
metoda openFileInput() este utilizată pentru a obține un
FileInputStream și a deschide un fișier pentru citire.
metoda deleteFile() șterge un fișier intern.
metoda fileList() generează o matrice String care conține numele
fișierelor private ale aplicației.
39
Serializarea și deserializareaobiectelor
Interfața Serializable
java.io
ObjectOutputStream
ObjectInputStream
transient
câmpurile nu vor fi serializate
Metodele interfeței
void writeObject(ObjectOutputStream out)
void readObject(ObjectInputStream in)
43
416.
Serializarea și deserializareaobiectelor
Clasa Parcel
Container de date
Transport interproces
Tipuri simple
writeByte(), writeDouble(), writeString() etc.
readByte(), readDouble(), readStrin() etc.
Tipuri complexe
writeList(), writeBundle(), writeStringArray() etc.
readList(), readBundle(), readStringArray() etc.
44
417.
Serializarea și deserializareaobiectelor
Interfața Parcelable
android.os
Metoda writeToParcel()
Scrie obiectul într-un Parcel
Constructor care primește un obiect de tip Parcel
Inițializează obiectul dintr-un Parcel
Metoda describeContents()
Câmpul static CREATOR
Implementează interfața ParcelableCreator
Apelează constructorul cu parametrul de tip Parcel
45
418.
Serializarea și deserializareaobiectelor
Interfața Parcelable
void writeToParcel(Parcel dest, int flags)
Clasa(Parcel in)
public static final Parcelable.Creator<Clasa> CREATOR =
new Parcelable.Creator<Clasa>() {
public Clasa createFromParcel(Parcel pc) {
return new Clasa(pc);
}
public Clasa[] newArray(int dim) {
return new Clasa[dim];
} };
public int describeContents()
46
419.
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
47
420.
Dispozitive și Aplicații
Mobile– curs 9
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
421.
Agenda
Stocarea persistentăa datelor
Baze de date
SQLite
Room Persistence Library
Fișiere de proprietăți
Serializarea și deserializarea obiectelor
2
422.
Baze de dateSQLITE – Biblioteca ROOM
Room
Nivel de abstractizare peste SQLite
ORM (Object Relational Mapping)
Dependențe
implementation "androidx.room:room-runtime:2.2.2"
annotationProcessor "androidx.room:room-compiler:2.2.2"
3
423.
Baze de dateSQLITE – Biblioteca ROOM
Entități
@Entity
clasa Java asociată unei tabele
tableName
Denumirea personalizată a tabelei
@PrimaryKey – câmp de tip cheie primară
autogenerate
@ColumnInfo
name
Denumirea personalizată a câmpului în tabelă
@Ignore – câmpul nu este inclus în tabelă 4
424.
Baze de dateSQLITE – Biblioteca ROOM
Relații între entități
Proprietatea foreignKey din @Entity
Valoarea de tip @ForeignKey
Atribute
entity
Clasa asociată entității părinte
parentColumns
Denumirile coloanelor din tabela părinte
childColumns
Denumirile coloanelor din tabela copil
onDelete , onUpdate
CASCADE
5
425.
Baze de dateSQLITE – Biblioteca ROOM
Relații între entități
Clase non-entitate
@Relation
Listă de obiecte asociate unei entități
parentColumn
entityColumn
entity
@Embedded
Includerea unei entități în cadrul clasei
6
426.
Baze de dateSQLITE – Biblioteca ROOM
Operații asupra datelor
@Dao
Definește interfața pentru operațiile asupra datelor
Include metode de selecție, inserare, modificare
Metodele trebuie adnotate
Operațiile trebuie executate asincron
7
427.
Baze de dateSQLITE – Biblioteca ROOM
Operații asupra datelor
@Query
Metodă de tip interogare
@Insert
Metodă pentru inserare
@Update
Metodă pentru actualizare
@Delete
Metodă pentru ștergere
8
428.
Baze de dateSQLITE – Biblioteca ROOM
Baza de date
Extinde clasa abstractă RoomDatabase
Clasă abstractă
Adnotare @Database
Clasa asociată bazei de date
entities
Clasele asociate entităților
version
Versiunea curentă a bazei de date
Metode care returnează obiectele de tip Dao asociate entităților
Managementul versiunilor (migrare)
9
429.
Baze de dateSQLITE – Biblioteca ROOM
Inițializarea bazei de date
O singură instanță
databaseBuilder(context, clasa_bd, nume_bd)
Metoda statică în clasa Room
Clasa RoomDatabase.Builder
Opțiuni creare
fallbackToDestructiveMigration()
allowMainThreadQueries()
Metoda build()
Returnează obiectul de tip baza de date
10
430.
Fișiere de proprietăți
Interfața SharedPreferences
Stocarea persistentă de perechi de forma cheie-valoare
Tipuri pentru valorile stocate:
boolean
int
float
long
String
Set<String>
11
431.
Fișiere de proprietăți
Obținerefișiere de proprietăți
Metodă în clasa Context
getSharedPreferences(String numeFisier, int mod)
Mai multe fișiere de proprietăți/aplicație
Metodă în clasa Activity
getPreferences(int mod)
Un singur fișier de proprietăți/aplicație/activitate
Funcție statică în clasa PreferenceManager
Pachetul androidx.preference (API 29+)
getDefaultSharedPreferences(context)
Un singur fișier de proprietăți/aplicație/activitate
Mod
Activity.MODE_PRIVATE
12
Activități pentru salvareapreferințelor
Clasa PreferenceFragmentCompat
Definire preferințe în fișier XML
R.xml.pref
Asociere conținut
Metoda cu apel invers onCreatePreferences()
Apel addPreferencesFromResource(R.xml.pref) sau
setPreferencesFromResource(R.xml.pref, root);
18
438.
Activități pentru salvareapreferințelor
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="Informatii conectare" >
<EditTextPreference
android:key="utilizator"
android:summary="Introduceti numele de utilizator"
android:title="Utilizator" />
19
439.
Activități pentru salvareapreferințelor
<EditTextPreference
android:inputType="textPassword"
android:key="parola"
android:negativeButtonText="Renunta"
android:positiveButtonText="Accepta"
android:summary="Introduceti parola"
android:title="Parola" />
<CheckBoxPreference
android:key="raminConectat"
android:summary="Se mentine sau nu autentificarea"
android:title="Raman conectat" />
</PreferenceCategory>
20
440.
Activități pentru salvareapreferințelor
<PreferenceCategory
android:summary="Preferinte cu privire la fonturi si culori"
android:title="Aspect" >
<ListPreference
android:entries="@array/optiuniCulori"
android:entryValues="@array/culoriDisponibile"
android:key="listaCulori"
android:negativeButtonText="Renunta"
android:summary="Selectati culoarea de fundal"
android:title="Culoarea de fundal" />
21
441.
Activități pentru salvareapreferințelor
<MultiSelectListPreference
android:entries="@array/optiuniFont"
android:entryValues="@array/setariFontDisponibile"
android:key="listaFont"
android:summary="Selectati proprietatile fontului"
android:title="Aspect text" />
<SwitchPreference
android:key="modNoapte"
android:summary="Activarea automata a modului de noapte"
android:title="Mod de noapte" />
</PreferenceCategory>
</PreferenceScreen>
22
Serializarea și deserializareaobiectelor
Interfața Serializable
java.io
ObjectOutputStream
ObjectInputStream
transient
câmpurile nu vor fi serializate
Metodele interfeței
void writeObject(ObjectOutputStream out)
void readObject(ObjectInputStream in)
26
446.
Serializarea și deserializareaobiectelor
Clasa Parcel
Container de date
Transport interproces
Tipuri simple
writeByte(), writeDouble(), writeString() etc.
readByte(), readDouble(), readStrin() etc.
Tipuri complexe
writeList(), writeBundle(), writeStringArray() etc.
readList(), readBundle(), readStringArray() etc.
27
447.
Serializarea și deserializareaobiectelor
Interfața Parcelable
android.os
Metoda writeToParcel()
Scrie obiectul într-un Parcel
Constructor care primește un obiect de tip Parcel
Inițializează obiectul dintr-un Parcel
Metoda describeContents()
Câmpul static CREATOR
Implementează interfața ParcelableCreator
Apelează constructorul cu parametrul de tip Parcel
28
448.
Serializarea și deserializareaobiectelor
Interfața Parcelable
void writeToParcel(Parcel dest, int flags)
Clasa(Parcel in)
public static final Parcelable.Creator<Clasa> CREATOR =
new Parcelable.Creator<Clasa>() {
public Clasa createFromParcel(Parcel pc) {
return new Clasa(pc);
}
public Clasa[] newArray(int dim) {
return new Clasa[dim];
} };
public int describeContents()
29
449.
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
30
450.
Dispozitive și Aplicații
Mobile– curs 10
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
451.
Agenda
Baze dedate la distanță
Firebase
Baze de date Firebase
Realtime Database
Cloud Firestore
2
452.
Baze de datela distanță
Partajarea datelor
Sincronizarea datelor
Datele sunt stocate pe un server
3
Baze de datela distanță
Soluții
Baze date + Aplicație + API
Baze date + Aplicație Web
Baze date + Servicii Web
Platforme online dedicate
Firebase (Realtime Database, Cloud Firestore)
Restdb.io
kumulos
5
455.
Firebase
Platformă proiectatăsă asigure integrarea soluțiilor bazate pe
cloud în aplicații
Aplicații mobile
Android
iOS
Aplicații Web
6
456.
Firebase
Componente Firebase
Authentication
Suport pentru gestiunea conturilor și autentificarea în aplicații
Cloud Storage
Stocarea de fișiere
Crash Reporting
Informații cu privire la problemele apărute în aplicații
Hosting
Găzduire aplicații Web
Realtime Databases și Cloud Firestore
Stocarea și sincronizarea datelor
7
457.
Firebase
Componente Firebase
GoogleAnalytics
Statistici cu privire la utilizarea aplicațiilor
Dynamic Links
Referirea dinamică a conținutului (aplicații sau Web)
Cloud Messaging
Transmiterea de mesaje și notificari
8
458.
Firebase
Conectarea prinintermediul unui cont Google
https://firebase.google.com/
Consola pentru gestiunea proiectelor
https://console.firebase.google.com/
Integrarea în aplicațiile Android
Manual
Android Studio | Tools | Firebase
9
459.
Firebase Realtime Database
Baze de date în timp real
NoSQL
Date stocate în format JSON
Autentificare
Multiplatformă
Găzduire în cloud
Sincronizare
10
Firebase Realtime Database
Structuradatelor
Format JSON
Fără vectori
Maxim 32 niveluri de imbricare
Aspecte de luat în considerare la proiectare
Evitarea imbricării datelor pe foarte multe niveluri
Date nenormalizate
12
462.
Firebase Realtime Database
Claseși interfețe
implementation 'com.google.firebase:firebase-database:19.2.0'
FirebaseDatabase
Baza de date
DatabaseReference
Referințe la elemente din baza de date
DataSnapshot
Copii ale datelor în memorie
ValueEventListener
ChildEventListener
13
463.
Firebase Realtime Database
Inițializareabazei de date
Clasa FirebaseDatabase
Metoda statică getInstance()
Exemplu
FirebaseDatabase database =
FirebaseDatabase.getInstance();
14
464.
Firebase Realtime Database
Referireadatelor
Referință la elementul rădăcină
DatabaseReference dbRef = database.getReference();
DatabaseReference dbRef = database.getReference("/");
Referință la un element specific
DatabaseReference refCarti = database.getReference("carti");
Referință unui sub-element
database.getReference("carti").child(cota);
database.getReference("/carti/cota");
Dacă elementele nu există, acestea vor fi create
15
465.
Firebase Realtime Database
Salvareadatelor
Adăugarea/înlocuirea unei valori
refCarteNoua.setValue(carte);
Generarea unei valori unice și inserarea acesteia
databaseReference.push();
Generarea, inserarea și obținerea unei valori unice
String cheie = databaseReference.push().getKey();
16
466.
Firebase Realtime Database
Preluareadatelor
Clasa DataSnapshot
Copie nemodificabilă a datelor referite
Metode
child(cale)
Obiect de tip DataSnapshot asociat căii
getValue(Clasa.class)
Clasa trebuie să aibă constructor implicit
getRef()
Referința la sursa asociată datelor
hasChildren()
getChildrenCount()
17
Firebase Realtime Database
Modificareadatelor
Metoda updateChildren(Map)
Obiectul de tip Map include
Proprietățile care se modifică (sau calea)
Valorile asociate
Posibilitatea de modificare a mai multor valori
refCarti.updateChildren(map)
19
Firebase Realtime Database
Interogareadatelor
Clasa Query
Sortare
Cheie
Valoare
Valoare copil
Indexare pentru îmbunătățirea performanțelor
Operațiile returnează tot obiecte de tip Query
21
471.
Firebase Realtime Database
Interogareadatelor
Sortare
orderByChild()
orderByKey()
orderByValue()
Filtrare
equalTo()
startAt()//mai mare sau egal
endAt() //mai mic sau egal
limitToFirst()
limitToLast() 22
472.
Firebase Realtime Database
Preluareadatelor
Preluarea datelor se realizează prin intermediul aceluiași mecanism
DatabaseReference extinde clasa Query
Asociere obiecte de tip listener
addListenerForSingleValueEvent()
addValueEventListener()
23
Cloud Firestore
Variantăoptimizată pentru aplicații mobile
Baze de date în timp real
NoSQL
Date stocate într-un format similar JSON
Colecții și documente
Suport extins pentru filtrări și sortări
Autentificare
Găzduire în cloud
Sincronizare
25
Cloud Firestore
Clase șiinterfețe
implementation 'com.google.firebase:firebase-firestore:21.3.0'
FirebaseFirestore
Baza de date
CollectionReference
Referință colecție
DocumentReference
Referință înregistrare (document)
QuerySnapshot
QueryDocumentSnapshot
27
477.
Cloud Firestore
Inițializarea referințeila baza de date
Setări prealabile
Android Studio
Consola Firebase
Clasa FirebaseFirestore
Metoda statică getInstance()
28
478.
Cloud Firestore
Referirea colecțiilor
CollectionReference
Instanțiere plecînd de la o referință la baza de date
Inițializare
metoda collection(nume_colecție)
CollectionReference biblRef = db.collection("biblioteca");
29
479.
Cloud Firestore
Referirea înregistrărilor(documente)
DocumentReference
Instanța asociată unei înregistrări
Se obține plecând de la o referință de colecție
DocumentReference c1Ref =
db.collection("biblioteca").document("c1");
sau
CollectionReference biblRef = db.collection("biblioteca");
DocumentReference c1Ref = biblRef.document("c1");
sau
DocumentReference c1Ref = db.document("biblioteca/c1");
30
480.
Cloud Firestore
Adăugarea înbaza de date
CollectionReference
metoda add(obiect)
metoda add(map)
Metoda document()
Returnează o referință la un document nou
Identificator generat
Adăugare cu metoda set()
31
481.
Cloud Firestore
Ștergerea dinbaza de date
DocumentReference
Metoda delete()
Identificare document
Referința colecție
metoda document(id)
32
482.
Cloud Firestore
Modificări înbaza de date
DocumentReference
Metoda set()
Identificare document
Referința colecție
metoda document(id)
33
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE, 2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications: A
Practical Development Guide, Editura ASE, 2015, ISBN 978-606-34-
0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android, Editura,
ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development, Wiley,
2012
http://developer.android.com
N. Smyth, Firebase Essentials Android Edition, Payload Media,
2017
https://firebase.google.com/docs/reference/
41
491.
Dispozitive și Aplicații
Mobile– curs 11
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
492.
Agenda
Grafică bidimensională
Imagini
Culori, instrumente, suprafața de scris
Figuri geometrice
Preluarea imaginilor folosind camera foto
Preluarea imaginilor din colecția de fotografii
2
493.
Resurse de tipmultimedia
Fișiere
Imagini
Clipuri audio
Clipuri video
În memorie
Grafică bi/tri-dimensională
Secvențe audio
Animații (bi/tri-dimensionale)
3
494.
Grafică bidimensională
Desenareaimaginilor în memorie
Clasa Bitmap
Culori și texturi
Instrumentul de desenat
clasa Paint
Suprafața de desenat
clasa Canvas
Figuri geometrice
ShapeDrawable
4
Grafică bidimensională
Imagini
Bitmap
Modificabile sau nemodificabile
Metode statice
createBitmap(lat, inalt, config)
Bitmap.Config
createBitmap(srcBitmap) + alte supraîncărcări
createScaledBitmap(src, wDest, hDest, filtru)
Metode
compress(format, calitate, flux_de_iesire)
getWidth(), getHeight()
BitmapFactory
Creare de obiecte de tip Bitmap din diferite surse
Metode statice de tipul decodeSURSA()
Resource, Stream, File etc. 6
Grafică bidimensională
Instrumentul dedesenat
Clasa Paint
Gestionează proprietățile referitoare la desenarea figurilor, textului și
imaginilor
Include metode pentru proprietăți
culoare
grosime
stilul liniei
font
alte efecte speciale
Majoritatea metodelor de desenare au un parametru de tip Paint
14
505.
Grafică bidimensională
Clasa Paint
Stabilire culoare
void setColor(int culoare)
void setARGB(int a, int r, int g, int b)
Proprietăți text
void setTextAlign(Paint.Align align)
void setTextSize(float textSize)
15
Grafică bidimensională
Paint creionGrad= new Paint(), creionNegru = new Paint(), creionText = new Paint();
creionNegru.setColor(Color.BLACK);
creionNegru.setStyle(Paint.Style.STROKE);
creionNegru.setAntiAlias(true);
creionText.setTextAlign(Paint.Align.CENTER);
creionText.setColor(Color.GREEN);
creionText.setTextSize(24);
creionGrad.setShader(gradientBmps);
creionGrad.setStrokeWidth(30);
17
508.
Grafică bidimensională
Suprafața dedesenare
Clasa Canvas
Include metode pentru desenare
Metode de tipul draw…()
Instrumentul de scris
Poziția
18
509.
Grafică bidimensională
Desenarea încontroale
Clasa derivată din View
Metoda cu apel invers onDraw()
de evitat alocarea obiectelor grafice aici
Metodele
invalidate()
postInvalidate()
19
Grafică bidimensională
Contururi geometrice- clasa Path
Suport pentru grafică vectorială
Permite crearea de contururi geometrice bazate pe linii și curbe
Adăugarea de conturi geometrice:
addCircle()
addRect()
addArc()
etc.
Combinarea contururilor
addPath()
27
518.
Grafică bidimensională
Exemplu: Canvas
//culoarefundal
canvas.drawColor(Color.YELLOW);
//linie
canvas.drawLine(10, 10, 300, 4000, creion); //----------creion este de tip Paint
//cerc
canvas.drawCircle(100, 100, 50, creion);
// dreptunghi
canvas.drawRect(rect, creion); //---------rect este de tip Rect sau RectF
//elipsa
canvas.drawOval(rect, creion);
//creare contur geometric
path.addArc(rect, 270, 90);//--------------path este de tip Path
// desenare dupa contur
canvas.drawPath(path, creion);
// scriere text dupa contur
canvas.drawTextOnPath("Contur arc", path, 0, 40, creion);
28
Grafică bidimensională
Decuparea
Zonade decupare (clip)
stabilește suprafața care va fi desenată cu ajutorul
contextului dispozitiv (clasa Canvas)
Inițial, zona de decupare coincide întregii ferestre.
Modificarea zonei de decupare se realizează prin metodele:
clipRect()
clipPath()
30
Figuri geometrice (codsursă Java)
ShapeDrawable drawable;
Canvas canvas;
int x, y, width, height;
drawable = new ShapeDrawable(new RectShape());
drawable.getPaint().setColor(Color.RED);
drawable.setBounds(x, y, x + width, y + height);
drawable.draw(canvas);
33
524.
Figuri geometrice (XML)
Elementul shape
Atributul android:shape reprezintă figura
rectangle
oval
line
ring
Proprietăți (elemente XML incluse)
stroke
solid
gradient
size
34
Preluarea imaginilor folosindcamera foto
Camera
Acces prin aplicații dedicate
Intent
Utilizare clase specializate
Camera
android.permission.CAMERA
37
528.
Preluarea imaginilor folosindcamera foto
Camera: aplicații instalate
Acces prin intermediul mesajelor (Intent)
Captare imagini
Acțiune MediaStore.ACTION_IMAGE_CAPTURE
Captare video
Acțiune MediaStore.ACTION_VIDEO_CAPTURE
38
529.
Preluarea imaginilor folosindcamera foto
Camera: aplicații instalate
Lansare aplicație
void startActivityForResult(Intent intent, int codCerere)
Preluare rezultat
protected void onActivityResult (int codCerere, int
codRezultat, Intent intent)
39
530.
Preluarea imaginilor folosindcamera foto
Camera: aplicații instalate
final int CAPTEAZA_IMAGINE = 1;
//…
Intent capteazaImagine = new
Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(capteazaImagine,
CAPTEAZA_IMAGINE);
40
531.
Preluarea imaginilor folosindcamera foto
Camera: aplicații instalate
private Bitmap fotografie = null;
...
@Override
protected void onActivityResult(int codCerere,
int codRezultat, Intent data) {
if (codRezultat== Activity.RESULT_OK &&
codCerere ==CAPTEAZA_IMAGINE) {
Bundle rezultat = data.getExtras();
fotografie = (Bitmap) rezultat.get("data");
}
} 41
532.
Preluarea imaginilor dincolecția de
fotografii
final int SELECTEAZA_IMAGINE = 2;
//creare intent
Intent intent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
//invocare activitate selectie imagine
startActivityForResult(intent, SELECTEAZA_IMAGINE);
42
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
44
535.
Dispozitive și Aplicații
Mobile– curs 12
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
Receptori de mesaje
Transmitereași recepționarea mesajelor globale
La nivel global pot fi transmite mesaje (obiecte de tip Intent)
Mesajele pot fi transmise din aplicații:
de sistem
utilizator
Aplicațiile pot reacționa la apariția mesajelor transmise global, la
nivelul sistemului
Exemple:
Finalizarea descărcării unui fișier
Identificarea unui dispozitiv (NFC, Bluetooth etc.)
Nivelul bateriei etc.
3
Receptori de mesaje
Recepționareamesajelor globale
Se implementează clasa abstractă BroadcastReceiver
Receptorii nu prezintă interfață grafică
O aplicație poate avea mai multe componente de acest tip
Includ filtre de mesaje
5
540.
Receptori de mesaje
Înregistrareareceptorilor
Receptorii sunt înregistrați:
Static: fișierul manifest XML (elementul receiver)
Dinamic: codul sursă
Receptorul
Independent (XML)
Legat de componenta în care este definit (Java)
6
541.
Receptori de mesaje
Înregistrareareceptorilor (XML)
Androidmanifest.xml
<receiver android:name=".ClasaReceptor" >
<intent-filter>
<action android:name="ACTIUNE_SPECIFICA" />
</intent-filter>
</receiver>
În fișierul Java
Crearea clasei ClasaReceptor derivată din clasa abstractă
BroadcastReceiver
7
542.
Receptori de mesaje
Înregistrareareceptorilor (Java)
Creare obiect de tip IntentFilter
Creare obiect care implementează clasa abstractă BroadcastReceiver
Înregistrarea unui receptor
registerReceiver()
Deconectarea receptorului
unregisterReceiver()
8
543.
Receptori de mesaje
Prelucrareamesajelor
Metoda onReceive(Context, Intent)
Mesajul este primit ca parametru
Prelucrări la recepționarea mesajului
Reprezintă durata de viață a unui receptor
Oprirea retransmiterii mesajului în sistem (pentru mesajele cu priorități)
abortBroadcast()
9
544.
Receptori de mesaje
Transmitereamesajelor globale
Mesajele sunt transmise
Fără prioritate
Cu priorități
sendBroadcast()
sendOrderedBroadcast()
Parametrul comun:
Mesajul (Intent)
O formă care include:
Permisiunea necesară (String)
10
545.
Servicii
Rutine carerulează în paralel cu firul principal
Nu prezintă interfaţă grafică
Permit derularea unor acţiuni în fundal fără a bloca firul principal de
execuţie şi interacţiunea cu aplicaţiile
Servicii predefinite (sistem) și servicii utilizator
11
546.
Servicii
Servicii locale
Rulează în același proces cu aplicația care a pornit serviciul
Servicii la distanță
Rulează în propriul proces
Comunicare inter-proces
RPC, AIDL (Android Interface Definition Language) etc.
12
547.
Servicii
Servicii de sistem
Servicii predefinite
Notificare
Conectivitate
Descărcare fișiere
Alarme
Localizare etc.
Gestionate prin clase specializate
Acces prin intermediul clasei Context
metoda getSystemService()
13
548.
Servicii
Servicii predefinite
getSystemService(Stringserviciu)
serviciu:
Denumirea seriviciului
Constante definite în clasa Context
returnează un obiect de tipul serviciului:
LocationManager
AudioManager
DownloadManager
WiFiManager etc.
prin intermediul căruia acesta este utilizat.
14
Servicii
PendingIntent
Mesaj transmisunei aplicații pentru efectuarea unor operații cu
permisiunile aplicației sursă
Acțiunea se execută în viitor
Aplicația care a transmis mesajul poate să fie inactivă în
momentul execuției acestuia
16
551.
Servicii
PendingIntent
Implementează interfațaParcelable
Parametri de inițializare
context, identificator, Intent, indicatori
Inițializare (metode statice)
Pentru lansarea unei activități
getActivity()
Pentru transmiterea unui mesaj global
getBroadcast()
Pentru lansarea unui serviciu
getService()
Indicatori
FLAG_ONE_SHOT, FLAG_NO_CREATE,
FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT 17
552.
Servicii
Servicii predefinite– Exemplu
private final int NOTIF_ID = 1; String url = "url valid";
//initializare manager notificari
NotificationManager notifManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
//comportamenul la click pe notficare
Intent intentNotificare = new
Intent(Intent.ACTION_VIEW, Uri.parse(url));
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, intentNotificare, 0);
18
Servicii
Servicii predefinite– Exemplu
DownloadManager dldManager =
(DownloadManager) getSystemService(
Context.DOWNLOAD_SERVICE);
Request request = new Request(
Uri.parse(urlCurs));
request.setDescription("PDM - Curs");
long idd = dldManager.enqueue(request);
20
555.
Servicii
Servicii predefinite– Exemplu
//asociere receptor
registerReceiver(descarcat, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
//definire receptor
BroadcastReceiver descarcat = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) { //fișier descărcat
}
//eliminare asociere receptor
unregisterReceiver(descarcat);
21
556.
Servicii
Servicii utilizator
Derivaredin clasa Service
Derivare din clasa IntentService
Declarare în fișierul manifest XML
<application ... >
<service android:name=".Serviciu" />
...
</application>
22
557.
Determinarea poziției geografice
Serviciu de sistem
Componentă Google Services
Necesită permisiuni
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_COARSE_LOCATION
23
558.
Determinarea poziției geografice
Poziționaregeografică
1. Inițializare serviciu de localizare
2. Asocierea unui obiect de tip listener cu precizarea:
Sursei utilizată la localizare
Intervalul de timp la care se face actualizarea datelor
3. Notificări în momentul apariției de modificări legate de:
Poziția geografică
Starea sursei de localizare
4. Întreruperea asocierii cu obiectul de tip listener
Frecvența de actualizare!
24
559.
Determinarea poziției geografice
Inițializareserviciu de localizare
Se inițializează serviciul de sistem identificat prin nume:
Context.LOCATION_SERVICE
Se obține un obiect de tip LocationManager
Localizare prin diferite surse:
Receptorul GPS
Rețele WiFi, celule mobile
25
560.
Determinarea poziției geografice
Asocierefurnizori serviciu de localizare
Clasa LocationManager
Metoda requestLocationUpdates()
informări cu privire la modificările poziției geografice:
obiecte de tip LocationListener sau PendingIntent
Metoda requestSingleUpdate()
26
561.
Determinarea poziției geografice
Asocierefurnizori serviciu de localizare: metoda requestLocationUpdates()
Parametri comuni:
Intervalul minim de actualizare
Distanța minimă de actualizare (corelată cu intervalul de actualizare)
Alți parametri
Sursa de localizare:
Constanta GPS_PROVIDER sau NETWORK_PROVIDER
(LocationManager)
Criteriu de selecție (clasa Criteria)
Obiectul care implementează interfața LocationListener sau de tip
PendingIntent
27
562.
Determinarea poziției geografice
Eliminareaasocierii
Metoda removeUpdates() din clasa LocationManager
Parametrul
Obiectul de tip LocationListener
Obiectul de tip PendingIntent
28
563.
Determinarea poziției geografice
ClasaLocationManager
Obținerea ultimei poziții cunoscute
Location getLastKnownLocation(String sursa)
Informații despre starea receptorului GPS
GpsStatus getGpsStatus(GpsStatus status)
Selectarea celui mai bun furnizor pe baza criteriilor definite
String getBestProvider(Criteria criteriu,
boolean doarFurnizoriActivi)
29
564.
Determinarea poziției geografice
InterfațaLocationListener
Recepționarea de notificări la modificarea poziției geografice
Pe baza cerințelor de actualizare (interval și distanță)
Metoda principală
void onLocationChanged(Location poz)
Coordonatele accesibile prin clasa Location
Alte metode
onProviderEnabled()
onProviderDisabled()
onStatusChanged()
30
565.
Determinarea poziției geografice
ClasaLocation
Coordonate
getLatitude(), getLongitude(), getAltitude()
Viteza
getSpeed()
Timp
getTime()
Acuratețea localizării
getAccuracy()
Alte informații
31
566.
Determinarea poziției geografice
Poziționaregeografică – Exemplu
class LocListener implements LocationListener {
@Override
public void onLocationChanged(Location poz) {
/*poz.getLatitude(), poz.getLongitude(), poz.getAltitude(); */
}
//…
}
32
Determinarea poziției geografice
Obținereaadreselor
Clasa Geocoder
Servicii de backend
Determinare disponibilitate serviciu
Metode statică isPresent()
Inițializare
Constructor cu un parametru de tip Context
Permisiune INTERNET
34
569.
Determinarea poziției geografice
Obținereaadreselor
Metode
getFromLocation(lat, long, nrMaxAdrese)
getFromLocationName()
Liste de adrese
Clasa Address
List<Address>
Clasa Address
getCountry()
getCountryCode()
getLocality()
getAddressLine() etc. 35
Google Maps
GoogleMaps API v2
Se bazează pe serviciul Google Maps
Biblioteca opțională
Inclusă în Google Play services
Categoria Extras în SDK Manager
Google Play services APK trebuie să fie instalat și pe dispozitivul mobil
Facilități
hărți 3D, interior, satelit, teren, trafic, marcaje, plane suprapuse,
trasare linii etc.
37
572.
Google Maps
Inițializare
Înregistrarela Google Maps Service pentru obținerea unei chei pentru
Maps API
https://code.google.com/apis/console
Cheia va fi inclusă în fișierul AndroidManifest.xml
Necesită un cont cu informații de facturare
Instalare Google Play services SDK
Adăugarea proiectului bibliotecii Google Play services la spațiul de
lucru
Referirea bibliotecii Google Play services în proiectul de lucru
38
573.
Google Maps
Clase GoogleMaps API v2
Pachetul com.google.android.gms.maps
MapView
Control care încapsulează o hartă
MapFragment, SupportMapFragment
Fragment care încapsulează o hartă
UiSettings
Control setări interfața hartă
39
574.
Google Maps
Inițializarea hărții
Inițializare
Clasele MapFragment, MapView sau SupportMapFragment
Metoda getMapAsync()
Interfața OnMapReadyCallback
Metoda onMapReady(GoogleMap map)
Stabilirea tipului hărtii
Metoda setMapType(tip_harta)
MAP_TYPE_NORMAL, MAP_TYPE_SATELLITE,
MAP_TYPE_TERRAIN
40
575.
Google Maps
Control setări
Clasa UiSettings
Inițializare: getUiSettings()
Facilități
Controale mărire/micșorare
Activare gesturi control
Afișare busolă
Buton localizare
Bară controale
41
Google Maps
Adăugarea defiguri geometrice
Cerc
Circle addCircle(CircleOptions)
Linii
Polyline addPolyline(PolylineOptions)
Imagine
GroundOverlay addGroundOverlay(GroundOverlayOptions)
Poligon
Polygon addPolygon(PolygonOptions)
43
578.
Google Maps
Marcaje
ClasaMarker
Pictograme pe hartă
Proprietăți
Titlu
Poziție (coordonate) – LatLng (latitudine și longitudine)
Pictogramă
etc.
Metoda addMarker(MarkerOptions) din clasa GoogleMaps
Clasa MarkerOptions
Stabilire opțiuni obiect de tip Marker
44
579.
Google Maps –Implementare
Fișierul xml asociat (res/layout)
fragment
android:id="@+id/harta"
android:name="com.google.android.gms.maps.MapFragment"
Fișierul java asociat
MapFragment mf = ((MapFragment) getFragmentManager()
.findFragmentById(R.id.harta)) ;
mf.getMapAsync(onMapReadyCallback);
45
580.
Google Maps –Implementare
@Override
public void onMapReady(GoogleMap googleMap) {
LatLng latLong = new LatLng(lat, longit);
map.setMyLocationEnabled(false);
map.moveCamera(CameraUpdateFactory.
newLatLngZoom(latLong, 18));
Marker marker = map.addMarker(new MarkerOptions().position(latLong));
marker.setTitle(locatie);
marker.showInfoWindow();
}
46
581.
Google Maps –Implementare
AndroidManifest.xml
Permisiuni (minim):
ACCCES_FINE_LOCATION pentru map.setMyLocationEnabled(true)
Cheia Google Maps API
<meta-data android:name="com.google.android.maps.v2.API_KEY"
android:value="cheia generata" />
47
582.
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
48
583.
Dispozitive și Aplicații
Mobile– curs 13
Prof. univ. dr. Paul POCATILU, Prof. univ. dr. Cristian CIUREA
Departamentul de Informatică și Cibernetică Economică
cristian.ciurea@ie.ase.ro
1
584.
Agenda
Furnizori deconținut
Gestiunea dinamică a permisiunilor
PIM (E-mail, SMS, Contacte)
Publicarea aplicațiilor în magazinul virtual Play Store
2
585.
Furnizori de conținut
Pentru partajarea datelor între aplicaţii se utilizează și furnizorii de
conţinut
pun la dispoziție un mecanism standardizat pentru transferul
datelor între aplicații
Surse de date:
fişiere
baze de date
alte surse
O alternativă la furnizorii de conţinut: comunicarea între procese
3
586.
Furnizori de conținut
Acces deseori ierarhic
Bază de date
Mai multe tabele
Coloane
Rânduri
Referire prin URI
tip MIME asociat conținutului
4
Furnizori de conținut
Referireafurnizorilor de conținut
URI
content://furnizor/cale[/id].
Furnizor + calea la obiect
Constante definite în clasa furnizorului de conținut
Calls.CONTENT_URI = "content://call_log/calls"
8
Furnizori de conținut
Interogareaunui furnizor de conținut
Metoda query() din clasa ContentResolver
Parametri:
Uri asociat furnizorului de conținut
Coloanele selectate
Criteriul de selecție
Valorile asociate parametrilor din criteriul de selecție
Ordinea de sortare
10
593.
Furnizori de conținut
Interogarea unui furnizor de conținut
Uri uri = …
ContentResolver cr = getContentResolver();
Cursor date = cr.query(uri, null, null, null, null);
if (date != null) {
while(date.moveToNext()) {
//prelucrare linie curenta
}
}
11
594.
Furnizori de conținut
Furnizori de conținut predefiniți – Exemplu
ContentResolver cr = getContentResolver();
Cursor log = cr.query(CallLog.Calls.CONTENT_URI,
null,
CallLog.Calls.TYPE + "=?",
new String[]{ String.valueOf(
CallLog.Calls.OUTGOING_TYPE) },
null);
12
595.
Furnizori de conținut
Furnizori de conținut predefiniți – Exemplu
if (log != null) {
while(log.moveToNext()) {
int iColTel = log.getColumnIndex(CallLog.Calls.NUMBER);
int iColData = log.getColumnIndex(CallLog.Calls.DATE);
int iColDurata = log.getColumnIndex(CallLog.Calls.DURATION);
String telefon = log.getString(iColTel);
Date data = new Date(Long.parseLong(log.getString(iColData)));
String durata = log.getString(iColDurata);
//utilizare telefon, data si durata
}
}
13
596.
Furnizori de conținut
Implementareafurnizorilor de conținut
Implementare ContentProvider
Metode:
query()
returnează un Cursor
insert()
Returnează un Uri asociat înregistrării inserate
update(
delete()
getType()
Tipul MIME asociat conținutului
14
597.
Furnizori de conținut
Implementareafurnizorilor de conținut
Declararea în fișierul AndroidManifest.xml
//…
<provider
android:name="com.pdm.provider.FC"
android:authorities="com.pdm.provider.FC"
android:exported="true" >
</provider>
15
598.
Furnizori de conținut
Partajarea/Transmitereadatelor între activități
Bundle
Tipuri simple
Tipuri care implementează interfața Parcelable
Tipuri care implementează interfața Serializable
Stocare persistentă
Fișiere de proprietăți
Fișiere
Baze de date
Membri statici
Clasa Application
Furnizori de conținut
16
599.
Gestiunea dinamică apermisiunilor
Tipuri de permisiuni
Normale
Accesul este acordat automat
Exemple: Internet, Bluetooth, NFC, Vibrații etc.
Cu risc/Periculoase
Accesul este acordat individual de către utilizator
Aplicațiile controlează accesul la execuție
Exemple: Calendar, Camera, Contacts, SMS, Location, Phone,
Storage etc.
17
600.
Gestiunea dinamică apermisiunilor
Etape în gestiunea permisiunilor
Verificarea existenței permisiunii
Efectuarea cererii de acceptare a unei permisiuni
Explicarea motivului
Efectuarea cererii
Gestionarea răspunsului
18
Gestiunea dinamică apermisiunilor
Preluarea răspunsului
Metoda cu apel invers din clasa ActivityCompat:
onRequestPermissionsResult()
Parametrii
Codul cererii
Lista permisiunilor (String [])
Lista răspunsurilor (int[])
PackageManager.PERMISSION_GRANTED
PackageManager.PERMISSION_DENIED
22
605.
Gestiunea dinamică apermisiunilor
Preluarea răspunsului
Dacă permisiunea a fost acordată
se execută codul
Dacă nu a fost acordată
Permisiunea poate fi solicitată din nou
23
606.
Publicarea aplicațiilor înGoogle Play
Necesită un cont Google
Taxa se plătește o singură dată
https://play.google.com/apps/publish
Consola dezvoltare
Listă aplicații
Fișiere binare aplicație (APK)
Descriere aplicație
Statistici
Părerea utilizatorilor și clasificări
etc.
24
Bibliografie
P. Pocatilu,Programarea dispozitivelor mobile, Editura ASE,
2012.
C. Boja, C. Ciurea, M. Doinea – Android Mobile Applications:
A Practical Development Guide, Editura ASE, 2015, ISBN 978-
606-34-0033-9, 418 pg.
P. Pocatilu, I. Ivan ș.a., Programarea aplicațiilor Android,
Editura, ASE, 2015.
S. Komatineni, D. MacLean, Pro Android 4, Apress, 2012
R. Meier, Professional Android 4 Application Development,
Wiley, 2012
http://developer.android.com
27