Proiectarea Si Realizarea Unei Aplicatii Pentru Monitorizarea Unei Flote de Autobuze
PROIECTAREA ȘI REALIZAREA UNEI APLICAȚII PENTRU MONITORIZAREA UNEI FLOTE DE AUTOBUZE
Cuprins
I.Introducere
II.Tehnologii utilizate
II.1 Android
II.2 Java
II.3 DBSlayer
II.4 JSON
II.5 MySQL
II.6 SQLite
II.7 Session Initiation Protocol (SIP)
III. Prezentarea lucrării
III.1 Descrierea aplicației
III.2 Implementarea aplicației
Concluzii
Bibliografie
CAPITOLUL I. Introducere
Lucrarea de față are ca și scop realizarea unei aplicații Android special concepute pentru a oferi accesul facil la informație celor care folosesc mijloacele de transport în comun.
Aplicația este realizată pe platforma Android, o platformă modernă pentru dispozitive mobile inteligente, ce permite scrierea unor aplicații complexe, oferind de asemenea fiabilitate și securitate.
Pentru dezvoltarea aplicației am decis să folosesc limbajul de programare Java deoarece este un limbaj portabil în sensul că care nu ține cont de mediul pe care rulează, acesta rulând într-o mașină virtuală. Am ales să utilizez acest limbaj ca și mediu de bază în aplicație pentru că acesta oferă stabilitate aplicației și deasemenea oferă suport pentru realizarea interfețelor grafice.
Am folosit Java pentru transmiterea cu ușurință a datelor prin intermediul Internetului, precum și generarea de elemente grafice care se actualizează în timp real. Alte tehnologii folosite: MySQL, JSON, DBSlayer și SQLite, SIP. Ca editor de text am folosit Eclipse – echipat cu plug-in-uri specifice pentru dezvoltarea aplicațiilor Android. Despre fiecare tehnologie în parte voi vorbi de-a lungul acestei lucrări, atât teoretic, cât și prin exemple simple și sugestive.
CAPITOLUL II. Tehnologii utilizate
II.1 Android
Android este un sistem de operare bazat pe Linux proiectat pentru dispozitivele mobile cu touchscreen cum ar fi telefoanele inteligente precum și tabletele. Android oferă dezvoltatorilor de software posibilitatea de a scrie cod in limbajele: Java, C și C++. Aplicațiile care sunt scrise în limbajul C sau alte limbaje pot fi compilate și executate în cod mașină ARM, dar această modalitate nu e sprijinită oficial.
Android are o mare comunitate de dezvoltatori ce scriu aplicații, care extind funcționalitatea dispozitivelor, aplicațiile fiind scrise într-o versiune personalizată a limbajului de programare Java, controlând dispozitivele prin intermediul unor biblioteci Java dezvoltate de Google.
Arhitectura Android
Kernel-ul
La baza sistemului de operare Android se află un kernel (nucleu) de Linux versiunea 2.6 care realizează comunicația cu hardware-ul dispozitivului, acesta poate suporta mai multe procesoare. Mare parte din „munca” sistemului de operare Android se realizează pe straturile superioare ale sistemului [1].
Android Runtime
Mediul Android runtime constă dintr-un set de biblioteci de bază și mașina virtuală. Bibliotecile de bază oferă majoritatea funcțiilor disponibile în bibliotecile de bază ale limbajului de programare Java.
Pe dispozitivele convenționale de calcul software-ul rulează direct pe nucleul sistemului de operare, dar o aplicatie Android rulează în propriul proces, cu propria instanță de mașină virtuală Dalvik. Dalvik VM a fost scris astfel încât un dispozitiv mobil poate rula mai multe instanțe de mașină virtuală într-un mod eficient.
Dalvik nu este ca și JVM (Java Virtual Machine), deși cele două sunt foarte asemănătoare. Dalvik VM execută fișiere în executabil Dalvik (.dex), format care este optimizat pentru volum minimal al memoriei. VM este pe bază de registru, și execută clasele compilate cu un compilator de limbaj Java, care au fost transformate în .dex
Biblioteci Android
Mediul android include un set de biblioteci C / C++ utilizate de diferitele componente ale sistemului Android. Aceste capacități sunt expuse dezvoltatorilor prin intermediul cadrului de aplicații Android. Unele dintre bibliotecile de bază sunt enumerate mai jos:
Biblioteci media – bazate pe OpenCORE; bibliotecile oferă suport pentru redarea și înregistrarea mai multor formate video și audio precum și fisiere imagine static, inclusive MPEG4, H.264, MP3, AAC, AMR, JPG și PNG.
Surface Manager – gestionează accesul la subsistemul de afișare.
LibWebCore – un motor de browser web care alimentează atât browser-ul Android cât și elementele web din aplicații.
SGL – motorul graphic 2D de bază
Biblioteci 3D – implementare bazată pe OpenGL ES 1.0 API, bibliotecile folosesc accelerare 3D (acolo unde este disponibilă).
FreeType – randarea fonturilor vectoriale si bitmap.
SQLite – un motor puternic și ușor de baze de date relaționale disponibil pentru toate aplicațiile.
Cadru de aplicații (Application Framework)
Dezvoltatorii au acces deplin la același cadru API utilizat de către aplicațiile de bază. Arhitectura aplicație este conceput pentru a simplifica reutilizarea componentelor, orice aplicație poate publica capacitățile sale și orice altă aplicație ar putea face apoi utilizarea acestor capacități (supuse unor constrângeri de securitate impuse de cadru). Același mecanism permite componentelor să fie înlocuite de către utilizator.
La baza tuturor aplicațiilor este un set de servicii și sisteme, inclusiv:
Un set bogat și extensibil de View-uri care pot fi folosite pentru a construi o cerere, inclusiv liste, grile, casete de text, butoane, și chiar un browser web încorporat.
Furnizorii de conținut, care permit aplicațiilor să acceseze date din alte aplicații (cum ar fi contactele), sau de a împărtăși propriile date.
Un manager de resurse, oferind acces la resurse non-cod, cum ar fi siruri de caractere localizate, grafice, și fișiere de aspect (layouts).
Un manager de notificare care permite toate cererile pentru a afișa alerte personalizate în bara de stare.
Un manager de activitate care gestionează ciclul de viață al aplicațiilor și oferă o navigare comună back-stack.
Aplicații de bază
Android vine cu un set de aplicații de bază, inclusiv un client de e-mail, programul de SMS-uri, calendar, hărți, browser-ul și altele. Toate cererile sunt scrise folosind sintaxa limbajului de programare Java. O aplicație Java scrisă pentru Android nu este compatibilă cu programele Java scrise pentru platformele Java ME și Java SE [4].
Activități Android
Pornirea unei activități
Spre deosebire de alte paradigme de programare în care aplicațiile sunt lansate cu o metodă main(), sistemul Android inițiază codul într-o instanță a clasei Activity, invocând metode de callback specifice, care corespund cu etapele specifice ale ciclului său de viață.
Există o serie de metode de callback, care încep o activitate și o secvență de metode de callback, care închide o activitate.
În timpul ciclului de vieță al unei activități, sistemul solicită un set de metode de bază într-o secvență similară cu o piramidă. Fiecare etapă a ciclului de viață al activității este un pas separat pe piramida[3].
Când sistemul creează o nouă instanță de activitate, fiecare metodă de callback mută starea activității cu un pas spre partea de sus. Partea de sus a piramidei este punctul în care activitatea se execută în prim-plan, iar utilizatorul poate interacționa cu ea.
Ciclul de viață al unei activități, din momentul creări unei activități și până când activitatea se distruge este prezentat in figura II.1.
Fig II.1 Ciclul de viață al unei activități
În funcție de complexitatea unei activități e probabil să nu trebuiască să se pună în aplicare toate metodele ciclului de viață. Implementarea metodelor din ciclul de viață al unei activități asigură în mod corespunzător că aplicația se comportă bine în mai multe moduri:
aplicația nu se oprește în cazul în care utilizatorul primește un apel telefonic sau dacă se comută pentru o altă aplicație.
nu consumă resurse valoroase de sistem atunci când utilizatorul nu este activ.
nu pierde progresele utilizatorului în cazul în care acesta părăsește aplicația.
aplicația nu se oprește și nu se pierde progresele utilizatorului atunci când ecranul se rotește din modul peisaj în modul portret sau invers.
Crearea unei aplicații simple în Android
Pași în crearea unei aplicații Android
Primul pas constă în crearea unui nou proiect Android cu ajutorul editorului Eclipse, selectând meniul File > New > Android Application.
Setăm proprietățile proiectului:
Project Name: Hello World
Build Target: Select Android 2.1
Application Name: Hello World
Package Name: com.android.test
Create Activity: HelloWorld
Prin apăsarea butonului Finish, Eclipse generează fișierele proiectului.
Fișierul main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:text="Hello World" android:id="@+id/textview01" android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
Fișierul HelloWorld.java
package com.android.test;
import android.app.Activity;
import android.os.Bundle;
public class HelloWorld extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
II.2 Java
Java este un limbaj de programare concurent, orientat pe obiect. Limbajul de programare Java este înrudit cu C și C++, dar este organizat destul de diferit, cu un număr de aspecte ale C și C++ omise și câteva idei din alte limbi sunt incluse. Acesta este destinat a fi un limbaj de producție, nu un limbaj de cercetare. Principalele caracteristici ale limbajului de programare Java sunt [2]:
simplitatea – elimină moștenirea multiplă, supraîncarcarea operatorilor pentru evitarea scrierii unui cod confuz.
robustețea – elimină sursele de erori ce apar în programare prin eliminarea pointerilor, administrarea automata a memoriei cu ajutorul garbage collection, acesta rulând în fundal
complet orientat pe obiecte – elimină programarea procedurală
securitate – cel mai sigur limbaj de programare
neutru din punct de vedere arhitectural
portabilitate – este un limbaj independent de sistemul de operare
dinamicitate
După modul de execuție al programelor, limbajele se împart în două categorii:
limbaje interpretate – instrucțiunile sunt citite de un interpretor și traduse în instrucțiuni mașină.
limbaje compilate – sursa este transformată de către compilator într-un cod ce poate fi executat direct pe procesor.
Programele scrise în limbajul de programare Java pot fi atât interpretate cât și compilate. Codul de octeți e diferit față de codul mașină. Codul mașină este reprezentat de o înșiruire de 1 și 0; codurile de octeți sunt seturi de instrucțiuni asemănătoare cu codul scris în limbaj de asamblare.
Codul mașină se execută direct pe ptocesor, putând fi folosit doar pe platforma pe care a fost creat; codul de octeți este interpretat de mediul Java, in consecință acesta poate rula pe orice platforma ce foloseste mediul Java.
Tipuri de date
Limbajul de programare Java suportă 8 tipuri de date primare, acestea sunt descrise în tabelul de mai jos [9]:
Operatori
Operatorii din limbajul Java sunt:
atribuire: =
operatori matematici: +, -, *, /, %, ++, –
operatori logici: &&(and), ||(or), !(not)
operatori relaționali: <, <=, >, >=, ==, !=
operatori pe biți: &(and), |(or), ^(xor), ~(not)
operatori de translație: <<, >>, >>>(shift la dreapta fară semn)
operatorul if-else: (expresie) ? valoare-true : valoare-false
operatorul , (virgulă) pentru evaluarea secvențială a operațiilor: a=1, b=5, c=2;
Controlul execuției
Instrucțiunile din Java sunt asemănătoare cu cele din C.
Instrucțiuni de decizie
Instrucțiuni repetitive
Instrucțiuni de tratare a excepțiilor
Alte instrucțiuni
Clase și obiecte
Ciclul de viață al unui obiect
În orice limbaj de programare orientat pe obiecte, crearea obiectelor se realizează prin instanțierea unei clase, aceasta implicând:
Declaraiuni de decizie
Instrucțiuni repetitive
Instrucțiuni de tratare a excepțiilor
Alte instrucțiuni
Clase și obiecte
Ciclul de viață al unui obiect
În orice limbaj de programare orientat pe obiecte, crearea obiectelor se realizează prin instanțierea unei clase, aceasta implicând:
Declararea – înseamnă specificarea tipului unui obiect.
Ex: NumeClasa obiect;
Instanțierea – se realizează cu ajutorul operatorului new, acesta alocă spațiul de memorie corespunzător obiectului.
Ex: obiect = new NumeClasa();
Inițializarea – se realizează prin intermediul constructorilor clasei respective.
Ex: obiect = new NumeClasa([parametrii constructor]);
Spațiul de memorie pentru un obiect nu este pre-alocat, alocarea spațiului de memorie se realizează doar la apelul operatorului new.
Ex:
Patrat p;
Patrat.x = 10; // eroare, lipsește instanțierea
Folosirea obiectelor
După ce a fost creat un obiect, acesta poate fi folosit în următoarele sensuri: extragerea unor informații despre obiect, schimbarea stării sale sau executarea unor acțiuni.
Extragerea valorii unei variabile se face astfel: obiect.var . De exemplu clasa Dreptunghi are variabilele publice x, y, L, l, origine. Aflarea valorilor acestor variabile se poate realiza prin operațiuni de genul:
Dreptunghi d = new Dreptunghi(0,0,50,100);
System.out.println(d.L); //se afiseaza 50
d.x = 10;
d.origine = new Point(10, 20) //schimba originea
Accesul la variabilele unui obiect se face în conformitate cu drepturile de acces pe care le oferă variabilele respective celorlalte clase.
Eliminarea obiectelor
Unele limbaje de programare impun ca programatorul să țină evidența obiectelor create și să le distrugă în mod explicit atunci când nu mai este nevoie de ele, cu alte cuvinte să administreze memoria ocupată de obiecte.
În Java, programatorul nu mai este responsabil de distrugerea obiectelor sale pentru că in timpul rulării unui program, simultan cu interpretorul Java, rulează și un proces care se ocupă cu distrugerea obiectelor care nu mai sunt folosite. Acest proces se numește garbage collector.
Obiectele se pot elimina în două moduri:
natural – de exemplu terminarea unei metode in care a fost declarat obiectul
explicit – prin atribuirea obiectului valoarea null.
Clase Java
În lumea reală, găsim de multe ori mai multe obiecte individuale, toate de același fel. Pot exista de exemplu mii de biciclete, toate de aceeași marcă și model. Fiecare bicicletă a fost construită din același set de planuri și, prin urmare, conține aceleași componente. În programarea orientată pe obiecte, spunem că bicicleta este o instanță a clasei de obiecte cunoscute sub numele de biciclete.
Clasa Bicicleta este o posibilă implementare a unei biciclete:
class Bicicleta {
int viteza = 0;
int treaptaViteza = 1;
void schimbaTreaptaViteza(int newValue) {
treaptaViteza = newValue;
}
void vitezaUp(int increment) {
viteza = viteza + increment;
}
void frana(int decrement) {
viteza = viteza – decrement;
}
void afisareDate() {
System.out.println(" viteza:" + viteza + " treapta viteza:" + treaptaViteza);
}
}
Câmpurile viteza și treaptaViteza reprezintă starea obiectului, iar metodele: schimbaTreaptaViteza, vitezaUp, frana și afisareDate definesc interacțiunea cu exteriorul.
Moștenirea
Programarea orientată pe obiecte permite claselor de a moșteni comportamentul din alte clase. Pentru exemplul de mai sus, clasa Bicicleta devine acum superclasă pentru clasele: Mountain bike și RoadBike. În limbajul de programare Java, fiecărei clase îi este permis să aibă o superclasa directă, și fiecare superclasă are potențial pentru un număr nelimitat de subclase ca și în figura II.3.
Figura II.3 Moștenirea
Sintaxa pentru crearea unei subclase este simplă. La începutul declarării clasei, utilizați cuvântul cheie extends, urmat de numele clasei care se dorește a fi moștenită.
class MountainBike extends Bicicleta {
// definire de câmpuri și metode
}
Fire de execuție în Java (Thread)
Aproape fiecare sistem de operare sprijină conceptul de procese – programele rulează independent și sunt izolate unele de altele într-o anumită măsură.
Threading-ul este o facilitate ce permite mai multor activități să coexiste într-un singur proces. Cele mai multe sisteme de operare moderne de suportă fire de execuție. Java este primul limbaj de programare ce include în mod explicit conceptul de fire de execuție.
Ca și procesele, firele de execuție sunt independente, concurente într-un program, fiecare fir de execuție având propria sa stivă, propriu contror de program și propriile variabile locale.
Un proces poate avea mai multe fire de execuție, acestea par să a fi executate simultan și asincron. Mai multe fire în cadrul unui proces împart aceeași memorie, spațiu de adrese, ceea ce înseamnă că au acces la aceleași variabile și obiecte.
Fiecare program Java are cel puțin un fir de execuție – firul principal. Când un program Java începe, JVM (Java Virtual Machine) creează firul principal și apelează metoda main() a programului.
De ce să folosim fire de execuție?
Există multe motive pentru a utiliza fire în programele Java. Unele dintre motivele utilizării firelor de execuție sunt că acestea pot ajuta la:
face interfața cu utilizatorul mai receptivă
se folosește din plin performanța sistemelor multiprocesor
simplificarea în modelare
execuția proceselor asincrone sau proceselor din fundal
Ciclul de viață al unui fir de execuție (Thread)
Crearea firelor de execuție
Există mai multe moduri de a crea un fir de execuție într-un program Java. Fiecare program Java conține cel puțin un fir de execuție – firul principal. Firele de execuție suplimentare sunt create prin apelul constructorului clasei Thread sau prin instanțierea claselor care extind clasa Thread.
Crearea și pornirea firelor de execuție nu sunt la fel. Un fir de execuție nu începe să se execute până când se apeleaza metoda start(). Obiectul de tipul Thread există înainte ca firul de execuție să pornească. Acest lucru permite controlul sau obținerea informațiilor despre un fir creat, chiar dacă firul nu a fost pornit încă sau dacă s-a terminat deja.
Terminarea firelor de execuție
Un fir de execuție se va încheia într-unul din cele trei moduri:
Firul de execuție ajunge la sfârșitul metodei sale run().
Firul aruncă o excepție sau eroare care nu este tratată.
Un alt fir de executie apeleaza metoda de oprire stop().
Exemplu:
public class Example extends Thread {
public void run() {
/* … */
}
public static void main(String[] args) {
Example e= new Exanple();
e.start(); //pornire thread
}
II.3 DBSlayer
DBSlayer este un strat de abstractizare a bazei de date pentru site-urile de mare capacitate în cazul în care este nevoie de optimizare a interogărilor la baza de date. DBSlayer este scris în limbajul de programare C pentru viteză, acesta schimbă date cu clienții prin JSON prin intermediul HTTP-ului, ceea ce înseamnă că este simplu de monitorizat și poate interopera rapid cu orice cadru de web.
Caracteristici [5]:
Interfață simplă HTTP
Mesajele se transmit în format JSON
MySQL adaptor
Gruparea conexiunilor
Multithread
Distribuție round-robin de interogări
Failover automat la bazele de date alternative
Configurația drept-înainte
Simplu, dar puternic
DBSlayer pornește un serviciu de tip daemon pe portul 9090 (acest port implicit poate fi schimbat), care acționează ca un proxy pentru server-ul MySQL. Acest proxy poate fi interogat cu ajutorul protocolului HTTP prin metoda $_GET, având ca parametru un JSON ca și în exemplul de mai jos:
SELECT * FROM test WHERE category=2;
http://localhost:9090/db?%7B%22SQL%22%3A%22SELECT%20*%20FROM%20test%20WHERE%20category%3D2%3B%22%7D
HTTP/1.0 200 OK
Date: Wed, 26 Jun 2013 20:55:59 GMT
Server: dbslayer/server beta-9
Connection: Close
Content-type: text/plain; charset=utf-8
Content-Length: 346
{"RESULT" :
{"TYPES" : ["MYSQL_TYPE_LONG" , "MYSQL_TYPE_LONG"] , "MYSQL_TYPE_STRING"] ,
"HEADER" : ["ID" , "CATEGORY" , "NAME" ],
"ROWS" : [ [37 , 2 , "NAME1"],
[38 , 2 , "NAME2"] ,
[39 , 2 , "NAME3"] ]
}
}
II.4 JSON
JSON (JavaScript Object Notation) este un standard bazat pe text, ușor de utilizat proiectat pentru a facilita schimbul de date între diferite limbaje de programare. JSON este derivat din limbajul JavaScript pentru a reprezenta structuri de date simple și tablouri asociative, numite obiecte. Formatul JSON este independent de limbaj, fiind existente interpretoare pentru mai multe limbaje de programare.
JSON este adesea folosit pentru serializarea și transmiterea datelor structurate pe o conexiune de rețea. Acesta este utilizat în principal pentru a transmite date între un server și aplicații web, servind ca o alternativă la XML [6].
Tipuri de bază in JSON:
Numeric (format în virgulă mobilă)
Șir de caractere (String)
Boolean (true sau false)
Array (o secvență ordonată de valori, separate prin virgule și paranteze drepte, valorile nu trebuie să fie de același tip)
Obiect (o colecție de cheie neordonate: perechi de valoare cu separatot: ":")
nul (null)
II.5 MySQL
MySQL este un sistem de management al bazelor de date relaționale (RDBMS), ce nu conține interfață grafică pentru administrarea sau gestionarea datelor din bazele de date. Utilizatorii pot folosi instrumente de linie de comandă, aplicații desktop sau aplicații web cu care se pot administra și crea baze de date MySQL.
Bazele de date MySQL, ca și alte tipuri de baze de date sunt compuse din tabele oarecum separate, acestea conțin diferite câmpuri de date corelate din punct de vedere logic. Bazele de date pot avea dimensiuni variate, de la câteva zeci de înregistrări și pot ajunge la ordinul de milioane de înregistrări.
Utilizatorii unei baze de date pot efectua mai multe operații asupra datelor:
Inserarea de date (insert)
Ștergerea de date (delete)
Modificarea datelor (update)
Citirea bazei de date (query) pentru a extrage anumite date
Bazele de date relaționale sunt de departe cel mai folosit tip de baze de date. Acestea au o bază teoretică solidă în algebra relațională.
Tipuri de date în MySQL
În limbajul MySQL întâlnim mai multe tipuri de date [7]:
Crearea unei tabele în baza de date
Mai înainte de a face vreo operatiune cu baza de date, trebuie să creăm o tabelă. O tabelă reprezintă o secțiune a bazei de date pentru stocarea unor informații structurate. Într-o tabelă vom defini diferite câmpuri care vor fi folosite în acea tabelă.
Exemplu:
CREATE TABLE nume_tabela
(
coloana1 tip_data(dimensiune),
coloana2 tip_data(dimensiune),
coloana3 tip_data(dimensiune),
…
);
Inserarea datelor în baza de date
Înainte de a putea face o mulțime de lucruri cu baza de date să stocăm nițte date în ea. Acest lucru se face de obicei cu instrucțiunea INSERT.
Tabelele conțin linii de date organizate în coloane. Fiecare linie din tabela descrie de obicei un obiect sau o relație din lumea reală, iar valorile din coloane pentru acea linie stochează informații despre obiectul din lumea reală. Instricțiunea INSERT o putem folosi pentru a introduce liniide date în baza de date.
Forma obișnuită a unei instrucțiuni INSERT este:
INSERT INTO tabela ([coloana1, coloana2, coloana3, …]) VALUES (valoare1, valoare2, valoare3, …);
Regăsirea datelor din baza de date
Instrumentul de bază al SQL este instrucțiunea SELECT. Este folosită pentru extragerea datelor dintr-o bază de date prin selectarea acelor linii din tabelă ce corespund criteriul specificat. Există multe opțiuni și mai multe moduri în care se poate utiliza instrucțiunea SELECT.
Forma de bază a instrucțiunii SELECT este:
SELECT [câmpuri | *]
FROM nume_tabela
[WHERE condiție]
[GROUP BY tip_grupare]
[HAVING definiție_where]
[ORDER BY tip_ordonare]
[LIMIT criteriu_limită]
Actualizarea înregistrărilor din baza de date
În afară de regăsirea datelor din baza de date, dorim de multe ori să le modificăm. Avem posibilitatea de a face acest lucru prin utilizarea unei instrucțiuni UPDATE.
Forma obișnuită a instrucținii UPDATE este:
UPDATE nume_tabela
SET coloana1 = expresie1, coloana2 = expresie2, …
[WHERE condiție]
[ORDER BY criteriu_ordonare]
[LIMIT număr]
O anumită instrucțiune UPDATE poate fi limitată la anumite linii folosind o clauză WHERE și se poate limita numarul total de linii afectate prin specificarea clauzei LIMIT. Clauza ORDER BY este folosită de obicei împreună cu o clauză LIMIT.
Modificarea tabelelor
În afară de actualizarea liniilor, este posibil să se modifice și structura tabelelor din baza de date. În acest scop se folosește instrucțiunea ALTER TABLE.
Sintaxa acestei instrucțiuni este următoarea:
ALTER TABLE [IGNORE] numetabela modificare [, modificare, …]
Dacă este specificată clauza IGNORE și încercăm să efectuăm o modificare în urma căreia vor apărea chei primare identice, prima va fi trecută în tabela modificată, iar restul vor fi șterse.
Ștergerea de înregistrări din baza de date
Ștergerea de linii dintr-o bază de date este o operațiune foarte simplă. Acest lucru se realizează cu ajutorul instrucțiunii DELETE care arată astfel:
DELETE FROM tabela
[WHERE condiție]
[ORDER BY ordine_coloane]
[LIMIT număr]
Eliminarea unor tabele din baza de date
Uneori se dorește să se șteargă o întreagă tabelă. Acest lucru se poate face cu instrucțiunea DROP TABLE. Este o instrucțiune simplă și arată astfel:
DROP TABLE nume_tabela
Această instrucțiune va șterge toate liniile din tabelă și va șterge chiar și tabela, deci trebuie utilizată cu mare atenție.
Ștergerea unei baze de date
Pentru eliminarea întregii baze de date există instrucțiunea DROP DATABASE care arată astfel:
DROP DATABASE baza_de _date
Această instrucțiune va șterge toate liniile, toate tabelele, toate indexurile și baza de date, deci trebuie folosită cu multă atenție! [10]
II.6 SQLite
SQLite este un sistem de management al bazelor de date conținut într-o mică (~350 KB) bibliotecă C. Spre deosebire de alte sisteme de management al bazelor de date, SQLite nu este un proces separat, care este accesat de aplicația client, ci este chiar o parte integrantă a acestea.
SQLite este disponibil pe fiecare dispozitiv Android. Folosind o bază de date SQLite în Android nu necesită nici o instalare sau administrare de baze de date.
Trebuiesc definite doar declarații SQL pentru crearea și actualizarea bazei de date. Ulterior, baza de date este gestionată în mod automat de platforma Android [8].
Accesul la o bază de date SQLite implică accesul la sistemul de fișiere. Acest lucru poate fi lent. Prin urmare, se recomandă ca operațiile asupra bazei de date să se efectueze asincron, de exemplu în interiorul clasei AsyncTask. Această clasă crează un fir de execuție în fundal și are metode cu care actualizează elementele grafice din interfața utilizator.
II.7 Session Initiation Protocol (SIP)
Session Initiation Protocol (SIP) este un protocol de comunicare de semnalizare, utilizat pe scară largă pentru a controla sesiunile de comunicare multimedia, cum ar fi apeluri de voce și video prin intermediului Internet Protocol (IP).
Protocolul definește mesajele care sunt trimise între clienții care guvernează stabilirea, terminarea și alte elemente esențiale ale unui apel. SIP poate fi utilizat pentru crearea și terminarea unui apel între două părți (unicast) sau sesiuni de mai mulți participanți (multicast), constând din unul sau mai multe fluxuri de date media. Alte aplicații SIP includ conferințe video, streaming de distribuție multimedia, mesagerie instant, transfer de fișiere.
SIP definește, de asemenea și elemente de server. Deși cele două terminale SIP pot comunica fără intervenția unei infrastructuri SIP, motivul pentru care protocolul este descris ca peer-to-peer, această abordare este de multe ori imposibil pentru un serviciu public.
SIP este un protocol bazat pe text cu sintaxa similară cu cea de HTTP. Există două tipuri diferite de mesaje SIP: cereri și răspunsuri. Prima linie a unei cereri are o metodă, care definește natura cererii, și o cerere-URI, indică unde ar trebui să fie trimis cererea. Prima linie a unui răspuns are un cod de răspuns [12].
Lista metodelor de interogare SIP
REGISTER: Folosit de un UA pentru a indica adresa IP curentă și URL-urile pentru care ar dori să primească apeluri.
INVITE: Folosit pentru a stabili o sesiune de mass-media între agentii utilizator.
ACK: confirmă schimburi de mesaje de încredere.
CANCEL: Termină o cerere în așteptare.
BYE: Termină o sesiune între doi utilizatori într-o conferință.
OPTIONS: solicită informații despre capacitățile unui apelant, fără crearea unui apel.
CAPITOLUL III. Prezentarea lucrării
III.1 Descrierea aplicației
Lucrarea constă în realizarea unei aplicații special concepute pentru a oferi accesul facil la informație celor care folosesc mijloacele de transport în comun. Aplicația monitorizează și afișează pe o hartă Google poziția unor vehicule pe anumite trasee de transport în comun dintr-un anumit oraș, acestea realizându-se în timp real. Liniile de trasnsport în comun sunt trasate pe hartă cu diferite culori și fiecare stație este reprezenată cu o iconiță sugestivă. Deasemenea pozițiile vehiculelor sunt reprezentate pe hartă în timp real.
Aplicația funcționează în două moduri:
Modul inactiv – în caz de inactivitate în aplicație, aceasta intră într-o stare de așteptare, în cazul de față rulând un clip video. Părasirea acestui mod se face printr-o simplă atingere a ecranului, sau acționând orice element sau meniu afișat în aplicație.
Modul activ – când aplicația este folosită în mod normal.
Structura bazelor de date
Aplicația folosește două tipuri de baze de date:
SQLite – folosită pentru stocarea locală a datelor.
MySQL – folosită pe partea de server care furnizează date în timp real.
În baza de date locală se stochează pozițiile GPS ale stațiilor precum și punctele intermediare dintre acestea. Aceste date se stochează local pentru a preveni utilizarea excesivă a conexiunii la internet, ceea ce presupune o viteză mai mare de încărcare a traseelor. În baza de date locală SQLite avem două tabele. Structura acestor tabele este prezentată in tabelele de mai jos:
Tabela routes:
Tabela routes_name:
Baza de date de pe partea de server a aplicației este stucturată pe mai multe tabele, acestea conțin date primite de la vehiculele care sunt echipate cu sisteme GPS. Structura tabelelor este prezentată în următoarele tabele:
Tabela statii
Tabela trasee
Tabela vehicule
Tabela poziții
III.2 Implementarea aplicației
Interfața grafică a aplicației este una dinamică, totodată fiind intuitivă și ușor de folosit. Aplicația conține mai multe module de bază prezentate în figura III.1.
Figura III.1
Modulul lista de vehicule
Acest modul afișează o listă cu detalii despre vehiculele ce sosesc în stația curentă, cum ar fi: numele traseului pe care rulează vehiculul, numărul de înmatriculare al acestuia, precum și timpul estimat sosirii în stație. Această listă se actualizează în timp real, în momentul în care vehiculul își schimbă poziția GPS. La apăsarea unui element din listă pe harta geografică se desenează traseul selectat.
Figura III.1 Modulul Lista trasee
Codul sursă:
public MyCustomBaseAdapter veh;
public ArrayList<Vehicul> arr;
list = (ListView) findViewById(R.id.list);
adapter = new MyCustomBaseAdapter(this, arr);
veh = adapter;
list.setAdapter(veh);
veh.notifyDataSetChanged();
list.setOnItemClickListener(this);
class VehiculReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
LayoutParams params = list.getLayoutParams();
params.height = Global.getVehicule().size() * 60;
if (params.height > 287)
params.height = 287;
list.setLayoutParams(params);
arr = new ArrayList<Vehicul>(Global.getVehicule());
veh = new MyCustomBaseAdapter(context, arr);
veh.notifyDataSetChanged();
}
}
Modulul hartă liniarizată
Acest modul desnează o hartă 2D a traseului selectat pe care afișează numele fiecărei stație, precum și autobuzul selectat. În cazul în care autobuzul pierde poziția GPS, harta liniarizată dispare de pe ecran, aceasta reapare atinci când autobuzul trimite din nou poziția GPS.
Figura III.2 Modulul Harta liniarizată
Clasa Java care realizează modulul de harta liniarizată se numește TransparentRelativePanel. Aceasta extinde clasa RelativeLayout, clasă care se folosește pentru a crea respectiv modificarea elementelor grafice din interfata grafică.
În cele de mai jos putem observa că poziția vehiculului se modifică în functie de mai mulți parametrii:
coordonata GPS (poziția vehiculului reprezentată sub forma de longitudine și latitudine, luându-se în considerare 8 zecmale)
cooronata GPS a stațiilor
reprezentarea grafică a traseului după multitudinea de coordinate GPS.
Codul sursă:
public class TransparentRelativePanel extends RelativeLayout implements Runnable {
public TransparentRelativePanel(Context context, AttributeSet attrs) {
super(context, attrs);
this.ctx = context;
init();
}
private void init() {
this.vehicul = Global.getVehicul();
this.route = getStatii(Global.getTraseu());
timer = Executors.newSingleThreadScheduledExecutor();
timer.scheduleAtFixedRate(this, 1, 3, TimeUnit.SECONDS);
elem = this;
}
private PozitieVehicul getAutobuz(ArrayList<PozitieVehicul> pozVehicule) {
for (PozitieVehicul v : pozVehicule) {
if (vehicul.getNume().equalsIgnoreCase(v.getNume()))
return v;
}
return null;
}
private ArrayList<Statii> getStatii(ArrayList<Statii> traseu) {
ArrayList<Statii> statii = new ArrayList<Statii>();
for (Statii s : traseu) {
if (s.isPunctIntermediar())
statii.add(s);
}
return statii;
}
private void drawTraseu() {
if (pozAutobuz == null){ elem.setVisibility(View.GONE); return; }
_canvas.drawRoundRect(drawRect, 5, 5, innerPaint);
_canvas.drawRoundRect(drawRect, 5, 5, borderPaint);
int numarStatii = route.size();
for (int i = 1; i <= numarStatii; i++) {
if ((i % 2) == 0) {
_canvas.drawLine( x * i + 20 , _height / 2, x * i + 20, _height / 2 + 30, getmTraseuPaint());
} else {
_canvas.drawLine( x * i – mStatii.getWidth() / 2 + 20, _height / 2 – 30, (x / numarStatii) * i + 20, _height / 2, getmTraseuPaint());
}
if (pozAutobuz != null){
if ((i – 1) == contorAutobuz) {
_canvas.drawBitmap(mAutobuze, (x / numarStatii) * i – mStatii.getWidth() / 2, yAutobuz – mStatii.getHeight(), null);
}
if(contorAutobuz==numarStatii-1){
elem.setVisibility(View.GONE);
}
}
_canvas.drawText("Traseul liniei " + Global.getSelectedRoute()+", autobuzul: "+Global.getSelectedBus(), 30, _height – 10,getmTraseuTextPaint());
}
}
@Override
public void run() {
this.post(new Runnable() {
@Override
public void run() {
Log.e("TAG", "run linear map");
try {
elem.invalidate();
if (pozAutobuz != null) {
drawTraseu();
elem.setVisibility(View.VISIBLE);
} elseĂ
elem.setVisibility(View.GONE);
elem.invalidate();
}}
}); }}
Modulul harta geografică
Cu Google Maps Android API, se pot adăuga hărți bazate pe datele Google Maps la cererea dumneavoastră. API-ul manipulează în mod automat accesul la serverele Google Maps, descărcarea de date, afișarea hărții, și răspunsul hărții la gesturi.
Se pot folosi, de asemenea, metode API pentru a adăuga markeri, poligoane, și overlay-uri la harta de bază. Aceste obiecte furnizează informații suplimentare pentru locațiile de pe hartă, și permite interacțiunea utilizatorului cu harta.
Figura III.3 Modulul harta geografică
API-ul Google Maps Android permite să adăugați următoarele elemente grafice pe o hartă [11]:
Iconițe (Markers)
Seturi de segmente de linie (Polylines)
Segmente închise (Polygons)
Elemente grafice de tip Bitmap (Ground Overlays)
Codul sursă:
public class MainActivity extends Activity{
public GoogleMap map;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
MapsInitializer.initialize(this);
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
setContentView(R.layout.activity_main);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
}
}
Modulul meniu principal
Acest modul conține un meniu format din butoane de tipul ImageButton. Butonul „Call Center” realizează conferință audio/video cu un client SIP în timp real. Aplicația folosește microfonul și camera dispozitivului în mod transparent, acest lucru fiind realizat de un set de biblioteci SIP cu implementare în limbajul de programare Java.
La apăsarea butonul „Harta” pe harta geografică se trasează toate traseele cu culori diferite, deasemenea se generează și o legendă a traseelor, fiecărui traseu îi corespunde o culoare unică. Totodată pe harta geografică se afișează toate stațiile traseelor, toate autobuzurile figurate sub formă de iconițe sugestive.
În acest modul se mai găsește un widget ce furnizează în timp real informații utile despre starea vremii din orașul curent. Acest element se sincronizează cu un server de la care primește datele în format JSON. Deasemenea acest widget afișează ora și data curentă.
Figura III.4 Modulul meniul principal
Codul sursă:
WeatherXmlParser parser = new WeatherXmlParser();
String xml = parser.getXmlFromUrl(weather);
Document doc = parser.getDomElement(xml);
NodeList nl = doc.getElementsByTagName("item");
NodeList elem = nl.item(0).getChildNodes();
NamedNodeMap x = elem.item(11).getAttributes();
final Node temp = x.getNamedItem("temp");
final Node code = x.getNamedItem("code");
final Node data = x.getNamedItem("date");
String[] parts = data.getNodeValue().split(" ");
final String dataCurenta = parts[0] + " " + parts[1]+ " " + parts[2] + " " + parts[3];
String imageURL = "http://l.yimg.com/a/i/us/we/52/"+ code.getNodeValue() + ".gif";
img = LoadImageFromWeb(imageURL);
runOnUiThread(new Runnable() {
public void run() {
imageWeather.setImageDrawable(img);
grad.setText("" + temp.getNodeValue() +getString(R.string.grad));
textViewDate.setText("" + dataCurenta);
}
});
CAPITOLUL IV. Concluzii
Pe parcursul lucrării au fost prezentate cele mai importante elemente necesare dezvoltării unei aplicații bazate pe platforma Android. Capitolul II prezintă pe scurt tehnologiile ce stau la baza proiectarii aplicației Android. Acest capitol poste avea atât rolul de a familiariza cititorul cu tehnologiile utilizate și de a fi sursă rapidă de documentație, prin exemplele prezentate.
Capitolul III prezintă realizarea efectivă a aplicației, pornind de la etapa de proiectare și continuând cu implementarea și utilizarea ei. Sunt descrise principalele avantaje oferite de aplicație, precum și modul în care acestea pot fi folosite.
Am ales platforma de dezvoltare Android pentru că dispune de o gamă largă de unelte pentru proiectarea implementarea și prezentarea aplicațiilor, fiind un mediu ideal de dezvoltare pentru aplicații complexe și cu cerințe înalte din punct de vedere al performanțelor.
Aplicația poate fi îmbunătățită și extinsă în mai multe moduri:
adăugarea de efecte sonore de notificare a sosirii unui vehicul în stație.
adaptarea interfeței grafice a aplicației pentru alte dispozitive mobile mai mici de genul telefoanelor inteligente care au ca sistem de operare Android.
folosirea aplicației pe diferite tipuri de transport în comun cum ar fi: linii de tramvaie, metrouri, etc.
Bibliografie
[1] Android, the first world's most popular mobile platform, android.com, http://developer.android.com/about/index.html Consultat la 10.06.2013
[2] What is Java technology, java.com, http://www.java.com/en/download/faq/whatis_java.xml Consultat la 18.06.2013
[3] Activity lifecycle, developer.android.com http://developer.android.com/training/basics/activity-lifecycle/starting.html#lifecycle-states Consultat la 20.06.2013
[4] Introduction to Java Threads, freejavaguide.com, http://www.freejavaguide.com/java-threads-tutorial.pdf Consultat la 28.06.2013
[5] DBSlayer, code.nytimes.com, http://code.nytimes.com/projects/dbslayer Consultat la 30.06.2013
[6] JSON, json.org, http://json.org/ Consultat la 31.06.2013
[7] MySQL, mysql.com http://mysql.com/about/ Consultat la 05.06.2013
[8] SQLite, sqlite.org, http://www.sqlite.org/about.html Consultat la 25.06.2013
[9] Java: de la 0 la expert, Ștefan Transă, Ștefan Andrei, Cristian Olaru. – Ed. A II-a rev – Iași: Polirom, 2007
[10] Traducere autorizată după ediția în limba engleză, intitulată PHP AND MYSQL WEB DEVELOPMENT, ediția a III-a, 0672326728 de WELLING LUKE, THOMSON LAURA, publicată de Pearson Education, Inc, Copyright © 2005 Sams Publishing
[11] Introduction to the Google Maps Android API v2, developers.google.com, https://developers.google.com/maps/documentation/android/intro Consultat la15.06.2013
[12] Session Initiation Protocol, wikipedia.org, http://en.wikipedia.org/wiki/Session_Initiation_Protocol Consultat la10.06.2013
Bibliografie
[1] Android, the first world's most popular mobile platform, android.com, http://developer.android.com/about/index.html Consultat la 10.06.2013
[2] What is Java technology, java.com, http://www.java.com/en/download/faq/whatis_java.xml Consultat la 18.06.2013
[3] Activity lifecycle, developer.android.com http://developer.android.com/training/basics/activity-lifecycle/starting.html#lifecycle-states Consultat la 20.06.2013
[4] Introduction to Java Threads, freejavaguide.com, http://www.freejavaguide.com/java-threads-tutorial.pdf Consultat la 28.06.2013
[5] DBSlayer, code.nytimes.com, http://code.nytimes.com/projects/dbslayer Consultat la 30.06.2013
[6] JSON, json.org, http://json.org/ Consultat la 31.06.2013
[7] MySQL, mysql.com http://mysql.com/about/ Consultat la 05.06.2013
[8] SQLite, sqlite.org, http://www.sqlite.org/about.html Consultat la 25.06.2013
[9] Java: de la 0 la expert, Ștefan Transă, Ștefan Andrei, Cristian Olaru. – Ed. A II-a rev – Iași: Polirom, 2007
[10] Traducere autorizată după ediția în limba engleză, intitulată PHP AND MYSQL WEB DEVELOPMENT, ediția a III-a, 0672326728 de WELLING LUKE, THOMSON LAURA, publicată de Pearson Education, Inc, Copyright © 2005 Sams Publishing
[11] Introduction to the Google Maps Android API v2, developers.google.com, https://developers.google.com/maps/documentation/android/intro Consultat la15.06.2013
[12] Session Initiation Protocol, wikipedia.org, http://en.wikipedia.org/wiki/Session_Initiation_Protocol Consultat la10.06.2013
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Proiectarea Si Realizarea Unei Aplicatii Pentru Monitorizarea Unei Flote de Autobuze (ID: 163132)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
