Documente Academic
Documente Profesional
Documente Cultură
Cursul 1
Prezentare disciplină
• Obiective
• Elemente de conținut
• Modalitatea de evaluare
Obiective
• Utilizarea eficientă a tehnologiilor mobile în
cadrul societății informaționale actuale
• 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
Elemente de conținut
• Introducere:
– Dispozitive mobile (DM)
– Sisteme de operare pentru DM
– Aplicații mobile
• Programarea aplicațiilor Android
– Instrumente de dezvoltare
– Interfața utilizator
– Accesul la rețea
– Stocarea persistentă a datelor
– Grafică bidimensională
– Introducere servicii, furnizori de conținut și receptori de mesaje
– Utilizarea Google Maps în aplicații
– Publicarea aplicațiilor în magazinul virtual
Sumar
• Dispozitive mobile
• Modelul de programare Android
• Instrumente de dezvoltare
• Structura aplicațiilor Android; componente
• Structura unui proiect
• Activități
Dispozitive mobile (DM)
• Telefoane mobile
• Smartphone-uri
• Tablete
– cu/fără suport telefonie
• PDA
– fără suport telefonie
• Dispozitive portabile (wearable)
– cu/fără suport telefonie
DM 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)
Dispozitive mobile
System on a
Chip (SoC)
Memorie Memorie Sursă
Flash RAM tensiune
Procesor Ecran
Grafic
(GPU)
Procesor Procesor
comunicaţii aplicaţii
SIM
Alte
Audio
dispozitive de I/O
Dispozitive mobile
Conector Procesor
SIM
Camera
Conector
cartelă
memorie
Ecran
Difuzor
Motor
vibrații
Placa de bază
(față/verso)
Dispozitive mobile
Sisteme de operare
• Sisteme de operare proprii
• Sisteme de operare
smartphones/tablete/portabile
– Posibilitatea dezvoltării de aplicații pe baza unui
SDK
Sisteme de operare
• Android (Google)
• Tizen (Tizen Association)
• iOS (Apple)
• Linux Mobile
• Windows 10 Mobile/Windows
Phone/Windows CE/Windows Mobile
(Microsoft)
Aplicații 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
ANDROID
Android
Windows Symbian
Mobile 57.12% BlackBerr
12.02% Linux y Windows Android
7.32% 20.90% Mobile 2.80%
9.00%
iPhone
OS
16.01%
BlackBer Altii Windows, Bada, 2.2 Altii, 0.9 Symbian,
2.96% 16.9
RIM, 11 1.5
ry Symbian
14.43% 30.63%
iOS, 15
Windows
Mobile
3.06%
Android
32.91%
Android,
52.5
Sursa: Canalys/Gartner
Smartphone 2012/13/15/16+
Android
69% Android,
Altii, 0.3 77
Windows Phone, 1.2
iOS, 18.6 iOS, 11.7 Windows Phone, 0.4 Altii, 0.3
Android,
79.6
Android, 87.6
http://ctstech.net/blog/2013/02/14/idcs-smartphone-stats-for-4q-2012-and-a-review-of-their-mobile-os-share-prediction-for-2015/
http://gadgets.ndtv.com/mobiles/news/windows-phone-grows-104-percent-year-over-year-in-q4-2013-abi-research-478672
http://www.idc.com/prodserv/smartphone-os-market-share.jsp
De ce Android?
Sursa: https://developer.android.com/about/dashboards/index.html
Ultima actualizare: 28 Septembrie 2018
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
Android SDK
• Build-tools
– Director: sdk/build-tools/versiune/
– Instrumente
• aapt – compilare resurse, generarea fișierului R.java, fișiere APK
• dx - conversie cod binar Java la cod binar Dalvik
• Platform-tools
– Specifice fiecărei platforme
– Director: sdk/platform-tools
– Instrumente:
• adb – comunicarea cu dispozitivele Android
• sqlite3
• SDK Tools
– Independente de platformă
– Subdirector: sdk/tools
– Instrumente:
• script-uri ant pentru obținerea pachetului binar al aplicației
• monitor(ddms)
• emulator-arm, emulator-x86
Android SDK Manager
• Gestiunea platformelor și a instrumentelor
necesare
• Acces direct sau din mediul de dezvoltare
• Platforma
– Biblioteci
– Cod sursă
– Documentație
– Imagini emulator
Android SDK Manager
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
• Comunicare prin aplicația adb.exe
Emulatoare
• Emulare
– ARM
– X86, x64
• Necesită Intel HAXM și procesor cu suport virtualizare
• API
– Standard
– Google API
– Google Play
Android Debug Bridge (ADB)
• Asigură comunicarea între mașina de
dezvoltare și dispozitivele Android (reale sau
virtuale)
• Componente
– Client
• Permite transmiterea de comenzi
– Server
• Mașina de dezvoltare
• Dispozitivul Android
Exemple de comenzi
• adb devices
• adb kill-server
• adb install
• adb pull
• adb push
• adb shell
AVD Manager
• Dispozitive virtuale
– Definire
– Modificare
– Ștergere
• Accesat direct sau din mediul integrat de
dezvoltare
• Pot fi definite oricîte dispozitive virtuale
– Se va alege unul la lansarea în execuție a aplicației
AVD Manager
AVD Manager
Consola de mesaje (LogCat)
• Afișează mesaje transmise din aplicații
– Utilizator
– Sistem
• Mesaje
– Avertizare (w)
– Depanare (d)
– Eroare (e)
– Informare (i)
– Informare detaliată (v)
– Eroare excepțională (wtf)
Consola de mesaje (LogCat)
Consola de mesaje (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.
Consola de mesaje (LogCat)
• Log.i("Activitate1", "Mesaj de informare");
• Log.println(Log.ASSERT, "Activitate 1",
"Aserțiune invalida!");
STRUCTURA APLICAȚIILOR
ANDROID
Structura aplicațiilor Android
• Includ una sau mai multe componente
• Componentele sînt înregistrate de sistem
– Pot fi și componente locale
• Componentele pot fi activate
– Local, în cadrul aplicației
– Global, la nivelul sistemului
Componente de bază ale aplicațiilor
Android
• Activități
– clasa de bază android.app.Activity
• Servicii
– clasa de bază android.app.Service
• Furnizori de conținut
– clasa de bază android.content.ContentProvider
• Receptori de mesaje
– clasa de bază android.content.BroadcastReceiver
– mesaje
• clasa de bază android.content.Intent
Activități
• 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
Activități
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
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://
Mesaje (obiecte de tip 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
Recepționarea evenimentelor
• 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
STRUCTURA PROIECTELOR
ANDROID
Aplicații Android cu interfață grafică
• Includ una sau mai multe activități
• Fiecare activitate are asociată o componentă
vizuală părinte
– Definită procedural, în fișiere XML
– Definită în cod
• Includ resurse:
– Asociate interfeței utilizator
– Fișiere prelucrate în cadrul aplicației
Structura unui proiect Android Studio
• Proiecte și module
• Proiect
– Include unul sau mai multe module
• Modul
– Fișiere sursă, resurse, fișiere de configurare
– Permit împărțirea proiectului în module
funcționale
– Dependențe între module
– Utilizare: biblioteci, tipuri de dispozitive etc.
Structura unui proiect Android Studio
• Fișiere sursă (src)
– Fișiere sursă Java (java)
– Resurse (res)
• drawable
• layout
• menu
• mipmap
• raw
• values
• xml
• Resurse preluate ca fluxuri de date (assets)
• Fișier de configurare (AndroidManifest.xml)
• Proprietățile sistemul de compilare (proiect și modul)
– build.gradle
• Fișiere generate (gen)
– R.java
AndroidManifest.xml
• Componentele aplicației
– declarare activități, servicii, furnizori de conținut,
receptori de mesaje
– denumirile claselor asociate
– Proprietăți
• Versiunile SDK (minim, maxim, dorită)
– Preluate de fișierul build.gradle
• Informații pachet (denumire, versiune)
• Atribute aplicație (denumire, pictograma
asociată, tema, opțiuni memorie, restricții,
permisiuni etc.)
AndroidManifest.xml
• 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"/>
Exemple de permisiuni
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 SEND_SMS, READ_SMS, WRITE_SMS
SMS-uri
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
Permisiuni
• API 23 (Marshmallow)
• 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.
Cerințe hardware și software pentru
dispozitive
• 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
AndroidManifest.xml
<?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>
build.gradle
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'
}
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
Fișierele binare Android
• javac • dx • aapt
Fișierele binare Android
apk
• /META-INF
• /lib
• /res
• /assets
• AndroidManifest.xml
• classes.dex
• resources.arsc
Fișierele binare Android
• dexopt
• dex2oat
ACTIVITĂȚI
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
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()
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
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.)
Ciclul de viață al activităților
Stare
onCreate()
Creată
(invizibilă)
onStart() onRestart()
Inițializată
(vizibilă)
onResume()
Activă
(vizibilă)
onPause()
Întreruptă
(parțial
vizibilă) onStop()
Inactivă
(ascunsă)
onDestroy()
Terminată
Stiva de activități
Cursul 2
Sumar
• 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
RESURSE
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
Selectori pentru configurații
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>
Clasa R
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
Referirea resurselor din cod
• Clasa Resources
– Metoda getResources() din clasa Context
• Metode dedicate
– getString()
– getColor()
– getDimension()
– etc.
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
Resurse
//preluarea unui sir de caractere
String sir = getResources().getString(R.string.mesaj);
• ProgressBar
– Bară de progres
– Determinată (limita
superioară stabilită)
– Indeterminată (fără limită
superioară, ciclică)
• SeekBar
– Derivat din ProgressBar,
– permite selectarea valorii
curente
Componente vizuale
• AnalogClock
– Ceas analogic
• TextClock
– DigitalClock (depreciată)
– Ceas digital
– Afișat conform setărilor de
sistem
• Chronometer
– Cronometru
• RadioGroup
– permite gruparea
butoanelor radio
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
Componente vizuale complexe
• ExpandableListView
– listă compusă în care
elementele sînt grupate
pe categorii
Componente vizuale complexe
• DatePicker
– selecția datei
– derivat din FrameLayout
• TimePicker
– selecția orei
– derivat din FrameLayout
Android Support Library
• AndroidX
• 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
Exemple dispozitiv Android
INTERFAȚA ÎN MOD DECLARATIV
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()
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
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
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
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
Densitatea (PPI/DPI)
ℎ𝑝2 +𝑣𝑝2
• Densitatea =
𝑑𝑖𝑎𝑔
– hp – rezoluția pe orizontală (pixeli)
– vp – rezoluția pe verticală (pixeli)
– diag – diagonala (inci)
Dimenisiuni - conversii
• Din pixeli în dp
𝑝𝑥 ∗160
– 𝑑𝑝 =
𝐷𝑃𝐼
• Din dp în pixeli
𝑑𝑝 ∗𝐷𝑃𝐼
– 𝑝𝑥 =
160
Dimenisiuni – conversii (în cod)
DisplayMetrics dm =
getResources().getDisplayMetrics();
//conversie la pixeli
int px = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, dp, dm);
//sau
Container
View
margin padding
Conținut View height
width
Exemplu
<!—res/layout/main.xml--> <!-- /res/values/strings.xnl -->
<LinearLayout <!-- … --> <resources>
<string name="titlu">Titlul</string>
android:layout_width="match_parent"
<string name="introduceti">Introduceti titlul</string>
android:layout_height="wrap_content" <string name="trimite">Trimite</string>
android:orientation="vertical" > </resources>
<TextView
android:id="@+id/textViewTitlul" // /src/Activitate.java
//in metoda onCreate()
android:layout_width="wrap_content" setContentView(R.layout.main)
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>
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()!
INTERFAȚA ÎN MOD PROCEDURAL
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
Proprietăți comune
• Dimensiuni:
– getWidth()
– getHeight()
• Aspect
– setBackgroundColor(int culoare)
– setBackground(Drawable)
– setBackgroundResource(int idResursa)
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()
Proprietăți comune
• Parametri container
– setLayoutParams(LayoutParams)
– LayoutParams getLayoutParams()
• Vizibilitate:
– setVisibility(int) – VISIBLE, INVISIBLE, GONE
Proprietăți comune
• Poziție (pixeli):
– absolută
• setX()/getX()
• setY()/getY()
– relativă la părinte
• setLeft()/getLeft()
• setTop()/getTop()
• setRight()/getRight()
• setBottom()/getBottom()
Proprietăți comune
• Tratare evenimente:
– setOnClickListener()
– setOnLongClickListener()
– setOnDragListener()
– setOnKeyListener()
– setOnTouchListener()
INTERFAȚA ÎN MOD PROCEDURAL
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:");
//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);
CONTAINERE
LinearLayout
• Modul de aranjare a componentelor:
android:orientation
– horizontal
– vertical
LinearLayout
• Distribuirea spațiului rămas liber (proporții)
– android:layout_weight
– android:layout_gravity
android:layout_gravitiy="center_horizontal"
"top"
"left" "right"
"bottom"
android:orientation="horizontal" android:orientation="vertical"
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
RelativeLayout
android:layout_alignLeft="@id/id3"
android:layout_alignParentTop = true
android:layout_toRightOf="@id/id8"
android:layout_below="@id/id1"
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
ConstraintLayout
dependencies {
implementation 'com.android.support.constraint:constraint-layout:x.x.x'
}
Restricții
• Puncte de conectare între controale și
– alte controale
– containerul părinte
– puncte de referință
Restricții
• 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ță
Poziționarea relativă
• app:layout_constraint[PunctSursă]_[PunctDestinație]=
"[IdentificatorDestinație]"
• PunctSursă
– Start
– Top
– Bottom
– End
• PunctDestinție
– toStartOf
– toEndOf
– toBottomOf
– toTopOf
Î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
• Dimensionare
• Restricții laturi
• Restricții puncte de referință
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
TableLayout
TableRow
android:layout_span="2"
android:layout_column="0"
GridLayout
• Număr coloane
– android:columnCount
• Întinderea pe mai multe linii:
– android:layout_rowSpan
• Întinderea pe mai multe coloane:
– android:layout_columnSpan
GridLayout
android:layout_rowSpan="3"
android:layout_columnCount="3"
android:layout_row="3"
android:layout_columnSpan="2"
android:layout_column="0"
FrameLayout
• În mod uzual, este afișată o singură
componentă vizuală
• Poziționarea componentelor:
– Implicit: colțul stînga-sus
– Suprapunere pe niveluri pe axa z
• adîncime
• android:layout_gravity
– Suprapunerea componentelor vizuale
FrameLayout
android:layout_gravitiy="center"
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"
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
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);
Metoda pentru
Interfața tratarea Înregistrarea obiectului
evenimentului
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ă
Tratarea evenimentelor (1)
public class Activitate extends Activity implements
View.OnClickListener {
//tratare eveniment
public void onClick(View view) {
// Tratarea evenimentului
}
}
Tratarea evenimentelor (2)
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());
//…
}
}
Tratarea evenimentelor (3)
//Î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
}
});
Tratarea evenimentelor (4)
• 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()
Bibliografie
• S. Komatineni, D. MacLean – Pro Android 4,
Apress, 2012
• R. Meier – Professional Android 4 Application
Development, Wiley, 2012
• P. Pocatilu, Programarea dispozitivelor mobile,
Editura ASE, 2012
• P. Pocatilu, I. Ivan ș.a. – Programarea
aplicațiilor Android, Editura, ASE, 2015
• http://developer.android.com
Dispozitive și aplicații mobile
Cursul 3 - 4
Sumar
• Stiluri și teme
• Deserializarea componentelor
• Meniuri și bara aplicației
– Menu, ActionBar, Toolbar
• Fragmente
• Ferestre de informare
• Mesaje (2)
STILURI ȘI TEME
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
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>
Stiluri: Referire
<TextView
style="@style/stil_titlu"/>
<TextView
...
style="@android:style/TextAppearance.Large" />
Teme
• Atributul android:theme la nivelul
– Aplicației (toate activitățile)
– Unei activități
– Unui container/control
• AndroidManifest.xml
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
Teme
<activity
android:theme =
"@android:style/Theme.Holo.Dialog">
...
</activity>
DESERIALIZAREA COMPONENTELOR
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)
MENIURI
Meniuri
• Meniu principal activitate
• Meniuri contextuale
– Apăsarea prelungită pe ecran
• Meniuri de tip popup
Opțiuni meniu
• Definire în fișiere de resurse dedicate
– res/menu
• Definire în mod programatic
– Interfața MenuItem
Opțiuni de 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
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
Meniul principal
Versiune Android Aspect Meniu
meniu.add(Menu.NONE,
MI_INAINTE, 0, "Inainte");
return true;
}
MI_INAINTE
– identificator constant pentru opțiune (int)
Meniul principal
public boolean onOptionsItemSelected(MenuItem mi)
{
//tratarea evenimentelor generate de selecția din meniu
switch (mi.getItemId()) {
case R.id.INAINTE : {
//
break;
}
//...
}
}
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)
BARA APLICAȚIEI
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
Bara aplicației
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ă
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
Bara aplicației
• Acces la obiectul de tip ActionBar
– getActionBar()
• Stabilire bară aplicație
– setActionBar()
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
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>
Afișare opțiuni meniu
• res/menu
• showAsAction
– always
– ifRoom
– withText
– never
FRAGMENTE
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
Fragmente
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
Fragmente – ciclul de viață
Activitate Fragment
1. onCreate()
1. onAttach()
2. onAttachFragment()
2. onCreate()
3. onCreateView()
4. onActivityCreated()
3. onStart()
5. onStart()
4. onResume()
6. onResume()
Fragmente – ciclul de viață (cont.)
Activitate Fragment
1. onPause()
1. onPause()
2. onSaveInstanceState()
2. onSaveInstanceState()
3. onStop()
3. onStop()
4. onDestroyView()
5. onDestroy()
6. onDetach()
4. onDestroy()
Clasa Fragment
• Referire activitate container
– getActivity()
Fragmente - XML
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()
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);
}
}
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)
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
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
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()
Tranzacții cu fragmente – exemplu
FragmentManager fm = getFragmentManager();
// adaugare fragment A
FragmentTransaction ft = fManager.beginTransaction();
ft.add(R.id.fragId, fragmentA, "fragmentA");
ft.commit();
Tranzacții cu fragmente - exemplu
// î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();
Fragmente
• DialogFragment
• ListFragment
• PreferenceFragment
• WebViewFragment
Bibliografie
• R. Meier – Professional Android 4 Application
Development, Wiley, 2012
• S. Komatineni, D. MacLean – Pro Android 4, Apress,
2012
• P. Pocatilu, Programarea dispozitivelor mobile,
Editura ASE, 2012
• P. Pocatilu, I. Ivan ș.a. – Programarea aplicațiilor
Android, Editura, ASE, 2015
• http://developer.android.com
Dispozitive și aplicații mobile
Cursul 5
Sumar
• Componente vizuale complexe
– Liste
• Adaptoare
• Tratarea selecțiilor
COMPONENTE VIZUALE COMPLEXE
Componente vizuale complexe
• Controale complexe (ViewGroup)
– Elemente de tip View
• Implementează clasa abstractă AdapterView
• Inițializate prin intermediul unui adaptor
• Asocierea
– metoda setAdapter()
Componente vizuale complexe
• ListView, GridView
• Spinner
• RecyclerView
• AutoCompleteTextView
• MultiAutoCompleteTextView
• Gallery
• ListActivity
– getListView()
– setListAdapter()
• ListFragment
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
Adaptoare
• Clase derivată din BaseAdapter
– implementează interfața Adapter
• ArrayAdapter
• CursorAdapter
– SimpleCursorAdapter
• SimpleAdapter
Componente vizuale complexe
Componente vizuale complexe
Layout element
• utilizator
• Implicite (android.R.layout.)
• simple_spinner_dropdown_item
• simple_list_item_1
• etc.
Resurse predefinite
Resursă predefinită Descriere
(android.R.layout… )
simple_spinner_item Text pe o singură linie
simple_spinner_dropdown_item Text pe o lini e care i nclude 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 lini e care i nclude suport
pentru selecț ia exclusivă
simple_list_item_multiple_choice Text pe o lini e care i nclude suport
pentru selecț ia multiplă
simple_expandable_list_item_1 Text pe o singură linie
simple_expandable_list_item_2 Text pe dou
ă linii
ArrayAdapter
• Sursa 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
Exemplu (1)
String [] tari = new String[] {"Romania", "Bulgaria", "Grecia"};
//inițializare listă
ListView lv = (ListView)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);
Exemplu (1-1)
String [] tari = new String[] {"Romania", "Bulgaria", "Grecia"};
//initializarea adaptor
ArrayAdapter<String> adaptor = new ArrayAdapter<>(
this,
R.layout.element_lista,
R.id.textViewTara
tari);
//asociere adaptor
lv.setAdapter(adaptor);
Exemplu (2)
class Tara {
String nume ;
int populatie;
Bitmap steag;
//metode de acces publice (ex. getNume()/setNume())
public String toString() {
return "Denumire: " + nume + ", populatie: " + populatie;
}
}
Exemplu (2)
ArrayList<Tara> listaTari = new ArrayList<>();
//inițializare listă
ListView lv = (ListView)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);
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
Exemplu (3)
ArrayList<Map<String, String>> tari = new ArrayList<>();
Container
Romania
TextView
19.544.000 locuitori
TextView
ImageView
res/layout/element_lista.xml
Exemplu (4) - Adaptorul
public class AdaptorTari extends BaseAdapter {
@Override
public Object getItem(int position) {
return tari.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
Exemplu (4.1) - cont.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
converView = layoutInflater.inflate(R.layout.element_lista,
parent, false);
}
//initializare obiecte controale
ImageView steag = (ImageView)
convertView.findViewById(R.id.imageViewSteag);
TextView nume = (TextView)
convertView.findViewById(R.id.textViewNume);
TextView populatie = (TextView)
convertView.findViewById(R.id.textViewPopulatie);
Tara tara = tari.get(position);
//initializare controale cu valori
steag.setImageBitmap(tara.getSteag());
nume.setText(tara.getNume());
populatie.setText(tara.getPopulatie() + "
locuitori");
return convertView;
}
Exemplu (4.2) - cont.
public class AdaptorTari extends BaseAdapter {
private static class ViewHolder {
public ImageView steag;
public TextView nume, populatie;
}
//…
}
Exemplu (4.2) - cont
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
convertView.setTag(holder);
}
//else în continuare
Exemplu (4.2) - cont
else {
holder = (ViewHolder)convertView.getTag();
/*reutilizare resurse*/
}
setListAdapter(adaptorTari);
NOTIFICAREA MODIFICĂRILOR
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)
ASOCIERE TEXT LISTĂ VIDĂ
Fișier de tip machetă
/res/layout/layout.xml
<ListView />
<TextView android:id="@+id/empty"
…
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);
SELECȚIA ELEMENTELOR
Spinner
• getSelectedItem()
• getSelectedItemId()
Spinner
• Interfața
– AdapterView.OnItemSelectedListener
• Metodele implementate
– onItemSelected()
– onNothingSelected()
• Asociere
– setOnItemSelectedListener()
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) {
}
});
ListView
• getItemAtPosition()
• getItemIdAtPosition()
ListView
• Interfața
– AdapterView.OnItemClickListener
• Metoda implementată
– onItemClick()
• Asociere
– setOnItemClickListener()
Selecția elementelor (liste)
lista.setOnItemClickListener(new
OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,
View item, int poz, long id){
//referim elementul selectat prin poz;
//parent.getItemAtPosition(poz);
}
});
Bibliografie
• R. Meier – Professional Android 4 Application
Development, Wiley, 2012
• S. Komatineni, D. MacLean – Pro Android 4, Apress,
2012
• P. Pocatilu, Programarea dispozitivelor mobile,
Editura ASE, 2012
• P. Pocatilu, I. Ivan ș.a. – Programarea aplicațiilor
Android, Editura, ASE, 2015
• http://developer.android.com
Programarea Dispozitivelor Mobile
Cursul 6 - 7
Sumar
• Ferestre de informare
• Mesaje (Intent)
• Operații asincrone
• Accesul la rețea
– Socket
– HTTP
– Servicii Web
• Prelucrarea fișierelor XML și JSON
FERESTRE DE INFORMARE
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
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()
AlertDialog.Builder
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)
new AlertDialog.Builder(this)
.setTitle("Info")
.setMessage("Exemplu AlertDialog")
.show();
Ferestre de informare cu liste
• setItems()
– Lista elemente
– Obiect tratare eveniment selecție
• setSingleChoiceItems()
– + element selectat sau -1
• setMultipleChoicheItems()
– + lista elemente selectate sau null
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()
Exemplu
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()
Clasa Toast
• Metode:
– setText()
– setDuration
– setGravity()
• poziționare pe ecran
• Poate fi personalizată
– setView()
Clasa Toast
Toast.makeText(this,
"Fisierul a fost salvat",
Toast.LENGTH_SHORT).show();
MESAJE (INTENT)
Obiecte de tip Intent
• Mesaje asincrone
• Utilizare
– Invocare activități
– Invocare servicii
– Transmitere mesaje globale
– Partajare date
Caracteristicile mesajelor de tip Intent
• Acțiuni
• Date
– Tip de date
• Categorie
• Date adiționale
• Componenta destinație
Tipuri de mesaje
• Explicite
– Sînt invocate anumite componente
– Necesară cunoașterea numelui componentei
• Implicite
– Sînt invocate acele componentele care corespund unor criterii
(acțiune, tip date etc.)
– Componentele nu sînt cunoscute la apel
Acțiuni
• Definite sub forma unor operații (String)
• Operații
– Predefinite (sistem)
– Definite de programator
• Generice sau specializate
– VIEW vs. CALL
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
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()
Acțiuni predefinite
Acţ iunea (Intent.__) Date asociate Semnificaţ ie
ACTION_VIEW Ur i reprezentâ nd con ţ inutul Lansează o apli caţ ie pe baza
care va fiî ncă rcat î napli caţ i a asoci erii acest ei a cu un anu mi t
asociată . tip de conţ inut.
ACTION_CALL Ur i reprezentâ nd un num ă rDeschide fereastra de apelare a
de telefon (schema tel://).
apelul.
ACTION_DIAL Deschide fereastra de iniţ iere a
apelurilor telefonice.
ACTION_PICK Ur i reprezentâ nd con ţ inutul
care va fiî ncă rcat î napli caţ i a dintr-o listă .
as oci ată î n veder ea
selectă rii.
ACTION_EDIT Ur i asoci at con
ț inut ul ui care
va fi editat datelor.
ACTION_WEB_SEARCH Ur i reprezentâ nd secvenţ aDeschide o fereastră de că utare.
de că utat sau un URL care va
fi deschisî n navigatorul Web.
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
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)
Modificarea proprietăților
• setAction(String)
• addCategory(String)
• setData(Uri)
• setType(String)
– Tip MIME
• setDataAndType()
• setComponent(Context)
• setClass(Class)
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.
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
• Sînt invocate direct
• Utilizatorul selectează componenta dintr-o listă de componente
– Dacă nu există
• Excepție
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
Lansarea unei activități din proiect
• Intent explicit
• Parametri constructor Intent:
– Contextul curent
– Clasa activității destinație
• Metode (clasa Context):
– startActivity(Intent)
Lansarea unei activități
startActivity(intent)
+ date (opțional)
Activitate 1 Activitate 2
}
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ă
Mesaje implicite: Exemplul 1
//Deschiderea navigatorului Web pe baza unui URL:
startActivityForResult(cod, intent)
Activitate Activitate
1 2
intent = getIntent()
onActivtiyResult(cod, codRez, intent) setResult(RESULT_OK, intent);
finish()
Lansarea unei activități pentru răspuns:
Exemplul 1
//Selectarea unui imagini din galerie
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();
}
Prelucrare conținut
• Fluxuri de date
• Octeți
– InputStream
• ByteArrayInputStream
• Caractere
– InputStreamReader
– BufferedReader
• StringBuilder
• StringBuffer
– sincronizat
Descărcarea fișierelor
• Serviciul de sistem DownloadManager
– getSystemService(DOWNLOAD_SERVICE)
• Inițiere
– enqueue()
• Verificare stare transfer
• REVENIRE
– Servicii, Recepționarea mesajelor (BroadcastReceiver), Cursor
SERVICII WEB
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 sînt legate de nici un sistem de operare sau limbaj de
programare
• Caracteristici: interoperabilitatea și extensibilitatea
Servicii Web
• SOAP
– Mesaje XML
– WSDL
• REST, RESTful (Representational State Transfer)
– XML, JSON, HTML
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()
Servicii Web REST
• Acțiunile sunt implementate uzual prin protocolul HTTP
• Comenzi (GET, POST, DELETE etc.) asociate acțiunilor
• Rezultatul returnat
– JSON
– XML
OPERAȚII ASINCRONE
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
Operații asincrone
Alt fir de execuție Firul principal de execuție
Prelucrare de durată +
Control
rezultat
Control.proprietate = rezultat
NU
Prelucrare de durată +
rezultat
Control.proprietate = rezultat
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
CLASA HANDLER
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
Clasa Handler
• Prelucrarea mesajelor
– metoda cu apel invers handleMessage()
• Trasmiterea mesajelor
– metode de forma sendYYY()
Clasa Handler
• Obiecte de tip Runnable
– Transmise către coada de obemesaje asociată firului de execuție
• Trasmiterea obiectelor Runnable
– Metode de forma postYYY()
Clasa Handler
Handler
Coada Looper
Fir secundar de
mesaje
Firul principal UI
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
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);
Exemplu (cont.): Receptionare 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);
}
};
Exemplu: Transmitere obiect Runnable
Handler handler = new Handler();
//...
handler.post(new Runnable() {
@Override
public void run() {
// prelucrări actualizare
}
});
Exemplu: Splash Screen
public class SplashScreen extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setari fereastra (full screen)
setContentView(R.layout.splash_screen);
...
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
Exemplu: Splash Screen
//ascundere titlu
requestWindowFeature(Window.FEATURE_NO_TITLE);
//afisare pe tot ecranul
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
);
Operații asincrone
Firul principal de execuție
run() Runnable
Control.proprietate = rezultat
Transmise ca parametri
metodelor specifice
METODE SPECIFICE
Metode specifice
• Clasa Activity
– runOnUiThread(Runnable)
• View
– post(Runnable)
– postDelayed(Runnable, long)
Exemplu: runOnUiThread()
this.runOnUiThread(new Runnable() {
@Override
public void run() {
editText.setText(text);
}
});
CLASA ASYNCTASK
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)
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
Apelurile Clasa AsyncTask
Firul principal Firul secundar
• 1. onPreExecute()
• 2. doInBackground()
• 4. onProgressUpdate() • 3. publishProgress()
• 5. onPostExecute()
Exemplu AsyncTask
//Parametrul transmis este un URL //Apelul din firul principal
//Rezultatul este un şir de caractere (String) URL url = new URL("http://pdm.ase.ro");
//progresul nu este monitorizat (Void)
class PrelAsinc extends AsyncTask<URL, Void, String> { PrelAsinc pa = new PrelAsinc ();
@Override pa.execute(url);
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);
}
}
FIȘIERE XML ȘI JSON
Fișiere XML
• Noduri/elemente
• Un nod rădăcină
• Atribute
Fișiere XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<element_radacina>
<element atribut="val_atribut">
val_element sau alte elemente
</element>
…
</element_radacina>
Fișiere XML
<?xml version="1.0" encoding="ISO-8859-1"?> <carte cota="19223">
<biblioteca> <autor>
<carte cota="19222"> <nume>S. Hashimi</nume>
<autor> <nume> S. Komatineni</nume>
<nume>R. Meier</nume> <nume> D. MacLean </nume>
</autor> </autor>
<titlu> Professional Android Application <titlu>Pro Android 3</titlu>
Development </titlu> <editura>Apress</editura>
<editura>wiley</editura> <an>2011</an>
<an>2009</an> <isbn>0-321-15040-6</isbn>
<isbn>1-72-11-2222</isbn> <pagini>336</pagini>
<pagini>500</pagini> </carte>
</carte> </biblioteca>
Fișiere JSON
• JavaScript Object Notation
• { } – obiect
• [ ] – vector de valori
• "proprietate" : "valoare"
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"
}
]
}
}
PRELUCRAREA FIȘIERELOR XML ȘI JSON
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
xmlReader.setContentHandler(handler);
xmlReader.parse(new InputSource(streamIn));
Exemplu SAX
XML Pull
• Interfața XmlPullParser
• Inițializare
– Resources#getXml()
• res/xml
– Xml.newPullParser()
– XmlPullParserFactory#newPullParser()
• XmlPullParserFactory
– XmlPullParserFactory.newInstance()
• Asociere flux de intrare (InputStream)
– setInput()
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
Exemplu XmlPullParser
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;}
Exemplu XmlPullParser
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;
}
DOM
• Interfețe
– Node
– Element (impl. Node)
– NodeList
• item(poz)
• Clasa DocumentBuilder
– metoda parse()
• InputStream
• Clasa Document (impl. Node)
DOM
– Document
• getElementsByTagName()
– NodeList
– Element
• getAttribute()
– Node
• getTextContent()
Exemplu DOM
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);
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();
}
}
}
Prelucrare fișiere JSON
• org.json
• JSONObject
– getTIP(): getString(), getBoolean(), getInt() etc.
– getJSONArray()
– getJSONObject()
• JSONArray
– length()
– getTIP(index)
Prelucrare fișiere JSON
JSONObject jObject = new JSONObject(stringJson);
JSONObject joBibl = jObject.getJSONObject("biblioteca");
JSONArray jaCarti = joBibl.getJSONArray("carte");
SQLITE
Baze de date
• SQLite
• Baze de date relaționale
• Pachetul android.database.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
SQLiteDatabase
• Asociată bazei de date
• Crearea unei baze de date
– Clasa SQLiteDatabase
• metoda statică openDatabase()
• metoda statică openOrCreateDatabase()
– Clasa Context
• openOrCreateDatabase()
– Clasa SQLiteOpenHelper
• getReadableDatabase()
• getWritableDatabase()
• Închiderea conexiunii
– close()
Crearea bazelor de date (Exemple)
SQLiteDatabase bd =
SQLiteDatabase.openDatabase(
"pim.db", null);
//sau
SQLiteDatabase bd =
openOrCreateDatabase("pim.db",
Context.MODE_PRIVATE, null);
//…
bd.close();
SQLiteDatabase
• Comenzi SQL:
– execSQL() – nu returneaza valori
– rawQuery() – returneaza valori (Cursor)
• Metode specializate
– query()
– insert()
– update()
– delete()
Selecția
• Metoda query() (Parametri comuni)
– Numele tabelei
– Coloanele selectate
• String[]
– Criteriul de selecție (WHERE)
• String
– Valorile asociate parametrilor din criteriul de
selecție
• String[]
Selecția
– Grupare (GROUP BY)
• String
– Condiție de grup (HAVING)
• String []
– Ordinea de sortare (ORDER BY)
• String
• Returnează
– Cursor
Selecția (Exemplu)
Cursor cursor = bd.query(
"studenti",
null,//toate coloanele
null,//fara selectie
null,
null,//fara grupare
null,
null//fara ordine de sortare
);
Selecția (Exemplu)
Cursor cursor = bd.query(
"studenti",
new String[] {"matricola", "nume", "tip" }
"tip=?",
new String[] {"buget"},
null,//fara grupare
null,
"matricola ASC"
);
Inserarea
• Clasa ContentValues
– put("cheie", valoare);
• Metoda SQLiteDatabase#insert()
– Numele tabelei
– null, dacă obiectul ContentValues are valori/un
nume de coloană, în caz contrar
– Obiectul de tip ContentValues
Inserarea (Exemplu)
ContentValues valori = new ContentValues();
valori.put("matricola", 1200);
valori.put("nume", "student");
long rez;
rez = bd.update("studenti" , valori, null, null);
rez = bd.update("studenti" , valori, "matricola=?",
new String[] {String.valueOf(1200)});
Ștergerea
• Metoda delete()
– Numele tabelei
– Parametrii pentru clauza WHERE
– Argumentele pentru clauza WHERE
• Exemple
long rez;
rez = bd.delete("studenti" , null, null);
rez = bd.delete("studenti", "matricola=?",
new String[] {String.valueOf(1200)});
Tranzacții
• Inițierea tranzacției
– beginTransaction()
• Aplicarea modificărilor
– setTransactionSuccessful()
• Finalizarea tranzacției
– endTransaction()
Tranzacții (Exemplu)
SQliteDatabase bd = …;
bd.beginTransaction();
try {
opereazaAsupraBazeiDeDate();
bd.setTransactionSuccessful();
}catch (SQLException e) {
//Tratare exceptie
}finally {
bd.endTransaction();
}
SQLiteOpenHelper
• Suport pentru crearea/actualizarea schemei bazei de date
• Se creează o clasă derivată
• Implementate metode cu apel invers
• Crearea bazei de date
– onCreate()
• Actualizarea bazei de date
– onUpgrade()
• Obținerea unei baze de date SQLiteDatabase se realizează
cu metodele
– getReadableDatabase()
– getWritableDatabase()
Exemplu: SQLiteOpenHelper
public class DBHelper extends
SQLiteOpenHelper {
int versiune = 1;
SQLiteDatabase bd =
dbHelper.getWritableDatabase();
…
dbHelper.close();
Cursor
• android.database
• Interfață
• permite gestiunea înregistrărilor rezultate în
urma interogării unei baze de date
• SQLiteCursor
– Implementare pentru baze de date SQLite
Cursor
• Parcurgere
– moveToNext()
– moveToPrevious()
– moveToFirst()
– moveToLast()
• Extragerea de valori
– getTIP(): getInt(), getString(), getFloat() etc.
– parametru: indexul coloanei
Cursor: Determinarea poziției
• isFirst()
• isLast()
• isBeforeFirst()
• isBeforeLast()
Cursor: Obținerea de informații
• Numărul de înregistrări
– getCount()
• Numele coloanei
– getColumnName()
• Poziția coloanei
– getColumnIndex()
Adaptoare de tip Cursor
• CursorAdapter
• Coloana _id
• SimpleCursorAdapter
Exmeplu: 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
);
STOCAREA ÎN CONTAINERUL
APLICAȚIEI
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
Stocarea în containerul aplicației
• getResources() -> Resources
• Fișiere din res/raw
– openRawResource() -> InputStream
• Fișiere din res/xml
– getXml() -> XmlPullParser
Stocarea în containerul aplicației
• AssetManager
– getAssets() (clasa Context)
• open(nume_fisier) -> InputStream
• list(cale)
– String[]
• Lista fișiere
FIȘIERE DE PROPRIETĂȚI
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>
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
– getDefaultSharedPreferences(context)
– Un singur fișier de proprietăți/aplicație/activitate
• Mod
– Activity.MODE_PRIVATE
Preluarea datelor
• Metode de forma getTIP()
– getBoolean(),
– getInt() etc.
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
Fișiere de proprietăți
SharedPreferences setari = getSharedPreferences("setari",
Activity.MODE_PRIVATE);
editorProp.putBoolean("titlu", false);
editorProp.putBoolean("ajutor", true);
editorProp.putInt("max", 5);
editorProp.commit();
Fișiere de proprietăți
SharedPreferences setari = getSharedPreferences("setari",
Activity.MODE_PRIVATE);
<EditTextPreference
android:key="utilizator"
android:summary="Introduceti numele de utilizator"
android:title="Utilizator" />
Exemplu: activitate pentru salvarea
preferințelor (cont.)
<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="Ramin conectat" />
</PreferenceCategory>
Exemplu: activitate pentru salvarea
preferințelor (cont.)
<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" />
Exemplu: activitate pentru salvarea
preferințelor (cont.)
<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>
Exemplu: activitate pentru salvarea
preferințelor (cont.)
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);
FIȘIERE
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
Clasa Environment
• Mediul extern amovibil:
– isExternalStorageRemovable()
• Stare mediu extern stocare
– getExternalStorageState()
• MEDIA_MOUNTED
• MEDIA_MOUNTED_READ_ONLY
• MEDIA_UNMOUNTED
• MEDIA_REMOVED
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()
Directoare speciale
• Director public mediu extern stocare
– getExternalStoragePublicDirectory(tip)
• tip (membri statici)
– DIRECTORY_PICTURES
– DIRECTORY_MUSIC
– DIRECTORY_DOWNLOADS
– DIRECTORY_DCIM
– DIRECTORY_RINGTONES
– DIRECTORY_ALARMS
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()
Clasa File
if (dir != null) {
// creare fisier
File fis = new File(dir, NUME_FISER2);
FileWriter os = new FileWriter(fis);
os.write("PDM 2014");
os.close();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
SERIALIZAREA ȘI DESERIALIZAREA
OBIECTELOR
Modalități de serializare
Serializable Parcelable
• Java • Android
• Stocare • Transport
• Versionare – Comunicație între procese
• Simplitate vs. viteză redusă • Parcel
de prelucrare • Eficiență vs. complexitate
– reflection
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)
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.
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
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()
Bibliografie
• S. Komatineni, D. MacLean – Pro Android 4, Apress,
2012
• R. Meier – Professional Android 4 Application
Development, Wiley, 2012
• P. Pocatilu, Programarea dispozitivelor mobile,
Editura ASE, 2012
• P. Pocatilu, I. Ivan ș.a. – Programarea aplicațiilor
Android, Editura, ASE, 2015
• http://developer.android.com
Programarea Dispozitivelor Mobile
Cursul 10
Sumar
• Baze de date la distanță
• Firebase
• Baze de date Firebase
BAZE DE DATE LA DISTANȚĂ
Baze de date la distanță
• Partajarea datelor
• Sincronizarea datelor
• Datele sînt stocate pe un server
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
– Restdb.io
– kumulos
FIREBASE
Firebase
• Platformă proiectată să asigure integrarea soluțiilor bazate pe
cloud în aplicații
• Aplicații mobile
– Android
– iOS
• Aplicații Web
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
– Stocarea și sincronizarea datelor
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 notificații
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
FIREBASE REALTIME DATABASE
Firebase Realtime Database
• Baze de date în timp real
• NoSQL
• Date stocate în format JSON
• Autentificare
• Multiplatformă
• Găzduire în cloud
• Sincronizare
Tipuri de date suportate
• String
• Boolean
• Long
• Double
• Map<String, Object>
• List<Object>
Structura datelor
• Format JSON
• Fără vectori
• Maxim 32 nivelul de imbricare
• Aspecte de luat în considerare la proiectare
– Evitarea imbricării datelor pe foarte multe niveluri
– Date nenormalizate
Clase și interfețe
• FirebaseDatabase
• DatabaseReference
• DataSnapshot
• ValueEventListener
• ChildEventListener
Accesul la baza de date
• Referirea bazei de date
– FirebaseDatabase database = FirebaseDatabase.getInstance();
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
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();
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()
Preluarea datelor
• ValueEventListener
– onDataChange(DataSnapshot)
– onCancelled(DatabaseError)
• Asociere (prin DatabaseReference)
– addValueEventListener()
– addListenerForSingleValueEvent()
• Eliminare asociere
– removeEventListener()
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)
Ștergerea datelor
• removeValue()
• setValue(null)
• updateChildren(map)
– valorile din map sînt nule
Interogarea datelor
• Clasa Query
• Sortare
– Cheie
– Valoare
– Valoare copil
• Indexare pentru îmbunătățirea performanțelor
• Operațiile returnează tot obiecte de tip Query
• Preluarea datelor se realizează prin intermediul aceluiași
mecanism
Interogarea datelor
• Sortare
– orderByChild()
– orderByKey()
– orderByValue()
• Filtrare
– equalTo()
– startAt()
– endAt()
– limitToFirst()
– limitToLast()
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)
AUTENTIFICARE/ÎNREGISTRARE
Autentificare/Înregistrare
• Furnizori multipli
• Definire din consola Firebase
• Clase specializate
Furnizori
• Email + parolă
• Google
• Facebook
• Twitter
• GitHub
Clase și interfețe
• FirebaseAuth
– AuthStateListener
• FirebaseUser
Înregistrare/autentificare
FirebaseAuth auth = FirebaseAuth.getInstance();
FirebaseUser user = auth.getCurrentUser();
if (user != null) {
//continuare in aplicatie
} else {
//autentificare utilizator
}
CLASE SUPORT
FirebaseUI
• https://github.com/firebase/FirebaseUI-Android
• FirebaseUI for Android — Auth
– AuthUI
• FirebaseUI for Realtime Database
– FirebaseListAdapter
– FirebaseRecyclerAdapter
Bibliografie
• Neil Smyth, Firebase Essentials Android Edition, Payload Media, 2017
• https://firebase.google.com/docs/reference/
• http://developer.android.com
Dispozitive și Aplicații Mobile
Cursul 11
Sumar
• Grafică bidimensională
– Imagini
– Culori, instrumente, suprafața de scris
– Figuri geometrice
• Preluarea imaginilor folosind camera foto
• Preluarea imaginilor din colecția de fotografii
Resurse de tip multimedia
• Fișiere
– Imagini
– Clipuri audio
– Clipuri video
• În memorie
– Grafică bi și tridimensională
– Secvențe audio
– Animații (bi și tridimensionale)
GRAFICĂ BIDIMENSIONALĂ
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
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
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.
Imagini
int w, h;
Bitmap bmp1 = Bitmap.createBitmap(w, h,
Bitmap.Config.ARGB_8888);
Bitmap bmp2 =
BitmapFactory.decodeResource(
getResources(), R.drawable.dice);
Componente de bază
• Culori și texturi
• Instrumentul de desenat
• Suprafața de desenat
– Contururi geometrice
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
Culori
• int culoare = getResources().getColor(R.id.fundal);
• int verde = Color.GREEN;
• int verdeSemiTransp = Color.argb(127, 0, 255, 0);
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).
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.
Gradienți
Bitmap bmpShader;
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);
Suprafața de desenare
• Clasa Canvas
• Include metode pentru desenare
• Metode de tipul draw…()
• Instrumentul de scris
• Poziția
Desenarea în controale
• Clasa derivată din View
• Metoda cu apel invers onDraw()
– de evitat alocarea obiectelor grafice aici
• Metodele
– invalidate()
– postInvalidate()
Canvas
public class DesenView extends View {
…
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//desenarea propriu-zisă
}
}
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);
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)
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)
Afișarea imaginilor
• void drawBitmap(Bitmap bmp, float left, float
top, Paint paint)
• void drawPicture(Picture picture, RectF dst)
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)
Afișarea textului
• void drawText(String text, float x, float y,
Paint paint)
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()
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);
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)
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()
Transformări
• Scalare
– Metoda scale(sx, sy)
• Translatare (mutare)
– Metoda translate(dx, dy)
• Rotiri
– Metoda rotate(grade)
• Înclinare
– Metoda skew(x, y)
FIGURI GEOMETRICE
Figuri geometrice (Java)
• ShapeDrawable
• Construire obiecte de tip Shape
– RectShape
– OvalShape
– ArcShape
– PathShape
• Metode
– getPaint()
– draw(Canvas)
– setBounds(x1, y1, x2, y2)
Exemplu: Figuri geometrice (Java)
ShapeDrawable drawable;
Canvas canvas;
int x, y, width, height;
//…
Intent capteazaImagine = new
Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(capteazaImagine,
CAPTEAZA_IMAGINE);
Camera: aplicații instalate
private Bitmap fotografie = null;
...
@Override
protected void onActivityResult(int codCerere,
int codRezultat, Intent data) {
//creare intent
Intent intent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
//invocare activitate selectie imagine
startActivityForResult(intent, SELECTEAZA_IMAGINE);
Preluarea imaginilor din colecția de
fotografii
protected void onActivityResult(int codCerere, int codRezultat, Intent intent) {
} catch (Exception e) {
e.printStackTrace();
}
}
}
Bibliografie
• S. Komatineni, D. MacLean – Pro Android 4, Apress,
2012
• R. Meier – Professional Android 4 Application
Development, Wiley, 2012
• P. Pocatilu, Programarea dispozitivelor mobile,
Editura ASE, 2012
• P. Pocatilu, I. Ivan ș.a. – Programarea aplicațiilor
Android, Editura, ASE, 2015
• http://developer.android.com
Dispozitive și aplicații mobile
Cursul 12
Sumar
• Utilizarea serviciilor Android
• Determinarea poziției geografice
• Google Maps în aplicații
SERVICII
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
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.
Servicii de sistem
• Servicii predefinite
– Notificare
– Conectivitate
– Descărcare fișiere
– Alarme
– Localizare etc.
• Gestionate prin clase specializate
• Acces prin intermediul clasei Context
Servicii predefinite
• getSystemService(String serviciu) – clasa Context
– serviciu:
• șir de caractere cu numele acestuia, definit în clasa Context
– returnează un obiect de tipul serviciului:
• LocationManager
• AudioManager
• DownloadManager
• WiFiManager etc.
prin intermediul căruia acesta este utilizat.
Servicii predefinite
//definire receptor
BroadcastReceiver descarcat = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) { //fișierul a fost
descărcat
}
//eliminare asociere receptor
unregisterReceiver(descarcat);
Servicii utilizator
• Derivare din clasa Service
• Derivare din clasa IntentService
• Declarare în fișierul manifest XML
<application ... >
<service android:name=".Serviciu" />
...
</application>
DETERMINAREA POZIȚIEI GEOGRAFICE
Poziționarea geografică
• Se utilizează serviciul de localizare 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
• Permisiuni
– android.permission.ACCESS_FINE_LOCATION
– android.permission.ACCESS_COARSE_LOCATION
Poziționare geografică
• Inițializare serviciu de localizare
• Asocierea unui obiect de tip listener cu precizarea:
– Sursei utilizată la localizare
– Intervalul de timp la care se face actualizarea datelor
• Notificări în momentul apariției de modificări legate de:
– Poziția geografică
– Starea sursei de localizare
• Întreruperea asocierii cu obiectul de tip listener
• Frecvența de actualizare!
Asociere furnizori serviciu de localizare
• Metoda requestLocationUpdates() din clasa LocationManager
• Informări cu privire la modificările poziției geografice: obiecte de tip
LocationListener sau PendingIntent
• 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)
• unui criteriu de selecție (clasa Criteria)
– Obiectul care implementează interfața LocationListener sau obiectul de tip
PendingIntent
• Metoda requestSingleUpdate()
Eliminarea asocierii
• Metoda removeUpdates() din clasa LocationManager
• Parametrul
– Obiectul de tip LocationListener
– Obiectul de tip PendingIntent
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)
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()
Clasa Location
• Coordonate
– getLatitude(), getLongitude(), getAltitude()
• Viteza
– getSpeed()
• Timp
– getTime()
• Acuratețea localizării
– getAccuracy()
• Alte informații
Poziționare geografică - Exemplu
class LocListener implements LocationListener {
@Override
public void onLocationChanged(Location poz) {
/*poz.getLatitude(), poz.getLongitude(), poz.getAltitude(); */
}
//…
}
Poziționare geografică - Exemplu
LocListener locListener = new LocListener();
Cursul 13-14
Sumar
• Furnizori de conținut
• Receptori de mesaje
• Publicarea aplicațiilor în magazinul virtual
Play Store
• Discuții
FURNIZORI DE CONȚINUT
Partajarea datelor
• 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
Furnizori de conținut
• Acces deseori ierarhic
• Bază de date
• Mai multe tabele
– Coloane
– Rînduri
• Referire prin URI
– tip MIME asociat conținutului
Furnizori de conținut
• Pachetul android.provider
• Predefiniți
• Definiți de utilizator
– Implementarea clasei abstracte ContentProvider
• ContentResolver
– Context#getContentResolver()
Furnizori de conținut predefiniți
• CallLog • MediaStore
– Calls – Audio
• ContactsContract – Images
– Contacts – Video
• CalendarContract • Settings
– Calendars – System
– Events – Global
– Reminders
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"
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 [])
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
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
}
}
Furnizori de conținut predefiniți –
Exemplu
ContentResolver cr = getContentResolver();
a) activitățile
b) serviciile
c) receptorii de mesaje
d) mesajele (clasa Intent)
e) furnizorii de conținut
În cadrul oricărei metode dintr-o clasă
derivată din clasa Activity, this poate fi
utilizat pentru tipul:
a) Context
b) Application
c) Intent
d) View
e) ViewGroup
În mod uzual, pictogramele asociate
unei aplicații se stochează în
directorul:
a) res/bitmaps
b) res/drawable
c) res/icons
d) res/raw
e) res/anim
Un container de tip LinearLayout
permite adăugarea componentelor:
a) doar pe verticală
b) pe verticală sau pe orizontală
c) doar pe orizontală
d) pe verticală și pe orizontală simultan
e) doar într-o singură poziție
Pentru selecția unor înregistrări dintr-o
tabelă SQLite se poate utiliza una din
metodele din clasa SQLiteDatabase:
a) rawQuery() sau query()
b) execSql() sau query()
c) rawQuery() sau select()
d) execSql() sau select()
e) rawSelect() sau select()
Bibliografie
• S. Komatineni, D. MacLean – Pro Android 4, Apress,
2012
• R. Meier – Professional Android 4 Application
Development, Wiley, 2012
• P. Pocatilu, Programarea dispozitivelor mobile,
Editura ASE, 2012
• P. Pocatilu, I. Ivan ș.a. – Programarea aplicațiilor
Android, Editura, ASE, 2015
• http://developer.android.com
07-Jan-20
Baze de date
• SQLite
• Baze de date relaționale
• Room
1
07-Jan-20
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
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"
2
07-Jan-20
Obiecte utilizate
• Entități
• Operații asupra datelor
• Baza de date
• Adnotări Java
Entități
• Clase Java asociate tabelelor
• Datele membre sînt asociate cîmpurilor tabelei
• Datele membre
• Publice
• Funcții accesor (set/get)
• Pot fi ignorate anumite cîmpuri
• Nu sînt incluse obiecte
• Posibilități de conversie
3
07-Jan-20
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
07-Jan-20
5
07-Jan-20
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)
6
07-Jan-20
Cursor
• android.database
• Interfață
• permite gestiunea înregistrărilor rezultate în urma interogării unei
baze de date
• SQLiteCursor
• Implementare pentru baze de date SQLite
7
07-Jan-20
Cursor
• Parcurgere
• moveToNext()
• moveToPrevious()
• moveToFirst()
• moveToLast()
• Extragerea de valori
• getTIP(): getInt(), getString(), getFloat() etc.
• parametru: indexul coloanei
8
07-Jan-20
9
07-Jan-20
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
);
10