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
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
Obiectivul disciplinei
 Utilizarea eficientă 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
Prezentare disciplină
 Site-ul disciplinei 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
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
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
Abilități necesare
 Experiență de dezvoltare în Java (sau Kotlin)
 Experiență de lucru în Android Studio (sau IntelliJ IDEA, sau
Eclipse cu ADT)
7
Introducere/Dispozitive mobile
 Telefoane mobile
 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
 Utilitate: comunicare (e-mail, mesaje scrise, telefon)
 Gestiunea informațiilor personale (date de contact, agenda,
calendar)
 Navigare Internet
 Rețele sociale
 Divertisment (jocuri, cărți)
 Multimedia (filme, imagini și muzică)
 Navigație (GPS, localizare)
 Plăți (NFC)
9
Introducere/Dispozitive mobile
Caracteristici:
 Portabilitate
 Accesibilitate: oriunde, oricând
 Personale
Limitări (vs. PC):
 Autonomie (baterie)
 Fragmentare
 Bandă de transfer (acoperirea)
 Modalități de interacțiune
 Dimensiuni (ecran)
 Putere de calcul
 Memorie (RAM şi ROM)
10
Introducere/Dispozitive mobile
Tendințe:
 Dezvoltare rapidă și variată (prețuri)
 Evoluție performanțe hardware
 Software cu aplicații în numeroase domenii
Caracteristici hardware:
 Procesor
 Memorie
 Ecran
 Modalități de introducere a datelor
 Conectivitate
11
Introducere/Dispozitive mobile
12
Introducere/Dispozitive mobile
13
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
Introducere/Dispozitive mobile
Procesoare de aplicaț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
Procesoare de aplicații
 Qualcomm
 Snapdragon seriile 400, 600 și 800
 Samsung
 Exynos seriile 5, 7 și 8
 NVIDIA
 Tegra 4
 Tegra K1
 Tegra X1
16
Introducere/Dispozitive mobile
Procesoare de aplicații
 Apple
 A7 (iPhone 5s)
 A8/A8x (iPhone 6/iPad Air 2)
 A9 (iPhone 6S și 6S Plus)
 A10 Fusion (iPhone 7 și 7 Plus)
 A11 Bionic (iPhone X)
 ……….
 A15 Bionic (iPhone 13 Pro)
 M1 (iPad Pro/Air)
 Texas Instruments
 OMAP
 Intel
 Atom 17
Introducere/Dispozitive mobile
Memorie
 Memorie RAM
 Memorie internă nevolatilă
 Flash
 NOR – XIP (eXecute In Place) - random access
 NAND (NOT-AND) - blockwise access only
 Memorie externă
 Cartelă memorie (uzual microSD)
18
Introducere/Dispozitive mobile
Ecran
 Diagonala
 Rezoluția
 Densitatea (ppi, dpi)
 Număr culori
 Tehnologia
 LCD TFT (Transmissive, Transflective, Reflective)/Super
LCD/IPS/OLED/AMOLED
 Tactil sau nu
 Capacitiv
 Rezistiv
19
Introducere/Dispozitive mobile
Metode de introducere a datelor
 Ecran tactil (touch screen)
 Tastatură virtuală
 Tastatură numerică
 Mini -Joystick (D-pad)
 Tastatură QWERTY
20
Introducere/Dispozitive mobile
Conectivitate wireless
21
Reţea
Wireless
Rata maximă de
transfer
Standarde/Tehnologii
WPAN 9.6 Kbps - 3 Mbps IR, Bluetooth, NFC
WLAN 1-300 Mbps 802.11 a, b, g, n
WWAN 8 Kbps-300 Mbps GSM (CSD, HCSD), GPRS, EDGE,
UMTS (WCDMA) cu
HSPDA/HSPA+, LTE
cdmaOne, CDMA2000
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
Introducere/Dispozitive mobile
Conectivitate WWAN
23
Standard Rata maximă de transfer
CSD 9.6 -14.4 kbps
HSCSD 28.8 - 56 kbps
GPRS 115 Kbps
EDGE 236.8 Kbps
UMTS 384 kpbs – 7.2/14/21/42 Mbps
(cu HSDPA/HSPA+)
LTE 300 Mbps
Introducere/Dispozitive mobile
Dispozitive mobile - caracteristici
24
Caracteristica
Dispozitiv
Dimensiunea
ecranului
Frecvență
procesor
Memoria
(RAM/Internă/E
xterna)
Conectivitate
Telefon mobil 1”-2.5”
160x160 -
QVGA
Minimală 1-64 MB/
MMC, mSD
GSM, GPRS, EDGE,
UMTS, Bluetooth, IR
Smartphone 2.5”-5”,
320x240 –
Full HD
144-2200 MHz 32 MB – 2 GB/
4-64GB
*SD, MMC
GSM, GPRS, EDGE,
UMTS,
WiFi (802.11b/g/n/ac),
Bluetooth, IR
Tabletă 7" – 10" 800– 2200 MHz 512 MB – 2 GB/
4-64GB
*SD
GSM, GPRS, EDGE,
UMTS, LTE/WiFi
(802.11b/g/n/ac)/Bluetoo
th, IR
Portabil
(wearable)
1.25" – 2"
128x128 –
320x480
1 – 1.2 GHz 512MB – 1GB/
4-8 GB/
-
Bluetooth, WiFi, LTE
Sisteme de operare pentru 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
26
Sisteme de operare pentru dispozitive mobile
 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 operare pentru dispozitive mobile
Smartphone (2008-2011)
28
Sisteme de operare pentru 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 operare pentru dispozitive mobile
Smartphone (2015 – 2016)
30
Sisteme de operare pentru dispozitive mobile
Smartphone (2009 – 2018)
31
Sisteme de operare pentru dispozitive mobile
Smartphone (2009 – 2020)
32
Sisteme de operare pentru 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
Sisteme de operare pentru 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
Sisteme de operare pentru 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
Sisteme de operare pentru dispozitive mobile
36
Arhitectura platformei Android:
Sisteme de operare pentru 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:
Sisteme de operare pentru 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:
Sisteme de operare pentru dispozitive mobile
39
Operating system API level
Android 12 (Snow Cone) 31, 32
Android 13 (Tiramisu) 33
Versiuni de Android:
Sisteme de operare pentru dispozitive mobile
40
Versiuni de Android:
Sisteme de operare pentru 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)
Sisteme de operare pentru 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 operare pentru dispozitive mobile
43
 Android 10 Highlights
Sisteme de operare pentru dispozitive mobile
44
 Android 11 Highlights
Sisteme de operare pentru 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.
Sisteme de operare pentru 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.
Sisteme de operare pentru 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
Android: concepte de bază
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
Android: concepte de bază
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:
Android: concepte de bază
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++
Android: concepte de bază
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
Android: concepte de bază
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
Android: concepte de bază
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
Android: concepte de bază
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
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
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
Agenda
 Structura aplicațiilor Android
 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
Android: concepte de bază
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 de bază
 Android SDK Tools: C:UsersCristianAppDataLocalAndroidsdktools
 Subfolder: sdk/tools
 Instrumente:
 script-uri ant pentru obținerea pachetului binar al aplicației
 monitor (ddms)
 emulator-arm, emulator-x86
 Android SDK Platform-tools: C:UsersCristianAppDataLocalAndroidsdkplatform-tools
 Folder: sdk/platform-tools
 Instrumente:
 adb – comunicarea cu dispozitivele Android
 sqlite3
 Android SDK Build-tools: C:UsersCristianAppDataLocalAndroidsdkbuild-tools25.0.2
 Folder: sdk/build-tools/version/
 Instrumente:
 aapt – compilare resurse, generarea fișierului R.java, fișiere APK
 dx - conversie cod binar Java la cod binar Dalvik
4
Android Debug Bridge (ADB)
 adb devices
 adb kill-server
 adb install
 adb pull
 adb push
 adb shell
5
Android: concepte de bază
.java
• javac
.class
• dx
.dex
(+resources)
• aapt
.apk
6
Android binary files:
Android: concepte de bază
Android SDK Manager:
 Gestiunea platformelor și a instrumentelor necesare
 Acces direct sau din mediul de dezvoltare
 Platforma
 Biblioteci
 Cod sursă
 Documentație
 Imagini emulator
7
Android SDK Manager
8
Android: concepte de bază
Android Virtual Device (AVD):
 Dispozitive virtuale Android:
 Emulatoare
 Caracteristici:
 Procesor (ARM, x86_x64), Ecran (rezoluție ,dimensiune), Memorie
(RAM, internă persistentă, externă), Versiune API, Camere
 Emulatoare
 ARM (Advanced RISC Machine)
 x86, x64
 Necesită Intel HAXM (Hardware Accelerated Execution Manager) și CPU cu
suport de virtualizare
 Comunicare prin aplicația adb.exe
9
AVD Manager
10
Android: concepte de bază
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
Android: concepte de bază
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
Android: concepte de bază
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
Android: concepte de bază – LogCat
14
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
Structura aplicațiilor Android
Componentele de 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
17
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
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
Structura aplicațiilor Android
Furnizori de 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
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
Structura aplicațiilor Android
Receptori de 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
Structura unui proiect Android:
 Fișiere sursă (src)
 Resurse (res)
 res/drawable
 res/layout
 res/values
 res/menu
 res/xml
 res/raw
 Resurse preluate ca fluxuri de date (assets)
 Fișier de configurare (AndroidManifest.xml)
 Fișiere generate(gen)
 R.java
23
Structura aplicațiilor Android
 Organizare resurse în Eclipse
24
Structura aplicațiilor Android
 Organizare resurse în Android Studio
25
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
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!
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
Cerințe hardware și software:
 android.hardware.camera
 android.hardware.camera.autofocus
 android.hardware.camera.flash
 android.hardware.nfc
 android.hardware.sensor.gyroscope
 android.hardware.Bluetooth
 android.software.live_wallpaper
 android.software.home_screen
29
AndroidManifest.xml
30
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ase.pdm.sem1" android:versionCode="1" android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET"/>
<application android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity> ... </activity>
<service>...</service>
<provider>...</provider>
<receiver>...</receiver>
</application>
</manifest>
Structura aplicațiilor Android
Gradle:
 Set de instrumente pentru automatizarea procesului de build
 Independent de Android Studio
 Android Gradle Plugin
31
build.gradle
32
android {
compileSdkVersion 24
buildToolsVersion "24.0.4"
defaultConfig {
applicationId "ro.ase.pdm.myapplication"
minSdkVersion 16
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
}
Procesul de build
33
Structura aplicațiilor Android
Fișierele binare 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
Structura aplicațiilor Android
Clasa Context:
 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
Structura aplicațiilor Android
Clasa Aplicaț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
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
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
Structura aplicațiilor Android
39
Ciclul de viață al activităților:
Structura aplicațiilor Android
Salvarea/restaurarea stării:
 Salvarea stării
 onSaveInstanceState(Bundle state)
 Apelată la ieșirea forțată din aplicație (modificarea configurației)
 Restaurarea stării
 onRestoreInstanceState(Bundle state) sau
 onCreate(Bundle state)
 state poate fi null!
40
Structura aplicațiilor Android
41
Ciclul de viață al activităților:
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
Ciclul de viață al activităților
43
Clasa Bundle
 Permite stocarea și regăsirea de valori după o cheie de tip String
 Valorile stocate
 Tipuri simple
 Tipuri care implementează interfețele
 Parcelable
 Serializable
 Adăugare valori
 putString(cheie, valoare_String),
 putInt (cheie, valoare_int),
 putObject(cheie, valoare_object),
 putLongArray(cheie, valoare_long_array) etc.
 Regăsire valori
 getString(cheie),
 getInt(cheie),
 getObject(cheie),
 getLongArray(cheie) etc.
44
Proprietățile activităților în
AndroidManifest.xml
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
45
Resurse
 Şiruri de caractere, culori, masive, stiluri (res/values):
 color
 string
 dimen
 array
 Imagini (res/drawable)
 Pictograme aplicație (res/mipmap)
 Fişiere XML compilate (res/xml)
 Fişiere necompilate (res/raw)
 Fişiere de animație (res/anim)
 Pentru fiecare resursă se generează identificatori în clasa R
 Clasa predefinită android.R
46
Resurse
<resources>
<string name="mesaj">Document nou</string>
</resources>
<resources>
<color name="culoare_fundal">#00CCCC</color>
</resources>
<resources>
<array name="optiuni">
<item>zip</item>
<item>rar</item>
<item>7z</item>
</array>
</resources>
47
Clasa R
48
Clasa R
 Subclase
 color
 string
 dimen
 array
 layout
 id
 menu
 etc.
 Membri
 Identificatori/denumire
 Exemple
 R.id.buton
 R.string.denumire_aplicatie
 R.color.rosu
49
Referirea resurselor din cod
 Clasa Resources
 Metoda getResources() din clasa Context
 Metode dedicate
 getString()
 getColor()
 getDimension()
 etc.
50
Referirea resurselor din fișiere XML
 @resursa/nume
 @android:resursa/nume
 Exemple
 @string/mesaj
 @color/culoare_fundal
 @array/optiuni
 @id/id_element
 @+id/id_text1
51
Resurse
//preluarea unui sir de 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
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
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
Containere
 Definesc structura vizuală a interfeței utilizator
 Structurarea conținutului vizual:
 Liniară (verticală/orizontală)
 Tabelară
 Relativă
 Clasă de bază în ierarhie: ViewGroup
 Definire
 Descriptiv
 Procedural
55
Containere
 LinearLayout
 Orizontal sau vertical
 TableLayout
 Linii si coloane
 TableRow
 GridLayout
 Linii și coloane
 Combină TableLayout cu LinearLayout
 RelativeLayout
 Relativ la alte componente
56
Containere
 ConstraintLayout
 Relativ la alte componente
 FrameLayout
 Componentele vizuale sînt suprapuse (stivă)
 ScrollView /HorizontalScrollView
 Permite derularea conținutului pe verticală/orizontală
 AbsoluteLayout (depreciat)
 Poziționare absolută
57
Componente vizuale
 Controale
 Pachetul android.widget.*;
 Incluse
 Text static
 Text editabil
 Butoane
 Liste
 Bare de progres
 etc.
58
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
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
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
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
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
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
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
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
Agenda
 Interfața cu utilizatorul
 componente vizuale
 containere
 Interfața grafică în mod declarativ
 Interfața grafică în mod procedural
 Containere
 Tratarea evenimentelor
2
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
Interfața în mod declarativ
 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
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
Proprietăți
 android:proprietate
 Specifice fiecă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
Referirea resurselor (XML)
 @pachet:tip_resursa/nume_resursa
 Proiectul curent
 @tip_resursa/nume_resursa
 Exemplu:
 @dimen/dim_font
 @color/culoare_fundal
 Resurse predefinite
 @android:tip_resursa/nume_resursa
 Exemplu
 @android:color/background_light
 @android:string/dialog_alert_title
7
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
Densitatea (PPI/DPI)
 Densitatea =
ℎ𝑝2+𝑣𝑝2
𝑑𝑖𝑎𝑔
 hp – rezoluția pe orizontală (pixeli)
 vp – rezoluția pe verticală (pixeli)
 diag – diagonala (inches)
9
Dimensiuni - conversii
 Din pixeli în dp
 𝑑𝑝 =
𝑝𝑥 ∗160
𝐷𝑃𝐼
 Din dp în pixeli
 𝑝𝑥 =
𝑑𝑝 ∗𝐷𝑃𝐼
160
10
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
Dimensiuni
12
Proprietăți
 Identificatorul componentei
 android:id
 Asociere identificator: "@+id/identificator"
 Referire identificator existent:
 XML: @id/identificator
 Java: R.id.identificator
13
Proprietăți
14
Proprietate Atribut Exemple de valori
Textul asociat
resursei
android:text "Text în clar"
@string/text_control
Distanţa
conţinutului faţă
de margini
android:padding
android:paddingTop|Left|Right
|
Bottom
10dp
Culoarea de fundal android:background #FF00FF
@drawable/imag
Modul de aliniere a
conţinutului
android:gravity center, left
Distanţa faţă
de marginile
containerului
android:layout_margin,
android:layout_marginTop|Left
|
Right|Bottom
30dp
Afișarea/ascundere
a componentei
android:visibility visible, invisible,
gone
Proprietăți
15
Exemplu
16
<!—res/layout/main.xml-->
<LinearLayout <!-- … -->
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/textViewTitlul"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:text="@string/titlul" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/introduceti" >
</EditText>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/trimite" />
</LinearLayout>
<!-- /res/values/strings.xnl -->
<resources>
<string name="titlu">Titlul</string>
<string name="introduceti">Introduceti
titlul</string>
<string name="trimite">Trimite</string>
</resources>
// /src/Activitate.java
//in metoda onCreate()
setContentView(R.layout.main)
Referirea componentelor în cod
 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
Interfața în mod procedural
 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
Proprietăți comune
 Dimensiuni:
 getWidth()
 getHeight()
 Aspect:
 setBackgroundColor(int culoare)
 setBackground(Drawable)
 setBackgroundResource(int idResursa)
19
Proprietăți comune
 Spațiere (distanţă faţă de conţinut):
 setPadding()
 getPaddingLeft()
 getPaddingTop()
 getPaddingRight()
 getPaddingBottom()
 Activare:
 setEnabled(boolean)
 isEnabled()
 Posibilitatea de selectare:
 setFocusable(boolean)
 isFocusable()
20
Proprietăți comune
 Parametri container:
 setLayoutParams(LayoutParams)
 LayoutParams getLayoutParams()
 Vizibilitate:
 setVisibility(int) – VISIBLE, INVISIBLE, GONE
21
Proprietăți comune
 Poziție (pixeli):
 absolută
 setX()/getX()
 setY()/getY()
 relativă la părinte
 setLeft()/getLeft()
 setTop()/getTop()
 setRight()/getRight()
 setBottom()/getBottom()
22
Proprietăți comune
 Tratare evenimente:
 setOnClickListener()
 setOnLongClickListener()
 setOnDragListener()
 setOnKeyListener()
 setOnTouchListener()
23
Interfața în mod procedural
//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
Interfața în mod procedural
//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
Interfața în mod procedural
//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
LinearLayout
 Modul de aranjare a componentelor: android:orientation
 horizontal
 vertical
27
LinearLayout
 Distribuirea spațiului rămas liber (proporții)
 android:layout_weight
view1, view2, view3:
android:layout_width="wrap_content“
view1, view2, view3:
android:layout_width="0dp"
android:layout_weight="1“
view1, view2
android:layout_width="wrap_content"
view3:
android:layout_width="0dp"
android:layout_weight="1"
28
LinearLayout
 Alinierea componentelor în cadrul containerului
 android:layout_gravity
29
RelativeLayout
 Aliniere
 Relativă la container (true/false):
 android:layout_alignParentTop|Left|Right|Bottom
 android:layout_centerHorizontal|Vertical
 android:layout_centerInParent
 Relativă la alte componente (id-ul):
 android:layout_alignLeft|Right|Start|Top|End
 Poziționare
 android:layout_below, android:layout_above
 android:layout_toEnd|Left|Start|RightOf
30
RelativeLayout
31
ConstraintLayout
 Ierarhie care nu 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
ConstraintLayout
Restricții
 Puncte de conectare î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
ConstraintLayout
Poziționarea relativă
 app:layout_constraint[PunctSursă]_[PunctDestinație]="[IdentificatorDestinație]"
 PunctSursă
 Start
 Top
 Bottom
 End
 PunctDestinție
 toStartOf
 toEndOf
 toBottomOf
 toTopOf
34
ConstraintLayout
Înlănțuiri
 Proprietăți
 layout_constraintHorizontal_chainStyle
 sau layout_constraintVertical_chainStyle
 Se aplică primului element din înlănțuire
 Valori
 spread
 spread_inside
 packed
Manipulatori
35
TableLayout
 Derivată din LinearLayout
 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
TableLayout
37
GridLayout
 Număr coloane
 android:columnCount
 Întinderea pe mai multe linii:
 android:layout_rowSpan
 Întinderea pe mai multe coloane:
 android:layout_columnSpan
38
GridLayout
39
FrameLayout
 În mod uzual, 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
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
Parametrii containerelor
 Clasa de 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
Parametrii containerelor
//inaltime 20 pixeli
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
Tratarea evenimentelor
 Interfețe de tip listener
 Ex: View.OnClickListener
 Metode pentru tratarea evenimentelor
 Ex.: onClick()
 Înregistrarea evenimentelor
 Ex.: setOnClickListener()
44
Tratarea evenimentelor
45
Interfața
Metoda pentru
tratarea
evenimentului
Înregistrarea obiectului
View.OnClickListener onClick() setOnClickListener()
View.OnKeyListener onKey() setOnKeyListener()
View.OnTouchListener onTouch() setOnTouchListener ()
View.OnLongClickListener onLongClick() setOnLongClickListener()
Tratarea evenimentelor
 Implementarea interfeț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
Tratarea evenimentelor
public class Activitate 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
Tratarea evenimentelor
public class EvenimClick 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
Tratarea evenimentelor
//Înregistrare și implementare 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
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
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
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
Agenda
 Interfața cu utilizatorul
 Stiluri și teme
 Deserializarea componentelor
 Meniuri și bara aplicației
 Menu, ActionBar, Toolbar
 Fragmente
2
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
Interfața cu utilizatorul
4
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
 Stiluri: Definire
<resources>
<style name="stil_titlu">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">#FF0000</item>
<item name="android:textStyle">bold</item>
</style>
</resources>
6
Stiluri și teme
 Stiluri: Referire
<TextView
style="@style/stil_titlu"/>
<TextView
...
style="@android:style/TextAppearance.Large" />
7
Stiluri și teme
 Teme
 Atributul android:theme la nivelul
 Aplicației (toate activitățile)
 Unei activități
 Unui container/control
 AndroidManifest.xml
8
Stiluri și teme
Exemple de teme predefinite
 Theme.Holo
 Theme.Holo.Light
 Theme.Holo.Light.DarkActionBar
 Theme.Material
 Theme.Material.Light
 Theme.Material.Light.DarkActionBar
 Theme.AppCompat
 Theme.AppCompat.NoActionBar
 Theme.AppCompat.Light
 Theme.AppCompat.Light.DarkActionBar
9
Stiluri și teme
 Teme
<activity
android:theme = "@android:style/Theme.Holo.Dialog">
...
</activity>
10
Deserializarea componentelor
 Crearea de 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
Meniuri
 Meniu principal activitate
 Meniuri contextuale
 Apăsarea prelungită pe ecran
 Meniuri de tip popup
12
Meniuri
Opțiuni meniu
 Definire în fișiere de resurse dedicate
 res/menu
 Definire în mod programatic
 Interfața MenuItem
13
Meniuri
Opțiuni meniu
 Identificatorul grupului 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
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
16
Versiune Android Aspect Meniu
2.3.3, buton Menu
4.x, buton Menu
4.x, fără buton Menu
Meniuri
Meniul principal
 Metode cu 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
Deserializarea meniurilor
 Clasa
 MenuInflator
 Inițializare
 Activity#getMenuInflater()
 Context#getSystemService(String)
 Deserializare
 inflate(int id_meniu, Menu meniu)
18
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
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)
Meniuri
 Meniul principal
public boolean onOptionsItemSelected(MenuItem mi)
{
//tratarea evenimentelor generate de selecția din meniu
switch (mi.getItemId()) {
case R.id.INAINTE : {
//
break;
}
//...
}
}
21
Meniuri
Meniuri contextuale
 Interfața ContextMenu
 Inițializare
public void onCreateContextMenu(ContextMenu menu,
View v, ContextMenuInfo menuInfo)
 Tratare evenimente
public boolean onContextItemSelected(MenuItem mi)
 Asociere control
registerForContextMenu(view)
22
Bara aplicației
 Acces rapid 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
24
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
Bara aplicației
 Control de 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
Bara aplicației
 Acces la obiectul de tip ActionBar
 getActionBar()
 Stabilire bară aplicație
 setActionBar()
27
Bara aplicației
ActionBar
 Ascundere/afișare bară
 hide()/show()
 Afișare titlu/subtitlu
 setTitle()/setSubtitle()
 Modificare mod de navigare (depreciat)
 setNavigationMode()
NAVIGATION_MODE_STANDARD
NAVIGATION_MODE_LIST
NAVIGATION_MODE_TABS
28
Bara aplicației
Toolbar
 Tema fă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
Afișare opțiuni meniu
30
Fragmente
 Posibilitatea de modularizare a interfeței
 Gestiunea facilă a dimensiunilor diferite
 Transmiterea obiectelor între ecranele aplicației
 Suport pentru navigare între ecrane
 Stiva de fragmente
31
Fragmente
 Un Fragment Android 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
33
Fragmente
 Derivate din clasa 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
 androidx.fragment.app.Fragment
 Jetpack și AndroidX
 Recomandat începând cu API 28
 android.support.v4.app.Fragment
 Recomandat până la API 28
 android.app.Fragment
 Depreciat API 28
35
Fragmente
 Ciclul de viață 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 – ciclul de viață
37
Fragmente – ciclul de viață
38
Fragmente – ciclul de viață
39
https://www.javatpoint.com/android-fragments
Fragmente
Clasa Fragment
 Referire activitate container
 getActivity()
40
Fragmente
 Fragmente - XML
41
Fragmente- XML
 Creare clasă 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
Fragmente - XML
public class 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
Fragmente
Referirea fragmentelor
 Inițializarea unui 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
Fragmente
Fragmente dinamice
 Nu se 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
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
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
Fragmente
Tranzacții cu fragmente
FragmentManager fm = 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
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
Fragmente
 DialogFragment
 ListFragment
 PreferenceFragment
 WebViewFragment
50
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
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
Agenda
 Componente vizuale complexe
 Liste
 Adaptoare
 Tratarea selecțiilor
 Ferestre de informare
 Mesaje (Intent)
2
Componente vizuale complexe
 Controale complexe (ViewGroup)
 Elemente de tip View
 Implementează clasa abstractă AdapterView
 Inițializate prin intermediul unui adaptor
 Asocierea
 metoda setAdapter()
3
Componente vizuale complexe
 ListView, GridView
 Spinner
 RecyclerView
 AutoCompleteTextView
 MultiAutoCompleteTextView
 Gallery
 ListActivity
 getListView()
 setListAdapter()
 ListFragment
4
Adaptoare
 Asigură legătura dintre 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
Adaptoare
 Clase derivată din BaseAdapter
 implementează interfața Adapter
 ArrayAdapter
 CursorAdapter
 SimpleCursorAdapter
 SimpleAdapter
6
Componente vizuale complexe
7
Componente vizuale complexe
8
Sursa de date
• Array
• ArrayList
• Cursor
• …
Adaptor
• ArrayAdapter
• SimpleCursorAdapter
• CursorAdapter
• utilizator
Controale complexe
(AdapterView)
• ListView
• GridView
• Spinner
Layout
element
• utilizator
• implicite (android.R.layout.)
•simple_spinner_dropdown_item
•simple_list_item_1
•etc.
Resurse predefinite
9
Resursă predefinită
(android.R.layout…)
Descriere
simple_spinner_item Text 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
Spinner: Inițializare din resurse
<string-array name="extensii_fisiere">
<item>zip</item>
<item>rar</item>
<item>arj</item>
</string-array>
10
Spinner: Inițializare din resurse
<Spinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content„
android:entries="@array/extensii_fisiere"
/>
11
ArrayAdapter
 Sursa de date 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
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
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
ArrayAdapter – Exemplu
class Tara {
String nume ;
int populatie;
Bitmap steag;
//metode de acces publice (ex. getNume()/setNume())
public String toString() {
return "Denumire: " + nume + ", populatie: " + populatie;
}
}
15
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
ArrayAdapter – Exemplu
17
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
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
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
SimpleAdapter – Exemplu
21
SimpleAdapter – Exemplu
22
Adaptor personalizat
 Derivare din 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
24
Adaptor personalizat – Exemplu
public class AdaptorTari extends BaseAdapter {
List<Tara> tari; LayoutInflater layoutInflater;
AdaptorTari(Context context, List<Tara> tari) {
layoutInflater = LayoutInflater.from(context);
this.tari = tari;
}
//urmează implementarea metodelor clasei abstracte
}
25
Adaptor personalizat – Exemplu
@Override
public int getCount() {
return tari.size();
}
@Override
public Object getItem(int position) {
return tari.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
26
Adaptor personalizat – Exemplu
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
view = layoutInflater.inflate(R.layout.element_lista, parent, false);
}
//initializare obiecte controale
ImageView ivSteag = view.findViewById(R.id.imageViewSteag);
TextView tvNume = view.findViewById(R.id.textViewNume);
TextView tvPopulatie = view.findViewById(R.id.textViewPopulatie);
Tara tara = tari.get(position);
27
Adaptor personalizat – Exemplu
//initializare controale cu valori
ivSteag.setImageBitmap(tara.getSteag());
tvNume.setText(tara.getNume());
tvPopulatie.setText(tara.getPopulatie() + " locuitori");
return view;
}
28
Adaptor personalizat – Exemplu
public class AdaptorTari extends BaseAdapter {
private static class ViewHolder {
public ImageView ivSteag;
public TextView tvNume, tvPopulatie;
}
//…
}
29
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
Adaptor personalizat – Exemplu
else {
holder = (ViewHolder)convertView.getTag();
/*reutilizare resurse*/
}
Tara tara = tari.get(position);
//initializare controale cu valori
holder.ivSteag.setImageBitmap(tara.getSteag());
holder.tvNume.setText(tara.getNume());
holder.tvPopulatie.setText(tara.getPopulatie() + " locuitori");
return view;
}
31
Adaptor personalizat – Asociere adaptor
AdaptorTari adaptorTari = new AdaptorTari(
this, listaTari);
setListAdapter(adaptorTari);
32
Notificarea modificărilor
 ArrayAdapter include 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
Asociere text listă vidă
 Fișier de tip machetă
/res/layout/layout.xml
<ListView />
<TextView android:id="@+id/empty"
…
34
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
Selecția elementelor – Spinner
 getSelectedItem()
 getSelectedItemId()
 Interfața
 AdapterView.OnItemSelectedListener
 Metodele implementate
 onItemSelected()
 onNothingSelected()
 Asociere
 setOnItemSelectedListener()
36
Selecția elementelor – Spinner
spinner.setOnItemSelectedListener(new
AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int poz, long id) {
//parent.getItemAtPosition(poz);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
37
Selecția elementelor – ListView
 getItemAtPosition()
 getItemIdAtPosition()
 Interfața
 AdapterView.OnItemClickListener
 Metoda implementată
 onItemClick()
 Asociere
 setOnItemClickListener()
38
Selecția elementelor – ListView
lista.setOnItemClickListener(new
OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,
View item, int poz, long id){
//referim elementul selectat prin poz;
//parent.getItemAtPosition(poz);
}
});
39
Ferestre de informare
 Clasa Activity
 @android:style/Theme.***.Dialog
 Clasa Dialog sau derivate
 Clasa AlertDialog
 Clasa DialogFragment
 Ferestre de dialog predefinite
 ProgressDialog
 TimePickerDialog
 DatePickerDialog
 Clasa Toast
40
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
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)
Ferestre de informare
new AlertDialog.Builder(this)
.setTitle("Info")
.setMessage("Exemplu AlertDialog")
.show();
43
Ferestre de informare cu liste
 setItems()
 Lista elemente
 Obiect tratare eveniment selecție
 setSingleChoiceItems()
 + element selectat sau -1
 setMultipleChoicheItems()
 + lista elemente selectate sau null
44
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 – Exemplu
46
Ferestre de informare
Clasa Toast
 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
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)
Obiecte de tip Intent
 Mesaje asincrone
 Utilizare
 Invocare activități
 Invocare servicii
 Transmitere mesaje globale
 Partajare date
49
Mesaje (Intent)
Caracteristicile mesajelor de tip Intent
 Acțiuni
 Date
 Tip de date
 Categorie
 Date adiționale
 Componenta destinație
50
Mesaje (Intent)
Tipuri de mesaje
 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
Mesaje (Intent)
Acțiuni
 Definite sub forma unor operații (String)
 Operații
 Predefinite (sistem)
 Definite de programator
 Generice sau specializate
 VIEW vs. CALL
52
Mesaje (Intent)
Date
 Prezentate sub forma unui URI (Uri)
 Caracterizate prin tip (formatul MIME)
 text/html, text/plain, application/pdf etc.
 Date suplimentare (Bundle atașat)
 Extras
53
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)
 Acțiuni predefinite
55
Mesaje (Intent)
Categorii
 Asociate componentei care prelucrează mesajul
 Informații suplimentare cu privire modalitatea de lansare a
activității destinație
 Exemple
 CATEGORY_LAUNCHER
 CATEGORY_HOME
 CATEGORY_PREFERENCE
56
Mesaje (Intent)
Constructori
 Mesaje generice
 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)
Modificarea proprietăților
 setAction(String)
 addCategory(String)
 setData(Uri)
 setType(String)
 Tip MIME
 setDataAndType()
 setComponent(Context)
 setClass(Class)
58
Mesaje (Intent)
Transmiterea și filtrarea 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
Mesaje (Intent)
Transmiterea și filtrarea 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
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)
Lansarea unei activități din proiect
 Intent explicit
 Parametri constructor Intent:
 Contextul curent
 Clasa activității destinație
 Metode (clasa Context):
 startActivity(Intent)
62
Mesaje (Intent)
 Lansarea unei activități
63
Mesaje (Intent)
 Lansarea unei 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
Mesaje (Intent)
 Preluarea datelor î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
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
Mesaje (Intent)
 Mesaje implicite: 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
Mesaje (Intent)
 Mesaje implicite: 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
Mesaje (Intent)
Invocarea unei activităț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)
 Invocarea unei activități pentru răspuns
70
Mesaje (Intent)
 Invocarea unei activități pentru răspuns
Activitatea apelantă (1)
1. Inițializare mesaj explicit/implicit
 Context + componentă sau acțiune/date
2. Adăugare date mesaj (opțional)
 putExtras()/putExtra()
3. Invocare activitate (metodă clasa Activity)
 startActivityForResult(Intent, codCerere)
71
Mesaje (Intent)
 Invocarea unei activități pentru răspuns
Activitatea invocată
4. Obținere mesaj
 getIntent()
5. Preluare date adiționale (opțional)
 getExtra()/getTIPExtras()
6. Adăugare răspuns în mesaj
 putExtras()/putExtra()
7. Stabilire rezultat activitate
 setResult()
 RESULT_OK, RESULT_CANCELED
8. Terminare activitate
 finish() 72
Mesaje (Intent)
 Invocarea unei activități pentru răspuns
Activitatea apelantă (2)
9. Preluare răspuns
 supraîncărcare metodă clasa Activity
 onActivityResult(codCerere, codRezultat, Intent)
 codRezultat = RESULT_OK, RESULT_CANCELED, …
73
Mesaje (Intent)
 Invocarea unei 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
Mesaje (Intent)
 Invocarea unei 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
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
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
Agenda
 Operații asincrone
 Accesul la rețea
 Socket
 HTTP
 Servicii Web
 Prelucrarea fișierelor XML și JSON
2
Accesul la rețea
 Controlul WebView
 Clase acces prin socket
 Socket
 ServerSocket
 DatagramSocket
 Clase HTTP API
 Java SE
3
Accesul la rețea
 Permisiunea android.permission.INTERNET
 Excepție
 Prelucrările au loc într-un alt fir de execuție
 Excepție
4
Accesul la rețea
WebView
 Afișare conținut HTML
 Implicit JavaScript nu este activat
 WebSettings
 getSettings()
 loadUrl()
 Adresa paginii
 loadData()
 Conținut HTML
5
Accesul la rețea
Accesul prin HTTP
 Specific Java SE
 Pachetul java.net
 Resursa
 URL
 Conexiune
 HttpURLConnection
 HttpsURLConnection
6
Accesul la rețea
HTTP/HTTPS
1. Inițializare obiect URL
 adresa resursei
2. Inițializare conexiune prin intermediul obiectului URL
 Metoda URL#openConnection()
HttpURLConnection
3. Stabilire parametri
4. Preluare conținut
 HttpURLConnection#getInputStream()
7
Accesul la rețea
 HTTP/HTTPS
1. Inițializare obiect URL
 adresa resursei
2. Preluare conținut
 URL#openStream()
8
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
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
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
Accesul la rețea
Prelucrare conținut
 Fluxuri de date
 Octeți
 InputStream
 ByteArrayInputStream
 Caractere
 InputStreamReader
 BufferedReader
 StringBuilder
 StringBuffer
 Sincronizat
 Tipuri de date
 Scanner
12
Accesul la rețea
Descărcarea fișierelor
 Serviciul de sistem DownloadManager
 getSystemService(DOWNLOAD_SERVICE)
 Inițiere
 enqueue()
 Verificare stare transfer
 REVENIRE
 Servicii, Recepționarea mesajelor (BroadcastReceiver), Cursor
13
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
Servicii Web
 SOAP
 Mesaje XML
 WSDL
 REST, RESTful (Representational State Transfer)
 XML, JSON, HTML
15
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
Servicii Web REST
 Acțiunile sunt implementate uzual prin protocolul HTTP
 Comenzi (GET, POST, DELETE etc.) asociate acțiunilor
 Rezultatul returnat
 JSON
 XML
17
Operații asincrone
 Activități consumatoare 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
Operații asincrone
19
Operații asincrone
 Java
 clasa Thread
 interfața Runnable
 Android
 clasa Handler
 Metode
runOnUiThread(Runnable) (clasa Activity)
post(Runnable) (clasa View)
postDelayed(Runnable, long) (clasa View)
 clasa AsyncTask
20
Clasa Handler
 Transmiterea de 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
Clasa Handler
 Prelucrarea mesajelor
 metoda cu apel invers handleMessage()
 Transmiterea mesajelor
 metode de forma sendYYY()
22
Clasa Handler
 Obiecte de tip Runnable
 Transmise către coada de mesaje asociată firului de execuție
 Transmiterea obiectelor Runnable
 Metode de forma postYYY()
23
Clasa Handler
24
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
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
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: Transmitere obiect Runnable
Handler handler = new Handler();
//...
handler.post(new Runnable() {
@Override
public void run() {
// prelucrări actualizare
}
});
28
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
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
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
Operații asincrone
32
Metode specifice
 Clasa Activity
 runOnUiThread(Runnable)
 View
 post(Runnable)
 postDelayed(Runnable, long)
33
Metode specifice
 Exemplu: runOnUiThread()
this.runOnUiThread(new Runnable() {
@Override
public void run() {
editText.setText(text);
}
});
34
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
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
Agenda
 Accesul la rețea
 Prelucrarea fișierelor XML și JSON
2
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
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
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
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
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
Accesul la rețea
Pentru a 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
Accesul la rețea
9
Clasa AsyncTask
 Clasa abstractă 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
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
Apelurile Clasa AsyncTask
12
Exemplu AsyncTask
//Parametrul transmis este 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
Exemplu AsyncTask
//Apelul din firul principal
URL url = new URL("http://pdm.ase.ro");
PrelAsinc pa = new PrelAsinc ();
pa.execute(url);
14
Servicii Web
 SOAP
 Mesaje XML
 WSDL
 REST, RESTful (Representational State Transfer)
 XML, JSON, HTML
15
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
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
Servicii Web SOAP
Pentru utilizarea 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
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
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
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
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
Fișiere JSON
 JavaScript Object Notation
 { } – obiect
 [ ] – vector de valori
 "proprietate" : "valoare"
23
Fișiere JSON
{
"biblioteca": {
"carte": [
{
"-cota": "19222", "autor": { "nume": "R. Meier" }, "titlu": " Professional Android Application
Development ", "editura": "wiley", "an": "2009", "isbn": "1-72-11-2222", "pagini": "500" },
{
"-cota": "19223", "autor": { "nume": [ "S. Hashimi", " S. Komatineni", " D. MacLean " ] },
"titlu": "Pro Android 3", "editura": "Apress", "an": "2011",
"isbn": "0-321-15040-6", "pagini": "336"
}
]
}
}
24
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
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
Prelucrare fișiere XML
Clasa derivată 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
SAXParserFactory fact = SAXParserFactory.newInstance();
SAXParser xmlParser = fact.newSAXParser();
XMLReader xmlReader = xmlParser.getXMLReader();
SAXHandler handler = new SAXHandler();
xmlReader.setContentHandler(handler);
xmlReader.parse(new InputSource(streamIn));
28
Prelucrare fișiere XML
XML Pull
 Interfața XmlPullParser
 Inițializare
 Resources#getXml()
 res/xml
 Xml.newPullParser()
 XmlPullParserFactory#newPullParser()
 XmlPullParserFactory
 XmlPullParserFactory.newInstance()
 Asociere flux de intrare (InputStream sau Reader)
 setInput()
29
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
Prelucrare fișiere XML
static ArrayList<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
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
Prelucrare fișiere XML
DOM
 Interfețe
 Node
 Element (impl. Node)
 NodeList
 item(poz)
 Clasa DocumentBuilder
 metoda parse()
 InputStream
 Clasa Document (impl. Node)
33
Prelucrare fișiere XML
DOM
 Document
 getElementsByTagName()
 NodeList
 Element
 getAttribute()
 Node
 getTextContent()
34
Prelucrare fișiere XML
DocumentBuilderFactory docBuilderFactory =
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
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
 org.json
 JSONObject
 getTIP(): getString(), getBoolean(), getInt() etc.
 getJSONArray()
 getJSONObject()
 JSONArray
 length()
 getTIP(index)
37
Prelucrare fișiere JSON
JSONObject jObject = 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
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
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
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
Stocarea persistentă a datelor
 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
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
Baze de date SQLITE
Baze de date
 SQLite
 Baze de date relaționale
 Room
5
Baze de date SQLITE
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
Baze de date SQLITE
 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
Baze de date SQLITE
 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
Baze de date SQLITE – 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
Baze de date SQLITE – Biblioteca ROOM
Obiecte utilizate
 Entități
 Operații asupra datelor
 Baza de date
 Adnotări Java
10
Baze de date SQLITE – 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
Baze de date SQLITE – 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
Baze de date SQLITE – 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
Baze de date SQLITE – 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
Baze de date SQLITE – 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
Baze de date SQLITE – Biblioteca ROOM
Operații asupra datelor
 @Query
 Metodă de tip interogare
 @Insert
 Metodă pentru inserare
 @Update
 Metodă pentru actualizare
 @Delete
 Metodă pentru ștergere
16
Baze de date SQLITE – 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
Baze de date SQLITE – 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
Baze de date SQLITE – 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 date SQLITE – Biblioteca ROOM
Cursor
 Parcurgere
 moveToNext()
 moveToPrevious()
 moveToFirst()
 moveToLast()
 Extragerea de valori
 getTIP(): getInt(), getString(), getFloat() etc.
 parametru: indexul coloanei
20
Baze de date SQLITE – Biblioteca ROOM
Cursor: Determinarea poziției
 isFirst()
 isLast()
 isBeforeFirst()
 isAfterLast()
21
Baze de date SQLITE – Biblioteca ROOM
Cursor: Obținerea de informații
 Numărul de înregistrări
 getCount()
 Numele coloanei
 getColumnName()
 Poziția coloanei
 getColumnIndex()
22
Baze de date SQLITE – Biblioteca ROOM
Adaptoare de tip Cursor
 CursorAdapter
 Coloana _id
 SimpleCursorAdapter
23
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
Stocarea în containerul aplicaț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
Stocarea în containerul aplicației
 getResources() -> Resources
 Fișiere din res/raw
 openRawResource() -> InputStream
 Fișiere din res/xml
 getXml() -> XmlPullParser
26
Stocarea în containerul aplicației
 AssetManager
 getAssets() (clasa Context)
 open(nume_fisier) -> InputStream
 list(cale)
 String[]
Lista fișiere
27
Fișiere
 Pot fi salvate î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
Fișiere
Clasa Environment
 Mediul extern amovibil:
 isExternalStorageRemovable()
 Stare mediu extern stocare
 getExternalStorageState()
MEDIA_MOUNTED
MEDIA_MOUNTED_READ_ONLY
MEDIA_UNMOUNTED
MEDIA_REMOVED
29
Fișiere
Directoare speciale
 Clasa Environment, 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
 Director public mediu extern stocare
 getExternalStoragePublicDirectory(tip)
tip (membri statici)
DIRECTORY_PICTURES
DIRECTORY_MUSIC
DIRECTORY_DOWNLOADS
DIRECTORY_DCIM
DIRECTORY_RINGTONES
DIRECTORY_ALARMS
depreciat API 29 31
Fișiere
Directoare speciale
 Clasa Activity (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
Fișiere
Clasa File
 Operații la nivel de fișier și director
 Obținere și stabilire proprietăți
 Mutare/redenumire
 Creare director
 Obținere conținut director etc.
33
Fișiere
 InputStream și OutputStream
 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
Fișiere
 InputStreamReader şi OutputStreamWriter
 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
 Metode în clasa Context
 FileInputStream openFileInput(String numeFisier)
 FileOutputStream openFileOutput(String numeFisier, int mod)
 Context.MODE_PRIVATE/ Context.MODE_APPEND
 boolean deleteFile(String numeFisier)
 String[] fileList()
 File getDir(String numeDir, int mod)
36
Fișiere
Pentru a salva date î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
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
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
Fișiere externe
 android.permission.WRITE_EXTERNAL_STORAGE
 Verificare disponibilitate mediu extern de stocare
 Verificare drepturi citire/scriere
40
Fișiere externe
try {
// obtinere starea mediului de stocare extern
String stareSD = Environment.getExternalStorageState();
// daca este montat
if (stareSD.equals(Environment.MEDIA_MOUNTED)) {
// obtinerm director extern asociat aplicatiei
File dir = getExternalFilesDir(null);
if (dir != null) {
// creare fisier
File fis = new File(dir, NUME_FISER2);
FileWriter os = new FileWriter(fis);
os.write("DAM 2020");
os.close();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
41
Serializarea și deserializarea obiectelor
 Modalități de serializare
42
Serializarea și deserializarea obiectelor
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
Serializarea și deserializarea obiectelor
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
Serializarea și deserializarea obiectelor
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
Serializarea și deserializarea obiectelor
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
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
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
Agenda
 Stocarea persistentă a datelor
 Baze de date
SQLite
Room Persistence Library
 Fișiere de proprietăți
 Serializarea și deserializarea obiectelor
2
Baze de date SQLITE – 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
Baze de date SQLITE – 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
Baze de date SQLITE – 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
Baze de date SQLITE – 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
Baze de date SQLITE – 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
Baze de date SQLITE – Biblioteca ROOM
Operații asupra datelor
 @Query
 Metodă de tip interogare
 @Insert
 Metodă pentru inserare
 @Update
 Metodă pentru actualizare
 @Delete
 Metodă pentru ștergere
8
Baze de date SQLITE – 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
Baze de date SQLITE – 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
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
Fișiere de proprietăți
Obținere fiș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
Fișiere de proprietăți
Preluarea datelor
 Metode de forma getTIP()
 getBoolean(),
 getInt() etc.
13
Fișiere de proprietăți
Editare fișiere de proprietăți
 Clasa SharedPreferences.Editor
 Inițializare
 SharedPreferences#edit()
 Scriere
 Metode de forma putTIP()
 Ștergere preferințe
 remove()
 Ștergerea tuturor preferințelor
 clear()
 Salvare modificări
 commit() – apel sincron
 apply() – apel asincron
14
Fișiere de proprietăți
SharedPreferences setari = getSharedPreferences("setari",
Activity.MODE_PRIVATE);
SharedPreferences.Editor editorProp = setari.edit();
editorProp.putBoolean("titlu", false);
editorProp.putBoolean("ajutor", true);
editorProp.putInt("max", 5);
editorProp.commit();
15
Fișiere de proprietăți
SharedPreferences setari = getSharedPreferences("setari",
Activity.MODE_PRIVATE);
boolean fTitlu = setari.getBoolean("titlu", false);
boolean fAjutor = setari.getBoolean("ajutor", true);
int nMax = setari.getInt("max", 5);
16
Activități pentru salvarea preferințelor
 Pachetul androidx.preference
 API 29
 Clase
 PreferenceFragmentCompat
 PreferenceScreen
 PreferenceCategory
 Preferences
 Ferestre de dialog
 EditTextPreference
 ListPreference
 MultiSelectListPreference
 Controale
 CheckBoxPreference
 SwitchPreference
17
Activități pentru salvarea preferinț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
Activități pentru salvarea preferinț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
Activități pentru salvarea preferinț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
Activități pentru salvarea preferinț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
Activități pentru salvarea preferinț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
Activități pentru salvarea preferințelor
23
Activități pentru salvarea preferințelor
SharedPreferences preferinte = PreferenceManager
.getDefaultSharedPreferences(this);
boolean modNoapte =
preferinte.getBoolean("modNoapte", false);
String user = preferinte.getString("utilizator",
"neconectat");
String [] setariFonturi = new String[5];
preferinte.getStringSet("listaFont", new
HashSet<String>()).toArray(setariFonturi);
24
Serializarea și deserializarea obiectelor
 Modalități de serializare
25
Serializarea și deserializarea obiectelor
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
Serializarea și deserializarea obiectelor
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
Serializarea și deserializarea obiectelor
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
Serializarea și deserializarea obiectelor
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
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
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
Agenda
 Baze de date la distanță
 Firebase
 Baze de date Firebase
 Realtime Database
 Cloud Firestore
2
Baze de date la distanță
 Partajarea datelor
 Sincronizarea datelor
 Datele sunt stocate pe un server
3
Baze de date la distanță
4
Baze de date la 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
Firebase
 Platformă proiectată să asigure integrarea soluțiilor bazate pe
cloud în aplicații
 Aplicații mobile
 Android
 iOS
 Aplicații Web
6
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
Firebase
Componente Firebase
 Google Analytics
 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
Firebase
 Conectarea prin intermediul 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
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
Tipuri de date suportate
 String
 Boolean
 Long
 Double
 Map<String, Object>
 List<Object>
11
Firebase Realtime Database
Structura datelor
 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
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
Firebase Realtime Database
Inițializarea bazei de date
 Clasa FirebaseDatabase
 Metoda statică getInstance()
 Exemplu
 FirebaseDatabase database =
FirebaseDatabase.getInstance();
14
Firebase Realtime Database
Referirea datelor
 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
Firebase Realtime Database
Salvarea datelor
 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
Firebase Realtime Database
Preluarea datelor
 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
Preluarea datelor
 ValueEventListener
 onDataChange(DataSnapshot)
 onCancelled(DatabaseError)
 Asociere (prin DatabaseReference)
 addValueEventListener()
 addListenerForSingleValueEvent()
 Eliminare asociere
 removeEventListener()
18
Firebase Realtime Database
Modificarea datelor
 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
Ștergerea datelor
 removeValue()
 setValue(null)
 updateChildren(map)
 valorile din map sunt nule
20
Firebase Realtime Database
Interogarea datelor
 Clasa Query
 Sortare
 Cheie
 Valoare
 Valoare copil
 Indexare pentru îmbunătățirea performanțelor
 Operațiile returnează tot obiecte de tip Query
21
Firebase Realtime Database
Interogarea datelor
 Sortare
 orderByChild()
 orderByKey()
 orderByValue()
 Filtrare
 equalTo()
 startAt()//mai mare sau egal
 endAt() //mai mic sau egal
 limitToFirst()
 limitToLast() 22
Firebase Realtime Database
Preluarea datelor
 Preluarea datelor se realizează prin intermediul aceluiași mecanism
 DatabaseReference extinde clasa Query
 Asociere obiecte de tip listener
 addListenerForSingleValueEvent()
 addValueEventListener()
23
Firebase Realtime Database
Monitorizarea actualizărilor
 ChildEventListener
 Metode
 abstract void onChildAdded(DataSnapshot snapshot, String
previousChildName)
 abstract void onChildChanged(DataSnapshot snapshot, String
previousChildName)
 abstract void onChildMoved(DataSnapshot snapshot, String
previousChildName)
 abstract void onChildRemoved(DataSnapshot snapshot)
 abstract void onCancelled(DatabaseError error)
24
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
Structura datelor
 Colecție
 Documente
 Date
 cheie, valoare
 Subcolecții
26
Cloud Firestore
Clase și interfeț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
Cloud Firestore
Inițializarea referinței la baza de date
 Setări prealabile
 Android Studio
 Consola Firebase
 Clasa FirebaseFirestore
 Metoda statică getInstance()
28
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
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
Cloud Firestore
Adăugarea în baza 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
Cloud Firestore
Ștergerea din baza de date
 DocumentReference
 Metoda delete()
 Identificare document
 Referința colecție
 metoda document(id)
32
Cloud Firestore
Modificări în baza de date
 DocumentReference
 Metoda set()
 Identificare document
 Referința colecție
 metoda document(id)
33
Cloud Firestore
Interogarea datelor
 Referința colecție
 Metoda get()
 Rezultatul Task<DocumentSnapshot>
 Rezultatul Task<QuerySnapshot>
 toObjects(class)
 toObject(class)
34
Cloud Firestore
Filtrarea și sortarea datelor
 Obiectul de tip colecție
 Filtrare
 whereEqualTo()
 whereLessThan()/whereLessThanOrEqualTo()
 whereGreaterThan()/whereGreaterThanOrEqualTo()
 whereArrayContains()/whereArrayContainsAny()
 whereIn()
 Sortare
 orderBy(cimp[, directie])
 Query.Direction.ASCENDING, Query.Direction.DESCENDING
 Număr maxim rezultate
 limit(valoare)
35
Autentificare/Înregistrare
 Furnizori multipli
 Definire din consola Firebase
 Clase specializate
36
Autentificare/Înregistrare
Furnizori
 Email + parolă
 Google
 Facebook
 Twitter
 GitHub
37
Autentificare/Înregistrare
Clase și interfețe
 FirebaseAuth
 AuthStateListener
 FirebaseUser
38
Autentificare/Înregistrare
FirebaseAuth auth = FirebaseAuth.getInstance();
FirebaseUser user = auth.getCurrentUser();
if (user != null) {
//continuare in aplicatie
} else {
//autentificare utilizator
}
39
Clase suport
FirebaseUI
 https://github.com/firebase/FirebaseUI-Android
 FirebaseUI for Android — Auth
 AuthUI
 FirebaseUI for Realtime Database
 FirebaseListAdapter
 FirebaseRecyclerAdapter
40
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
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
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
Resurse de tip multimedia
 Fișiere
 Imagini
 Clipuri audio
 Clipuri video
 În memorie
 Grafică bi/tri-dimensională
 Secvențe audio
 Animații (bi/tri-dimensionale)
3
Grafică bidimensională
 Desenarea imaginilor în memorie
 Clasa Bitmap
 Culori și texturi
 Instrumentul de desenat
 clasa Paint
 Suprafața de desenat
 clasa Canvas
 Figuri geometrice
 ShapeDrawable
4
Grafică bidimensională
Desenare imagini în controale
 ImageView
 Drawable (clasă abstractă)
 res/drawable, res/raw
 Imagini
Fișiere grafice
 Figuri
Fișiere xml
 Canvas
 Desen liber/figuri
 android.graphics
5
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ă
int w, h;
Bitmap bmp1 = Bitmap.createBitmap(w, h,
Bitmap.Config.ARGB_8888);
Bitmap bmp2 = BitmapFactory.decodeResource(
getResources(), R.drawable.dice);
7
Grafică bidimensională
Componente de bază
 Culori și texturi
 Instrumentul de desenat
 Suprafața de desenat
 Contururi geometrice
8
Grafică bidimensională
Culori
 Clasa Color
 Constante (RED, BLUE etc.)
 Metoda statică argb(a, r, g, b)
 Metoda statică parseColor(String)
#RRGGBB
#AARRGGBB
Nume culoare
 Resurse
 Resources#getColor()
res/values
9
Grafică bidimensională
Culori
 int culoare = getResources().getColor(R.id.fundal);
 int verde = Color.GREEN;
 int verdeSemiTransp = Color.argb(127, 0, 255, 0);
10
Grafică bidimensională
Gradienți
 Culori și sau imagini
 clasa Shader si derivate
 Modul de umplere:
 repetarea șablonului (Shader.TileMode.REPEAT)
 repetarea șablonului cu alternarea imaginii inversate
(Shader.TileMode.MIRROR)
 replicarea culorii exterioare la depășirea limitelor
(Shader.TileMode.CLAMP).
11
Grafică bidimensională
Gradienți
 clasa Shader şi subclasele acesteia
 BitmapShader – desenarea folosind imagini
 LinearGradient – gradienți liniari
 RadialGradient – gradienți circulari
 SweepGradiet – gradienți unghiulari
 ComposeShader – combinarea doi gradienți.
12
Grafică bidimensională
Gradienți
Bitmap bmpShader;
BitmapShader gradientBmp = new BitmapShader(bmpShader,
Shader.TileMode.REPEAT, Shader.TileMode.REPEAT );
LinearGradient gradientLinear = new LinearGradient(0, 0, 150, 150, Color.RED,
Color.BLUE, Shader.TileMode.CLAMP);
13
Grafică bidimensională
Instrumentul de desenat
 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
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ă
Clasa Paint
 Proprietăți linie contur/umplere:
 void setStyle(Paint.Style style)
 void setStrokeWidth(float width)
 PathEffect setPathEffect(PathEffect effect)
 void setAntialias(boolean aa)
 Inițializare gradient
 Shader setShader(Shader shader)
16
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
Grafică bidimensională
Suprafața de desenare
 Clasa Canvas
 Include metode pentru desenare
 Metode de tipul draw…()
 Instrumentul de scris
 Poziția
18
Grafică bidimensională
Desenarea în controale
 Clasa derivată din View
 Metoda cu apel invers onDraw()
 de evitat alocarea obiectelor grafice aici
 Metodele
 invalidate()
 postInvalidate()
19
Grafică bidimensională
Canvas
public class DesenView extends View {
…
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//desenarea propriu-zisă
}
}
20
Grafică bidimensională
Desenarea în imagini (Bitmap)
 Se utilizează constructorul
 Canvas(Bitmap)
 Pași
 Crearea/Obținerea unui obiect de tip Bitmap
Bitmap bmp = Bitmap.createBitmap(l, L, tip);
 Inițializarea obiectului de tip Canvas
Canvas canvas = new Canvas(bmp);
21
Grafică bidimensională
Desenarea figurilor geometrice
 void drawPoint(float x, float y, Paint paint)
 void drawPoints(float[ ] pts, int offset, int count, Paint paint)
 void drawLine(float startX, float startY, float stopX, float stopY, Paint
paint)
 void drawLines(float[ ] pts, Paint paint)
22
Grafică bidimensională
Desenarea figurilor geometrice
 void drawRect(RectF rect, Paint paint)
 void drawRoundRect(RectF rect, float rx, float ry, Paint paint)
 void drawCircle(float cx, float cy, float radius, Paint paint)
 void drawOval(RectF oval, Paint paint)
 void drawArc(RectF oval, float startAngle, float sweepAngle, boolean
useCenter, Paint paint)
23
Grafică bidimensională
Afișarea imaginilor
 void drawBitmap(Bitmap bmp, float left, float top, Paint paint)
 void drawPicture(Picture picture, RectF dst)
24
Grafică bidimensională
Modificarea fundalului
 void drawColor(int color)
 void drawRGB(int r, int g, int b)
 void drawARGB(int a, int r, int g, int b)
 void drawPaint(Paint paint)
25
Grafică bidimensională
Afișarea textului
 void drawText(String text, float x, float y, Paint paint)
26
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
Grafică bidimensională
Exemplu: Canvas
//culoare fundal
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ă
Desenare/afișare text după contururi geometrice
 void drawPath(Path path, Paint paint)
 void drawTextOnPath(String text, Path path, float hOffset, float
vOffset, Paint paint)
29
Grafică bidimensională
Decuparea
 Zona de 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
Grafică bidimensională
Transformări
 Scalare
 Metoda scale(sx, sy)
 Translatare (mutare)
 Metoda translate(dx, dy)
 Rotiri
 Metoda rotate(grade)
 Înclinare
 Metoda skew(x, y)
31
Figuri geometrice (cod sursă Java)
 ShapeDrawable
 Construire obiecte de tip Shape
 RectShape
 OvalShape
 ArcShape
 PathShape
 Metode
 getPaint()
 draw(Canvas)
 setBounds(x1, y1, x2, y2)
32
Figuri geometrice (cod sursă 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
Figuri geometrice (XML)
 Elementul shape
 Atributul android:shape reprezintă figura
 rectangle
 oval
 line
 ring
 Proprietăți (elemente XML incluse)
 stroke
 solid
 gradient
 size
34
Figuri geometrice (XML)
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners android:radius="10dp" />
<size
android:height="@dimen/lat"
android:width="@dimen/lung" />
<solid
android:color="@android:color/transparent" />
<stroke
android:width="2dp"
android:color="#000000" />
</shape>
35
Figuri geometrice (XML)
 Referire XML:
 @drawable/numeFisierXMLFigura
 Referire Java
 R.drawable.numeFisierXMLFigura
 Resources#getDrawable
36
Preluarea imaginilor folosind camera foto
Camera
 Acces prin aplicații dedicate
 Intent
 Utilizare clase specializate
 Camera
 android.permission.CAMERA
37
Preluarea imaginilor folosind camera 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
Preluarea imaginilor folosind camera 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
Preluarea imaginilor folosind camera foto
Camera: aplicații instalate
final int CAPTEAZA_IMAGINE = 1;
//…
Intent capteazaImagine = new
Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(capteazaImagine,
CAPTEAZA_IMAGINE);
40
Preluarea imaginilor folosind camera 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
Preluarea imaginilor din colecț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
Preluarea imaginilor din colecția de
fotografii
protected void onActivityResult(int codCerere, int codRezultat, Intent intent) {
if (codCerere == SELECTEAZA_IMAGINE && codRezultat == RESULT_OK) {
Uri uriImagine = intent.getData();
Bitmap bmp;
try {
bmp = MediaStore.Images.Media.getBitmap(
getContentResolver(), uriImagine);
//utilizare bmp
} catch (Exception e) {
e.printStackTrace();
}
}
}
43
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
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
Agenda
 Receptori de mesaje
 Utilizarea serviciilor Android
 Determinarea poziției geografice
 Utilizarea Google Maps
 Senzori, GPS, Google Maps
2
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
Mesaje globale
 Intent.ACTION_BATTERY_LOW
 Intent.ACTION_BOOT_COMPLETED
 Intent.ACTION_MEDIA_MOUNTED
 Intent.ACTION_SCREEN_OFF
 Telephony.Sms.Intents.SMS_RECEIVED
4
Receptori de mesaje
Recepționarea mesajelor 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
Receptori de mesaje
Înregistrarea receptorilor
 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
Receptori de mesaje
Înregistrarea receptorilor (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
Receptori de mesaje
Înregistrarea receptorilor (Java)
 Creare obiect de tip IntentFilter
 Creare obiect care implementează clasa abstractă BroadcastReceiver
 Înregistrarea unui receptor
 registerReceiver()
 Deconectarea receptorului
 unregisterReceiver()
8
Receptori de mesaje
Prelucrarea mesajelor
 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
Receptori de mesaje
Transmiterea mesajelor globale
 Mesajele sunt transmise
 Fără prioritate
 Cu priorități
 sendBroadcast()
 sendOrderedBroadcast()
 Parametrul comun:
 Mesajul (Intent)
 O formă care include:
 Permisiunea necesară (String)
10
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 şi interacţiunea cu aplicaţiile
 Servicii predefinite (sistem) și servicii utilizator
11
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
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
Servicii
Servicii predefinite
 getSystemService(String serviciu)
 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
 Servicii predefinite
15
Servciu Constantă asociată (clasa Context)
Alarm ALARM_SERVICE
Bluetooth AUDIO_SERVICE
Location LOCATION_SERVICE
Notification NOTIFICATION_SERVICE
Sensor SENSOR_SERVICE
Telephony TELEPHONY_SERVICE
Wifi WIFI_SERVICE
Servicii
PendingIntent
 Mesaj transmis unei 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
Servicii
PendingIntent
 Implementează interfața Parcelable
 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
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
Notification notif = new Notification.Builder(this)
.setContentTitle("Notificare")
.setSmallIcon(R.drawable.icon)
.setContentText("Serviciu Info")
.setContentIntent(pendingIntent).build()
//transmiterea notificarii notif
notifManager.notify(NOTIF_ID, notif);
//Pentru oprirea notificărilor:
notifManager.cancel(NOTIF_ID);
19
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
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
Servicii
Servicii utilizator
 Derivare din clasa Service
 Derivare din clasa IntentService
 Declarare în fișierul manifest XML
<application ... >
<service android:name=".Serviciu" />
...
</application>
22
Determinarea poziției geografice
 Serviciu de sistem
 Componentă Google Services
 Necesită permisiuni
 android.permission.ACCESS_FINE_LOCATION
 android.permission.ACCESS_COARSE_LOCATION
23
Determinarea poziției geografice
Poziționare geografică
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
Determinarea poziției geografice
Inițializare serviciu 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
Determinarea poziției geografice
Asociere furnizori 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
Determinarea poziției geografice
Asociere furnizori 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
Determinarea poziției geografice
Eliminarea asocierii
 Metoda removeUpdates() din clasa LocationManager
 Parametrul
 Obiectul de tip LocationListener
 Obiectul de tip PendingIntent
28
Determinarea poziției geografice
Clasa LocationManager
 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
Determinarea poziției geografice
Interfața LocationListener
 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
Determinarea poziției geografice
Clasa Location
 Coordonate
 getLatitude(), getLongitude(), getAltitude()
 Viteza
 getSpeed()
 Timp
 getTime()
 Acuratețea localizării
 getAccuracy()
 Alte informații
31
Determinarea poziției geografice
Poziționare geografică – Exemplu
class LocListener implements LocationListener {
@Override
public void onLocationChanged(Location poz) {
/*poz.getLatitude(), poz.getLongitude(), poz.getAltitude(); */
}
//…
}
32
Determinarea poziției geografice
Poziționare geografică – Exemplu
LocListener locListener = new LocListener();
LocationManager locManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
//asociere furnzizor servicii localizare
locManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0, locListener);
//dezactivare asociare servicii localizare
locManager.removeUpdates(locListener); 33
Determinarea poziției geografice
Obținerea adreselor
 Clasa Geocoder
 Servicii de backend
 Determinare disponibilitate serviciu
 Metode statică isPresent()
 Inițializare
 Constructor cu un parametru de tip Context
 Permisiune INTERNET
34
Determinarea poziției geografice
Obținerea adreselor
 Metode
 getFromLocation(lat, long, nrMaxAdrese)
 getFromLocationName()
 Liste de adrese
 Clasa Address
 List<Address>
 Clasa Address
 getCountry()
 getCountryCode()
 getLocality()
 getAddressLine() etc. 35
Determinarea poziției geografice
Obținerea adreselor
if (Geocoder.isPresent()) {
Geocoder geocoder = new Geocoder(getApplicationContext());
try {
List<Address> adrese = geocoder.getFromLocation(lat, lon, 1);
if (adrese.size() > 0) {
//adrese.get(0).getCountryName()
//adrese.get(0).getLocality()) //etc.
}
}
catch (IOException ex) {
ex.printStackTrace();
}
} 36
Google Maps
 Google Maps 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
Google Maps
Inițializare
 Înregistrare la 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
Google Maps
Clase Google Maps 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
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
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
Control cameră
 Parametri vizualizare
 Locație
 Unghi înclinare
 Zoom
 Clase
 CameraUpdate
 CameraPosition
 Obținere CameraUpdate
 CameraUpdateFactory
 Metode
 moveCamera(CameraUpdate)
 animateCamera(CameraUpdate) 42
Google Maps
Adăugarea de figuri geometrice
 Cerc
 Circle addCircle(CircleOptions)
 Linii
 Polyline addPolyline(PolylineOptions)
 Imagine
 GroundOverlay addGroundOverlay(GroundOverlayOptions)
 Poligon
 Polygon addPolygon(PolygonOptions)
43
Google Maps
Marcaje
 Clasa Marker
 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
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
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
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
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
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
Agenda
 Furnizori de conținut
 Gestiunea dinamică a permisiunilor
 PIM (E-mail, SMS, Contacte)
 Publicarea aplicațiilor în magazinul virtual Play Store
2
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
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
 Pachetul android.provider
 Predefiniți
 Definiți de utilizator
 Implementarea clasei abstracte ContentProvider
 ContentResolver
 Context#getContentResolver()
5
Furnizori de conținut
Furnizori de conținut predefiniți
 CallLog
 Calls
 ContactsContract
 Contacts
 CalendarContract
 Calendars
 Events
 Reminders
6
Furnizori de conținut
Furnizori de conținut predefiniți
 MediaStore
 Audio
 Images
 Video
 Settings
 System
 Global
7
Furnizori de conținut
Referirea furnizorilor 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
Operații asupra furnizorilor
 Acces prin clasa ContentResolver
 query(Uri, String[], String, String[], String)
 insert(Uri, ContentValues)
 update(Uri, ContentValues, String, String [])
 delete(Uri, String, String [])
9
Furnizori de conținut
Interogarea unui 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
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
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
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
Furnizori de conținut
Implementarea furnizorilor 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
Furnizori de conținut
Implementarea furnizorilor 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
Furnizori de conținut
Partajarea/Transmiterea datelor î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
Gestiunea dinamică a permisiunilor
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
Gestiunea dinamică a permisiunilor
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ă a permisiunilor
Verificarea existenței permisiunii
 Metoda ContextCompat.checkSelfPermission()
 Parametrii
 Contextul
 Permisiunea
 Manifest.permission.WRITE_CALENDAR,
 Manifest.permission.ACCESS_COARSE_LOCATION
 etc.
 Returnează
 PackageManager.PERMISSION_GRANTED
 PackageManager.PERMISSION_DENIED
19
Gestiunea dinamică a permisiunilor
Cererea permisiunii
 Metoda ActivityCompat.requestPermissions()
 Parametrii
 Contextul
 Lista permsiunilor (String [])
 Codul asociat cererii pentru metoda cu apel invers
20
Gestiunea dinamică a permisiunilor
 Cererea permisiunii
21
Gestiunea dinamică a permisiunilor
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
Gestiunea dinamică a permisiunilor
Preluarea răspunsului
 Dacă permisiunea a fost acordată
 se execută codul
 Dacă nu a fost acordată
 Permisiunea poate fi solicitată din nou
23
Publicarea aplicațiilor în Google 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
Publicarea aplicațiilor în Google Play
25
Publicarea aplicațiilor în Google Play
26
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

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
  • 9.
    Introducere/Dispozitive mobile  Utilitate:comunicare (e-mail, mesaje scrise, telefon)  Gestiunea informațiilor personale (date de contact, agenda, calendar)  Navigare Internet  Rețele sociale  Divertisment (jocuri, cărți)  Multimedia (filme, imagini și muzică)  Navigație (GPS, localizare)  Plăți (NFC) 9
  • 10.
    Introducere/Dispozitive mobile Caracteristici:  Portabilitate Accesibilitate: oriunde, oricând  Personale Limitări (vs. PC):  Autonomie (baterie)  Fragmentare  Bandă de transfer (acoperirea)  Modalități de interacțiune  Dimensiuni (ecran)  Putere de calcul  Memorie (RAM şi ROM) 10
  • 11.
    Introducere/Dispozitive mobile Tendințe:  Dezvoltarerapidă și variată (prețuri)  Evoluție performanțe hardware  Software cu aplicații în numeroase domenii Caracteristici hardware:  Procesor  Memorie  Ecran  Modalități de introducere a datelor  Conectivitate 11
  • 12.
  • 13.
  • 14.
    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
  • 16.
    Introducere/Dispozitive mobile Procesoare deaplicații  Qualcomm  Snapdragon seriile 400, 600 și 800  Samsung  Exynos seriile 5, 7 și 8  NVIDIA  Tegra 4  Tegra K1  Tegra X1 16
  • 17.
    Introducere/Dispozitive mobile Procesoare deaplicații  Apple  A7 (iPhone 5s)  A8/A8x (iPhone 6/iPad Air 2)  A9 (iPhone 6S și 6S Plus)  A10 Fusion (iPhone 7 și 7 Plus)  A11 Bionic (iPhone X)  ……….  A15 Bionic (iPhone 13 Pro)  M1 (iPad Pro/Air)  Texas Instruments  OMAP  Intel  Atom 17
  • 18.
    Introducere/Dispozitive mobile Memorie  MemorieRAM  Memorie internă nevolatilă  Flash  NOR – XIP (eXecute In Place) - random access  NAND (NOT-AND) - blockwise access only  Memorie externă  Cartelă memorie (uzual microSD) 18
  • 19.
    Introducere/Dispozitive mobile Ecran  Diagonala Rezoluția  Densitatea (ppi, dpi)  Număr culori  Tehnologia  LCD TFT (Transmissive, Transflective, Reflective)/Super LCD/IPS/OLED/AMOLED  Tactil sau nu  Capacitiv  Rezistiv 19
  • 20.
    Introducere/Dispozitive mobile Metode deintroducere a datelor  Ecran tactil (touch screen)  Tastatură virtuală  Tastatură numerică  Mini -Joystick (D-pad)  Tastatură QWERTY 20
  • 21.
    Introducere/Dispozitive mobile Conectivitate wireless 21 Reţea Wireless Ratamaximă de transfer Standarde/Tehnologii WPAN 9.6 Kbps - 3 Mbps IR, Bluetooth, NFC WLAN 1-300 Mbps 802.11 a, b, g, n WWAN 8 Kbps-300 Mbps GSM (CSD, HCSD), GPRS, EDGE, UMTS (WCDMA) cu HSPDA/HSPA+, LTE cdmaOne, CDMA2000
  • 22.
    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
  • 23.
    Introducere/Dispozitive mobile Conectivitate WWAN 23 StandardRata maximă de transfer CSD 9.6 -14.4 kbps HSCSD 28.8 - 56 kbps GPRS 115 Kbps EDGE 236.8 Kbps UMTS 384 kpbs – 7.2/14/21/42 Mbps (cu HSDPA/HSPA+) LTE 300 Mbps
  • 24.
    Introducere/Dispozitive mobile Dispozitive mobile- caracteristici 24 Caracteristica Dispozitiv Dimensiunea ecranului Frecvență procesor Memoria (RAM/Internă/E xterna) Conectivitate Telefon mobil 1”-2.5” 160x160 - QVGA Minimală 1-64 MB/ MMC, mSD GSM, GPRS, EDGE, UMTS, Bluetooth, IR Smartphone 2.5”-5”, 320x240 – Full HD 144-2200 MHz 32 MB – 2 GB/ 4-64GB *SD, MMC GSM, GPRS, EDGE, UMTS, WiFi (802.11b/g/n/ac), Bluetooth, IR Tabletă 7" – 10" 800– 2200 MHz 512 MB – 2 GB/ 4-64GB *SD GSM, GPRS, EDGE, UMTS, LTE/WiFi (802.11b/g/n/ac)/Bluetoo th, IR Portabil (wearable) 1.25" – 2" 128x128 – 320x480 1 – 1.2 GHz 512MB – 1GB/ 4-8 GB/ - Bluetooth, WiFi, LTE
  • 25.
    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
  • 26.
    26 Sisteme de operarepentru dispozitive mobile
  • 27.
     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
  • 28.
    Sisteme de operarepentru dispozitive mobile Smartphone (2008-2011) 28
  • 29.
    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
  • 30.
    Sisteme de operarepentru dispozitive mobile Smartphone (2015 – 2016) 30
  • 31.
    Sisteme de operarepentru dispozitive mobile Smartphone (2009 – 2018) 31
  • 32.
    Sisteme de operarepentru dispozitive mobile Smartphone (2009 – 2020) 32
  • 33.
    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:
  • 40.
    Sisteme de operarepentru dispozitive mobile 40 Versiuni de Android:
  • 41.
    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)
  • 43.
    Sisteme de operarepentru dispozitive mobile 43  Android 10 Highlights
  • 44.
    Sisteme de operarepentru dispozitive mobile 44  Android 11 Highlights
  • 45.
    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
  • 59.
    Android: concepte debază  Android SDK Tools: C:UsersCristianAppDataLocalAndroidsdktools  Subfolder: sdk/tools  Instrumente:  script-uri ant pentru obținerea pachetului binar al aplicației  monitor (ddms)  emulator-arm, emulator-x86  Android SDK Platform-tools: C:UsersCristianAppDataLocalAndroidsdkplatform-tools  Folder: sdk/platform-tools  Instrumente:  adb – comunicarea cu dispozitivele Android  sqlite3  Android SDK Build-tools: C:UsersCristianAppDataLocalAndroidsdkbuild-tools25.0.2  Folder: sdk/build-tools/version/  Instrumente:  aapt – compilare resurse, generarea fișierului R.java, fișiere APK  dx - conversie cod binar Java la cod binar Dalvik 4
  • 60.
    Android Debug Bridge(ADB)  adb devices  adb kill-server  adb install  adb pull  adb push  adb shell 5
  • 61.
    Android: concepte debază .java • javac .class • dx .dex (+resources) • aapt .apk 6 Android binary files:
  • 62.
    Android: concepte debază Android SDK Manager:  Gestiunea platformelor și a instrumentelor necesare  Acces direct sau din mediul de dezvoltare  Platforma  Biblioteci  Cod sursă  Documentație  Imagini emulator 7
  • 63.
  • 64.
    Android: concepte debază Android Virtual Device (AVD):  Dispozitive virtuale Android:  Emulatoare  Caracteristici:  Procesor (ARM, x86_x64), Ecran (rezoluție ,dimensiune), Memorie (RAM, internă persistentă, externă), Versiune API, Camere  Emulatoare  ARM (Advanced RISC Machine)  x86, x64  Necesită Intel HAXM (Hardware Accelerated Execution Manager) și CPU cu suport de virtualizare  Comunicare prin aplicația adb.exe 9
  • 65.
  • 66.
    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
  • 69.
    Android: concepte debază – LogCat 14
  • 70.
    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
  • 72.
  • 73.
    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
  • 78.
    Structura aplicațiilor Android Structuraunui proiect Android:  Fișiere sursă (src)  Resurse (res)  res/drawable  res/layout  res/values  res/menu  res/xml  res/raw  Resurse preluate ca fluxuri de date (assets)  Fișier de configurare (AndroidManifest.xml)  Fișiere generate(gen)  R.java 23
  • 79.
    Structura aplicațiilor Android Organizare resurse în Eclipse 24
  • 80.
    Structura aplicațiilor Android Organizare resurse în Android Studio 25
  • 81.
    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
  • 84.
    Structura aplicațiilor Android Cerințehardware și software:  android.hardware.camera  android.hardware.camera.autofocus  android.hardware.camera.flash  android.hardware.nfc  android.hardware.sensor.gyroscope  android.hardware.Bluetooth  android.software.live_wallpaper  android.software.home_screen 29
  • 85.
    AndroidManifest.xml 30 <?xml version="1.0" encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="ase.pdm.sem1" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <activity> ... </activity> <service>...</service> <provider>...</provider> <receiver>...</receiver> </application> </manifest>
  • 86.
    Structura aplicațiilor Android Gradle: Set de instrumente pentru automatizarea procesului de build  Independent de Android Studio  Android Gradle Plugin 31
  • 87.
    build.gradle 32 android { compileSdkVersion 24 buildToolsVersion"24.0.4" defaultConfig { applicationId "ro.ase.pdm.myapplication" minSdkVersion 16 targetSdkVersion 24 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:design:23.0.1' }
  • 88.
  • 89.
    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
  • 94.
    Structura aplicațiilor Android 39 Ciclulde viață al activităților:
  • 95.
    Structura aplicațiilor Android Salvarea/restaurareastării:  Salvarea stării  onSaveInstanceState(Bundle state)  Apelată la ieșirea forțată din aplicație (modificarea configurației)  Restaurarea stării  onRestoreInstanceState(Bundle state) sau  onCreate(Bundle state)  state poate fi null! 40
  • 96.
    Structura aplicațiilor Android 41 Ciclulde viață al activităților:
  • 97.
    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
  • 98.
    Ciclul de viațăal activităților 43
  • 99.
    Clasa Bundle  Permitestocarea și regăsirea de valori după o cheie de tip String  Valorile stocate  Tipuri simple  Tipuri care implementează interfețele  Parcelable  Serializable  Adăugare valori  putString(cheie, valoare_String),  putInt (cheie, valoare_int),  putObject(cheie, valoare_object),  putLongArray(cheie, valoare_long_array) etc.  Regăsire valori  getString(cheie),  getInt(cheie),  getObject(cheie),  getLongArray(cheie) etc. 44
  • 100.
    Proprietățile activităților în AndroidManifest.xml <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> 45
  • 101.
    Resurse  Şiruri decaractere, culori, masive, stiluri (res/values):  color  string  dimen  array  Imagini (res/drawable)  Pictograme aplicație (res/mipmap)  Fişiere XML compilate (res/xml)  Fişiere necompilate (res/raw)  Fişiere de animație (res/anim)  Pentru fiecare resursă se generează identificatori în clasa R  Clasa predefinită android.R 46
  • 102.
    Resurse <resources> <string name="mesaj">Document nou</string> </resources> <resources> <colorname="culoare_fundal">#00CCCC</color> </resources> <resources> <array name="optiuni"> <item>zip</item> <item>rar</item> <item>7z</item> </array> </resources> 47
  • 103.
  • 104.
    Clasa R  Subclase color  string  dimen  array  layout  id  menu  etc.  Membri  Identificatori/denumire  Exemple  R.id.buton  R.string.denumire_aplicatie  R.color.rosu 49
  • 105.
    Referirea resurselor dincod  Clasa Resources  Metoda getResources() din clasa Context  Metode dedicate  getString()  getColor()  getDimension()  etc. 50
  • 106.
    Referirea resurselor dinfișiere XML  @resursa/nume  @android:resursa/nume  Exemple  @string/mesaj  @color/culoare_fundal  @array/optiuni  @id/id_element  @+id/id_text1 51
  • 107.
    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
  • 112.
    Containere  ConstraintLayout  Relativla alte componente  FrameLayout  Componentele vizuale sînt suprapuse (stivă)  ScrollView /HorizontalScrollView  Permite derularea conținutului pe verticală/orizontală  AbsoluteLayout (depreciat)  Poziționare absolută 57
  • 113.
    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
  • 127.
    Referirea resurselor (XML) @pachet:tip_resursa/nume_resursa  Proiectul curent  @tip_resursa/nume_resursa  Exemplu:  @dimen/dim_font  @color/culoare_fundal  Resurse predefinite  @android:tip_resursa/nume_resursa  Exemplu  @android:color/background_light  @android:string/dialog_alert_title 7
  • 128.
    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
  • 132.
  • 133.
    Proprietăți  Identificatorul componentei android:id  Asociere identificator: "@+id/identificator"  Referire identificator existent:  XML: @id/identificator  Java: R.id.identificator 13
  • 134.
    Proprietăți 14 Proprietate Atribut Exemplede valori Textul asociat resursei android:text "Text în clar" @string/text_control Distanţa conţinutului faţă de margini android:padding android:paddingTop|Left|Right | Bottom 10dp Culoarea de fundal android:background #FF00FF @drawable/imag Modul de aliniere a conţinutului android:gravity center, left Distanţa faţă de marginile containerului android:layout_margin, android:layout_marginTop|Left | Right|Bottom 30dp Afișarea/ascundere a componentei android:visibility visible, invisible, gone
  • 135.
  • 136.
    Exemplu 16 <!—res/layout/main.xml--> <LinearLayout <!-- …--> android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/textViewTitlul" android:layout_width="wrap_content" android:layout_height="20dp" android:text="@string/titlul" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:ems="10" android:hint="@string/introduceti" > </EditText> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/trimite" /> </LinearLayout> <!-- /res/values/strings.xnl --> <resources> <string name="titlu">Titlul</string> <string name="introduceti">Introduceti titlul</string> <string name="trimite">Trimite</string> </resources> // /src/Activitate.java //in metoda onCreate() setContentView(R.layout.main)
  • 137.
    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
  • 139.
    Proprietăți comune  Dimensiuni: getWidth()  getHeight()  Aspect:  setBackgroundColor(int culoare)  setBackground(Drawable)  setBackgroundResource(int idResursa) 19
  • 140.
    Proprietăți comune  Spațiere(distanţă faţă de conţinut):  setPadding()  getPaddingLeft()  getPaddingTop()  getPaddingRight()  getPaddingBottom()  Activare:  setEnabled(boolean)  isEnabled()  Posibilitatea de selectare:  setFocusable(boolean)  isFocusable() 20
  • 141.
    Proprietăți comune  Parametricontainer:  setLayoutParams(LayoutParams)  LayoutParams getLayoutParams()  Vizibilitate:  setVisibility(int) – VISIBLE, INVISIBLE, GONE 21
  • 142.
    Proprietăți comune  Poziție(pixeli):  absolută  setX()/getX()  setY()/getY()  relativă la părinte  setLeft()/getLeft()  setTop()/getTop()  setRight()/getRight()  setBottom()/getBottom() 22
  • 143.
    Proprietăți comune  Tratareevenimente:  setOnClickListener()  setOnLongClickListener()  setOnDragListener()  setOnKeyListener()  setOnTouchListener() 23
  • 144.
    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
  • 148.
    LinearLayout  Distribuirea spațiuluirămas liber (proporții)  android:layout_weight view1, view2, view3: android:layout_width="wrap_content“ view1, view2, view3: android:layout_width="0dp" android:layout_weight="1“ view1, view2 android:layout_width="wrap_content" view3: android:layout_width="0dp" android:layout_weight="1" 28
  • 149.
    LinearLayout  Alinierea componentelorîn cadrul containerului  android:layout_gravity 29
  • 150.
    RelativeLayout  Aliniere  Relativăla container (true/false):  android:layout_alignParentTop|Left|Right|Bottom  android:layout_centerHorizontal|Vertical  android:layout_centerInParent  Relativă la alte componente (id-ul):  android:layout_alignLeft|Right|Start|Top|End  Poziționare  android:layout_below, android:layout_above  android:layout_toEnd|Left|Start|RightOf 30
  • 151.
  • 152.
    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
  • 154.
    ConstraintLayout Poziționarea relativă  app:layout_constraint[PunctSursă]_[PunctDestinație]="[IdentificatorDestinație]" PunctSursă  Start  Top  Bottom  End  PunctDestinție  toStartOf  toEndOf  toBottomOf  toTopOf 34
  • 155.
    ConstraintLayout Înlănțuiri  Proprietăți  layout_constraintHorizontal_chainStyle sau layout_constraintVertical_chainStyle  Se aplică primului element din înlănțuire  Valori  spread  spread_inside  packed Manipulatori 35
  • 156.
    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
  • 157.
  • 158.
    GridLayout  Număr coloane android:columnCount  Întinderea pe mai multe linii:  android:layout_rowSpan  Întinderea pe mai multe coloane:  android:layout_columnSpan 38
  • 159.
  • 160.
    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
  • 165.
    Tratarea evenimentelor 45 Interfața Metoda pentru tratarea evenimentului Înregistrareaobiectului View.OnClickListener onClick() setOnClickListener() View.OnKeyListener onKey() setOnKeyListener() View.OnTouchListener onTouch() setOnTouchListener () View.OnLongClickListener onLongClick() setOnLongClickListener()
  • 166.
    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
  • 175.
  • 176.
    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
  • 177.
    Stiluri și teme Stiluri: Definire <resources> <style name="stil_titlu"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:textSize">14sp</item> <item name="android:textColor">#FF0000</item> <item name="android:textStyle">bold</item> </style> </resources> 6
  • 178.
    Stiluri și teme Stiluri: Referire <TextView style="@style/stil_titlu"/> <TextView ... style="@android:style/TextAppearance.Large" /> 7
  • 179.
    Stiluri și teme Teme  Atributul android:theme la nivelul  Aplicației (toate activitățile)  Unei activități  Unui container/control  AndroidManifest.xml 8
  • 180.
    Stiluri și teme Exemplede teme predefinite  Theme.Holo  Theme.Holo.Light  Theme.Holo.Light.DarkActionBar  Theme.Material  Theme.Material.Light  Theme.Material.Light.DarkActionBar  Theme.AppCompat  Theme.AppCompat.NoActionBar  Theme.AppCompat.Light  Theme.AppCompat.Light.DarkActionBar 9
  • 181.
    Stiluri și teme Teme <activity android:theme = "@android:style/Theme.Holo.Dialog"> ... </activity> 10
  • 182.
    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
  • 184.
    Meniuri Opțiuni meniu  Definireîn fișiere de resurse dedicate  res/menu  Definire în mod programatic  Interfața MenuItem 13
  • 185.
    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
  • 187.
    Meniuri 16 Versiune Android AspectMeniu 2.3.3, buton Menu 4.x, buton Menu 4.x, fără buton Menu
  • 188.
    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
  • 189.
    Meniuri Deserializarea meniurilor  Clasa MenuInflator  Inițializare  Activity#getMenuInflater()  Context#getSystemService(String)  Deserializare  inflate(int id_meniu, Menu meniu) 18
  • 190.
    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
  • 195.
  • 196.
    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
  • 201.
  • 202.
    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
  • 204.
  • 205.
    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
  • 206.
    Fragmente  androidx.fragment.app.Fragment  Jetpackși AndroidX  Recomandat începând cu API 28  android.support.v4.app.Fragment  Recomandat până la API 28  android.app.Fragment  Depreciat API 28 35
  • 207.
    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
  • 208.
    Fragmente – ciclulde viață 37
  • 209.
    Fragmente – ciclulde viață 38
  • 210.
    Fragmente – ciclulde viață 39 https://www.javatpoint.com/android-fragments
  • 211.
    Fragmente Clasa Fragment  Referireactivitate container  getActivity() 40
  • 212.
  • 213.
    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
  • 221.
    Fragmente  DialogFragment  ListFragment PreferenceFragment  WebViewFragment 50
  • 222.
    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
  • 226.
    Componente vizuale complexe ListView, GridView  Spinner  RecyclerView  AutoCompleteTextView  MultiAutoCompleteTextView  Gallery  ListActivity  getListView()  setListAdapter()  ListFragment 4
  • 227.
    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
  • 228.
    Adaptoare  Clase derivatădin BaseAdapter  implementează interfața Adapter  ArrayAdapter  CursorAdapter  SimpleCursorAdapter  SimpleAdapter 6
  • 229.
  • 230.
    Componente vizuale complexe 8 Sursade date • Array • ArrayList • Cursor • … Adaptor • ArrayAdapter • SimpleCursorAdapter • CursorAdapter • utilizator Controale complexe (AdapterView) • ListView • GridView • Spinner Layout element • utilizator • implicite (android.R.layout.) •simple_spinner_dropdown_item •simple_list_item_1 •etc.
  • 231.
    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
  • 232.
    Spinner: Inițializare dinresurse <string-array name="extensii_fisiere"> <item>zip</item> <item>rar</item> <item>arj</item> </string-array> 10
  • 233.
    Spinner: Inițializare dinresurse <Spinner android:id="@+id/spinner" android:layout_width="match_parent" android:layout_height="wrap_content„ android:entries="@array/extensii_fisiere" /> 11
  • 234.
    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
  • 239.
  • 240.
    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
  • 243.
  • 244.
  • 245.
    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
  • 246.
  • 247.
    Adaptor personalizat –Exemplu public class AdaptorTari extends BaseAdapter { List<Tara> tari; LayoutInflater layoutInflater; AdaptorTari(Context context, List<Tara> tari) { layoutInflater = LayoutInflater.from(context); this.tari = tari; } //urmează implementarea metodelor clasei abstracte } 25
  • 248.
    Adaptor personalizat –Exemplu @Override public int getCount() { return tari.size(); } @Override public Object getItem(int position) { return tari.get(position); } @Override public long getItemId(int position) { return position; } 26
  • 249.
    Adaptor personalizat –Exemplu @Override public View getView(int position, View view, ViewGroup parent) { if (view == null) { view = layoutInflater.inflate(R.layout.element_lista, parent, false); } //initializare obiecte controale ImageView ivSteag = view.findViewById(R.id.imageViewSteag); TextView tvNume = view.findViewById(R.id.textViewNume); TextView tvPopulatie = view.findViewById(R.id.textViewPopulatie); Tara tara = tari.get(position); 27
  • 250.
    Adaptor personalizat –Exemplu //initializare controale cu valori ivSteag.setImageBitmap(tara.getSteag()); tvNume.setText(tara.getNume()); tvPopulatie.setText(tara.getPopulatie() + " locuitori"); return view; } 28
  • 251.
    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
  • 253.
    Adaptor personalizat –Exemplu else { holder = (ViewHolder)convertView.getTag(); /*reutilizare resurse*/ } Tara tara = tari.get(position); //initializare controale cu valori holder.ivSteag.setImageBitmap(tara.getSteag()); holder.tvNume.setText(tara.getNume()); holder.tvPopulatie.setText(tara.getPopulatie() + " locuitori"); return view; } 31
  • 254.
    Adaptor personalizat –Asociere adaptor AdaptorTari adaptorTari = new AdaptorTari( this, listaTari); setListAdapter(adaptorTari); 32
  • 255.
    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
  • 258.
    Selecția elementelor –Spinner  getSelectedItem()  getSelectedItemId()  Interfața  AdapterView.OnItemSelectedListener  Metodele implementate  onItemSelected()  onNothingSelected()  Asociere  setOnItemSelectedListener() 36
  • 259.
    Selecția elementelor –Spinner spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int poz, long id) { //parent.getItemAtPosition(poz); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); 37
  • 260.
    Selecția elementelor –ListView  getItemAtPosition()  getItemIdAtPosition()  Interfața  AdapterView.OnItemClickListener  Metoda implementată  onItemClick()  Asociere  setOnItemClickListener() 38
  • 261.
    Selecția elementelor –ListView lista.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View item, int poz, long id){ //referim elementul selectat prin poz; //parent.getItemAtPosition(poz); } }); 39
  • 262.
    Ferestre de informare Clasa Activity  @android:style/Theme.***.Dialog  Clasa Dialog sau derivate  Clasa AlertDialog  Clasa DialogFragment  Ferestre de dialog predefinite  ProgressDialog  TimePickerDialog  DatePickerDialog  Clasa Toast 40
  • 263.
    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
  • 268.
    Ferestre de informare– Exemplu 46
  • 269.
    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
  • 271.
    Mesaje (Intent) Obiecte detip Intent  Mesaje asincrone  Utilizare  Invocare activități  Invocare servicii  Transmitere mesaje globale  Partajare date 49
  • 272.
    Mesaje (Intent) Caracteristicile mesajelorde tip Intent  Acțiuni  Date  Tip de date  Categorie  Date adiționale  Componenta destinație 50
  • 273.
    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
  • 277.
  • 278.
    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
  • 280.
    Mesaje (Intent) Modificarea proprietăților setAction(String)  addCategory(String)  setData(Uri)  setType(String)  Tip MIME  setDataAndType()  setComponent(Context)  setClass(Class) 58
  • 281.
    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
  • 284.
    Mesaje (Intent) Lansarea uneiactivități din proiect  Intent explicit  Parametri constructor Intent:  Contextul curent  Clasa activității destinație  Metode (clasa Context):  startActivity(Intent) 62
  • 285.
    Mesaje (Intent)  Lansareaunei activități 63
  • 286.
    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
  • 292.
    Mesaje (Intent)  Invocareaunei activități pentru răspuns 70
  • 293.
    Mesaje (Intent)  Invocareaunei activități pentru răspuns Activitatea apelantă (1) 1. Inițializare mesaj explicit/implicit  Context + componentă sau acțiune/date 2. Adăugare date mesaj (opțional)  putExtras()/putExtra() 3. Invocare activitate (metodă clasa Activity)  startActivityForResult(Intent, codCerere) 71
  • 294.
    Mesaje (Intent)  Invocareaunei activități pentru răspuns Activitatea invocată 4. Obținere mesaj  getIntent() 5. Preluare date adiționale (opțional)  getExtra()/getTIPExtras() 6. Adăugare răspuns în mesaj  putExtras()/putExtra() 7. Stabilire rezultat activitate  setResult()  RESULT_OK, RESULT_CANCELED 8. Terminare activitate  finish() 72
  • 295.
    Mesaje (Intent)  Invocareaunei activități pentru răspuns Activitatea apelantă (2) 9. Preluare răspuns  supraîncărcare metodă clasa Activity  onActivityResult(codCerere, codRezultat, Intent)  codRezultat = RESULT_OK, RESULT_CANCELED, … 73
  • 296.
    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
  • 300.
    Agenda  Operații asincrone Accesul la rețea  Socket  HTTP  Servicii Web  Prelucrarea fișierelor XML și JSON 2
  • 301.
    Accesul la rețea Controlul WebView  Clase acces prin socket  Socket  ServerSocket  DatagramSocket  Clase HTTP API  Java SE 3
  • 302.
    Accesul la rețea Permisiunea android.permission.INTERNET  Excepție  Prelucrările au loc într-un alt fir de execuție  Excepție 4
  • 303.
    Accesul la rețea WebView Afișare conținut HTML  Implicit JavaScript nu este activat  WebSettings  getSettings()  loadUrl()  Adresa paginii  loadData()  Conținut HTML 5
  • 304.
    Accesul la rețea Accesulprin HTTP  Specific Java SE  Pachetul java.net  Resursa  URL  Conexiune  HttpURLConnection  HttpsURLConnection 6
  • 305.
    Accesul la rețea HTTP/HTTPS 1.Inițializare obiect URL  adresa resursei 2. Inițializare conexiune prin intermediul obiectului URL  Metoda URL#openConnection() HttpURLConnection 3. Stabilire parametri 4. Preluare conținut  HttpURLConnection#getInputStream() 7
  • 306.
    Accesul la rețea HTTP/HTTPS 1. Inițializare obiect URL  adresa resursei 2. Preluare conținut  URL#openStream() 8
  • 307.
    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
  • 317.
  • 318.
    Operații asincrone  Java clasa Thread  interfața Runnable  Android  clasa Handler  Metode runOnUiThread(Runnable) (clasa Activity) post(Runnable) (clasa View) postDelayed(Runnable, long) (clasa View)  clasa AsyncTask 20
  • 319.
    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
  • 322.
  • 323.
    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
  • 326.
    Clasa Handler  Exemplu:Transmitere obiect Runnable Handler handler = new Handler(); //... handler.post(new Runnable() { @Override public void run() { // prelucrări actualizare } }); 28
  • 327.
    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
  • 330.
  • 331.
    Metode specifice  ClasaActivity  runOnUiThread(Runnable)  View  post(Runnable)  postDelayed(Runnable, long) 33
  • 332.
    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
  • 335.
    Agenda  Accesul larețea  Prelucrarea fișierelor XML și JSON 2
  • 336.
    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
  • 342.
  • 343.
    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
  • 345.
  • 346.
    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
  • 356.
    Fișiere JSON  JavaScriptObject Notation  { } – obiect  [ ] – vector de valori  "proprietate" : "valoare" 23
  • 357.
    Fișiere JSON { "biblioteca": { "carte":[ { "-cota": "19222", "autor": { "nume": "R. Meier" }, "titlu": " Professional Android Application Development ", "editura": "wiley", "an": "2009", "isbn": "1-72-11-2222", "pagini": "500" }, { "-cota": "19223", "autor": { "nume": [ "S. Hashimi", " S. Komatineni", " D. MacLean " ] }, "titlu": "Pro Android 3", "editura": "Apress", "an": "2011", "isbn": "0-321-15040-6", "pagini": "336" } ] } } 24
  • 358.
    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
  • 361.
    Prelucrare fișiere XML SAXParserFactoryfact = SAXParserFactory.newInstance(); SAXParser xmlParser = fact.newSAXParser(); XMLReader xmlReader = xmlParser.getXMLReader(); SAXHandler handler = new SAXHandler(); xmlReader.setContentHandler(handler); xmlReader.parse(new InputSource(streamIn)); 28
  • 362.
    Prelucrare fișiere XML XMLPull  Interfața XmlPullParser  Inițializare  Resources#getXml()  res/xml  Xml.newPullParser()  XmlPullParserFactory#newPullParser()  XmlPullParserFactory  XmlPullParserFactory.newInstance()  Asociere flux de intrare (InputStream sau Reader)  setInput() 29
  • 363.
    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
  • 370.
    Prelucrare fișiere JSON org.json  JSONObject  getTIP(): getString(), getBoolean(), getInt() etc.  getJSONArray()  getJSONObject()  JSONArray  length()  getTIP(index) 37
  • 371.
    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
  • 392.
    Baze de dateSQLITE – Biblioteca ROOM Cursor  Parcurgere  moveToNext()  moveToPrevious()  moveToFirst()  moveToLast()  Extragerea de valori  getTIP(): getInt(), getString(), getFloat() etc.  parametru: indexul coloanei 20
  • 393.
    Baze de dateSQLITE – Biblioteca ROOM Cursor: Determinarea poziției  isFirst()  isLast()  isBeforeFirst()  isAfterLast() 21
  • 394.
    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
  • 399.
    Stocarea în containerulaplicației  AssetManager  getAssets() (clasa Context)  open(nume_fisier) -> InputStream  list(cale)  String[] Lista fișiere 27
  • 400.
    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
  • 403.
    Fișiere Directoare speciale  Directorpublic mediu extern stocare  getExternalStoragePublicDirectory(tip) tip (membri statici) DIRECTORY_PICTURES DIRECTORY_MUSIC DIRECTORY_DOWNLOADS DIRECTORY_DCIM DIRECTORY_RINGTONES DIRECTORY_ALARMS depreciat API 29 31
  • 404.
    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
  • 408.
    Fișiere  Metode înclasa Context  FileInputStream openFileInput(String numeFisier)  FileOutputStream openFileOutput(String numeFisier, int mod)  Context.MODE_PRIVATE/ Context.MODE_APPEND  boolean deleteFile(String numeFisier)  String[] fileList()  File getDir(String numeDir, int mod) 36
  • 409.
    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
  • 412.
    Fișiere externe  android.permission.WRITE_EXTERNAL_STORAGE Verificare disponibilitate mediu extern de stocare  Verificare drepturi citire/scriere 40
  • 413.
    Fișiere externe try { //obtinere starea mediului de stocare extern String stareSD = Environment.getExternalStorageState(); // daca este montat if (stareSD.equals(Environment.MEDIA_MOUNTED)) { // obtinerm director extern asociat aplicatiei File dir = getExternalFilesDir(null); if (dir != null) { // creare fisier File fis = new File(dir, NUME_FISER2); FileWriter os = new FileWriter(fis); os.write("DAM 2020"); os.close(); } } } catch (IOException ex) { ex.printStackTrace(); } 41
  • 414.
    Serializarea și deserializareaobiectelor  Modalități de serializare 42
  • 415.
    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
  • 432.
    Fișiere de proprietăți Preluareadatelor  Metode de forma getTIP()  getBoolean(),  getInt() etc. 13
  • 433.
    Fișiere de proprietăți Editarefișiere de proprietăți  Clasa SharedPreferences.Editor  Inițializare  SharedPreferences#edit()  Scriere  Metode de forma putTIP()  Ștergere preferințe  remove()  Ștergerea tuturor preferințelor  clear()  Salvare modificări  commit() – apel sincron  apply() – apel asincron 14
  • 434.
    Fișiere de proprietăți SharedPreferencessetari = getSharedPreferences("setari", Activity.MODE_PRIVATE); SharedPreferences.Editor editorProp = setari.edit(); editorProp.putBoolean("titlu", false); editorProp.putBoolean("ajutor", true); editorProp.putInt("max", 5); editorProp.commit(); 15
  • 435.
    Fișiere de proprietăți SharedPreferencessetari = getSharedPreferences("setari", Activity.MODE_PRIVATE); boolean fTitlu = setari.getBoolean("titlu", false); boolean fAjutor = setari.getBoolean("ajutor", true); int nMax = setari.getInt("max", 5); 16
  • 436.
    Activități pentru salvareapreferințelor  Pachetul androidx.preference  API 29  Clase  PreferenceFragmentCompat  PreferenceScreen  PreferenceCategory  Preferences  Ferestre de dialog  EditTextPreference  ListPreference  MultiSelectListPreference  Controale  CheckBoxPreference  SwitchPreference 17
  • 437.
    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
  • 442.
  • 443.
    Activități pentru salvareapreferințelor SharedPreferences preferinte = PreferenceManager .getDefaultSharedPreferences(this); boolean modNoapte = preferinte.getBoolean("modNoapte", false); String user = preferinte.getString("utilizator", "neconectat"); String [] setariFonturi = new String[5]; preferinte.getStringSet("listaFont", new HashSet<String>()).toArray(setariFonturi); 24
  • 444.
    Serializarea și deserializareaobiectelor  Modalități de serializare 25
  • 445.
    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
  • 453.
    Baze de datela distanță 4
  • 454.
    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
  • 460.
    Firebase Realtime Database Tipuride date suportate  String  Boolean  Long  Double  Map<String, Object>  List<Object> 11
  • 461.
    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
  • 467.
    Firebase Realtime Database Preluareadatelor  ValueEventListener  onDataChange(DataSnapshot)  onCancelled(DatabaseError)  Asociere (prin DatabaseReference)  addValueEventListener()  addListenerForSingleValueEvent()  Eliminare asociere  removeEventListener() 18
  • 468.
    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
  • 469.
    Firebase Realtime Database Ștergereadatelor  removeValue()  setValue(null)  updateChildren(map)  valorile din map sunt nule 20
  • 470.
    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
  • 473.
    Firebase Realtime Database Monitorizareaactualizărilor  ChildEventListener  Metode  abstract void onChildAdded(DataSnapshot snapshot, String previousChildName)  abstract void onChildChanged(DataSnapshot snapshot, String previousChildName)  abstract void onChildMoved(DataSnapshot snapshot, String previousChildName)  abstract void onChildRemoved(DataSnapshot snapshot)  abstract void onCancelled(DatabaseError error) 24
  • 474.
    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
  • 475.
    Cloud Firestore Structura datelor Colecție  Documente  Date  cheie, valoare  Subcolecții 26
  • 476.
    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
  • 483.
    Cloud Firestore Interogarea datelor Referința colecție  Metoda get()  Rezultatul Task<DocumentSnapshot>  Rezultatul Task<QuerySnapshot>  toObjects(class)  toObject(class) 34
  • 484.
    Cloud Firestore Filtrarea șisortarea datelor  Obiectul de tip colecție  Filtrare  whereEqualTo()  whereLessThan()/whereLessThanOrEqualTo()  whereGreaterThan()/whereGreaterThanOrEqualTo()  whereArrayContains()/whereArrayContainsAny()  whereIn()  Sortare  orderBy(cimp[, directie])  Query.Direction.ASCENDING, Query.Direction.DESCENDING  Număr maxim rezultate  limit(valoare) 35
  • 485.
    Autentificare/Înregistrare  Furnizori multipli Definire din consola Firebase  Clase specializate 36
  • 486.
    Autentificare/Înregistrare Furnizori  Email +parolă  Google  Facebook  Twitter  GitHub 37
  • 487.
    Autentificare/Înregistrare Clase și interfețe FirebaseAuth  AuthStateListener  FirebaseUser 38
  • 488.
    Autentificare/Înregistrare FirebaseAuth auth =FirebaseAuth.getInstance(); FirebaseUser user = auth.getCurrentUser(); if (user != null) { //continuare in aplicatie } else { //autentificare utilizator } 39
  • 489.
    Clase suport FirebaseUI  https://github.com/firebase/FirebaseUI-Android FirebaseUI for Android — Auth  AuthUI  FirebaseUI for Realtime Database  FirebaseListAdapter  FirebaseRecyclerAdapter 40
  • 490.
    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
  • 495.
    Grafică bidimensională Desenare imaginiîn controale  ImageView  Drawable (clasă abstractă)  res/drawable, res/raw  Imagini Fișiere grafice  Figuri Fișiere xml  Canvas  Desen liber/figuri  android.graphics 5
  • 496.
    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
  • 497.
    Grafică bidimensională int w,h; Bitmap bmp1 = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Bitmap bmp2 = BitmapFactory.decodeResource( getResources(), R.drawable.dice); 7
  • 498.
    Grafică bidimensională Componente debază  Culori și texturi  Instrumentul de desenat  Suprafața de desenat  Contururi geometrice 8
  • 499.
    Grafică bidimensională Culori  ClasaColor  Constante (RED, BLUE etc.)  Metoda statică argb(a, r, g, b)  Metoda statică parseColor(String) #RRGGBB #AARRGGBB Nume culoare  Resurse  Resources#getColor() res/values 9
  • 500.
    Grafică bidimensională Culori  intculoare = getResources().getColor(R.id.fundal);  int verde = Color.GREEN;  int verdeSemiTransp = Color.argb(127, 0, 255, 0); 10
  • 501.
    Grafică bidimensională Gradienți  Culoriși sau imagini  clasa Shader si derivate  Modul de umplere:  repetarea șablonului (Shader.TileMode.REPEAT)  repetarea șablonului cu alternarea imaginii inversate (Shader.TileMode.MIRROR)  replicarea culorii exterioare la depășirea limitelor (Shader.TileMode.CLAMP). 11
  • 502.
    Grafică bidimensională Gradienți  clasaShader şi subclasele acesteia  BitmapShader – desenarea folosind imagini  LinearGradient – gradienți liniari  RadialGradient – gradienți circulari  SweepGradiet – gradienți unghiulari  ComposeShader – combinarea doi gradienți. 12
  • 503.
    Grafică bidimensională Gradienți Bitmap bmpShader; BitmapShadergradientBmp = new BitmapShader(bmpShader, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT ); LinearGradient gradientLinear = new LinearGradient(0, 0, 150, 150, Color.RED, Color.BLUE, Shader.TileMode.CLAMP); 13
  • 504.
    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
  • 506.
    Grafică bidimensională Clasa Paint Proprietăți linie contur/umplere:  void setStyle(Paint.Style style)  void setStrokeWidth(float width)  PathEffect setPathEffect(PathEffect effect)  void setAntialias(boolean aa)  Inițializare gradient  Shader setShader(Shader shader) 16
  • 507.
    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
  • 510.
    Grafică bidimensională Canvas public classDesenView extends View { … protected void onDraw(Canvas canvas) { super.onDraw(canvas); //desenarea propriu-zisă } } 20
  • 511.
    Grafică bidimensională Desenarea înimagini (Bitmap)  Se utilizează constructorul  Canvas(Bitmap)  Pași  Crearea/Obținerea unui obiect de tip Bitmap Bitmap bmp = Bitmap.createBitmap(l, L, tip);  Inițializarea obiectului de tip Canvas Canvas canvas = new Canvas(bmp); 21
  • 512.
    Grafică bidimensională Desenarea figurilorgeometrice  void drawPoint(float x, float y, Paint paint)  void drawPoints(float[ ] pts, int offset, int count, Paint paint)  void drawLine(float startX, float startY, float stopX, float stopY, Paint paint)  void drawLines(float[ ] pts, Paint paint) 22
  • 513.
    Grafică bidimensională Desenarea figurilorgeometrice  void drawRect(RectF rect, Paint paint)  void drawRoundRect(RectF rect, float rx, float ry, Paint paint)  void drawCircle(float cx, float cy, float radius, Paint paint)  void drawOval(RectF oval, Paint paint)  void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) 23
  • 514.
    Grafică bidimensională Afișarea imaginilor void drawBitmap(Bitmap bmp, float left, float top, Paint paint)  void drawPicture(Picture picture, RectF dst) 24
  • 515.
    Grafică bidimensională Modificarea fundalului void drawColor(int color)  void drawRGB(int r, int g, int b)  void drawARGB(int a, int r, int g, int b)  void drawPaint(Paint paint) 25
  • 516.
    Grafică bidimensională Afișarea textului void drawText(String text, float x, float y, Paint paint) 26
  • 517.
    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
  • 519.
    Grafică bidimensională Desenare/afișare textdupă contururi geometrice  void drawPath(Path path, Paint paint)  void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) 29
  • 520.
    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
  • 521.
    Grafică bidimensională Transformări  Scalare Metoda scale(sx, sy)  Translatare (mutare)  Metoda translate(dx, dy)  Rotiri  Metoda rotate(grade)  Înclinare  Metoda skew(x, y) 31
  • 522.
    Figuri geometrice (codsursă Java)  ShapeDrawable  Construire obiecte de tip Shape  RectShape  OvalShape  ArcShape  PathShape  Metode  getPaint()  draw(Canvas)  setBounds(x1, y1, x2, y2) 32
  • 523.
    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
  • 525.
    Figuri geometrice (XML) <shapexmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <corners android:radius="10dp" /> <size android:height="@dimen/lat" android:width="@dimen/lung" /> <solid android:color="@android:color/transparent" /> <stroke android:width="2dp" android:color="#000000" /> </shape> 35
  • 526.
    Figuri geometrice (XML) Referire XML:  @drawable/numeFisierXMLFigura  Referire Java  R.drawable.numeFisierXMLFigura  Resources#getDrawable 36
  • 527.
    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
  • 533.
    Preluarea imaginilor dincolecția de fotografii protected void onActivityResult(int codCerere, int codRezultat, Intent intent) { if (codCerere == SELECTEAZA_IMAGINE && codRezultat == RESULT_OK) { Uri uriImagine = intent.getData(); Bitmap bmp; try { bmp = MediaStore.Images.Media.getBitmap( getContentResolver(), uriImagine); //utilizare bmp } catch (Exception e) { e.printStackTrace(); } } } 43
  • 534.
    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
  • 536.
    Agenda  Receptori demesaje  Utilizarea serviciilor Android  Determinarea poziției geografice  Utilizarea Google Maps  Senzori, GPS, Google Maps 2
  • 537.
    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
  • 538.
    Receptori de mesaje Mesajeglobale  Intent.ACTION_BATTERY_LOW  Intent.ACTION_BOOT_COMPLETED  Intent.ACTION_MEDIA_MOUNTED  Intent.ACTION_SCREEN_OFF  Telephony.Sms.Intents.SMS_RECEIVED 4
  • 539.
    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
  • 549.
    Servicii  Servicii predefinite 15 ServciuConstantă asociată (clasa Context) Alarm ALARM_SERVICE Bluetooth AUDIO_SERVICE Location LOCATION_SERVICE Notification NOTIFICATION_SERVICE Sensor SENSOR_SERVICE Telephony TELEPHONY_SERVICE Wifi WIFI_SERVICE
  • 550.
    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
  • 553.
    Servicii  Servicii predefinite– Exemplu Notification notif = new Notification.Builder(this) .setContentTitle("Notificare") .setSmallIcon(R.drawable.icon) .setContentText("Serviciu Info") .setContentIntent(pendingIntent).build() //transmiterea notificarii notif notifManager.notify(NOTIF_ID, notif); //Pentru oprirea notificărilor: notifManager.cancel(NOTIF_ID); 19
  • 554.
    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
  • 567.
    Determinarea poziției geografice Poziționaregeografică – Exemplu LocListener locListener = new LocListener(); LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); //asociere furnzizor servicii localizare locManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, locListener); //dezactivare asociare servicii localizare locManager.removeUpdates(locListener); 33
  • 568.
    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
  • 570.
    Determinarea poziției geografice Obținereaadreselor if (Geocoder.isPresent()) { Geocoder geocoder = new Geocoder(getApplicationContext()); try { List<Address> adrese = geocoder.getFromLocation(lat, lon, 1); if (adrese.size() > 0) { //adrese.get(0).getCountryName() //adrese.get(0).getLocality()) //etc. } } catch (IOException ex) { ex.printStackTrace(); } } 36
  • 571.
    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
  • 576.
    Google Maps Control cameră Parametri vizualizare  Locație  Unghi înclinare  Zoom  Clase  CameraUpdate  CameraPosition  Obținere CameraUpdate  CameraUpdateFactory  Metode  moveCamera(CameraUpdate)  animateCamera(CameraUpdate) 42
  • 577.
    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
  • 587.
    Furnizori de conținut Pachetul android.provider  Predefiniți  Definiți de utilizator  Implementarea clasei abstracte ContentProvider  ContentResolver  Context#getContentResolver() 5
  • 588.
    Furnizori de conținut Furnizoride conținut predefiniți  CallLog  Calls  ContactsContract  Contacts  CalendarContract  Calendars  Events  Reminders 6
  • 589.
    Furnizori de conținut Furnizoride conținut predefiniți  MediaStore  Audio  Images  Video  Settings  System  Global 7
  • 590.
    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
  • 591.
    Furnizori de conținut Operațiiasupra furnizorilor  Acces prin clasa ContentResolver  query(Uri, String[], String, String[], String)  insert(Uri, ContentValues)  update(Uri, ContentValues, String, String [])  delete(Uri, String, String []) 9
  • 592.
    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
  • 601.
    Gestiunea dinamică apermisiunilor Verificarea existenței permisiunii  Metoda ContextCompat.checkSelfPermission()  Parametrii  Contextul  Permisiunea  Manifest.permission.WRITE_CALENDAR,  Manifest.permission.ACCESS_COARSE_LOCATION  etc.  Returnează  PackageManager.PERMISSION_GRANTED  PackageManager.PERMISSION_DENIED 19
  • 602.
    Gestiunea dinamică apermisiunilor Cererea permisiunii  Metoda ActivityCompat.requestPermissions()  Parametrii  Contextul  Lista permsiunilor (String [])  Codul asociat cererii pentru metoda cu apel invers 20
  • 603.
    Gestiunea dinamică apermisiunilor  Cererea permisiunii 21
  • 604.
    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
  • 607.
  • 608.
  • 609.
    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