Professional Documents
Culture Documents
Vjezba6TL Odt
Vjezba6TL Odt
Poput svake aplikacije kod koje je potrebno da se podaci koji su prikupljeni tokom njenog
rada ostanu dostupni i prilikom sljedećeg pokretanja te aplikacije i Android aplikacije imaju
mehanizam za perzistenciju podataka.
Na ovoj vježbi radit će se SQLite baza podataka koja omogućava da se na struktuiran
način sačuvaju podaci, na isti način kako ste radili i sa bilo kojom drugom SQL bazom.
SQLite baza podataka je relaciona baza podataka čiji fajlovi su privatni i dostupni samo za
onu aplikaciju koja ih je kreirala.
Nakon što se kreira baza moguće je kreirati ContentProvidera kako bi se aplikacijska
logika i struktura podataka odvojila. Ovo je dobra praksa jer tada aplikacija ne mora brinuti
o tome kakav je izvor podataka već koristi standardizovani interfejs koji ContentProvideri
pružaju. A putem njih je moguće učiniti podatke iz naše aplikacije dostupne drugim
aplikacijama.
Postoje ContentProvideri za različite izvore podataka poput: kalendara, imenika, media
store-a i sl. Moguće je takođe implementirati i vlastiti ContentProvider kako bi uključili i
druge podatke u vašu aplikaciju. O ContentProviderima više na sljedećim vježbama.
ContentValues i Cursors
Za ubacivanje novog reda u tabelu koriste se objekti tipa ContentValues. Oni sadrže sve
vrijednosti koje se trebaju ubaciti u odgovarajući red u obliku ključa vrijednosti. Sa
ContentValues možemo lakše pripremiti podatke za upite tipa insert i update.
Svi upiti prema bazi rezultuju u odgovoru koji se smješta u objekat tipa Cursor. Cursor je
privremeni buffer koji čuva rezultate nakon upita. Oni omogućavaju više načina za
pomjeranje kroz rezultujući skup. To je realizovano putem sljedećih metoda Cursor klase:
moveToFirst – pomjeranje na prvi red rezultujućeg skupa,
moveToNext – pomjeranje za jednu poziciju unaprijed (tj. sljedeći red),
moveToPrevious – pomjeranje za jednu poziciju unazad (tj. prethodni red),
moveToPosition – pomjeranje na specificiranu poziciju ...
Postoje i metode unutar Cursor klase za dobijanje određenih informacija o rezultujućem
skupu:
getCount – broj redova u rezultujućem skupu,
getColumnIndexOrThrow – vraća indeks kolone počevši od nule ukoliko postoji
kolona sa specificiranim imenom, inače baca izuzetak,
getColumnName – daje naziv kolone sa zadanim indeksom,
getColumnNames – daje nazive svih kolona u vidu niza stringova,
getPosition – daje trenutnu poziciju kursora.
Svaki upit nad bazom se vraća kao objekat tipa Cursor. Na ovaj način Android upravlja sa
resursima tako što dobavlja i oslobađa redove i kolone po potrebi.
Jedan upit nad bazom obično sadrži:
● naziv tabele nad kojom vršimo upit,lista kolona koje se trebaju dobaviti sa upitom,
● WHERE dio upita gdje se dodatno definiše koji se redovi traže, u WHERE dijelu
upita mogu stajati i argumenti iz promjenjljivih
● GROUP BY – grupisanje redova
● HAVING – koji redovi se trebaju grupisati
● poredak sortiranja
● limit – najveći broj redova koji će se vratiti
Primjer jednog upita:
// Izvršimo upit
Cursor cursor = db.query(MuzicarDBOpenHelper.MUZICAR_TABLE,
kolone_rezultat, where,
whereArgs, groupBy, having, order);
Ukoliko bi iz prethodnog kursora željeli proći kroz imena muzičara tada trebamo dohvatiti
odgovarajuću kolonu (MUZICAR_IME) i proći kroz sve redove.
while(cursor.moveToNext()){
Log.d(“Ime: ”,cursor.getString(I NDEX_KOLONE_IME)”;
}
Kod brisanja redova trebate specificirati where dio i pozvati metodu delete.
Sada imamo sve potrebno za pravljenje upita nad bazom osim helper objekta
muzicarDBOpenHelper. Ovaj helper se implementira na način da se nasljedi klasa
SQLiteDBOpenHelper. U klasi se trebaju implementirati dvije metode:
1. Metoda za kreiranje baze ako ne postoji na disku - onCreate()
2. Metoda za ažuriranje baze na disku ako se ne poklapa sa trenutnom -
onUpgrade()
Pored ove dvije metode obično se definišu i stringovne kontrante za nazive kolona, tabela,
baze i konstanta za verziju baze.
public class MuzicarDBOpenHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = “mojaBaza.db”;
public static final String DATABASE_TABLE = “Muzicari”;
public static final int DATABASE_VERSION = 1;
public static final String MUZICAR_ID ="_id";
public static final String MUZICAR_IME ="ime";
public static final String MUZICAR_ZANR ="zanr";
//... ostale potrebne kolone
Šta se dešava u ovoj klasi? Ako ne postoji baza helper će pozvati onCreate metodu i
kreirati novu, ako je baza promjenjena tada se poziva onUpgrade. U svakom slučaju
rezultat ovog helpera je keširana baza koju možete koristiti za vaše upite.
U ranijem kodu kada smo spominjali kako se prave upiti nad bazom vidjeli smo da se
poziva metoda getWritableDatabase(), ova metoda može da se ne izvrši uspješno pa je
dobra praksa pozvati getReadableDatabase() ukoliko se to desi. U tom slučaju imate
bazu koja je dostupna samo za čitanje.
Kako SQLiteOpenHelper kešira bazu možete prije svakog upita zatražiti instancu baze sa
navedenim metodama.
NAPOMENA: Insancu baze zatvorite u slučaju kada ste sigurni da neće više biti
upita nad njom (pri gašenju aktivnosti ili servisa)!
ResourceCursorAdapter
Često nam treba da rezultate upita prikažemo u nekom ListView elementu. Da bi rezultate
iz cursor-a na najjednostavniji način prikazali u listi koristit ćemo ResourceCursorAdapter.
Ova klasa služi poput ArrayAdaptera iz prve vježbe stim da sada kao izvor podataka
imamo Cursor.
Da bi implementirali ResourceCursorAdapter trebamo mu definisati layout, za ovo
možemo iskoristiti isti layout liste iz prve vježbe.
Dalje je potrebno implementirati klasu adaptera i tu navesti konstruktor i implementaciju
metode bindView. Ova metoda se poziva i koristi se kako bi povezali pojedine vrijednosti iz
Cursora u polja layouta liste.
Primjer:
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView ime = (TextView) view.findViewById(R.id.ime);
ime.setText(cursor.getString(cursor.getColumnIndex(MUZICAR_IME)));
Zadaci za vježbu:
Zadatak 1:
Napravite da se pri paljenju vaše aplikacije pokrene upit koji će upisati nekoliko muzičara u
bazu. U listu muzičara upišite muzičare iz baze pri čemu trebate koristiti
ResourceCursorAdapter. Pri gašenju aplikacije pokrenite upit koji će obrisati sve unose iz
baze.
Zadatak 2:
Pri pokretanju aplikacije potrebno je da se prikaže 5 muzičara koje je korisnik ranije
pretraživao.
Zadatak 3:
Muzičar se dodaje u bazu u slučaju kada korisnik klikne na njega (tj. kada se otvori
fragment detalji) (on ulazi u onih 5 muzičara iz prethodnog zadatka). Tada je potrebno
zapisati sve podatke o njemu u bazu uključujući i top 5 pjesama i albuma.
Zadatak 4:
U slučaju da korisnik unese u polje za pretragu naziv nekog muzičara i klikne na dugme, a
internet nije dostupan, korisniku se treba ispisati poruka da pretraživanje nije moguće i dati
unos trebate smjestiti u tabelu prethodne pretrage. Ova tabela treba da sadrži listu
pretraga na način da se čuvaju podaci o stringu pretrage, vremenu i tipu pretrage. Tip
pretrage može biti (uspješna ili neuspješna). Korisniku u fragmentu liste muzičara trebate
ponuditi opciju da vidi prethodne pretrage (dodatno dugme npr.) i u slučaju da korisnik
odabere opciju pregleda prethodnih pretraga lista muzičara se treba zamjeniti sa listom
pretraga (možete iskoristiti fragmente za ovo). Lista prethodnih pretraga treba da se
prikazuje na način da se prikaže string pretrage i vrijeme, a u zavisnosti od tipa potrebno
je obojiti element u zelenu ili crvenu boju. Ukoliko korisnik klikne na neku od pretraga tada
se treba pozvati web servis na isti način kako bi se pozvao da korisnik unese istu pretragu
u edit text i pritisne dugme pretraži. Tada se umjesto liste prethodnih pretraga prikazuju
rezultati za navedenu pretragu kako ste radili i na prethodnoj vježbi.