mtiplab06 - 2017 - 2018 - pdf - r2.pdf · dr predrag pecev – mobilne tehnologije i programiranje...

29
dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 - Podložno izmeni - Nerecenzirani materijal 1 MOBILNE TEHNOLOGIJE I PROGRAMIRANJE MTIPLAB06 Vežba 6 – GSON, AsyncTask Callbacks, Progress Dialogs, povezivanje sa REST servisom UVOD U okviru ove vežbe biće dorađena MTIP Studenti Android aplikacija koja je formirana u prethodnoj vežbi (MTIPLab05). Dorada spomenute aplikacije se odnosi na dodavanje GSON biblioteke (Google open source biblioteka za serijalizaciju i deserijalizaciju Java objekata i/u JSON format, komunikaciju sa REST servisom putem AsyncTask Callback-ova uz čekanje na izvršavanje spomenute komunikacije u kombinaciji sa Progress Dialogom. Takđe biće formirani adapteri za odgovarajuće kontrolere kako bi se podaci koji se preuzmu od REST servisa mogli prikazati unutar spomenute aplikacije. GSON GSON je open source biblioteka za serijalizaciju i deserijalizaciju Java objekata i/u JSON format i izvorni kod iste se može preuzeti sa https://github.com/google/gson Za potrebe ovog projekta, pristupiće se kompajliranoj verziji iste u formi *.jar arhive putem Maven Central-a. Aktuelna verzija spomenute biblioteke u trenutku formiranja ove vežbe je 2.8.2 i repozitorijum spomenute verzije se nalazi na linku http://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.2/ Slika broj 1. MTIP Studenti u Project perspektivi i libs folder

Upload: others

Post on 27-Oct-2019

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

1

MOBILNE TEHNOLOGIJE I PROGRAMIRANJE –

MTIPLAB06

Vežba 6 – GSON, AsyncTask Callbacks, Progress Dialogs, povezivanje sa

REST servisom

UVOD

U okviru ove vežbe biće dorađena MTIP Studenti Android aplikacija koja je formirana u

prethodnoj vežbi (MTIPLab05). Dorada spomenute aplikacije se odnosi na dodavanje GSON

biblioteke (Google open source biblioteka za serijalizaciju i deserijalizaciju Java objekata i/u JSON

format, komunikaciju sa REST servisom putem AsyncTask Callback-ova uz čekanje na izvršavanje

spomenute komunikacije u kombinaciji sa Progress Dialogom. Takđe biće formirani adapteri za

odgovarajuće kontrolere kako bi se podaci koji se preuzmu od REST servisa mogli prikazati

unutar spomenute aplikacije.

GSON

GSON je open source biblioteka za serijalizaciju i deserijalizaciju Java objekata i/u JSON format i

izvorni kod iste se može preuzeti sa https://github.com/google/gson Za potrebe ovog projekta,

pristupiće se kompajliranoj verziji iste u formi *.jar arhive putem Maven Central-a. Aktuelna

verzija spomenute biblioteke u trenutku formiranja ove vežbe je 2.8.2 i repozitorijum spomenute

verzije se nalazi na linku http://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.2/

Slika broj 1. MTIP Studenti u Project perspektivi i libs folder

Page 2: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

2

Slika broj 2. Kopiranje gson-2.8.2.jar arhive u libs folder

Slika broj 3. Add to Library Slika broj 4. Create Library

Potrebno je preuzeti fajl gson-2.8.2.jar, promeniti perspektivu MTIP Studenti rešenja na Project

i otvoriti libs folder kao što je to prikazano na slici broj 1. Zatim je potrebno prekopirati fajl gson-

2.8.2.jar u libs folder kao što je to prikazano na slici broj 2, i dodati spomenutu arhivu u formi

biblioteke modulu App. Desnim klikom na arhivu gson-2.8.2.jar prikazuje se meni koji je

prikazan na slici broj 3, dok se izborom stavke Add to Library prikazuje dijalog Create Library

koji je prikazan na slici broj 4.

Page 3: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

3

PRISTUP INTERNETU I POMOĆNE KLASE ZA RAD SA HTTP

ZAHTEVIMA

Android je specifična platforma i zasniva se na sistemu dozvola za upotrebu određenih sistema.

Konkretno, ukoliko neka aplikacija treba da koristi usluge skladištenja prostora na SD kartici,

navedena aplikacija treba i da je zatraži unutar manifesta iste. Pošto MTIP Studenti Android

aplikacija koristi usluge REST servisa koji se nalazi na nekom računaru (idealno na internetu

povezano sa nekim domenom radi lakšeg poziva) unutar AndroidManifest.xml fajla potrebno je

dodati sledeću liniju koda kako bi spomenuta aplikacija imala pristup internetu putem

odgovarajućih protokola (HTTP).

<uses-permission android:name="android.permission.INTERNET" />

Listing broj 1. Pristup internetu (linuju koda smestiti unutar AndroidManifest.xml fajla)

U listingu koda broj 2 je klasa MTIPShared koju treba oformiti unutar paketa rs.tfzr.data.

Spomenuta klasa sadrži jednu statičku promenljivu tipa String koja ukazuje na osnovnu putanju

do REST servisa koja MTIP Studenti android aplikacija koristi. Pošto Android kao operativni

sistem poseduje loopback adresu localhost i 127.0.0.1, URL adrese koje koriste navedene pozive

se ne mogu koristiti čak iako se aplikacija izvršava unutar emulatora i REST servis se nalazi na

istom računaru. Dakle ako se navede adresa koja u sebi sadrži spomenuti poziv, Android

operativni sistem će tražiti REST servis na uređaju na kojem se Android aplikacija i izvršava, tako

da je u URL adresi do servisa potrebno koristiti IP adresu računara ili domensku adresu. U ovom

slučaju koristi se IP adresa lokalnog računara na kojem je podignut REST servis a i sam emulator

Android aplikacije. Spomenutu adresu je potrebno promeniti da vodi do računara na kojem se

nalazi REST servis.

package rs.tfzr.rs.tfzr.data;

public class MTIPShared {

private static String _serviceBaseURL =

"http://192.168.1.150/mtip/services/";

public static String get_serviceBaseURL() {

return _serviceBaseURL;

}

public static void set_serviceBaseURL(String _serviceBaseURL) {

MTIPShared._serviceBaseURL = _serviceBaseURL;

}

}

Listing broj 2. Sadržaj klase MTIPShared

Naredni korak odnosi se na formiranje paketa rs.tfzr.utility i klasa HTTPPostCaller i

JSONReader. Klasa JSONReader poseduje statičke metode koje čitaju JSON string koji REST

servis pošalje dok klasa HTTPPostCaller poseduje statičke metode koje putem POST metode

šalju HTTP zahtev sa podacima ka bilo kojem HTTP serveru. U ovom slučaju spomenuta klasa

biće korišćena da se pošalju podatci REST servisu putem POST metode. U listingu koda broj 3 je

prikazan sadržaj klase JSONReader, dok se u listingu koda broj 4 nalazi sadržaj klase

HTTPPostCaller.

Page 4: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

4

package rs.tfzr.utility;

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.HttpURLConnection;

import java.net.URL;

public class JSONReader {

public static String getJSONfromURL(String urlInput){

InputStream inputStream = null;

String result = "";

try {

URL url = new URL(urlInput);

HttpURLConnection urlConnection = (HttpURLConnection)

url.openConnection();

urlConnection.connect();

InputStream stream = urlConnection.getInputStream();

if (stream!=null) result = convertInputStreamToString(stream);

} catch (Exception e) {

result = e.toString();

}

return result;

}

private static String convertInputStreamToString(InputStream inputStream)

{

BufferedReader bufferedReader = new BufferedReader( new

InputStreamReader(inputStream));

String line = "";

String result = "";

try

{

while((line = bufferedReader.readLine()) != null)

result += line;

inputStream.close();

}

catch (Exception ex) {}

return result;

}

}

Listing broj 3. Sadržaj klase JSONReader

package rs.tfzr.utility;

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.io.UnsupportedEncodingException;

import java.net.HttpURLConnection;

import java.net.URL;

import java.net.URLEncoder;

import java.util.HashMap;

import java.util.Map;

import javax.net.ssl.HttpsURLConnection;

Page 5: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

5

public class HTTPPostCaller {

public static String performPostCall(String requestURL,

HashMap<String, String> postDataParams) {

URL url;

String response = "";

try

{

url = new URL(requestURL);

HttpURLConnection connection = (HttpURLConnection)

url.openConnection();

connection.setRequestMethod("POST");

connection.setDoInput(true);

connection.setDoOutput(true);

OutputStream outputStream = connection.getOutputStream();

BufferedWriter bufferedWriter = new BufferedWriter(new

OutputStreamWriter(outputStream, "UTF-8"));

bufferedWriter.write(getPostDataString(postDataParams));

bufferedWriter.flush();

bufferedWriter.close();

outputStream.close();

int responseCode=connection.getResponseCode();

if (responseCode == HttpsURLConnection.HTTP_OK)

{

String line;

BufferedReader br=new BufferedReader(new

InputStreamReader(connection.getInputStream()));

while ((line=br.readLine()) != null) {

response+=line;

}

}

else response="";

} catch (Exception e) {

e.printStackTrace();

}

return response;

}

public static String getPostDataString(HashMap<String, String> params) throws

UnsupportedEncodingException {

StringBuilder result = new StringBuilder();

boolean first = true;

for(Map.Entry<String, String> entry : params.entrySet())

{

if (first)

first = false;

else

result.append("&");

result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));

result.append("=");

result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));

}

return result.toString();

}

}

Listing broj 4. Sadržaj klase HTTPPostCaller

Page 6: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

6

DODAVANJE FUNKCIONALNOSTI FRAGMENTIMA I KLASE

MTIPSTUDENT I MTIPSTUDIJSKIPROGRAM

U listingu koda broj 5 prikazan je sadržaj klase MTIPStudijskiProgram, dok je u listingu koda

broj 6 prikazan sadržaj klase MTIPStudent. Objekat klase MTIPStudent sadrži objekat klase

MTIPStudijskiProgram pošto svaki student pripada nekom studijskom programu tj. smeru.

Spomenute klase sadrže anotacije serijalizacije polja koje vode poreklo iz prethodno dodate

GSON biblioteke. Vrednosti navedenih anotacija su nazivi polja iz JSON stringa koje treba dodeliti

odgovarajućim atributima klase. Spomenute anotacije se trebaju navoditi samo ako se naziv

atributa unutar klase razlikuje od naziva polja unutar JSON fajla. Ako se spomenuti nazvi slažu,

anotacije nema potrebe stavljati. Iako se u ovom slučaju nazivi atributa klasa i polja unutar JSON

fajla slažu, anotacije su postavljene primera radi. Takođe ukoliko se promeni naziv polja unutar

JSON fajla (stringa) promenom vrednosti unutar anotacije lako se ponovo uspostavlja veza.

Navedene anotacije se koriste sa deserijalizaciju JSON fajlova u Java objekte, i serijalizaciju Java

objekata u JSON fajlove (format). Navedene klase se nalaze unutar paketa rs.tfzr.classes.

package rs.tfzr.classes;

import com.google.gson.annotations.SerializedName;

public class MTIPStudijskiProgram {

@SerializedName("_idSmer")

protected int _idSmer;

@SerializedName("_nazivSmera")

protected String _nazivSmera;

@SerializedName("_sifra")

protected String _sifra;

public int get_idSmer() {

return _idSmer;

}

public void set_idSmer(int _idSmer) {

this._idSmer = _idSmer;

}

public String get_nazivSmera() {

return _nazivSmera;

}

public void set_nazivSmera(String _nazivSmera) {

this._nazivSmera = _nazivSmera;

}

public String get_sifra() {

return _sifra;

}

public void set_sifra(String _sifra) {

this._sifra = _sifra;

}

public MTIPStudijskiProgram()

{

this._idSmer = 0;

this._nazivSmera = "";

this._sifra = "";

Page 7: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

7

}

@Override

public String toString() {

return this._nazivSmera;

}

}

Listing broj 5. Sadržaj klase MTIPStudijskiProgram

Klasa MTIPStudijskiProgram poseduje konstruktor i preklopljenu metodu toString koja se

koristi prilikom popunjavanja combobox-a (Spinner-a) koji se nalazi na formama (fragmentima)

za dodavanje i izmenu studenta.

package rs.tfzr.classes;

import com.google.gson.annotations.SerializedName;

public class MTIPStudent {

@SerializedName("_idStudent")

private int _idStudent;

@SerializedName("_ime")

private String _ime;

@SerializedName("_prezime")

private String _prezime;

@SerializedName("_index")

private String _index;

@SerializedName("_smer")

private MTIPStudijskiProgram _smer;

public int get_idStudent() {

return _idStudent;

}

public void set_idStudent(int _idStudent) {

this._idStudent = _idStudent;

}

public String get_ime() {

return _ime;

}

public void set_ime(String _ime) {

this._ime = _ime;

}

public String get_prezime() {

return _prezime;

}

public void set_prezime(String _prezime) {

this._prezime = _prezime;

}

public String get_index() {

return _index;

}

public void set_index(String _index) {

this._index = _index;

}

public MTIPStudijskiProgram get_smer() {

return _smer;

}

Page 8: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

8

public void set_smer(MTIPStudijskiProgram _smer) {

this._smer = _smer;

}

public MTIPStudent()

{

this._idStudent = 0;

this._ime = "";

this._prezime = "";

this._index = "";

this._smer = new MTIPStudijskiProgram();

}

}

Listing broj 6. Sadržaj klase MTIPStudent

Funkcionalnost fragmentata (stranica) iz prethodne vežbe (MTIPLab05) će biti proširena i fokus

će biti na klasama PretragaFragment, StudentiFragment, StudentiDodavanjeFragment i

StudentiIzmenaFragment.

U listingu koda broj 7 prikazan je sadržaj klase PretragaFragment. Unutar spomenutog

fragmenta uspotavljena je veza sa EditText kontrolom i definisana je lista studenata koja će se

popuniti nakon poziva odgovarajuće metode REST servisa koji je formiran u vežbama MTIPLab01

i MTIPLab02. Takođe definisana je metoda PronadjiStudente koja prima jedan parametar tipa

String koji se odnosi na celo ili deo prezimena studenta kojeg treba pronaći. Ukoliko je vrednost

navedenog parametra prazan string metoda će prikazati sve studente koje se nalaze u bazi

podataka, u suprotnom, prikazuje studente čije prezime se parcijalno ili u potpunosti slaže sa

unetom vrednošću. Spomenuta metoda putem Handlera postuje odgovarajući zadatak (Task)

koji treba da se izvrši u pozadini (Runnable). U arhitekturi Android aplikacije (u višim verzijama)

nije dozvoljeno da se komunikacija sa HTTP servisima i ostala procesiranja izvršavaju u okviru

niti (thread-a) koja opslužuje korisnički interfejs. Unutar MTIP Studenti android aplikacije

spomenuta komunikacija se izvršava kao pozadinski proses i pri tome se upotrebom

ProgressDialog-a korisniku oduzima kontrola nad aplikacijom uz obaveštavanje korisnika o

izvršavanju pozadinskog procesa. Kad se pozadinski proces izvrši, spomenuti dijalog se uklanja, i

korisniku se dalje predaje kontrola nad aplikacijom. Pozadinski proces koji će prikupiti podatke

o studentima tako što će pozvati spomenuti REST servsis, preuzeti odgovor od istog, i poslati ga

GSON builderu koji će od navedenog napraviti objekte tipa MTIPStudenti oformljen je u formi

klase HTTPPretragaStudenataJSON koja nasleđuje klasu AsyncTask<String, Void, String> i

implementira metode doInBackground i onPostExecute. Unutar metode doInBackground se

poziva REST servis na osnovu parametara koje se prosleđuju objektu spomenute klase.

Spomenutom objektu se putem execute metode prosleđuje niz parametara. U ovom slučaju, to su

dva parametra: naziv metode REST servisa koji se poziva, i vrednost parametra koji se prosleđuje

spomenutom servisu. Pošto se radi o pretrazi studenata, vrednost prvog parametra je

“studentipregraga/?search=” i prezimeStudenta koje se preuzima iz EditText kontrole koja je

namenjena za pretragu. Unutar metode onPostExecute (koja se izvršava nakon metode

doInBackground) uklanjaju se svi rezultati pretrage iz LinearLayout-a _linearLayoutResults i

popunjavaju se rezultatima pretrage koji se nalaze unutar liste _studenti tako što se formira View

(pogled) na osnovu rasporeda komponenti layout_studenti_universal.xml, pristupa se layoutu

koji sadrži tastere za izmenu i brisanje radi uklanjanja istih (linearLayoutTasteri), formiraju se

veze ka labelama koje trebaju da prikažu odgovarajuće podatke o studentu, i unutar for petlje,

ciklično, pogled se formira, popuni podacima, i dodaje rasporedu linearLayoutResults koji ih

Page 9: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

9

prikazuje redosledno, jedan ispod drugog. Na slici broj 5 prikazan je aktivan ProgressDialog

pretrage studenata, dok je na slici broj 6 prikazan je izgled fragmenta Pretraga sa rezultatima

pretrage.

package rs.tfzr.mtipstudenti;

import android.app.ProgressDialog;

import android.content.Context;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.app.Fragment;

import android.os.Handler;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.EditText;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.TextView;

import com.google.gson.Gson;

import com.google.gson.GsonBuilder;

import java.util.ArrayList;

import java.util.Arrays;

import rs.tfzr.classes.MTIPStudent;

import rs.tfzr.rs.tfzr.data.MTIPShared;

import rs.tfzr.utility.JSONReader;

public class PretragaFragment extends Fragment {

// TODO: Rename parameter arguments, choose names that match

// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER

private static final String ARG_PARAM1 = "param1";

private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters

private String mParam1;

private String mParam2;

private OnFragmentInteractionListener mListener;

protected TextView _textViewDodajNovogStudenta;

protected ImageView _imageViewPretraga;

protected Context _context;

protected ProgressDialog _progressDialog = null;

protected Runnable _studentiTask;

protected Handler _studentiHandler;

protected EditText _textPretraga;

protected LinearLayout _topLevelContainer;

protected LinearLayout _linearLayoutResults;

protected ArrayList<MTIPStudent> _studenti;

public PretragaFragment() {

// Required empty public constructor

}

// TODO: Rename and change types and number of parameters

public static PretragaFragment newInstance(String param1, String param2) {

PretragaFragment fragment = new PretragaFragment();

Bundle args = new Bundle();

args.putString(ARG_PARAM1, param1);

args.putString(ARG_PARAM2, param2);

Page 10: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

10

fragment.setArguments(args);

return fragment;

}

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

if (getArguments() != null) {

mParam1 = getArguments().getString(ARG_PARAM1);

mParam2 = getArguments().getString(ARG_PARAM2);

}

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

View rootView = inflater.inflate(R.layout.fragment_pretraga, container,

false);

this._studenti = new ArrayList<MTIPStudent>();

this._context = rootView.getContext();

this._topLevelContainer =

(LinearLayout)rootView.findViewById(R.id.mainContainerPrezime);

this._textViewDodajNovogStudenta =

(TextView)rootView.findViewById(R.id.textViewDodajNovogStudenta);

this._topLevelContainer.removeView(this._textViewDodajNovogStudenta);

this._textPretraga =

(EditText)rootView.findViewById(R.id.editTextPrezimePretraga);

this._imageViewPretraga =

(ImageView)rootView.findViewById(R.id.imageViewPretraga);

this._imageViewPretraga.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

String prezimePretraga = _textPretraga.getText().toString();

PronadjiStudente(prezimePretraga);

}

});

this._linearLayoutResults =

(LinearLayout)rootView.findViewById(R.id.layoutRezultatiPretrage);

return rootView;

}

// TODO: Rename method, update argument and hook method into UI event

public void onButtonPressed(Uri uri) {

if (mListener != null) {

mListener.onFragmentInteraction(uri);

}

}

@Override

public void onAttach(Context context) {

super.onAttach(context);

if (context instanceof OnFragmentInteractionListener) {

mListener = (OnFragmentInteractionListener) context;

} else {

throw new RuntimeException(context.toString()

+ " must implement OnFragmentInteractionListener");

}

}

Page 11: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

11

@Override

public void onDetach() {

super.onDetach();

mListener = null;

}

public interface OnFragmentInteractionListener {

// TODO: Update argument type and name

void onFragmentInteraction(Uri uri);

}

protected void PronadjiStudente(final String prezimeStudenta)

{

this._studentiHandler = new Handler();

this._studentiTask = new Runnable() {

@Override

public void run() {

HTTPPretragaStudenataJSON pretragaREQ = new

HTTPPretragaStudenataJSON();

String[] params = new String[2];

params[0] = "studentipretraga/?search=";

params[1] = prezimeStudenta;

pretragaREQ.execute(params);

}

};

this._studentiHandler.post(this._studentiTask);

this._progressDialog = ProgressDialog.show(this._context,

"Molimo Vas sačekajte ...", "Preuzimam podatke ...", true);

}

protected class HTTPPretragaStudenataJSON extends AsyncTask<String, Void,

String> {

@Override

protected String doInBackground(String... strings) {

String serviceURL =

MTIPShared.get_serviceBaseURL()+strings[0]+strings[1];

GsonBuilder gsonBuilder = new GsonBuilder();

Gson gson = gsonBuilder.create();

_studenti.clear();

_studenti.addAll(Arrays.asList(gson.fromJson(

JSONReader.getJSONfromURL(serviceURL),

MTIPStudent[].class)));

return null;

}

@Override

protected void onPostExecute(String result) {

_progressDialog.dismiss();

_linearLayoutResults.removeAllViews();

LayoutInflater inflater = (LayoutInflater)

_context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

for (MTIPStudent stud : _studenti)

{

View view = inflater.inflate(R.layout.layout_studenti_uiversal,

null);

Page 12: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

12

LinearLayout layoutUniversal =

(LinearLayout)view.findViewById(R.id.linearLayoutStudentiUniversalContainer);

LinearLayout layoutTasteri =

(LinearLayout)view.findViewById(R.id.linearLayoutTasteri);

layoutUniversal.removeView(layoutTasteri);

TextView textViewPrezime =

(TextView)view.findViewById(R.id.textViewPrezimeDATA);

TextView textViewIme =

(TextView)view.findViewById(R.id.textViewImeDATA);

TextView textViewBrojIndeksa =

(TextView)view.findViewById(R.id.textViewBrojIndeksaDATA);

TextView textViewStudijskiProgram =

(TextView)view.findViewById(R.id.textViewStudijskiProgramDATA);

textViewPrezime.setText(stud.get_prezime());

textViewIme.setText(stud.get_ime());

textViewBrojIndeksa.setText(stud.get_index());

textViewStudijskiProgram.setText(stud.get_smer().get_nazivSmera());

_linearLayoutResults.addView(view);

}

}

}

}

Listing broj 7. Sadržaj klase PretragaFragment

Slika broj 5. Aktivna pretraga Slika broj 6. Rezultati pretrage

Page 13: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

13

U listingu koda broj 8 prikazan je sadržaj klase StudentiFragment dok je na slici broj 7 prikazan

izgled navedenog fragmenta. Sadržaj spomenute klase gotovo je identičan sadržaju klase

PretragaFragmet i sa aspekta funkcionalnosti predstavlja proširenje spomenutog fragmenta.

Ključna razlika je u tome što se prilikom formiranja rezultata pretrage ne uklanja pogled (view)

koji sadrži tastere za izmenu (btnIzmeniStudenta) i brisanje (btnObrisiStudenda) studenta pa

se njima dodaju odgovarajući onClickListener-i kako bi se realizovala predviđena

funkcionalnost spomenutih tastera. Klikom na taster Izmena poziva se fragment

StudentiIzmenaFragment i istom se prosleđuje identifikator studenta koji treba da se izmeni.

Identifikator se čita na osnovu pozicije rezultata u listi rezultata (_linearLayoutResults) koji

odgovara poziciji objekta koji predstavlja odabranog studenta u listi studenata (_studenti).

Klikom na taster btnObrisiStudenta prikazuje se dijalog koji je prikazan na slici broj 8. Navedeni

dijalog pita korisnika da li želi da obriše odabranog studenta ili ne. Ukoliko je odgovor potvrdan

analogno klasi HTTPPretragaStudenataJSON formira se instanca klase

HTTPObrisiStudentaPost i putem execute metode prosleđuje se URL servisa koji treba da

realizuje brisanje studenta čiji se identifikator prosleđuje u listi parametara. Navedeno se

realizuje u doInBackground metodu spomenutog objekta. U onPostExecute metodi

spomenutog objekta se, ukoliko se spomenuti student uspešno obriše u bazi podataka, obrisani

student izbacuje iz liste objekata unutar Android aplikacije i osvežavaju se rezultati pretrage

uklanjanjem odgovarajućeg pogleda (view-a). Takođe deo koda koji se nalazio u klasi

HTTPPretragaStudenataJSON u onPostExecute metodi premešten je u metodu

PopulateResults.

package rs.tfzr.mtipstudenti;

import android.app.AlertDialog;

import android.app.ProgressDialog;

import android.content.Context;

import android.content.DialogInterface;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.app.Fragment;

import android.os.Handler;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.TextView;

import com.google.gson.Gson;

import com.google.gson.GsonBuilder;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.HashMap;

import rs.tfzr.classes.MTIPStudent;

import rs.tfzr.rs.tfzr.data.MTIPShared;

import rs.tfzr.utility.HTTPPostCaller;

import rs.tfzr.utility.JSONReader;

public class StudentiFragment extends Fragment {

// TODO: Rename parameter arguments, choose names that match

// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER

private static final String ARG_PARAM1 = "param1";

private static final String ARG_PARAM2 = "param2";

Page 14: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

14

// TODO: Rename and change types of parameters

private String mParam1;

private String mParam2;

private OnFragmentInteractionListener mListener;

protected TextView _textViewDodajNovogStudenta;

protected ImageView _imageViewPretraga;

protected Context _context;

protected ProgressDialog _progressDialog = null;

protected Runnable _studentiTask;

protected Handler _studentiHandler;

protected EditText _textPretraga;

protected LinearLayout _topLevelContainer;

protected LinearLayout _linearLayoutResults;

protected ArrayList<MTIPStudent> _studenti;

public StudentiFragment() {

// Required empty public constructor

}

// TODO: Rename and change types and number of parameters

public static StudentiFragment newInstance(String param1, String param2) {

StudentiFragment fragment = new StudentiFragment();

Bundle args = new Bundle();

args.putString(ARG_PARAM1, param1);

args.putString(ARG_PARAM2, param2);

fragment.setArguments(args);

return fragment;

}

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

if (getArguments() != null) {

mParam1 = getArguments().getString(ARG_PARAM1);

mParam2 = getArguments().getString(ARG_PARAM2);

}

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

View rootView = inflater.inflate(R.layout.fragment_pretraga, container,

false);

this._studenti = new ArrayList<MTIPStudent>();

this._context = rootView.getContext();

this._topLevelContainer =

(LinearLayout)rootView.findViewById(R.id.mainContainerPrezime);

this._textPretraga =

(EditText)rootView.findViewById(R.id.editTextPrezimePretraga);

this._textViewDodajNovogStudenta =

(TextView)rootView.findViewById(R.id.textViewDodajNovogStudenta);

this._textViewDodajNovogStudenta.setOnClickListener(new

View.OnClickListener() {

@Override

public void onClick(View view) {

MTIPStudentiMain.displayView(new

StudentiDodavanjeFragment(),MTIPStudentiMain._activity);

Page 15: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

15

}

});

this._imageViewPretraga =

(ImageView)rootView.findViewById(R.id.imageViewPretraga);

this._imageViewPretraga.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

String prezimePretraga = _textPretraga.getText().toString();

PronadjiStudente(prezimePretraga);

}

});

this._linearLayoutResults =

(LinearLayout)rootView.findViewById(R.id.layoutRezultatiPretrage);

return rootView;

}

// TODO: Rename method, update argument and hook method into UI event

public void onButtonPressed(Uri uri) {

if (mListener != null) {

mListener.onFragmentInteraction(uri);

}

}

@Override

public void onAttach(Context context) {

super.onAttach(context);

if (context instanceof OnFragmentInteractionListener) {

mListener = (OnFragmentInteractionListener) context;

} else {

throw new RuntimeException(context.toString()

+ " must implement OnFragmentInteractionListener");

}

}

@Override

public void onDetach() {

super.onDetach();

mListener = null;

}

public interface OnFragmentInteractionListener {

// TODO: Update argument type and name

void onFragmentInteraction(Uri uri);

}

protected void PronadjiStudente(final String prezimeStudenta)

{

this._studentiHandler = new Handler();

this._studentiTask = new Runnable() {

@Override

public void run() {

HTTPPretragaStudenataJSON pretragaREQ = new

HTTPPretragaStudenataJSON();

String[] params = new String[2];

params[0] = "studentipretraga/?search=";

params[1] = prezimeStudenta;

pretragaREQ.execute(params);

}

};

Page 16: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

16

this._studentiHandler.post(this._studentiTask);

this._progressDialog = ProgressDialog.show(this._context,

"Molimo Vas sačekajte ...", "Preuzimam podatke ...", true);

}

protected void ObrisiStudenta(final int idStudenta)

{

this._studentiHandler = new Handler();

this._studentiTask = new Runnable() {

@Override

public void run() {

HTTPObrisiStudentaPOST pretragaREQ = new

HTTPObrisiStudentaPOST();

String[] params = new String[2];

params[0] = "obrisistudenta";

params[1] = String.valueOf(idStudenta);

pretragaREQ.execute(params);

}

};

this._studentiHandler.post(this._studentiTask);

this._progressDialog = ProgressDialog.show(this._context,

"Molimo Vas sačekajte ...", "Izvršavam zahtev ...", true);

}

protected void PopulateResults()

{

_linearLayoutResults.removeAllViews();

LayoutInflater inflater = (LayoutInflater)

_context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

for (MTIPStudent stud : _studenti)

{

View view = inflater.inflate(R.layout.layout_studenti_uiversal,

null);

TextView textViewPrezime =

(TextView)view.findViewById(R.id.textViewPrezimeDATA);

TextView textViewIme =

(TextView)view.findViewById(R.id.textViewImeDATA);

TextView textViewBrojIndeksa =

(TextView)view.findViewById(R.id.textViewBrojIndeksaDATA);

TextView textViewStudijskiProgram =

(TextView)view.findViewById(R.id.textViewStudijskiProgramDATA);

final Button btnIzmeniStudenta =

(Button)view.findViewById(R.id.buttonIzmeniStudenta);

btnIzmeniStudenta.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

View removeView = (View)

btnIzmeniStudenta.getParent().getParent();

int itemIndex =

_linearLayoutResults.indexOfChild(removeView);

int idStudenta = _studenti.get(itemIndex).get_idStudent();

MTIPStudentiMain.displayView(StudentiIzmenaFragment.newInstance(idStudenta),MTIPS

tudentiMain._activity);

}

});

final Button btnObrisiStudenta =

(Button)view.findViewById(R.id.buttonObrisiStudenta);

btnObrisiStudenta.setOnClickListener(new View.OnClickListener() {

@Override

Page 17: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

17

public void onClick(View view) {

new AlertDialog.Builder(_context)

.setTitle("MTIP Studenti")

.setMessage("Da li želite da obrišete studenta?")

.setPositiveButton("Da", new

DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int

which) {

// continue with delete

View removeView = (View)

btnObrisiStudenta.getParent().getParent();

int itemIndex =

_linearLayoutResults.indexOfChild(removeView);

MTIPStudent studentToDelete =

_studenti.get(itemIndex);

ObrisiStudenta(studentToDelete.get_idStudent());

}

})

.setNegativeButton("Ne", new

DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface

dialogInterface, int i) {

}

})

.setIcon(android.R.drawable.ic_dialog_alert)

.show();

}

});

textViewPrezime.setText(stud.get_prezime());

textViewIme.setText(stud.get_ime());

textViewBrojIndeksa.setText(stud.get_index());

textViewStudijskiProgram.setText(stud.get_smer().get_nazivSmera());

_linearLayoutResults.addView(view);

}

}

protected class HTTPPretragaStudenataJSON extends AsyncTask<String, Void,

String> {

@Override

protected String doInBackground(String... strings) {

String serviceURL =

MTIPShared.get_serviceBaseURL()+strings[0]+strings[1];

GsonBuilder gsonBuilder = new GsonBuilder();

Gson gson = gsonBuilder.create();

_studenti.clear();

_studenti.addAll(Arrays.asList(gson.fromJson(

JSONReader.getJSONfromURL(serviceURL),

MTIPStudent[].class)));

return null;

}

Page 18: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

18

@Override

protected void onPostExecute(String result) {

_progressDialog.dismiss();

PopulateResults();

}

}

protected class HTTPObrisiStudentaPOST extends AsyncTask<String, Void,

String>{

protected boolean _executed = false;

protected int _idStudenta = 0;

@Override

protected String doInBackground(String... strings) {

String serviceURL = MTIPShared.get_serviceBaseURL()+strings[0];

HashMap<String, String> postDataParams = new HashMap<>();

postDataParams.put("id",strings[1]);

this._idStudenta = Integer.parseInt(strings[1]);

this._executed =

Boolean.parseBoolean(HTTPPostCaller.performPostCall(serviceURL,postDataParams));

return null;

}

@Override

protected void onPostExecute(String result) {

_progressDialog.dismiss();

if(this._executed)

{

int studentListIndex = 0;

boolean found = false;

for(MTIPStudent stud : _studenti)

{

if (stud.get_idStudent() == this._idStudenta) {found = true;

break;}

studentListIndex++;

}

if (found)

{

_studenti.remove(studentListIndex);

_linearLayoutResults.removeViewAt(studentListIndex);

}

}

}

}

}

Listing broj 8. Sadržaj klase StudentiFragment

U listingu koda broj 9 prikazan je sadržaj klase StudentiDodavanjeFragment dok je na slici broj

9 prikazan izgled navedenog fragmenta. Sadržaj spomenute klase je krajnje specifičan u odnosu

na prethodno izložene listinge koda pošto se u onCreate metodu prvo uspostavljaju veze sa

komponentama koje se nalaze unutar rasporeda fragment_studenti_dodavanje_izmena.xml i

zatim se poziva metoda PreuzimiStudijskePrograme čija je uloga da formira objekat tipa

HTTPProcitajStudijskeProgrameJSON koji predstavlja pozadinski proces (izvedena je iz klase

AsyncTask) i analogno klasi HTTPPretragaStudenataJSON iz klasa (fragmenata)

PretragaFragment i StudentiFragment pozove REST servis i formira listu postojećih studijskih

programa (_studijskiProgrami). Spomeniti pozadinski proces pokreće se pozivom execute

metode uz prosleđivanje odgovarajućih parametara. Ukoliko je poziv spomenutog servisa

Page 19: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

19

uspešan i lista studijskih programa (smerova) se oformi (navedeno se odvija u doInBackground

metodi) onda se spomenuta lista na osnovu preklopljene toString metode klase

MTIPStudijskiProgram putem ArrayAdapter-a povezujue sa Spinner kontrolom i unutar istog

se prikazuju trenutno dostupni smerovi (navedeno se odvija u onPostExecute metodi). Klikom

na taster btnPotvrdi poziva se metoda DodajStudenta čija je uloga da preuzme vrednosti iz

EditText i Spinner kontrola i zatim prosledi iste instanci klase HTTPDodajStudentaPOST koja

će iste proslediti odgovarajućem metodu REST servisa kako bi se dodao novi student u bazu

podataka. Navedeno se podrazumevano odvija u formi pozadinskog procesa (AsyncTask) uz

prikazivanje odgovarajućeg ProgressDialog-a. Ukoliko se student uspešno doda u bazu podataka

tj. poziv REST servisa je uspešan, korisnik se preusmerava na fragment StudentiFragment.

Klikom na taster btnOdustani korisnik se takođe preusmerava na fragment StudentiFragment.

Slika broj 7. Izgled fratmenta Studenti Slika broj 8. Dijalog brisanja studena

package rs.tfzr.mtipstudenti;

import android.app.ProgressDialog;

import android.content.Context;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.app.Fragment;

import android.os.Handler;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.EditText;

Page 20: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

20

import android.widget.LinearLayout;

import android.widget.Spinner;

import android.widget.TextView;

import com.google.gson.Gson;

import com.google.gson.GsonBuilder;

import org.w3c.dom.Text;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.HashMap;

import rs.tfzr.classes.MTIPStudent;

import rs.tfzr.classes.MTIPStudijskiProgram;

import rs.tfzr.rs.tfzr.data.MTIPShared;

import rs.tfzr.utility.HTTPPostCaller;

import rs.tfzr.utility.JSONReader;

public class StudentiDodavanjeFragment extends Fragment {

// TODO: Rename parameter arguments, choose names that match

// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER

private static final String ARG_PARAM1 = "param1";

private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters

private String mParam1;

private String mParam2;

private OnFragmentInteractionListener mListener;

protected TextView _textViewDodavanjeLabela;

protected Context _context;

protected Button _btnPotvrdi;

protected Button _btnOdustani;

protected LinearLayout _linearLayoutIDStudenta;

protected LinearLayout _linearLauyoutMain;

protected ArrayList<MTIPStudijskiProgram> _studijskiProgrami;

protected Spinner _spinnerStudijskiProgram;

protected ProgressDialog _progressDialog = null;

protected Runnable _studijskiProgramiTask;

protected Handler _studijskiProgramiHandler;

protected MTIPStudijskiProgram _odabraniStudijskiProgram;

protected EditText _editTextPrezimeStudenta;

protected EditText _editTextimeStudenta;

protected EditText _editTextBrojIndeksa;

public StudentiDodavanjeFragment() {

// Required empty public constructor

}

// TODO: Rename and change types and number of parameters

public static StudentiDodavanjeFragment newInstance(String param1, String

param2) {

StudentiDodavanjeFragment fragment = new StudentiDodavanjeFragment();

Bundle args = new Bundle();

args.putString(ARG_PARAM1, param1);

args.putString(ARG_PARAM2, param2);

fragment.setArguments(args);

return fragment;

}

Page 21: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

21

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

if (getArguments() != null) {

mParam1 = getArguments().getString(ARG_PARAM1);

mParam2 = getArguments().getString(ARG_PARAM2);

}

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

View rootView =

inflater.inflate(R.layout.fragment_studenti_dodavanje_izmena, container, false);

this._context = rootView.getContext();

this._textViewDodavanjeLabela =

(TextView)rootView.findViewById(R.id.textViewStudentiNazivAkcije);

this._textViewDodavanjeLabela.setText("Dodavanje studenta");

this._linearLauyoutMain =

(LinearLayout)rootView.findViewById(R.id.dodavanjeIzmenaMainLinearLayout);

this._linearLayoutIDStudenta =

(LinearLayout)rootView.findViewById(R.id.linearLayoutIDStudenta);

this._linearLauyoutMain.removeView(this._linearLayoutIDStudenta);

this._btnPotvrdi = (Button)rootView.findViewById(R.id.buttonPotvrdi);

this._btnOdustani = (Button)rootView.findViewById(R.id.buttonOdustani);

this._btnPotvrdi.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

DodajStudenta();

}

});

this._btnOdustani.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

MTIPStudentiMain.displayView(new

StudentiFragment(),MTIPStudentiMain._activity);

}

});

this._editTextPrezimeStudenta =

(EditText)rootView.findViewById(R.id.editTextPrezimeDATA);

this._editTextimeStudenta =

(EditText)rootView.findViewById(R.id.editTextImeDATA);

this._editTextBrojIndeksa =

(EditText)rootView.findViewById(R.id.editTextIndeksDATA);

this._studijskiProgrami = new ArrayList<MTIPStudijskiProgram>();

this._spinnerStudijskiProgram =

(Spinner)rootView.findViewById(R.id.spinnerStudijskiProgrami);

this.PreuzmiStudijskePrograme();

return rootView;

}

// TODO: Rename method, update argument and hook method into UI event

public void onButtonPressed(Uri uri) {

if (mListener != null) {

mListener.onFragmentInteraction(uri);

}

}

Page 22: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

22

@Override

public void onAttach(Context context) {

super.onAttach(context);

if (context instanceof OnFragmentInteractionListener) {

mListener = (OnFragmentInteractionListener) context;

} else {

throw new RuntimeException(context.toString()

+ " must implement OnFragmentInteractionListener");

}

}

@Override

public void onDetach() {

super.onDetach();

mListener = null;

}

public interface OnFragmentInteractionListener {

// TODO: Update argument type and name

void onFragmentInteraction(Uri uri);

}

protected void PreuzmiStudijskePrograme()

{

this._studijskiProgramiHandler = new Handler();

this._studijskiProgramiTask = new Runnable() {

@Override

public void run() {

HTTPProcitajStudijskeProgrameJSON smeroviREQ = new

HTTPProcitajStudijskeProgrameJSON();

String[] params = new String[1];

params[0] = "smerovi";

smeroviREQ.execute(params);

}

};

this._studijskiProgramiHandler.post(this._studijskiProgramiTask);

this._progressDialog = ProgressDialog.show(this._context,

"Molimo Vas sačekajte ...", "Preuzimam podatke ...", true);

}

protected class HTTPProcitajStudijskeProgrameJSON extends AsyncTask<String,

Void, String> {

@Override

protected String doInBackground(String... strings) {

String serviceURL = MTIPShared.get_serviceBaseURL()+strings[0];

GsonBuilder gsonBuilder = new GsonBuilder();

Gson gson = gsonBuilder.create();

_studijskiProgrami.clear();

_studijskiProgrami.addAll(Arrays.asList(gson.fromJson(

JSONReader.getJSONfromURL(serviceURL),

MTIPStudijskiProgram[].class)));

return null;

}

@Override

protected void onPostExecute(String result) {

_progressDialog.dismiss();

ArrayAdapter<MTIPStudijskiProgram> adapter =

new ArrayAdapter<MTIPStudijskiProgram>(_context,

android.R.layout.simple_spinner_dropdown_item, _studijskiProgrami);

Page 23: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

23

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

_spinnerStudijskiProgram.setAdapter(adapter);

if (_studijskiProgrami.size()>0) _odabraniStudijskiProgram =

_studijskiProgrami.get(0);

else _odabraniStudijskiProgram = new MTIPStudijskiProgram();

}

}

protected void DodajStudenta()

{

final String prezime =

this._editTextPrezimeStudenta.getText().toString();

final String ime = this._editTextimeStudenta.getText().toString();

final String brojIndeksa =

this._editTextBrojIndeksa.getText().toString();

final int idSmera =

_studijskiProgrami.get(_spinnerStudijskiProgram.getSelectedItemPosition()).get_id

Smer();

this._studijskiProgramiHandler = new Handler();

this._studijskiProgramiTask = new Runnable() {

@Override

public void run() {

HTTPDodajStudentaPOST dodajStudentaREQ = new

HTTPDodajStudentaPOST();

String[] params = new String[5];

params[0] = "dodajstudenta";

params[1] = prezime;

params[2] = ime;

params[3] = brojIndeksa;

params[4] = String.valueOf(idSmera);

dodajStudentaREQ.execute(params);

}

};

this._studijskiProgramiHandler.post(this._studijskiProgramiTask);

this._progressDialog = ProgressDialog.show(this._context,

"Molimo Vas sačekajte ...", "Izvršavam zahtev ...", true);

}

protected class HTTPDodajStudentaPOST extends AsyncTask<String, Void,

String>{

protected boolean _executed = false;

@Override

protected String doInBackground(String... strings) {

String serviceURL = MTIPShared.get_serviceBaseURL()+strings[0];

HashMap<String, String> postDataParams = new HashMap<>();

postDataParams.put("Prezime",strings[1]);

postDataParams.put("Ime",strings[2]);

postDataParams.put("Indeks",strings[3]);

postDataParams.put("idSmer",strings[4]);

this._executed =

Boolean.parseBoolean(HTTPPostCaller.performPostCall(serviceURL,postDataParams));

return null;

}

@Override

protected void onPostExecute(String result) {

Page 24: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

24

_progressDialog.dismiss();

if(this._executed) MTIPStudentiMain.displayView(new

StudentiFragment(),MTIPStudentiMain._activity);

}

}

}

Listing broj 9. Sadržaj klase StudentiDodavanjeFragment

Slika broj 9. Izgled fratmenta

StudentiDodavanjeFragment

Slika broj 10. Izgled fratmenta

StudentiIzmenaFragment

U listingu koda broj 10 prikazan je sadržaj klase StudentiIzmenaFragment dok je na slici broj

10 prikazan izgled navedenog fragmenta. Sadržaj spomenute klase je veoma sličan sadržaju klase

(fragmenta) StudentiDodavanjeFragment uz par krucijalnih razlika. Prvo, instanca klase

StudentiIzmenaFragment se formira pozivom statičke metode newInstance i pri tome se

preuzima parametar idStudenta. Na osnovu prosleđenog parametra, pozivom metode

PreuzmiPodatkeOStudentuISmerovima (koja kao parametar prima identifikator studenta)

formira se instanca klase HTTPProcitajPodatkeOStudentuISmerovimaJSON koja je izvedena

iz klase AsyncTask i u doInBacground metodu formira listu dostupnih studijskih programa

(kako bi se popunila Spinner kontrola) a zatim preuzima i informacije o studentu koji treba da se

izmeni. Navedene informacije preuzimaju se pozivom metoda REST servisa. U onPostExecute

metodu spomenute klase lista dostupnih studijskih programa se povezuje putem ArrayAdapter-

a sa odgovarajućom Spinner kontrolom i zatim se na osnovu informacija o traženom studentu

popunjava sadržaj EditText kontrola i (unutar spomenute Spinner kontrole) prikazuje se

studijski program trenutno odabranog studenta iz spomenute liste dostupnih studijskih

programa. Klikom na taster btnPotvrdi poziva se metoda IzmeniStudenta čija je uloga da

Page 25: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

25

preuzme vrednosti iz EditText i Spinner kontrola i zatim prosledi iste instanci klase

HTTPIzmeniStudentaPOST koja će iste proslediti odgovarajućem metodu REST servisa kako bi

se izmenio postojeći (odabrani) student. Navedeno se podrazumevano odvija u formi

pozadinskog procesa (AsyncTask) uz prikazivanje odgovarajućeg ProgressDialog-a. Ukoliko se

informacije odabranog studenta uspešno izmene tj. poziv REST servisa je uspešan, korisnik se

preusmerava na fragment StudentiFragment. Klikom na taster btnOdustani korisnik se takođe

preusmerava na fragment StudentiFragment.

package rs.tfzr.mtipstudenti;

import android.app.Fragment;

import android.app.ProgressDialog;

import android.content.Context;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.os.Handler;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Spinner;

import android.widget.TextView;

import com.google.gson.Gson;

import com.google.gson.GsonBuilder;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.HashMap;

import rs.tfzr.classes.MTIPStudent;

import rs.tfzr.classes.MTIPStudijskiProgram;

import rs.tfzr.rs.tfzr.data.MTIPShared;

import rs.tfzr.utility.HTTPPostCaller;

import rs.tfzr.utility.JSONReader;

public class StudentiIzmenaFragment extends Fragment {

// TODO: Rename parameter arguments, choose names that match

// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER

private static final String _idStudentaNaziv = "idStudenta";

// TODO: Rename and change types of parameters

private int _idStudenta = 0;

private StudentiIzmenaFragment.OnFragmentInteractionListener mListener;

protected TextView _textViewDodavanjeLabela;

protected Context _context;

protected Button _btnPotvrdi;

protected Button _btnOdustani;

protected EditText _editTextIDStudenta;

protected EditText _editTextPrezimeStudenta;

protected EditText _editTextimeStudenta;

protected EditText _editTextBrojIndeksa;

protected Spinner _spinnerStudijskiProgram;

protected ArrayList<MTIPStudijskiProgram> _studijskiProgrami;

protected MTIPStudent _izabraniStudent;

protected ProgressDialog _progressDialog = null;

protected Runnable _studijskiProgramiTask;

protected Handler _studijskiProgramiHandler;

Page 26: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

26

public StudentiIzmenaFragment() {

// Required empty public constructor

}

// TODO: Rename and change types and number of parameters

public static StudentiIzmenaFragment newInstance(int idStudenta) {

StudentiIzmenaFragment fragment = new StudentiIzmenaFragment();

Bundle args = new Bundle();

args.putInt("idStudenta",idStudenta);

fragment.setArguments(args);

return fragment;

}

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

if (getArguments() != null) this._idStudenta =

getArguments().getInt(_idStudentaNaziv);

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

View rootView =

inflater.inflate(R.layout.fragment_studenti_dodavanje_izmena, container, false);

this._context = rootView.getContext();

this._textViewDodavanjeLabela =

(TextView)rootView.findViewById(R.id.textViewStudentiNazivAkcije);

this._textViewDodavanjeLabela.setText("Izmena studenta");

this._btnPotvrdi = (Button)rootView.findViewById(R.id.buttonPotvrdi);

this._btnPotvrdi.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

IzmeniStudenta();

}

});

this._btnOdustani = (Button)rootView.findViewById(R.id.buttonOdustani);

this._btnOdustani.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

MTIPStudentiMain.displayView(new

StudentiFragment(),MTIPStudentiMain._activity);

}

});

this._editTextIDStudenta =

(EditText)rootView.findViewById(R.id.editTextIDStudentaDATA);

this._editTextPrezimeStudenta =

(EditText)rootView.findViewById(R.id.editTextPrezimeDATA);

this._editTextimeStudenta =

(EditText)rootView.findViewById(R.id.editTextImeDATA);

this._editTextBrojIndeksa =

(EditText)rootView.findViewById(R.id.editTextIndeksDATA);

this._studijskiProgrami = new ArrayList<MTIPStudijskiProgram>();

this._spinnerStudijskiProgram =

(Spinner)rootView.findViewById(R.id.spinnerStudijskiProgrami);

this.PreuznmiPodatkeOStudentuISmerovima(this._idStudenta);

return rootView;

}

Page 27: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

27

// TODO: Rename method, update argument and hook method into UI event

public void onButtonPressed(Uri uri) {

if (mListener != null) {

mListener.onFragmentInteraction(uri);

}

}

@Override

public void onAttach(Context context) {

super.onAttach(context);

if (context instanceof

StudentiDodavanjeFragment.OnFragmentInteractionListener) {

mListener = (StudentiIzmenaFragment.OnFragmentInteractionListener)

context;

} else {

throw new RuntimeException(context.toString()

+ " must implement OnFragmentInteractionListener");

}

}

@Override

public void onDetach() {

super.onDetach();

mListener = null;

}

public interface OnFragmentInteractionListener {

// TODO: Update argument type and name

void onFragmentInteraction(Uri uri);

}

protected void PreuznmiPodatkeOStudentuISmerovima(final int idStudenta)

{

this._studijskiProgramiHandler = new Handler();

this._studijskiProgramiTask = new Runnable() {

@Override

public void run() {

HTTPProcitaPodatkeOStudentuISmerovimaJSON studentISmeroviREQ =

new HTTPProcitaPodatkeOStudentuISmerovimaJSON();

String[] params = new String[3];

params[0] = "student/?idStudent=";

params[1] = "smerovi";

params[2] = String.valueOf(idStudenta);

studentISmeroviREQ.execute(params);

}

};

this._studijskiProgramiHandler.post(this._studijskiProgramiTask);

this._progressDialog = ProgressDialog.show(this._context,

"Molimo Vas sačekajte ...", "Preuzimam podatke ...", true);

}

protected class HTTPProcitaPodatkeOStudentuISmerovimaJSON extends

AsyncTask<String, Void, String> {

@Override

protected String doInBackground(String... strings) {

String serviceURLStudent =

MTIPShared.get_serviceBaseURL()+strings[0]+strings[2];

String serviceURLSmerovi =

MTIPShared.get_serviceBaseURL()+strings[1];

GsonBuilder gsonBuilder = new GsonBuilder();

Gson gson = gsonBuilder.create();

Page 28: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

28

// smerovi

_studijskiProgrami.clear();

_studijskiProgrami.addAll(Arrays.asList(gson.fromJson(

JSONReader.getJSONfromURL(serviceURLSmerovi),

MTIPStudijskiProgram[].class)));

// student

_izabraniStudent = new MTIPStudent();

_izabraniStudent = Arrays.asList(gson.fromJson(

JSONReader.getJSONfromURL(serviceURLStudent),

MTIPStudent[].class)).get(0);

return null;

}

@Override

protected void onPostExecute(String result) {

_progressDialog.dismiss();

ArrayAdapter<MTIPStudijskiProgram> adapter =

new ArrayAdapter<MTIPStudijskiProgram>(_context,

android.R.layout.simple_spinner_dropdown_item, _studijskiProgrami);

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

_spinnerStudijskiProgram.setAdapter(adapter);

_editTextIDStudenta.setText(String.valueOf(_izabraniStudent.get_idStudent()));

_editTextPrezimeStudenta.setText(_izabraniStudent.get_prezime());

_editTextimeStudenta.setText(_izabraniStudent.get_ime());

_editTextBrojIndeksa.setText(_izabraniStudent.get_index());

int indexSmera = 0;

for(MTIPStudijskiProgram sp : _studijskiProgrami)

{

if (sp.get_idSmer()==_izabraniStudent.get_smer().get_idSmer())

{break;}

indexSmera++;

}

_spinnerStudijskiProgram.setSelection(indexSmera);

}

}

protected void IzmeniStudenta()

{

_izabraniStudent.set_prezime(_editTextPrezimeStudenta.getText().toString());

_izabraniStudent.set_ime(_editTextimeStudenta.getText().toString());

_izabraniStudent.set_index(_editTextBrojIndeksa.getText().toString());

_izabraniStudent.set_smer(_studijskiProgrami.get(_spinnerStudijskiProgram.getSele

ctedItemPosition()));

this._studijskiProgramiHandler = new Handler();

this._studijskiProgramiTask = new Runnable() {

@Override

public void run() {

HTTPIzmeniStudentaPOST izmeniStudentaPOST = new

HTTPIzmeniStudentaPOST();

String[] params = new String[6];

Page 29: MTIPLab06 - 2017 - 2018 - PDF - R2.pdf · dr Predrag Pecev – Mobilne tehnologije i programiranje – ežbe 2017 – 2018 – R2 - odložno izmeni - Nerecenzirani materijal 3 PRISTUP

dr Predrag Pecev – Mobilne tehnologije i programiranje – Vežbe 2017 – 2018 – R2 -

Podložno izmeni - Nerecenzirani materijal

29

params[0] = "izmenistudenta";

params[1] = _izabraniStudent.get_prezime();

params[2] = _izabraniStudent.get_ime();

params[3] = _izabraniStudent.get_index();

params[4] =

String.valueOf(_izabraniStudent.get_smer().get_idSmer());

params[5] = String.valueOf(_izabraniStudent.get_idStudent());

izmeniStudentaPOST.execute(params);

}

};

this._studijskiProgramiHandler.post(this._studijskiProgramiTask);

this._progressDialog = ProgressDialog.show(this._context,

"Molimo Vas sačekajte ...", "Izvršavam zahtev ...", true);

}

protected class HTTPIzmeniStudentaPOST extends AsyncTask<String, Void,

String>{

protected boolean _executed = false;

@Override

protected String doInBackground(String... strings) {

String serviceURL = MTIPShared.get_serviceBaseURL()+strings[0];

HashMap<String, String> postDataParams = new HashMap<>();

postDataParams.put("Prezime",strings[1]);

postDataParams.put("Ime",strings[2]);

postDataParams.put("Indeks",strings[3]);

postDataParams.put("idSmer",strings[4]);

postDataParams.put("id",strings[5]);

this._executed =

Boolean.parseBoolean(HTTPPostCaller.performPostCall(serviceURL,postDataParams));

return null;

}

@Override

protected void onPostExecute(String result) {

_progressDialog.dismiss();

if(this._executed) MTIPStudentiMain.displayView(new

StudentiFragment(),MTIPStudentiMain._activity);

}

}

}

Listing broj 10. Sadržaj klase StudentiIzmenaFragment

NAPOMENA : Dizajn izložene aplikacije je krajnje jednostavan i nije optimizovan sa aspetka

detaljnog definisanja resursa za sve rezolucije, tačnog pozicioniranja labela i dr. pošto je cilj istih

da se pokaže osnovna koncepcija i funkcionalnost Android aplikacija i povezivanje istih sa REST

servisom. Namerni dizajnerski propusti će biti korigovani u narednoj verziji vežbi.