Aplicatie Android – Planificator Examene

UNIVERSITATEA “LUCIAN BLAGA” DIN SIBIU

FACULTATEA DE INGINERIE

DEPARTAMENTUL DE CALCULATOARE ȘI INGINERIE ELECTRICĂ

PROIECT DE DIPLOMĂ

Îndrumător: Șef lucr. dr. mat. Crețulescu Radu

Absolvent:

Nemeș Florin-Cristian

Specializarea Ingineria Sistemelor Multimedia

– Sibiu, 2016 –

UNIVERSITATEA “LUCIAN BLAGA” DIN SIBIU

FACULTATEA DE INGINERIE

DEPARTAMENTUL DE CALCULATOARE ȘI INGINERIE ELECTRICĂ

Aplicație Android – Planificator Examene

Îndrumător: Șef lucr. dr. mat. Crețulescu Radu

Absolvent:

Nemeș Florin-Cristian

Specializarea Ingineria Sistemelor Multimedia

-Sibiu 2016 –

Motivarea temei

Am ajuns în punctul în care vrem nu vrem, suntem înconjurați de tehnologie , scopul ei fiind sa ne ușureze munca , de la a comunica mai ușor sau rezolva mult mai repede probleme din orice domeniu, până la a ne comanda mâncarea noastră preferata de oriunde am fi, printr-o singură apăsare de buton . Toate acestea poate încep sa ni se pară lucruri banale, dar după cum știm din legea lui Gordon Moore , la interval de 18 luni tranzistorii se vor dubla, astfel tehnologia va fi tot mai avansată din toate punctele de vedere (hardware/software) , iar ideile de a le exploata vor fi nelimitate.

Fiind student in domeniul IT la facultatea de inginerie, un loc unde se nasc idei intuitive , m-a îndrumat la ideea de a concepe ceva util în sprijinul secretar, profesorilor și studenților, adoptând tehnologia din ziua de azi. Odată cu apariția „smartphone-urilor” , au fost dezvoltate aplicații cu capabilități din aproape orice domeniu , scopul lor fiind de a adopta o lume modernă, inteligentă și cu un „user experience” cât mai ușor. De la începutul anilor de studiu eu și mulți alții ne-am confruntat cu situații in care nu știam in ce dată avem următorul examen , la ce oră și in ce sală , pentru a ști cum să ne organizam programul de studiu. Rezolvând această dilemă, de multe ori se ajungea la întrebări repetate șefului de grupă, ceea ce devenise o problemă.

Aceeași dilemă apare la un moment dat si in cazul unui profesor , care trebuie să verifice când va susține un examen , utilizând un calculator . In ceea ce o privește pe secretara, pot exista cazuri in care nu poate avea acces la un calculator pentru a planifica un examen. Așa am ajuns la decizia de a dezvolta o aplicație pentru dispozitive Android în care secretara poate planifica un examen pentru orice specializare din orice an cu regulile aferente , un profesor poate vedea detaliile examinărilor lui , iar un student poate verifica examenele din sesiunea respectivă.

Obiectivele dezvoltării acestui proiect au fost:

dezvoltarea unei aplicații care să se comporte diferit in funcție de secretara/profesor/student

dezvoltarea unor restricții in ceea ce privește planificarea : dimensiunea sălilor, suprapunerii materiilor, profesorilor, asistenților, grupelor , interval 3 zile examen pentru o grupă , durata unui examen

dezvoltarea unei baze de date online

comunicarea datelor între baza de date și aplicație

vizualizarea examenelor pentru student/profesor in ordine cronologică după dată

interfață cât mai prietenoasă pentru utilizator

Considerații Teoretice

MySQL

MySQL este un SGBD(Sistem de gestiune a bazelor de date relaționale) folosit foarte des în aplicațiile web. Își are rădăcinile într-un sistem de baze de date in-house (non-SQL) numit Unireg folosit de către compania suedeză TcX care a fost dezvoltată pentru prima oară in 1980 și optimizată pentru depozitele de date[1]. Prima versiune la nivel larg a fost MySQL 3.11, lansată la mijlocul lui 1996.

MySQL -> limbaj de program stocat este un limbaj structurat-bloc (asemănător limbajului Pascal) care conține comenzi familiare pentru manipularea variabilelor, de punere in aplicare condiționată , execuție , procesare iterativa și tratare a erorilor[1].

Sistemul MySQL folosit pentru aplicația noastră este phpMyAdmin .

2.2 JSON (JavaScript Object Notation)

Formatul JavaScript Object Notation , sau JSON pe scurt, este derivat din limbajul de programare JavaScript, ulterior devenind un format independent de limbajele de programare.[2]

JSON este un format standard care folosește text pentru a transmite perechi de date cheie-valoare. Este știut ca fiind creația lui Douglas Crockford , deși recunoscând ca nu el este creatorul , a fost cel care i-a dat un nume și inventat extensia .json .[2]

JSON suportă mai multe tipuri de date : string, numere intregi/reale , boolean, obiecte, liste.

De-a lungul timpului s-a constatat ca fiind o alternativă a formatului XML , fiind mai ușor de interpretat.

Exemplu format JSON cheie-valoare:

2.3 PHP (Hypertext Preprocessor)

PHP este un limbaj de programare folosit pentru construirea dinamică a site-urilor web .O pagină web dinamica este o pagină a cărui conținut se poate schimba in mod automat de fiecare dată când este vizualizata pagina. Ca și o regulă generală , programele de tip PHP rulează pe un Web Server și scopul lor este de a servi cereri utilizatorului cu serverul[3]. Ca prin urmare, este un limbaj de Server. O pagină web nu știe dacă PHP este implicat , deci este ’transparent’ pentru HTML.

O facilitate foarte bună – este cross/platform , compatibil cu Linux, Windows, FreeBSD, Mac OS X , Solaris și multe altele. Se poate integra ușor cu toate Web server ’urile comune, incluzând Apache, Internet Information Server(IIS) , Zeus, lighthttpd[3].

A fost creat de Rasmus Lerdorf in 1994. A început ca un simplu utilitar scris în limbajul C pentru a înlocui scripturile Perl care Rasmus le folosea pe pagina lui Web personală . A fost lansat publicului larg in 1995 numit PHP versiunea 2[3].

Exemplu Hello World PHP

Interpretorul PHP execută numai cod PHP in cadrul delimitatorilor lui. Orice din afara delimitatorilor nu este procesat de PHP. Delimitatorii sunt <?php pentru a deschide și ?> pentru a închide secțiunea.

Variabilele au ca prefix un simbol cu un dolar iar tipul lor nu trebuie specificat. De la PHP 5 s-a introdus „type hinting” care permite funcțiilor să forțeze parametri lor ca fiind obiecte ale unei anumite clase , tablouri sau interfețe. Conține trei tipuri de sintaxe pentru comentarea codului: „/**/” comentează un întreg bloc de cod, „//” și „#” comentează o singura linie. Declarația „echo” este una dintre cele mai comune facilități pentru a afișa un text undeva. De exemplu, într-un browser web.

In ceea ce privește cuvintele cheie și sintaxa limbii , PHP este similar cu sintaxa C pentru condiții „if” ,bucle ”for” și „while” și returnarea funcțiilor sunt similare cu C,C++,C#,Java și Pearl.

2.4 Java

Java este un limbaj și o platformă realizată de Sun Microsystems. Este un limbaj în care devoltatorii pot exprima un cod sursă (textul programului). Sintaxa Java este parțial corelată după C și C++ pentru a putea fi mai ușor de învățat de către dezvoltatorii C/C++. A fost proiectat pentru a fi un limbaj mai sigur ,realizând o așa numită siguranța prin faptul că nu lasă supraîncărcarea operatorilor și se omit anumite caracteristici din C/C++ , cum ar fi pointerii.[11]

Java mai este in același timp și o platformă care constă într-o mașină virtuală și un mediu de execuție. Mașina virtuală este un procesor bazat pe software , care prezintă un set de instrucțiuni. Mediul de execuție constă in librarii pentru rularea programelor și interacțiunea cu sistemul de operare. Acesta conține o bibliotecă mare de fișiere tip .class precompilate care execută sarcini comune, cum ar fi operațiuni matematice sau comunicații in rețea.

Un program special cunoscut sub numele de compilator Java traduce codul sursa în instrucțiuni , care apoi sunt executate de către mașina virtuală. Aceste instrucțiuni sunt cunoscute sub denumirea de bytecode. Platforma promovează portabilitatea . Același bytecode neschimbat rulează pe Windows, Linux , Mac OS-X și altele.[11]. Java a fost introdus cu sloganul „scrie o dată , rulează oriunde”[12] .

Există mai multe ediții ale platformei Java , fiecare având un anumit scop:

Java Platform , Standard Edition (Java SE). Folosit pentru dezvoltarea aplicațiilor care rulează pe desktopuri și pentru a dezvolta applet-uri , programe care rulează pe browsere web.

Java Platform, Enterprise Edition(Java EE). Folosit pentru dezvoltarea aplicațiilor de tip server . Are la bază Java SE.

Java Platform, Micro Edition (Java ME). Folosit pentru dezvoltarea MIDlets’urilor , care reprezintă programe pentru dispozitive mobile și Xlet’surilor care sunt programe care rulează pe sisteme dedicate.

O a patra platformă este una creată de Google pentru a crea Aplicații Android care rulează pe dispozitive cu Android. Aceasta platformă este cunoscuta sub numele de Platforma Android.

2.5 Android

Android este un sistem de operare mobil, dezvoltat în special pentru telefoanele inteligente , care se bazează pe o versiune modificată a Linux. A fost creat sub același nume in 2003 de către Andy Rubin, Rich Miner, Nick Sears și Chris White , ca parte a unei strategii de a intra in piața dispozitivelor mobile. In 2005 a fost achiziționat de către Google si astfel , gigantul a dus mai departe dezvoltarea lui. Google a hotărât ca toată lumea sa poată avea acces la codul sursă , gratuit. Astfel, toate marile companii de telefoane inteligente folosesc Androidul ca Sistem de Operare principal, modificându-l după stilul fiecăruia.

Principalul avantaj de a adopta Android este ca oferă o abordare unica in dezvoltarea aplicațiilor. Dezvoltatorii trebuie sa dezvolte numai pentru Android , iar aplicațiile lor pot rula pe numeroase dispozitive diferite de la producători diferiți , atâta timp cât dispozitivele rulează Android.

Android este văzut ca principalul competitor al iOS-ului (SO iPhone) , datorită pieței de aplicații[4].

Pe lângă kernel-ul Linux, Android mai conține librarii , API-uri scrise in C și un Framework de aplicații cu librarii compatibile cu Java, XML.

Până la versiunea 5.0 , Android folosea o mașină virtuala numita Dalvik care folosea compilare just-in-time (JIT) pentru a rula executabile Dalvik. In versiunea Android 4.4 a fost introdus Android Runtime (ART) ca o nouă mașină virtuală , care folosea compilare ahead-of-time (AOT) pentru a compila bytecode-ul aplicației in cod mașină , la instalarea unei aplicații. In versiunea 4.4 , ART a fost experimental ,implicit nepermis, iar apoi introdus definitiv ca singură opțiune de compilator in versiunea majora Android 5.0[5] .

Deoarece dispozitivele care rulează Android sunt în mare parte alimentate de baterii, Android este conceput pentru a gestiona procesele pentru a menține consumul de energie la un nivel minim. Astfel, daca o aplicație nu mai este folosită , ea rămâne suspendata in memorie.

In caz de RAM indisponibil, procesele din memorie sunt menajate automat , sistemul începând ,sa închidă procese inactive , începând cu cele inactive de o perioadă mai lunga de timp.

In Mai 2016, Google a anunțat o nouă platformă numita Daydream care va fi implementată nativ începând cu Android N , destinata realității virtuale cu capabilități specifice realității virtuale împreuna cu un controller pe cască virtuală dezvoltată de Google însuși[5].

Arhitectura[4] SO Android:

Figura 1-1.Arhitectura SO Android [4]

Aplicațiile dezvoltate pentru Android extind funcționalitatea dispozitivelor și sunt dezvoltate folosind Android Software Development Kit (SDK) . Ca limbaj de programare principal este folosit Java deoarece are acces complet la API-urile SO-ului. Java poate fi combinat și cu C/C++.

In 2014, Google a dezvăluit alt Framework bazat pe Apache Cordova care permite portarea de aplicații web tip Chrome HTML5 pe Android[5].

4 componente esențiale care le oferă SDK-ul pentru a dezvolta o aplicație pentru Android sunt[6]:

Activitate

O activitate reprezintă un singur ecran cu o interfață grafică pentru utilizator. O aplicație poate avea mai multe activități . De exemplu, o aplicație de e-mail poate avea o activitate care arată e-mailurile noi, o alta activitate pentru compunere e-mail și alta pentru toate e-mailurile. Fiecare activitate lucrează independent de celelalte , dar numai una poate sa fie activa la un moment dat(doar o interfață este vizibila la un moment dat).

Serviciu

Un serviciu este o componentă care rulează in fundal pentru a duce la capăt taskuri de lunga durată sau pentru control la distanță. Un serviciu nu are o interfață (asemeni activităților ).De exemplu, un serviciu poate rula pe fundal o melodie cât timp utilizatorul este in altă aplicație , sau să descarce date de pe web fără a opri interacțiunea utilizatorului cu o activitate/interfață.

Furnizor de conținut

Un furnizor de conținut administrează datele comune ale aplicației . Poate stoca date in fișiere de sistem, într-o bază de date de tip SQL , pe web, sau în orice alt tip de stocare în care aplicația are acces. Prin acest Furnizor de conținut, o aplicație poate interoga sau chiar modifica datele altei aplicații (daca este permis).

Broadcast Reciever

Broadcast Reciever-ul este o componentă care răspunde la semnale la nivel de sistem. Multe semnale provin de la sistem , de exemplu , un semnal care anunță ca s-a stins ecranul, baterie epuizată sau apel ratat. Nu utilizează o interfață , dar poate crea notificări in bara de stare pentru a notifica utilizatorul ca a avut loc un eveniment.

Activitățile, Serviciile și Broadcast Reciever-ii pot fi activate prin mesaje asincrone numite Intent. Un intent trimite un mesaj pentru a activa o componentă sau un tip de componentă.

Android folosește limbajul de marcare XML (Extensible Markup Language) pentru a declara elemente de interfață grafică . Oferă un vocabular XML simplu, care corespunde vizualizării claselor și subclaselor , cum ar fi cele pentru widget-uri și machete[7]. Fiecare widget/ element grafic poate fi declarat implicit in XML și apoi poate fi adăugat cod în aplicație care poate schimba starea acelor elemente grafice.

Exemplu cod XML pentru un container de tip text și un buton, încadrat intr-un Layout Linear:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >
    <TextView android:id="@+id/textView_login"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="TextView 1" />
    <Button android:id="@+id/button_login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Autentificare" />
</LinearLayout>

Un layout(aspect) definește structura vizuală pentru o interfață(cum vor fi așezate elementele grafice una față de alta). De exemplu , unei activități i se poate însușii un aspect linear(vertical/orizontal), relativ, grilă, tabel.

Pentru dezvoltarea acestui proiect s-a folosit mediul de dezvoltare Android Studio 2.1.0.0 , oferit gratuit de Google .

2.6 Medii de dezvoltare folosite

2.6.1 Android Studio

Pentru crearea aplicației Android , am folosit mediul de dezvoltare Android Studio 2.1.1 oferit gratuit de Google , împreuna cu Android SDK (Software Developer Kit). A fost prima oară anunțat in 16 Mai 2013 , scopul lui fiind un înlocuitor principal al ADT(Eclipse Android Development Tools). Este compatibil cu Windows, Mac OS X și Linux. Este bazat pe softul JetBrains' IntelliJ IDEA[9].

Din motive de compatibilitate cu anumite funcții și metode ale Android SDK , aplicația poate fi instalata pe orice tableta sau telefon care conține API 19(Android 4.4.4 KitKat) pana la API 23(Android 6.0.1 Marshmallow).

2.6.2 Wamp

Din motive de siguranța a conexiunii cu baza de date MySQL , am folosit serverul local numit WampServer , care este bazat pe Apache web server , baza de date MySQL phpMyAdmin și programare PHP. Astfel, aplicația Android se conectează local la baza de date aflată pe sistemul computațional local cu mediul de dezvoltare.

Arhitectura Aplicației

3.1 Structura Generală

Proiectul este bazat pe trei componente principale: Aplicația Android , comunicarea datelor bazată pe scripturi PHP și baza de date MySQL

Figura 3.1 Structura Claselor și Modulelor

Aplicația Android este formată din patru clase principale care conțin o interfață fiecare și cinci module.clase destinate prelucrării în fundal. Clasă LoginActivity impreună cu BackGroundTask decid la momentul lansării aplicației ,în funcție de utilizatorul care se conectează, ce activitate să lanseze mai departe :Admin(secretară),Profesor sau Student. Cele trei sunt independente una față de cealaltă. Dacă utilizatorul este deja conectat , atunci LoginActivity va decide ce să lanseze mai departe.

Figura 3.2 Use-Case Modul Login

App Student – AdminMainActivity- Activitate cu interfață specifică Secretarei

App Profesor – ProfesorMainActivity – Activitate cu interfață specifică Profesorului

App Secretara – StudentMainActivity – Activitate cu interfață specifică Studentului

Clasa Session păstrează utilizatorul conectat, cu toate detaliile necesare , inclusiv la oprirea aplicației, până când acesta își va da Log Ouț. În date_json se memorează temporar datele json referitoare la o înregistrare din baza de date, primite prin scripturile php , iar DateJsonStorage conține variabile statice de tip vector în care se păstrează toate înregistrările din baza de date .

În BackGroundTask se află metodele care moștenesc AsyncTask din SDK-ul Android care utilizează fire de execuție în fundal pentru conexiunile la baza de date fără a afecta interfețele grafice. ExpandableListAdapter(8) este o clasă pentru popularea containerelor de tip ExpandableListView folosite pentru afișarea examenelor planificate.

Scripturile PHP sunt folosite pentru a comunica cu baza de date MySQL locală aflată pe un server local pe sistemul de pe care a fost dezvoltată aplicația.

3.2 Aplicația Android

3.2.1 LoginActivity

În LoginActivity se află variabilele și metodele care moștenesc Activity din SDK-ul Android care se ocupă cu crearea unei ferestre unde dezvoltatorul poate adăuga elemente grafice. Acest modul este primul care intră în execuție în momentul lansării aplicației.

Variabilele de tip EditText sunt câmpuri în care utilizatorul va introduce Email-ul și parolă, urmat de apăsarea buttonului de autentificare.

Metoda onCreate(..) inițializează activitatea. Cel mai important este că aici se setează layout-ul care definește interfața. Această metodă este apelată în momentul lansării aplicației.

În momentul apăsării butonului de autentificare , metoda attemptLogin() este apelată , unde se încearcă autentificarea folosind datele din câmpurile EditText.

Dacă autentificarea este validă și existentă în baza de date MySQL, în obiectul sesiune se vor păstra toate datele necesare utilizatorului conectat .

Metodele isEmailValid verifică caracterele introduse în câmpul Email să conțină “@” , iar isPasswordValid să conțină mai mult de patru caractere.

3.2.2 AdminMainActivity

Clasa AdminMainActivity conține șase obiecte importante de tipul BackGroundTask și sunt folosite pentru a lansa în fundal fire de execuție care fac comunicarea cu baza de date MySQL. Fiecare obiect are rolul lui de a trimite sau primi informații din bază de date, apoi cu ajutorul metodelor destinate spinnerelor (spinner este un container care însușeste un „drop-down list”) se populează drop-down-list’urile cu informații primite din rețea. De exemplu, lansând în execuție sendSemestruIDBackGroundTask.execute(“get_materie_peSem”,semID) va returna din MySQL conform cheii transmise “ get_materie_peSem” și parametrului semID care reprezintă semestrul selectat de utilizator , toate materiile în funcție de semestru respectiv ,apoi datele/materiile primite vor fi populate în drop-down-list folosind metoda AddMaterieSpinnerItems(String[] v) care primește ca parametru vectorul cu materii.

Metoda onCreate(..) inițializează activitatea. Cel mai important este că aici se setează layout-ul care definește interfața. Această metodă este apelată în momentul lansării aplicației. Layout-ul este definit separat prin LinearLayout adaugă_ex_layout , ca după o planificare să poată fi înlăturat și afișat examenele planificate. Modulul Admin moștenește Activity din SDK-ul Android care se ocupă cu crearea unei ferestre unde dezvoltatorul poate adaugă elemente grafice.

VerificaPotAdaugaExamen() se apelează în momentul în care din baza de date au fost returnate toate datele necesare unui examen deja planificat pe perioadă a plus/minus trei zile față de data selectată la planificarea care urmează. Odată returnate , sunt aplicate anumite reguli :

Să nu mai fie un alt examen planificat pentru grupa selectată pe perioada respectivă.

Profesorul să nu fie ocupat cu alt examen in acea dată/oră.

Asistentul să nu fie ocupat cu alt examen la acea dată/oră.

Sala să nu fie ocupată la aceeași dată/oră.

Toate aceste reguli se verifica prin a se compara datele examenelor deja planificate pe perioada a plus/minus trei zile fata de data selectata , cu datele selectate de către utilizator din interfața grafica. Dacă în procesul de comparație nu a intervenit nici o regulă, examenul este planificat folosind PlanificaExamenBackGroundTask.

3.2.3 StudentMainActivity

Clasa StudentMainActivity conține două obiecte de tipul BackGroundTask care sunt folosite în a lansa în fundal fire de execuție pentru a returna din baza de date examene planificate(recent) în ordinea planificării și examene în ordinea cronologică după dată.

Examenele sunt afișate folosind obiectul expListView de tip ExpandableListView . Acest „view” afisează câmpuri într-o listă verticală pe două niveluri. Grupuri care apoi pot fi extinse individual pentru a le afișa copii(children). Astfel , listele groupList și childList sunt folosite pentru a memora numele materiei pentru care se susține examenul, respectiv detaliile despre acel examen. ColectieExamen este un obiect de tip Map care funcționează asemănător unei clase de tip dicționar, cheie-valoare. Este folosită pentru a memora toate grupurile(examenele) care trebuie afișate.

Metoda onCreate(..) inițializează activitatea. Cel mai important este că aici se setează layout-ul care definește interfață. Această metodă este apelată în momentul lansării aplicației, împreună cu GetExameneRecente(), astfel studentul autentificat să vizualizeze direct examenele adăugate recent. În GetExameneRecente() se realizează conexiunea la MySQL prin getExamenRecenteBackGroundTask.execute(…), trimițând ca și parametru Grupa din care face parte studentul autentificat.

GetExamenCronologic() este apelat în momentul apăsării butonului pentru a vizualiza examenele cronologic . Funcționează pe același principiu că și GetExameneRecente().

CreateGroupList() populează expListView în momentul returnării tuturor examenelor din baza de date.

3.2.4 ProfesorMainActivity

ProfesorMainActivity funcționează pe același principiu ca și StudentMainActivity , diferența fiind parametru trimis pentru fiecare BackgroundTask. În loc de Grupa va fi trimis numele profesorului iar selecția se va face in funcție de acel nume. Din motive de simplitate a implementării se trimite numele și nu id-ul profesorului.

3.2.5 Session

Clasa Session folosește obiectul prefs de tip SharedPreferences din Android SDK. Un obiect de acest tip indică un fișier care conține perechi cheie-valoare , utilizând metode simple pentru a le citi/scrie. Fișierul de tip SharedPreferences se află pe dispozitivul în care este instalată aplicația. SharedPreferences.Editor este o interfață folosită pentru a modifica valori unui astfel de obiect precum prefs.

Metodele de tip set sunt definite de dezvoltator și nu de SDK. În momentul unei autentificări valide , SetLoginTrue() va fi apelat iar apoi getUserLoggedIn() va returna true. Astfel în prefs se va scrie aceste detalii , iar aplicația va ști dacă utilizatorul este conectat sau nu , chiar și când această este oprită și repornită . Restul detaliilor utilizatorului sunt scrise și citite din prefs folosind restul metodelor de tip „set” și „get”.

setUserDetails(…) și getUserDetails() sunt folosite pentru a popula secțiunea Detalii Student sau [anonimizat] din StudentMainActivity respectiv ProfesorMainActivity.

Aplicația deține toate informațiile despre utilizator până când acesta apasă pe butonul Log Out . Astfel , tot ce este scris în fișierul prefs este șters iar aplicația revine la activitatea de Login(autentificare).

3.2.6 BackGroundTask

În BackGroundTask(BT) se află clasele care moștenesc AsyncTask din SDK-ul Android. AsyncTask-urile folosesc fire de execuție care rulează în fundal fără a interacționa cu interfața. Scopul lor este de a rulă fără că utilizatorul să își dea seamă , fără a apărea întreruperi în interfața grafică. Metodele din această clasă sunt autogenerate de AsyncTask. De exemplu, în momentul ce unui obiect de tip BT îi este apelată metoda „.execute(…)”, onPreExecute() din BT rulează înaintea doInBackGround(…). Scopul ei este de a inițializa anumite obiecte/variabile care vor fi utilizate mai departe . În cazul nostru, de obicei doInBackGround (…) primește ca parametrii variabile de tip string care le folosește la a determina ce conexiune să facă cu bază de date MySQL : să primească date , să trimită date sau ambele. Prin a trimite date s-a folosit metoda de a face o cerere prin „POST” , iar pentru a primi date, „GET”. La finalul unei cereri , doInBackground(…) va returna un strîng care reprezintă datele de tip JSON primite din baza de date MySQL prin intermediul scripturilor PHP.

Acest string de tip JSON este transmis apoi la onPostExecute(String result) . Fiecare JSON transmis de scripturile PHP , conține o pereche exemplu : {„code”:”….”}. În funcție de acel code, onPostExecute(…) știe cum să interpreteze mai departe datele JSON . ProgressDialog este folosit pentru a afișa o fereastră mică care indica progresul prin interfața grafică. De exemplu, metoda showDialog() indică faptul că aplicația incearcă să se conecteze la serverul MySQL de fiecare dată când se face o cerere.

Obiectele de tip AdminMainActivity și StudentMainActivity sunt utilizate pentru a putea avea acces la metode din activitătile admin respectiv student.

3.2.7 DateJson

3.2.7 date_json & DateJsonStorage

Modulul DateJson conține două clase DateJsonStorage(DS) și date_json(DJ). DS este format din vectori de obiecte de tip DJ. Fiecare vector este folosit pentru a ține minte informații referitoare la specializare ,grupă, semestru ,materie, An, Sală , Examene . De exemplu , în momentul în care au fost returnate date JSON referitoare la Sală din bază de date MySQL, în metoda onPostExecute() din BackGroundTask vor fi interpretate și apoi salvate în DS .

Ex: DateJsonStorage.dateJsonSala[i].setNume(element.get("nume_sala"));

DateJsonStorage.dateJsonSala[i].setID(element.get("sala_id"));

DateJsonStorage.dateJsonSala[i].setCapacitate(element.get("capaictate"));

Desigur, pentru Sală sunt îndeajuns a se apela doar 3 metode din DJ, dar pentru un alt caz , cum ar fi informații pentru un examen planificat sunt nevoie de apelări a mai multor metode.

Vectorii de tip DJ sunt declarați statici pentru a putea fi vizibili și la fel pentru tot restul aplicației.

3.2.8 ExpandableListAdapter [8]

ExpandableListAdapter este un modul preluat de pe web [8] și adaptat la proiectul curent. Este utilizat pentru popularea containerelor de tip ExpandableListView folosite la afișarea examenelor planificate. Inițial a fost construit pentru afișarea a mai multor modele de laptopuri.

În Figura 3.3 [8] , este evidențiat cum este structurat modulul , format în principal dintr-o structură de tip Listă și Map . Map este folosit pentru a stoca Grupurile(Nume Firme Laptopuri) care la rândul lor fiecare Group conține un Child List reprezentând o lista de detalii(modele laptop de la firmă respectivă).În cazul aplicației noastre , Group reprezintă ce examen este planificat ,iar Child List detaliile despre examenul respectiv. Pentru a ști cum sa fie afișate cele două nivele in interfața grafică , se folosesc două fișiere

de tip .xml : group_item.xml și child_item.xml. Astfel , interfața știe să își preia caracteristici precum înălțimea, lățimea, mărimea textului , culoarea etc.

3.3 Scripturile PHP

Conexiunea la baza de date se face prin cereri de tip „POST” sau „GET” prin intermediul aplicației. Fiecare cerere este interpretată de fișierele PHP corespunzătoare. Scopul fișierelor .php in proiectul acesta este de a extrage informații din baza de date MySQL și a le returna înapoi aplicației in format JSON. Mai departe totul este interpretat de către modulul BackGroundTask din aplicație.

Figura 3.4 PHP Script

De exemplu , când va intra in execuție getExamenCronologicBackGroundTask.execute(param), o cerere va fi trimisă scriptului get_examen_planificat_student_cronologic.php care va returna toate examenele studentului autentificat in ordine cronologica după data. Daca data examinării a trecut , atunci scriptul nu va returna examenele respective.

connect.php este un script esențial in realizarea conexiunii la baza de date indicând un cont cu nume și parolă , numele bazei de date și locația acesteia . Acest script este inclus in toate celelalte fișiere te tip .php .

3.4 Baza de date MySQL

Sistemul de gestiune a bazelor de date pe care l-am ales a fost MySQL. Motivele au fost compatibilitatea cu majoritatea sistemelor de operare și familiaritatea cu interfața phpMyAdmin.

numele bazei de date

tabelele utilizate pentru Planificarea . unui examen .

Figura 3.5 Tabele Baza de date

În Figura 3.5 se observă că structura bazei de date este relativ simplă. Tabela an_universitar conține un câmp referitor la anul I,ÎI,III sau IV și este legată de tabela grupă prin câmpul an_id.

Tabela grupă este folosită pentru a menține informații referitoare la numele grupei, din ce specializare face parte și ce an. Este legată de specializare, an_universitar și users.

materie reprezintă tabela ce deține informații despre specializarea din care face parte, numele profesorului și asistentului , tipul examinării materiei și semestrul din care face parte. Este legată de tabela specializare, sală și semestru.

sala menține informații referitoare la numele sălii și nr. locuri .Este legată de materie.

semestru tine informații despre anul din care face parte semestrul, acestea fiind structurate ca fiind 8 semestre. Ex. AN I, sem 1= Sem I, AN III, sem 2= Sem.6. Este legata de materie.

specializare are un câmp reprezentând numele specializării . Ex. Ingineria Sistemelor Multimedia (ISM). Este legată de materie și grupă.

tip_user reprezintă cele trei tipuri de utilizatori ai aplicației. 1.Student, 2. Profesor, 3.secretara. Este legata de users.

users reprezintă tabela cu utilizatorii înregistrați in baza de date, împreună cu detaliile personale fiecăruia. Este legata de grupa și tip_user.

Tabela planificări reprezintă toate informațiile referitoare la o planificare rezultată din toate celelalte tabele. Din motive de simplitate a implementării, nu am legat tabela cu restul folosind id-uri ci am transformat totul in string .

UI

După cum am menționat mai sus, aplicația este structurată pe trei activități principale: Student, Profesor și Secretara. Fiecare dintre cele trei conține o interfață grafică generală , având diferit secțiunile din meniu. Meniul folosit este standard , tipic Android, preluat din Android SDK. O scurtă structură a interfeței este evidențiat in Figura de mai jos.

Figura 3.6 Mockup Meniu StudentMainActivity

4. Implementarea Modulelor

In prima idee , proiectul a fost gândit pe principiu unei pagini Web, care apoi sa fie accesat de o aplicație Android. Totul era bazat pe acel site și aplicația care nu făcea decât sa acceseze site-ul și sa-l afișeze într-un WebView (container din SDK-ul Android pentru a afișa pagini web). În scurt timp am constatat că aplicația care mi-am propus să o realizez nu era decât un fel de browser pentru Android ,iar acest lucru nu era ceea ce îmi doream.

In continuare voi prezenta componentele proiectului ,din ce sunt formate, cum au fost implementate si cu ce medii de dezvoltare au fost dezvoltate, totul având responsabilitate proprie. Din motive de simplitate in anumite circumstanțe, unele componente au fost implementate utilizând metode mai convenabile. Din lipsa unor resurse, implementarea unei baze de date locală pe dispozitivul Android nu s-a putut realiza până la final. Toate modulele au fost realizate in iterații , in timp aplicând refractoring pentru reorganizarea tuturor variabilelor și metodelor. Aplicația este structurată pentru trei tipuri de utilizatori: 1.Student , 2.Profesor, 3.Secretara.

4.1 Implementare Aplicație Android + Scripturi PHP

4.1.1 Logo și Denumire Aplicație

Pentru logoul aplicației s-a folosit o iconița preluată de pe web [10] și adaptată puțin in stilul Android. Acesta sugerează un om/student, ne-absolvent încă, care citește dintr-o carte, reprezentând studiul pentru un examen. Pentru denumire am ales o prescurtare din limba engleză .

OES – Online Exam Scheduling (Planificator online de examene).

4.1.2 Autentificare

4.2.2.1 Autentificare Validă

In momentul în care un utilizator lansează aplicația și nu s-a mai autentificat pana acum, poate sa se autentifice folosind un cont oferit de universitate la scurt timp de înscriere in facultate in anul I. Contul consta într-o adresă de email și parolă. Pentru simplitate in teste, s-au folosit parole de un caracter.

Tot in momentul lansării aplicației , Activitatea LoginActivity va executa după toate inițializările elementelor grafice, următorul cod:

Figura 4.1

sesiune.getUserLoggedIn() returnează true daca pentru o autentificare din trecut nu a fost apăsat butonul de Log Out , iar false in caz contrar.

sesiune.getTipConectat() returnează un string conținând una din cele trei cifre:1 , 2 sau 3 .

Acest cod executat verifica daca mai exista deja o sesiune existentă și ce tip de utilizator este deja autentificat: 1.Student , 2.Profesor, 3.Secretară . Daca una dintre aceste condiții este îndeplinita , va fi lansată mai departe activitatea corespunzătoare utilizatorului deja conectat. In caz contrar , interfața pentru autentificare va fi afișată.

Obiectul „sesiune” folosește clasa Session care utilizează obiectul prefs de tip SharedPreferences din Android SDK. Un obiect de acest tip indică un fișier care conține perechi cheie-valoare , utilizând metode simple pentru a le citi/scrie. Fișierul de tip SharedPreferences se află pe dispozitivul în care este instalată aplicația. SharedPreferences.Editor este o interfața folosită pentru a modifica valori unui astfel de obiect precum prefs.

In momentul autentificării valide a unui utilizator , metodele SetLoginTrue() și SetTipConectat() din clasa Session vor fi apelate.

Toate acțiunile de tip “write” in fișierul prefs se realizează prin apelurile metodelor respective urmat de .commit() sau .apply(), acestea fiind metodele clasei SharedPreferences din Android SDK.

SetLoginTrue() , scrie local in fișierul prefs din Android cum că o autentificare este validă , folosind cheia "login_status" cu valoarea true de tip boolean . setTipConectat(String tip) , scrie in fișierul prefs tipul utilizatorului conectat (1,2 sau 3) , primit ca valoare in momentul apelării metodei. Este folosita cheia “tip” cu valoarea tip(String) . Pentru a cunoaște tipul utilizatorului care încearcă sa se autentifice , se executa următorul cod din LoginActivity:

Figura 4.3

In Figura 4.3 avem String email si password care reprezintă datele completate de către utilizator în interfața grafica , String method care reprezintă “cheia” “login” identificata apoi in fundal de către modulul BackgroundTask pentru a lansa fire de execuție în scopul de a returna informații din baza de date MySQL.

backgroundtask.execute(method,email,password) primește ca parametrii cheia folosită, emailul si parola utilizatorului cu care apoi creează un nou fir de execuție folosind acei parametrii (Figura 4.4).

Figura 4.4 cod Java Android clasa BackGroundTask

În Figura 4.4 avem method care reprezintă parametrul 0 primit în momentul apelării metodei .execute, login_name și login_password parametrul 1 respectiv parametrul 2, iar login_url care semnifica adresa url a scriptului PHP aflat local pe serverul Wamp, destinat extragerii informațiilor din baza de date MySQL.

Se creează conexiunea către scriptul PHP folosind obiectul de tip HttpURLConnection , prin login_url.

Se setează metoda de cerere „POST” deoarece trimitem email și parola către script care apoi trimite la server. httpURLConnection.setRequestMethod("POST");

Setăm pe true faptul că trimitem și primim informații de la server.

Creăm un obiect de tip OutputStream pentru a trimite un stream la server.

Folosind un BufferedWriter setăm tipul de encodare UTF-8 pentru outputstream.

În String data scriem datele noastre primite ca parametru 1 și 2 pe principiu cheie – valoare ca apoi sa poată fi interpretat de scriptul PHP. Exemplu: cheia „login_name” cu valoarea de tip String login_name.

Scriem String data folosind bufferedWriter. bufferedWriter.write(data);

Trimitem bufferedWriter. bufferedWriter.flush();

Închidem bufferedWriter. bufferedWriter.close();

Închidem outputStream. outputStream.close();

În acest moment datele au fost trimise către scriptul PHP care la rândul lui trimite înapoi un răspuns de tip JSON.

Creăm un obiect de tip inputStream pentru a băga informațiile de la server.

Creăm un obiect de tip bufferedReader pentru a citi informațiile din inputStream ,folosind Unicode „iso-8859-1” deoarece primim informații de la un script PHP utilizat în general pentru cereri pentru pagini web.

atâta timp cât se pot citi date din bufferedReader , în variabila răspuns este scrisă fiecare linie citită din buffer .

se închide bufferedReader. bufferedReader.close();

se închide inputStream. inputStream.close();

se închide conexiunea httpURLConnection. httpURLConnection.disconnect();

se returnează răspunsul de la server. return raspuns;

În momentul apelării funcției bufferedWriter.flush(); , login_name si login_pass introduse de utilizator în câmpurile din interfața grafică, vor fi trimise scriptului php login.php prin login_url de la HttpURLConnection. Scriptul login.php arată cam așa:

Figura 4.5 cod PHP din scriptul login.php

In Figura 4.5 , connect.php este un script esențial in realizarea conexiunii la baza de date indicând un cont cu nume și parolă , numele bazei de date și locația acesteia . Acest script este inclus în toate celelalte fișiere te tip .php .

$user_name=$_POST["login_name"]; și $user_pass=$_POST["login_pass"]; sunt variabilele în care se vor stoca informațiile , în cazul acesta numele și parola primite prin „POST” de la aplicație . Modul de a le identifica este cheia "login_name" sau "login_pass" introduse anterior in BackGroundTask din aplicație.

În variabila $sql_query este selectul corespunzător pentru returnarea întregii înregistrări din baza de date, unde câmpurile email și parola corespund cu datele venite prin „POST”.

$result execută selectul de mai sus folosind $con (conexiunea la MySQL) din connect.php

Mai departe , daca există înregistrări după acele câmpuri , se vor salva in variabile separate fiecare detaliu necesar despre utilizatorul respectiv preluate din baza de date MySQL , tabela users Figura 4.6.

Figura 4.6 Tabela users din MySQL

Câmpurile extrase sunt împărțite pe doua categorii și o categorie care reprezintă răspunsul de la server, pozitiv sau negativ. În variabila $code este scris dacă autentificarea a fost cu succes sau cu eșec. În cazul în care este cu succes , datele vor fi trimise și apoi interpretate de aplicația Android.

Cele trei categorii care se trimit sunt de fapt trei array’uri $response, $credentials și $user_details , reprezentând răspunsul de la server , datele de autentificare alte utilizatorului și ultimul array, datele personale .

Astfel , la final scriptul va face un echo de tip JSON , reprezentând un array de array’uri cu cele trei categorii ca in Figura 4.7 .

Figura 4.7 echo JSON login.php

Datele de tip JSON din Figura 4.7 vor fi introduse in InputStream din BackGroundTask-ul anterior (Figura 4.4) și returnate într-un final in variabila „raspuns”. Acest JSON conține și perechile cheie-valoare necesare pentru a ști tipul de utilizator care se conectează și dacă conexiunea a fost cu succes..

După ce „raspuns” a fost returnat , mai departe se va apela metoda onPostExecute(String raspuns) ca va interpreta toate datele JSON in funcție de cele doua perechi.

Codul executat este următorul:

Figura 4.8 onPostExecute(..)

Parametru primit la apelare reprezintă String’ul cu datele returnate din baza de date. Interpretarea datelor se realizează in funcție de ordinea array’urilor din String. Prima oară se extrag din „server_response” , cel mai important informațiile după cheia numita „code” pentru a ști mai departe de la ce script au venit datele și cum trebuie interpretate. Array’urile se păstrează folosind obiecte de tip JSONArray , apoi fiecare element cu JSONObject.

In cazul autentificării valide , codul primit este „login_true”. Folosind tot obiecte de tip JSONArray și JSONObject se salvează datele de autentificare (email, nume, prenume, tip , grupa_id , user_id) și datele personale ale utilizatorului ( cnp, telefon , adresa , data_nasterii, loc_nastere, cetatenie , religie). Desigur, toate acestea puteau fi puse într-un singur JSONArray , dar pentru un mod mai organizat s-a împărțit pe categorii.

După ce toate datele au fost introduse in variabile și obiecte , se creează o noua sesiune de tip Session și se setează fiecare informație folosind metodele specifice din Session. Datele personale ale utilizatorului vor fi folosite ulterior în activitatea StudentMainActivity , respectiv ProfesorMainActivity.

In continuare , ca și in momentul lansării aplicației , se verifica faptul ca autentificarea este valida (true) și ce tip de utilizator s-a autentificat: 1.Student , 2.Profesor, 3.Secretară . Când una dintre aceste condiții este îndeplinită , va fi lansată mai departe activitatea corespunzătoare utilizatorului și așa se poate considera ca unul dintre cele trei persoane este autentificat și poate utiliza aplicația mai departe. .

4.2.2.2 Autentificare Invalidă

Daca datele introduse de utilizator nu corespund cu datele din baza de date MySQL , scriptul login.php va returna tot un Array de tip JSON , având codul „login_false” care apoi va fi tratat corespunzător . Astfel, se va executa următorul cod:

Figura 4.9 login_false

Codul „login_false” va îndruma aplicația în a afișa un mesaj de alertă utilizatorului în care specifica cum că autentificarea este nereușita și sa încerce din nou. Mesajul de eroare afișat este preluat din datele de tip JSON venite de la server/scriptul login.php . Mesajul se afla in Array’ul cu cheia „message” . Figura 4.10

Figura 4.10 Eroare Autentificare

4.1.3 AdminMainActivity – Planificare Examen

În cazul autentificării cu un cont de secretară , se va lansa AdminMainActivity conform Figurii 5.8 , afișând o interfață grafică specifică aplicației pentru secretara. Ca și ecran de pornire , utilizatorului ii va fi afișat secțiunea de examene planificate recent. La apăsarea butonului care indica crearea unei noi înregistrări, poziționat dreapta-jos , un nou „layout” pentru planificare(Adaugă Ex. ) va trece din starea „gone” în „visible” Figura 4.11, iar butonul împreuna cu „layout”ul anterior vor dispărea.

adauga_ex_layout.setVisibility(View.VISIBLE);

Datorită dimensiunii înguste a ecranului unui dispozitiv Android , cel mai convenabil mod de a selecta anumite informații încadrate pe categorii , este prin utilizarea unui sistem de meniuri care folosește spinner Android (drop-down list) Figura 4.11 . Pentru selectarea ora/data s-au folosit containerele TimePicker și DatePicker din Android SDK.

Fiecare drop-down list reprezintă o categorie . Fiecare categorie conține mai multe elemente . De exemplu, in cazul nostru , din categoria Specializare se poate alege dintr-o listă , un element reprezentând o anumita specializare. Implicit este selectat primul element din lista.

Elementele din fiecare categorie sunt preluate din baza de date MySQL . O mare parte din popularea listelor drop-down se realizează secvențial, cu excepția categoriei sălii, anului și a specializării , deoarece extragerea lor nu depind de nici o condiție. Ultimele două categorii reprezintă data și ora actuală a dispozitivului Android.

Popularea secvențiala se realizează in felul următor:

În momentul inițializării „layout-ului” , prima oară se populează specializarea, anul , sala și se selectează implicit prima înregistrare din fiecare lista. Aici apare secvențialitatea.

După ce Specializarea și Anul au fost selectate , id-ul specializării și al anului sunt folosite pentru a popula mai departe categoria Grupa cu grupele corespunzătoare specializării, in funcție de an . Anul mai este folosit pentru a popula Semestru. Semestru depinde de an deoarece în baza de date , există tabela an_universitar cu câmpurile I,II,II,IV , iar fiecărui an ii sunt asociate doua semestre: De exemplu , pentru anul I corespund semestrele 1 și 2, pentru anul II semestrele 3 și 4. Astfel, anul universitar este încadrat pe opt semestre , respectiv patru ani. Popularea materiilor depind de Specializarea aleasă și semestru ales iar Sala nu depinde de nici un alt factor.

Popularea secvențiala ca și implementare se realizează in felul următor:

Elementul selectat din lista cu specializări este preluat folosind metoda .setOnItemSelectedListener(…) pentru spinner din Android SDK. Următorul cod se va executa:

Figura 4.12 On Select Spinner Specializare

După selecție , se verifica daca elementul de pe poziția „i” din lista corespunde cu elementul de pe aceeași poziție din vectorul de specializări primit din baza de date. Această verificare se realizează pentru a putea extrage id-ul specializării selectate , deoarece spinnerul din Android SDK nu poate stoca și id-ul elementelor din listă. Astfel , după identificarea specializării , se lansează fire de execuție in fundal folosind BackGroundTask , asemeni Figurii 5.4 împreuna cu 5.8 , pentru a putea popula mai departe Grupa și Materia, bazat pe id-ul specializării.

La momentul selectării unei specializări , categoriile pentru an și semestru sunt deja populate din momentul lansării layout’ului.

Popularea secvențiala se realizează asemănător pentru fiecare categorie.

Pentru extragerea informațiilor din baza de date, s-au folosit următoarele scripturi PHP corespunzătoare cererii SQL.

Specializare: get_specialziare.php.

Cererea pentru selectarea specializării nu depinde de nimic , deci nu este pusă nici o condiție.

An: get_an.php

Cererea pentru an este la fel ca pentru specializare.

Grupa:get_grupa.php

In $var1 și $var2 se stochează id-ul specializare respectiv id-ul anului venite prin „POST”, conform Figurii 4.4 și 4.12, iar apoi se realizează cererea SQL in funcție de cele doua variabile. Din tabela grupa este extrasă capacitatea (nr locuri ) pentru a putea fi comparat numărul studenților cu numărul de locuri din sală. Pentru asta, in corpul .setOnItemSelectedListener(…) din spGrupa(Spinner Grupa)este executat următorul cod:

Dacă Nr. Studenți mai mare ca Nr.Locuri sală, utilizatorul este notificat printr-o alertă . Aceeași alertă este afișată și în cazul selectării unei Sali cu Nr locuri mai puține decât nr Studenți Grupă.

Semestru:get_semestru.php

In $var se stochează id-ul anului venit prin POST , conform Figurii 4.4 și 4.12, iar apoi se realizează cererea SQL bazată pe acea variabila.

Materia:get_materie.php

În cele doua variabile se stochează id-ul specializării, respectiv id-ul semestrului venite prin POST, conform Figurii 4.4 și 4.12, iar apoi se realizează cererea SQL bazată pe aceste variabile.

Sala: get_sala.php

Cererea pentru sală este asemeni cererii anului și specializării.

După ce toate categoriile au fost alese și Data/Ora au fost setate corespunzător , la apăsarea butonului de „Adauga Examen” se va crea un nou fir de execuție de tip BackGroundTask cu toate datele selectate din interfață (VerificaPlanificareExamenBackGroundTask.execute(method,Specializare,Grupa,Materie,Profesor,Asistent,Tip_examinare,Data,Ora,Sala);), în scopul de a verifica daca planificarea poate avea loc in funcție de anumite restricții :

Planificarea unui examen pentru o grupă trebuie sa fie la interval de 3 zile înainte sau după data unui alt examen.

Se verifică ca profesorul să nu fie prezent la un alt examen in acea dată și oră.

Se verifică ca asistentul să nu fie prezent la un alt examen in acea dată și oră.

Se verifică ca sala selectată sa nu fie ocupată la aceeași dată/oră.

Verificarea acestor restricții se realizează în aplicație prin cod Java și nu prin scripturi PHP. La momentul apelării VerificaPlanificareExamenBackGroundTask.execute(..) , se folosește scriptul verifica_planificare.php care primește ca parametru doar data selectată de utilizator și apoi se extrag toate informațiile necesare din baza de date la interval de +/- trei zile de la data primită prin POST. Figura 4.13 . Code returnat de acest script este „verifica_planificare”.

Figura 4.13 verifica_planificare.php

Astfel , toate informațiile pe acele șase zile sunt returnate și stocate în aplicație folosind modulul DateJsonStorage. Ca și pentru restul informațiilor , stocarea se face in funcția onPostExecute(..) din BackgroundTask . In cazul curent , codul pentru interpretare returnat de scriptul PHP se numește „verifica_planificare”. Fiecare câmp este salvat in DateJsonStorage.DateJsonExameneVerificare[i].

După cum se poate observa in Figura 4.14 logica de verificare a restricțiilor este in felul următor:

Se inițializează o variabila poateAdaugaExamen de tip Boolean pe true.

Se compara fiecare grupă de pe cele șase zile cu grupa selectată de utilizator, iar dacă se găsește o potrivire , poateAdaugaExamen trece pe false.

Se compară dacă un profesor apare in cele șase zile in aceeași data si același interval de examinare (3 ore). Daca există, poateAdaugaExamen se setează pe false.

Figura 4.14 VerificaPotAdaugaExamen();

Se compară dacă un asistent apare in cele șase zile in aceeași dată si același interval de examinare. Dacă exista, poateAdaugaExamen se setează pe false.

Se compară dacă sala selectată de utilizator este ocupată în aceeași dată si oră cu profesorul sau asistentul. Dacă există, poateAdaugaExamen se setează pe false.

După ce toate verificările au fost făcute si poateAdaugaExamen este pe true ,se creează un alt fir de execuție folosind BackGroundTask in care se trimit toate informațiile selectate de utilizator , în baza de date unde se creează o noua înregistrare .În caz contrar, se afișează un mesaj de alertă pentru cazul respectiv, iar poateAdaugaExamen este setat pe false.

4.1.4 StudentMainActivity – Vizualizare Examene

În cazul autentificării cu un cont de student , se va lansa StudentMainActivity conform Figurii 5.8 , afișând o interfață grafica specifica aplicației pentru student. Ca și ecran de pornire , utilizatorului ii va fi afișat secțiunea de examene planificate recent. La accesarea meniului lateral și apăsarea butonului pentru secțiunea de „vizualizare examene”, un nou „layout” pentru afișarea examenelor utilizatorului va trece din starea „gone” în „visible” Figura 4.11, iar meniul împreuna cu „layout”ul anterior vor dispărea. Examenele din aceasta secțiune sunt afișate cronologic, după dată.

Figura 4.15 layout Viz.Examene

Evident, examenele sunt preluate in funcție de grupă din care face parte utilizatorul. Se poate observa ca intervalul dintre examenele planificate este de 3 zile, conform Figurii 5.14.

Afișarea lor se face utilizând ExpandableListView [8]. In momentul returnării datelor din baza de date , se apelează metoda studentMainActivity.createGroupList(). Containerele de tip ExpandableListView sunt structurate pe doua nivele. În corpul metodei se creează un nou „LinkedHashMap” pentru a memora examenele, adică GroupList și childList și un groupList de tip ArrayList pentru numele materiilorFigura 4.16 . Group reprezintă ce examen este planificat ,iar Child List detaliile despre examenul respectiv.

Pentru a ști cum să fie afișate cele doua nivele in interfața grafică , se folosesc doua fișiere de tip .xml : group_item.xml și child_item.xml. Astfel , interfața știe să își preia caracteristici precum înălțimea, lățimea, mărimea textului , culoarea etc.

Figura 4.16 createGroupList();

4.1.5 ProfesorMainActivity – Vizualizare Examene

In cazul autentificării cu un cont de profesor , se va lansa ProfesorMainActivity conform Figurii 4.8 , afișând o interfață grafică specifică aplicației pentru profesor. Ca și ecran de pornire , utilizatorului ii va fi afișat secțiunea de examene planificate recent. La accesarea meniului lateral și apăsarea butonului pentru secțiunea de „vizualizare examene”, un nou „layout” pentru afișarea examenelor utilizatorului va trece din starea „gone” in „visible” Figura 4.11, iar meniul împreuna cu „layout”ul anterior vor dispărea. Examenele din aceasta secțiune sunt afișate cronologic, după dată.

Implementarea este asemănătoarea cu cea de la StudentMainActivity (4.2.4) , diferența fiind parametrul trimis către scriptul PHP. Extragerea informațiilor se va face in funcție de numele profesorului autentificat.

4.1.6 UI

Modulul UI conține toate activitățile și clasele care asamblează interfață cu utilizatorul. Fiecare activitate reprezintă un ecran al aplicației , scopul lui fiind interacțiunea cu utilizatorul.

Orice activitate din aplicație moștenește o clasă numită Activity din Android SDK . Prima activitate în care intră aplicația este tot timpul LoginActivity unde, dacă nu este deja autentificat un utilizator , este afișata o imagine cu logo-ul aplicației si câmpurile care trebuie completate pentru autentificare. La fiecare lansare, LoginActivity verifică in fundal daca utilizatorul este autentificat deja sau nu. Daca este , se pornește mai departe activitatea corespunzătoare utilizatorului.

Fiecare activitate folosește un meniu standard din Android SDK numit „Navigation Drawer” care constă într-un meniu lateral din care se pot selecta opțiuni/câmpuri care oferă orice funcționalitate, definita de dezvoltator.

In Figura 4.17 se observă meniul activității studentului. Este structurat pe doua nivele :

Primul nivel conține in mare parte detalii personale , cum ar fi logoul aplicației, câmp cu numele și prenumele preluate din baza de date, email , apoi trei câmpuri pentru a lansa alte layout-uri pentru date personale, specializare și schimba parola. Din motive convenabile, specializare și schimba parola nu au fost implementate.

Al doilea nivel se axează pe examene, conținând câmpuri pentru a vizualiza examenele recent adăugate și vizualizarea în ordine cronologică.

Ultimul câmp reprezintă butonul de Log Out , care în momentul apăsării lui , utilizatorul va fi deconectat din aplicație și revenit la activitatea LoginActivity pentru autentificare.

Figura 4.17 Meniu Navigation Drawer StudentMainActivity

4.1.7 Buton Log Out

Pentru ca utilizatorul sa se poată deconecta de la aplicație , se va apăsa butonul de Log Out din meniul „Navigation Drawer” Figura 4.17 unde se va apela metoda sesiune.logoutUser();

din clasa Session . Figura 4.18

Figura 4.18 Session- logoutUser();

În metoda logoutUser() nu se executa altceva decât metodele .clear() și .commit() din clasa SharedPreferences pentru a șterge tot fișierul prefs de pe dispozitivul Android . Astfel , nu mai există nici o informație despre vreun utilizator , deci getUserLoggedIn() apelat la lansarea aplicației va returna false.

4.2 Implementare baza de date MySQL

Sistemul de gestiune a bazelor de date pe care l-am ales a fost MySQL. Motivele au fost compatibilitatea cu majoritatea sistemelor de operare și familiaritatea cu interfata phpMyAdmin. Structura tabelelor a fost realizată într-un mod cat mai convenabil și ușor de abordat Figura 4.19.

Câmpurile din fiecare tabelă au caracteristicile lor specifice. De exemplu , pentru id-uri se folosește tipul int iar pentru nume se folosește tipul String. Din motive de implementare ,în multe cazuri se întâmplă ca într-un câmp sa fie un nume și nu un id , iar doua câmpuri dintr-o tabelă să conțină aceleași informații. De exemplu, tabela grupa conține câmpul cu nume_grupa , și nume-short, ambele reprezentând același nume , diferența fiind că la nume_grupa mai este scris și specializarea și anul din care face parte grupa ,”210 (ISM) AN I” , scopul lor fiind de a ajuta secretara la planificare în interfața grafică. Nume-Short conține doar numele grupai „210”.

Figura 4.19 Structura Bazei de date oesdb

5.Concluzii și dezvoltări ulterioare

Scopul acestui proiect a fost de a aborda o tehnologie foarte des utilizată la momentul actual, pentru a dezvolta o aplicație in sprijinul secretar , profesorilor și studenților , fără a implica alte dispozitive suplimentare față de cele utilizate în activitatea noastră zilnică. Prin faptul că aplicația se comporta diferit in funcție de utilizatorul conectat, se poate spune ca înglobează trei tipuri de aplicații diferite, independente una de cealaltă. De exemplu, dacă se scoate modulul pentru un anumit tip de utilizator , aplicația va putea fi utilizată de celelalte doua tipuri. Deci, fiecare tip de aplicație in parte urmărește obiective proprii esențiale. Astfel, pentru un utilizator identificat ca și secretară , aplicația va îndeplini obiectivul planificării unui examen , având următoarele restricții :

Planificarea unui examen pentru o anumită grupă trebuie să respecte intervalul de minim 3 zile între acesta și un alt examen.

Profesorul să fie disponibil la data și ora aferente examenului.

Asistentul să fie disponibil la data și ora aferente examenului.

Sala să fie disponibilă la data și ora aferente examenului și de asemenea să îndeplinească numărul de locuri necesare grupei.

Pentru fiecare materie se poate planifica cel mult un examen pe sesiune , pentru o anumită grupă.

Dacă utilizatorul se autentifică ca și student sau profesor, obiectivul esențial urmărește afișarea examenelor in ordine cronologică . In plus, in momentul în care data examenului a fost depășita , înregistrarea respectivă nu va mai fi afișată.

Astfel , versiunea curentă poate fi considerată baza unei soluții utile in sprijinul universitar , cu scopul de a aborda o lume moderna din punctul de vedere tehnologic. Următoarele obiective pot fi considerate ca implementări ulterioare:

Implementarea unui sistem de alerte pentru a notifica studentul sau profesorul când are un examen nou planificat

Pentru Student, in secțiunea de vizualizări examene să-i fie afișat dacă a promovat laboratorul sau nu

La selecția datei și a orei să fie afișate doar sălile disponibile pentru ora aia

Pentru student, implementarea unui catalog online

Pentru Studenți din anul I , afișare mesaj/videoclip de bun venit

Un chat pentru Profesori și unul pentru Studenți.

Presupunând că aplicația va fi pusă in funcțiune într-un stadiu cu funcționalități multiple , cum ar fi un chat, se dă următorul Scenariu: Un student X se află la facultate in primele săptămâni din anul I . Își instalează aplicația ca o alegere personală, de acasă sau oriunde. Se autentifică folosind contul oferit de facultate. Este întâmpinat cu mesajul de bun venit și scurtă prezentare a facultății. Trec câteva săptămâni și vrea sa ia legătura din diferite motive cu unul dintre colegi. Aici apare o problema des întâlnita . În primele săptămâni de facultate , de multe ori se întâmpla sa se uite cum îl cheamă pe colegul Y sau Z, dar se știe cum arata. Astfel , Studentul X poate accesa aplicația OES , rubrica de chat , pentru a lua legătura cu colegul Y sau Z prin a-l identifica după pozele și numele de profil al tuturor colegilor din grupa în care face parte.

6. Bibliografie și Webliografie

Cărți despre tehnologii, articole

[1] Guy Harrison,Steven Feuerstein, MySQL Stored Procedure Programming,Editura O’Reilly Media, ISBN-13: 978-0-596-10089-6 , 2006, USA

[2] Ben Smith, Beginning JSON, Editura Apress, ISBN-13 (electronic): 978-1-4842-0202-9 , 2015, California

[3] Matt Doyle, Beginning PHP 5.3, Editura Wrox , ISBN: 978-0-470-41396-8, 2010, USA, Indianapolis, Indiana

[4] Wei-Meng Lee, Beginning Android 4 Application Development , Editura Wrox, ISBN: 978-1-118-19954-1 , 2012 ,USA, Indianapolis ,Indiana

[11] Jeff Friesen , Learn Java for Android Development, 2nd Edition , Editura Apress , ISBN: 978-1-4302-5722-6 ,2013 ,California

Pagini Web Accesate

[5] https://en.wikipedia.org/wiki/Android_(operating_system) , ultima accesare 15.05.2016

[6] https://developer.android.com/guide/components/fundamentals.html, ultima accesare 15.05.2016

[7] https://developer.android.com/guide/topics/ui/declaring-layout.html , ultima accesare 15.05.2016

[8] http://theopentutorials.com/tutorials/android/listview/android-expandable-list-view-example/ , ultima accesare 16.05.2016

[9] https://en.wikipedia.org/wiki/Android_Studio , ultima accesare 18.05.2016

[10] https://www.iconfinder.com/search/?q=learn , ultima accesare 05.11.2015

[12] https://en.wikipedia.org/wiki/Java_(programming_language), ultima accesare 24.06.2016

[13] https://en.wikipedia.org/wiki/PHP , ultima accesare 24.06.2016

Similar Posts

  • Aplicatie Informatica Pentru Un Bar Cafenea

    UNIVERSITATEA TEHNICĂ DIN CLUJ NAPOCA CENTRUL UNIVERSITAR NORD DIN BAIA MARE FACULTATEA DE ȘTIINȚE SPECIALIZAREA INFORMATICĂ ECONOMICĂ LUCRARE DE LICENȚĂ ÎNDRUMĂTOR ȘTIINȚIFIC: PROF. UNIV. DR. CEZAR TOADER ABSOLVENT: ARDELEANU RAFAEL ANDREI 2016 ÎNDRUMĂTOR ȘTIINȚIFIC: PROF. UNIV. DR. CEZAR TOADER ABSOLVENT: ARDELEANU RAFAEL ANDREI 2016 INTRODUCERE Evoluția societății în ultimii ani, marcată fundamental de transformarea ei…

  • Managementul Aproviozionării CU Produse Agroalimentare Într O Unitate DIN M. Ap.n

    UNIVERSITATEA ARTIFEX FACULTATEA DE MANAGEMENT-MARKETING PROGRAMUL DE STUDII UNIVERSITATE DE LICENTA MANAGEMENT LUCRARE DE LICENȚĂ Coordonator Conf. Univ. Dr. Dan Nastase Absolvent Danila Marian Bebe București 2015 UNIVERSITATEA ARTIFEX FACULTATEA DE MANAGEMENT-MARKETING PROGRAMUL DE STUDII UNIVERSITATE DE LICENTA MANAGEMENT MANAGEMENTUL APROVIOZIONĂRII CU PRODUSE AGROALIMENTARE ÎNTR-O UNITATE DIN M. Ap.N. – Studiu de caz la U.M.O1111…

  • Purtarea Abuziva

    === 196965a56ac9fb3a00d067ce75d358a8227961c5_500889_1 === Сuрrinѕ Introduϲеrе ϹАРIТОLUL I ϹОΝЅIDΕRАȚII IΝТRОDUϹТIVΕ РRIVIΝD IΝFRАϹȚIUΝΕА DΕ РURТАRΕ АΒUΖIVĂ 1.1 Νοțiunеɑ dе рurtɑrе ɑbuzivă 1.2 Аѕресtе dе οrdin iѕtοriс în inсriminɑrеɑ fɑрtеlοr dе рurtɑrе ɑbuzivă 1.3 Rеglеmеntɑrеɑ ɑсtuɑlă ɑ рurtării ɑbuzivе în drерtul реnɑl rοmânеѕс ϹАРIТОLUL II РURТАRΕА АΒUΖIVĂ ÎΝ DRΕРТUL РΕΝАL ϹОМРАRАТ 2.1 Рurtɑrеɑ ɑbuzivă în drерtul реnɑl frɑnсеz…

  • Analiza Si Contabilitatea Decontarilor cu Personalul

    Analiza ṣi contabilitatea decontarilor cu personalul Coordonator ṣtiințific: Absolvent: Bucureṣti 2016 Cuprins Introducere Capitolul I Resursele umane – Prezentare generală 1.1.Notiuni teoretice privind salariile 1.2. Formele de salarizare 1.3. Elementele de bază privind calculul salariilor 1.4. Continutul si structura retinerilor salariale 1.5. Subsistemul documentelor si evidentei salariilor Capitolul II Contabilitatea decontarilor cu personalul 2.1. Contabilitatea…

  • Climatul Investițional

    Climatul investițional TURISM • Turismul montan include: zona Bicaz – Ceahlău, cu munții Hășmaș, Bistrița, Tarcău, Stănișoara, rezervația naturală Cheile Bicazului – Hășmaș • Turismul cultural – ecumenic ; • Turismul rural si agro – turism : Ceahlău – Durău, Filioara – Agapia, Vânători – Neamț, Viișoara, Vaduri, Farcașa, Piatra Neamț, Almaș, Tg. Neamt, Tupilați,…