Proiectarea Si Realizarea Unei Aplicatii Android Native

Cuprins

TOC \o 1-2

CAPITOLUL I. Introducere PAGEREF _Toc \h 2

CAPITOLUL II. TEHNOLOGII UTILIZATE PAGEREF _Toc1 \h 3

2.1 Android PAGEREF _Toc2 \h 3

2.1.1 Arhitectura Android PAGEREF _Toc3 \h 3

2.1.2 Activități Android PAGEREF _Toc4 \h 7

2.1.3 Crearea unei aplicații simple în Android PAGEREF _Toc5 \h 8

2.2 Java PAGEREF _Toc6 \h 10

2.2.1 Clase și obiecte PAGEREF _Toc7 \h 12

2.2.2 Ciclul de viață al unui fir de execuție (Thread) PAGEREF _Toc8 \h 16

2.3 Extensible Markup Language PAGEREF _Toc9 \h 17

2.4 SQLite PAGEREF _Toc10 \h 21

CAPITOLUL III. Proiectarea aplicației PAGEREF _Toc11 \h 22

3.1 Elemente generale PAGEREF _Toc12 \h 22

3.2 Modul de implementare al aplicației PAGEREF _Toc13 \h 22

CAPITOLUL vI. cONCLUZII PAGEREF _Toc14 \h 35

Bibliografie PAGEREF _Toc15 \h 36

CAPITOLUL I. Introducere

Tema aleasă pentru lucrarea de diplomă reprezintă o aplicație Android scrisă în cod nativ ce permite unui utilizator să salveze notițe cu un context de timp sau spațiu pentru a fi reamintit de acestea. Aplicația este scrisă să respecte ultimele standarde cu referire la proiectarea interfeței utilizator.

Am ales această tema deoarece pe parcursul ultimilor ani am devenit din ce în ce mai interesat de dezvoltarea aplicațiilor pe platformele mobile.

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 de asemenea 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. Ca mediu de dezvoltare integrat 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 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.

CAPITOLUL II. TEHNOLOGII UTILIZATE

2.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 în 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.

2.1.1 Arhitectura Android

Figura 2.1 Arhitectura Sitemului de operare Android

Sistemul de operare este structurat pe nivele, unde fiecare nivel este alcătuit dintr-un grup de programe. Fiecare nivel din arhitectura, oferă diferite servicii nivelului superior.

Kernel-ul

La baza sistemului de operare Android se află un kernel (nucleu) de Linux versiunea 3.4 pentru versiunile actuale de Android 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].

Faptul ca sistemul de operare Android a fost construit pe baza unui kernel linux a permis portarea cu relativă ușurință a acestuia pe diferite configurații hardware.

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 fișiere 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 și bitmap.

SQLite – un motor puternic și ușor de baze de date relaționale disponibil pentru toate aplicațiile.

Surface Manager-ul a fost utilizat pentru înregistrarea și tratarea evenimentelor de tip touch în aplicația proiectată iar SQLite a fost utilizat pentru persistența datelor.

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 șiruri 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.

View-urile sunt utilizate în aplicație pentru generarea interfeței utilizator. Aceste view-uri sunt create utilizând XML (Extensible Markup Language). Managerul de resurse oferă acces la resursele de tip layout ce descriu interfața utilizator cât și la șirurile de caractere localizate. Managerul de notificări este utilizat în serviciul aplicației, pentru generarea notificărilor în cazul unei alarme (Figura 3.9).

Managerul de activitate este utilizat în navigarea aplicației în momente cheie, unde utilizatorul poate reveni la pagina anterioară în cazul în care acesta apasă butonul Înapoi și pentru gestionarea ciclului de viață al aplicației, prin definirea metodelor cheie onCreate, onPause, onResume, onStop, onDestroy.

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 [2].

2.1.2 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 viată 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.

Figura 2.2 Ciclul de viață al unei aplicații Android

Ciclul de viață al unei activități, din momentul creări unei activități și până când activitatea se distruge este prezentat în figura 2.2.

Î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.

2.1.3 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.

Odată ce proiectul a fost creat, putem să începem să scriem cod. In directorul src avem activitatea HelloWorld.java, unde vom scrie funcționalitatea aplicației în limbajul de programare JAVA, folosind biblioteci Android scrise de Google.

Figura 2.3 Organizarea fișierelor într-o aplicație Android

Fișierele de aspect ale aplicației le putem localiza în directorul res/layout. Fișierul main.xml conține elementele grafice ce vor fi afișate în aplicație.

Elementele ce pot fi adăugate sunt: TextView, ListView, ImageView, Button, dar se pot și compune elemente grafice customizabile.

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" andfi adăugate sunt: TextView, ListView, ImageView, Button, dar se pot și compune elemente grafice customizabile.

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);

    }

}

Aplicația HelloWorld prezentată în exemplul de mai sus a fost folosită ca și punct de pornire pentru implementarea aplicației descrise în aceasta lucrare.

2.2 Java

Java este un limbaj de programare de nivel înalt, creat din dorința de a reduce dependința dintre aplicațiile dezvoltate și sistemul de operare pe care acestea rulează, cu alte cuvinte, Java permite inginerilor software să scrie codul sursă o singura data pentru a rula pe diferite sisteme de operare fără a necesita adaptarea codului pentru fiecare platformă în parte.[4]

Codul sursă Java este convertit în cod de octeți, un cod intermediar ce este mai apoi executat de către Mașina Virtuala Java, independent de arhitectura sistemului de operare utilizat.

La sfârșitul anului 2013, Java a devenit unul dintre cele mai populare limbaje de programare în folosința, în special pentru aplicații client-server cât și pentru aplicații mobile.[5]

In dezvoltarea limbajului de programare, cei de la Sun au avut în vedere 5 principii [6]:

Simplu, Orientat pe Obiecte și Familiar – Java este un limbaj simplu, ce poate fi folosit imediat, fără a necesita o durata lungă de acomodare, datorită asemănării sintaxei cu cea a limbajul C++. Elimină moștenirea multipla și supraîncărcarea operatorilor pentru a evita scrierea unui cod confuz. A fost creat ca fiind un limbaj de programare complet orientat pe obiecte, eliminând astfel programarea procedurala.

Robust și Securizat – Elimină sursele de erori ce apar în programare prin eliminarea pointerilor, administrarea automata a memoriei cu ajutorul garbage collection, acesta rulând în fundal. Limbajul este protejat de posibilele intruziuni cauzate de cod neautorizat.

Neutru din punct de vedere arhitectural și Portabil – Java a fost conceput să ruleze pe diferite platforme indiferent de sistemul de operare de pe acestea prin generarea așa-numitului „cod de octeți”, un limbaj interpretat de către Mașina Virtuala Java. Mașina Virtuala este creată pentru fiecare sistem de operare în parte, având o implementare specifica pentru fiecare dintre acestea. Aceasta este bazata pe specificațiile POSIX, un standard pentru platforme portabile.

Performanță ridicata – Interpretorul Java rulează la capacitate maximă fără a trebui să verifice starea mediului, iar garbage collector-ul rulează în fundal ca și un proces de prioritate scăzută pentru a asigura existența memoriei libere când va fi nevoie de aceasta.

Interpretat, Folosind fire de execuție și Dinamic – Interpretorul Java poate rula codul de octeți pe orice platforma pe care acesta a fost portat. Limbajul de programare oferă capabilitatea de a utiliza fire de execuție multiple, oferind un grad ridicat de interacțiune pentru utilizatorul final. Toate clasele prezente în bibliotecile Java sunt Thread seafe.

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 procesor, putând fi folosit doar pe platforma pe care a fost creat; codul de octeți este interpretat de mediul Java, în consecință acesta poate rula pe orice platforma ce folosește mediul Java.

2.2.1 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 [7]:

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ă în 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 în 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.

Figura 2.4 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 să 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

2.2.2 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

}

Un fir de execuție a fost utilizat pentru opțiunea de salvare pe Google Drive a bazei de date, pentru a nu bloca firul de execuție principal al aplicației.

2.3 Extensible Markup Language

Extensible Markup Language (XML) este un limbaj de marcare folosit pentru a defini un set de reguli pentru encodarea unor documente într-o formă lizibilă atât pentru oameni cât și pentru mașini. Este un standard definit de către World Wide Web Consortium (W3C) prin specificația XML 1.0. [8]

Deși XML este utilizat în mare parte pentru documente, acesta este folosit deseori și pentru reprezentarea structurilor de date. [9]

Pe Android, XML este utilizat pentru definirea interfeței utilizator, acesta oferind posibilitatea definirii statice, cât și manipularea dinamică în momentul rulării aplicației [10]. XML este un limbaj lizibil pentru oameni dar nu este cunoscut pentru eficienta sa, cu toate acestea XML a fost ales pentru Android, dar nu este folosit în forma simplă, ci este compresat într-o formă binară.

În realizarea aplicației am utilizat XML atât pentru definirea structurilor de date, a layout-urilor cât și pentru generarea dinamică de elemente și manipularea elementelor existente. Un exemplu se găsește în XML-ul ce definește structura unui element din lista de notițe și în codul de generare al listei, unde elementele sunt manipulate.

Codul sursa:

list_item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="?android:attr/listPreferredItemHeight"

android:padding="6dip" >

<ImageView

android:id="@+id/icon"

android:layout_width="60dip"

android:layout_height="fill_parent"

android:layout_alignParentBottom="true"

android:layout_alignParentTop="true"

android:layout_marginRight="6dip"

android:contentDescription="@string/list_item_image"

android:src="@drawable/ic_launcher" />

<TextView

android:id="@+id/secondLine"

android:layout_width="fill_parent"

android:layout_height="26dip"

android:layout_alignParentBottom="true"

android:layout_alignParentRight="true"

android:layout_toRightOf="@id/icon"

android:ellipsize="marquee"

android:singleLine="true"

android:textSize="12sp" />

<TextView

android:id="@+id/firstLine"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_above="@id/secondLine"

android:layout_alignParentRight="true"

android:layout_alignParentTop="true"

android:layout_alignWithParentIfMissing="true"

android:layout_toRightOf="@id/icon"

android:ellipsize="marquee"

android:singleLine="true"

android:gravity="center_vertical"

android:textSize="16sp" />

</RelativeLayout>

IconListArrayAdapter

ItemHolder viewHolder = new ItemHolder();

viewHolder.icon = (ImageView) row.findViewById(R.id.icon);

viewHolder.textContent = (TextView)row.findViewById(R.id.firstLine);

viewHolder.textTitle = (TextView)row.findViewById(R.id.secondLine);

row.setTag(viewHolder);

}

ItemHolder holder = (ItemHolder)row.getTag();

holder.icon.setImageDrawable(drawable);

holder.textTitle.setText(item.getContent());

holder.textContent.setText(String.valueOf(item.getTitle()));

2.4 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 [11].

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ă creează un fir de execuție în fundal și are metode cu care actualizează elementele grafice din interfața utilizator.

O alta optimizare al accesului la baza de date se poate realiza prin crearea unei clase de tip Singleton care realizează toate operațiile pe baza de date. Astfel nu se creează decât un singur obiect și se face economie de memorie. [12] [13]

CAPITOLUL III. Proiectarea aplicației

3.1 Elemente generale

Aplicația realizată ca parte a acestei lucrări este o aplicație Android nativă menită să fie utilizată de către persoanele care doresc să-și salveze notițe cu posibilitatea de a atribui o locație sau o data acesteia. In momentul în care utilizatorul se afla în preajma locației stabilite, o notificație va informa utilizatorul cu privire la notița înregistrată.

Stocarea datelor necesare funcționării aplicației: informații privind notițele cât și setările aplicației. se face folosind o bază de date SQLite.

3.2 Modul de implementare al aplicației

În următoarele pagini voi descrie funcționalitățile principale ale aplicației și interacțiunea utilizatorului cu diferitele controale.

Figura 3.1 Schema bloc a aplicației

Figura 3.1 prezintă structura generală a aplicației. Sistemul de operare Android stă la baza aplicațiilor, fiecare aplicație rulează separat de celelalte, într-un mediu izolat. Sitemul pornește Activitatea Principală a aplicației în momentul în care utilizatorul dorește, sau Serviciul în momentul în care a fost pornită conexiunea la rețea sau modulul GPS.

Aplicația Principală permite navigarea între paginile aplicației cât și selectarea unor acțiuni. Unele acțiuni, ca de exemplu acțiunea de Setări, sunt globale, în timp ce altele sunt accesibile în funcție de pagina selectată.

Fișierele aplicației sunt structurate în pachete Java, în funcție de rolul pe care acestea le îndeplinesc. Exista cinci mari pachete în proiect, acestea sunt:

com.degree.locationreminder.sqlutilities – conține codul pentru operațiile cu baza de date SQLite, oferind o serie de metode pentru operații de creare, actualizare, citire și ștergere a informațiilor din baza de date.

com.degree.locationreminder.apputilities – conține utilități generale utilizate de aplicație, printre care se numără și codul pentru serviciul de locație sau broadcast receiver-ul.

com.degree.locationreminder.interfaceutilities – conține codul pentru operații pe interfața cu utilizatorul, ca de exemplu generarea imaginilor pentru obiectele din lista, sau generarea listei.

com.degree.locationreminder.fragments – conține fragmentele aplicației. Fiecare fragment descrie o pagina cu particularitățile funcționale ale acesteia.

com.degree.locationreminder – pachetul părinte care conține codul principal al activității.

Figura 3.2 Organizarea fișierelor aplicației

Orice operație realizată asupra unor notițe implică realizarea unor acțiuni asupra bazei de date. Pentru a ușura lucrul cu baza de date am creat doua clase utilizate pentru operațiile cu SQLite ce expun o serie de metode pentru operțiile de bază CRUD (Create, Read, Update, Delete). Aceste clase sunt: SQLiteHelper și DatabaseAdapter.

SQLiteHelper realizează operațiile de creare și actualizare a bazei de date prin metodele moștenite din SQLiteOpenHelper : onCreate și onUpgrade. DatabaseAdapter implementează modelul de proiectare numit Singleton. Acest model presupune crearea unui constructor privat și existența unei metode statice ce returnează o instanță a clasei, astfel același obiect va fi folosit în diferite metode optimizând astfel utilizarea memoriei. [12] [13]

Aplicația respectă ultimele standarde Android cu privire la interacțiunea om-mașina, cu intenția de a prezenta o interfață familiară pentru navigarea diferitelor pagini ale aplicației. Interfața este creata utilizând elemente precum meniul de tip sertar, folosirea fragmentelor și incorporarea acțiunilor utile precum căutarea în interiorul barei de meniu. [14] [17]

Logica de selecție al elementului curent din meniu se găsește în activitatea aplicației, în entry point-ul aplicației. Când utilizatorul selectează un element, metoda onNavigationDrawerItemSelected este apelata. Această metodă conține logica de încărcare a diferitelor fragmente ale aplicației, clasa principală a aplicației, MainActivity fiind doar un coordonator al flow-ului, fără a conține logica de procesare a datelor.

public void onNavigationDrawerItemSelected(int position) {

// update the main content by replacing fragments

FragmentManager fragmentManager = getFragmentManager();

switch (position) {

case 0:

fragmentManager.beginTransaction()

.replace(R.id.container, NoteListFragment.newInstance(position + 1))

.commit();

break;

}

La pornirea aplicației, se deschide prima opțiune din meniul de navigare: opțiunea “Notițe”.  In cazul în care utilizatorul a pornit pentru prima dată aplicația, meniul este vizibil pentru a indica utilizatorului existența acestuia și modul de utilizare.

Figura 3.3 Meniul principal

În momentul în care Fragmentul Notițe este încărcat, aplicația preia lista de notițe din baza de date și o afișează utilizatorului sub forma unei liste de elemente, unde fiecare element are o imagine, un titlu și conținutul notiței.

Imaginea fiecărui element din listă este generată la momentul rulării aplicației, în funcție de textul din titlul elementului. Culoarea este generata pe baza hash-ului șirului de caractere, iar litera din imagine este prima litera din titlu convertita într-o litera mare.

Codul sursă:

public CharacterDrawable(char character, int color) {

super(color);

this.character = character;

this.textPaint = new Paint();

this.borderPaint = new Paint();

// text paint settings

textPaint.setColor(Color.WHITE);

textPaint.setAntiAlias(true);

textPaint.setFakeBoldText(true);

textPaint.setStyle(Paint.Style.FILL);

textPaint.setTextAlign(Paint.Align.CENTER);

// border paint settings

borderPaint.setColor(getDarkerShade(color));

borderPaint.setStyle(Paint.Style.STROKE);

borderPaint.setStrokeWidth(STROKE_WIDTH);

}

Această pagină oferă utilizatorului o serie de interacțiuni posibile cu elementele listei. In momentul în care utilizatorul apasă scurt pe un element din lista, acesta va fi redirecționat spre pagina de editare al notiței respective.

Daca, în schimb, utilizatorul apasă lung pe un element din lista și trage elementul spre stânga, acesta va fi marcat ca și stres.

Figura 3.4 Pagina de Notițe

A doua opțiune din meniul de navigare este opțiunea Alarme. In acest meniu se încarcă o listă cu toate notițele care au setate o locație sau o dată pentru lansarea unei alarme.

Controalele specifice listei sunt prezente și aici, oferind-ui utilizatorului opțiunea să editeze sau să șteargă o notița din lista.

A treia opțiune din meniul de navigare este opțiunea Coș de Gunoi. In acest meniu se încarcă o listă cu toate elementele care au fost marcate ca și șterse. Acestea vor fi păstrate pentru o durata de timp în această stare, după care, daca utilizatorul nu inversează acțiunea de ștergere, notițele vor fi șterse permanent.

A patra opțiune din meniul de navigare este opțiunea Hartă. Această opțiune încarcă un Fragment cu o harta, ce permite utilizatorului să vadă pe hartă toate notițele ce au o alarmă de tip locație, pe o anumita rază. Daca utilizatorul apasă pe marker-ul elementului, titlul și conținutul notiței vor apărea într-un popup. Dacă utilizatorul apasă pe popup, acesta va fi redirectat la pagina de editare a notiței. [15]

Figura 3.5 Pagina de Hartă

A cincea opțiune din meniul de navigare este opțiunea Salvează în Drive. Aceasta opțiune redirectează utilizatorul la o pagina care ii permite acestuia să salveze o copie a bazei de date locale, pe Google Drive, sau de a copia o baza de date salvată pe Drive, pe dispozitivul local.

Mai departe voi prezenta opțiunile meniului de context. Acest meniu a fost gândit ca fiind un meniu global. Același meniu apare pe toate paginile aplicației. Opțiunile sunt: Căutare, Adaugă Notița, Setări, Ajutor, Despre și Ieșire.

Opțiunile meniului au nume sau icoane sugestive, fiecare redirectând utilizatorul la o pagina separata în cadrul aplicației.

Opțiunea Setări prezintă utilizatorului o serie de opțiuni specifice aplicației pe care acesta le poate configura.

Opțiunea Ajutor oferă utilizatorului o serie de instrucțiuni cu privire la utilizarea aplicației.

Opțiunea Despre prezinta utilizatorului informații referitoare la versiunea aplicației și autorul acesteia, cât și o lista cu schimbările realizate în ultima versiune.

Opțiunea Ieșire, oferă utilizatorului o metoda de a ieși din aplicație.

Prima opțiune, Căutare oferă utilizatorului de a filtra lista de notițe pe meniurile care prezinta aceasta listă. Textul introdus va fi căutat atât în titlul cât și în conținutul notițelor.

Figura 3.6 Opțiunea de căutare

Lista este filtrată în timp real în funcție de textul introdus. Filtrarea se realizeară direct pe baza de date folosind metoda getForSearchText din clasa DatabaseAdapter.

Figura 3.7 Funcționalitatea de căutare

Codul sursă:

public ArrayList<NoteModel> getForSearchText(String text) {

ArrayList<NoteModel> model = new ArrayList<NoteModel>();

Cursor cursor = database.query(databaseTable, allColumns,

SQLiteHelper.COLUMN_TITLE + " like '%" + text + "%' OR " + SQLiteHelper.COLUMN_CONTENT + " like '%" + text + "%'", null, null, null, null);

cursor.moveToFirst();

while (!cursor.isAfterLast()) {

NoteModel item = cursorToNoteModel(cursor);

model.add(item);

cursor.moveToNext();

}

// Make sure to close the cursor

cursor.close();

return model;

}

Metoda getForSearchText primește șirul de caractere de căutat ca și parametru și construiește query-ul pentru căutarea în cele două câmpuri: Titlu, respectiv Conținut și generează o listă de elemente care va fi returnată.

Figura 3.8 Funcționalitatea de căutare

Căutarea este realizată pentru fiecare Fragment prin moștenirea clasei SearchView.OnQueryTextListener, un handler de evenimente ce apelează metoda onQueryTextChange în momentul în care textul din câmpul de căutare se schimbă.

Codul sursă:

NoteListFragment

@Override

public boolean onQueryTextChange(String newText) {

Context applicationContext = getActivity();

ArrayList<NoteModel> model = IconListArrayAdapter.filterModel(newText, applicationContext);

this.arrayAdapter = new IconListArrayAdapter(applicationContext, model);

ListView listView = (ListView) this.getView().findViewById(R.id.listView1);

listView.setAdapter(arrayAdapter);

return false;

}

IconListArrayAdapter

public static ArrayList<NoteModel> filterModel(String text, Context context) {

DatabaseAdapter dbAdapter = DatabaseAdapter.getInstance(context);

ArrayList<NoteModel> model = dbAdapter.getForSearchText(text);

return model;

}

A doua opțiune, Adaugă Notița, deschide pagina de configurare a unei notițe noi. Aceasta pagina conține doua câmpuri pentru introducere de text: una pentru titlu și una pentru conținut. Tot pe aceasta pagina este și cate un control pentru setarea unei date și locații pentru notița, în funcție de opțiunea selectată.

Una din componentele majore ale aplicației este serviciul. Utilizatorul nu poate interacționa direct cu serviciul, acesta fiind un proces ce rulează în fundal. Serviciul este pornit în momentul în care utilizatorul pornește conexiunea la internet sau GPS-ul și citește locația curenta a utilizatorului. Daca utilizatorul este în apropierea unei locații setate o notificare va informa utilizatorul ca exista notițe în apropiere. [15] [16]

Codul care pornește serviciul se afla în clasa LocationReminderBroadcastReveiver.

Codul sursă:

public class LocationReminderBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Intent serviceIntent = new Intent(context, LocationService.class);

context.startService(serviceIntent);

}

}

Figura 3.9 Notificare generată de Serviciu

În momentul în care utilizatorul apasă pe notificare, acesta va fi redirectat către pagina de editare a notiței.

CAPITOLUL vI. cONCLUZII

Pe parcursul lucrării au fost prezentate cele mai importante elemente necesare dezvoltării unei aplicații native bazate pe platforma Android. În realizarea ei s-au folosit următoarele tehnologii: Java, Android SDK, XML, SQLite.

Aplicația oferă utilizatorului posibilitatea de a-și seta o alarmă pe o notiță în funcție de locație sau timp, aceste funcționalități fiind realizate prin utilizarea modulului GPS și utilizarea API-ului GoogleMaps. Aplicația a fost gândită să respecte ultimele standarde în crearea interfeței utilizator, pentru a păstra familiaritatea navigării și controlului cu care utilizatorii sunt obișnuiți.

Un alt aspect important în dezvoltarea aplicației este modularitatea acesteia, codul fiind structurat într-un mod ce permite extinderea funcționalității cu relativa ușurință. Fiecare funcționalitate a aplicației este încapsulată într-un fragment, iar logica responsabilă de implementarea interfeței utilizator este separată de cea a managementului bazei de date.

Pe viitor aplicația poate fi extinsă prin: adăugarea funcționalității de notițe criptate, protejate printr-o parolă setată de utilizator sau crearea unui modul pentru backup automat pe un server.

De asemenea poate fi adăugată opțiunea de a insera elemente multimedia în notițe, cum ar fi imaginile sau de a șterge automat un element din listă dacă data curentă este mai mare decât data setată cu un anumit număr de zile.

Bibliografie

[1] Android, the first world's most popular mobile platform, android.com, http://developer.android.com/about/index.html, Consultat la 10.06.2014

[2] Introduction to Java Threads, freejavaguide.com, http://www.freejavaguide.com/java-threads-tutorial.pdf, Consultat la 20.06.2014

[3] Activity lifecycle, developer.android.com, http://developer.android.com/training/basics/activity-lifecycle/starting.html#lifecycle-states, Consultat la 23.06.2014

[4] The History of Java Technology, www.oracle.com, http://www.oracle.com/technetwork/java/javase/overview/javahistory-index-198355.html, Consultat la 23.06.2014

[5] Programming Language Popularity, langpop.com, http://www.langpop.com/, Consultat la 23. 06.2014

[6] The Java Language Environment, oracle.com, http://www.oracle.com/technetwork/java/intro-141325.html, Consultat la 23. 06.2014

[7] Java: de la 0 la expert, Ștefan Transă, Ștefan Andrei, Cristian Olaru. – Ed. A II-a rev – Iași: Polirom, 2007

[8] Extensible Markup Language (XML) 1.0 (Fifth Edition), http://www.w3.org, http://www.w3.org/TR/REC-xml, Consultat la 18.06.2013

[9] Fennell, Philip. "Extremes of XML", 2013

[10] Layouts, developers.google.com, http://developer.android.com/guide/topics/ui/declaring-layout.html, Consultat la 18.06.2013

[11] SQLite, sqlite.org, http://www.sqlite.org/about.html, Consultat la 25.06.2013

[12] Singleton Design Pattern, sourcemaking.com, http://sourcemaking.com/design_patterns/singleton, Consultat la 20.06.2013

[13] Best Practices for performance, developers.google.com, https://developer.android.com/training/best-performance.html, Consultat la 19.06.2013

[14] Best Practices for User Interface, developers.google.com, https://developer.android.com/training/best-ui.html, Consultat la 17.06.2013

[15] Introduction to the Google Maps Android API v2, developers.google.com, https://developers.google.com/maps/documentation/android/intro, Consultat la 17.06.2013

[16] Best Practices for Background Jobs, developers.google.com, https://developer.android.com/training/best-background.html, Consultat la 19.06.2013

[17] Android Design Patterns, developers.google.com, https://developer.android.com/design/patterns/index.html, Consultat la 20.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.2014

[2] Introduction to Java Threads, freejavaguide.com, http://www.freejavaguide.com/java-threads-tutorial.pdf, Consultat la 20.06.2014

[3] Activity lifecycle, developer.android.com, http://developer.android.com/training/basics/activity-lifecycle/starting.html#lifecycle-states, Consultat la 23.06.2014

[4] The History of Java Technology, www.oracle.com, http://www.oracle.com/technetwork/java/javase/overview/javahistory-index-198355.html, Consultat la 23.06.2014

[5] Programming Language Popularity, langpop.com, http://www.langpop.com/, Consultat la 23. 06.2014

[6] The Java Language Environment, oracle.com, http://www.oracle.com/technetwork/java/intro-141325.html, Consultat la 23. 06.2014

[7] Java: de la 0 la expert, Ștefan Transă, Ștefan Andrei, Cristian Olaru. – Ed. A II-a rev – Iași: Polirom, 2007

[8] Extensible Markup Language (XML) 1.0 (Fifth Edition), http://www.w3.org, http://www.w3.org/TR/REC-xml, Consultat la 18.06.2013

[9] Fennell, Philip. "Extremes of XML", 2013

[10] Layouts, developers.google.com, http://developer.android.com/guide/topics/ui/declaring-layout.html, Consultat la 18.06.2013

[11] SQLite, sqlite.org, http://www.sqlite.org/about.html, Consultat la 25.06.2013

[12] Singleton Design Pattern, sourcemaking.com, http://sourcemaking.com/design_patterns/singleton, Consultat la 20.06.2013

[13] Best Practices for performance, developers.google.com, https://developer.android.com/training/best-performance.html, Consultat la 19.06.2013

[14] Best Practices for User Interface, developers.google.com, https://developer.android.com/training/best-ui.html, Consultat la 17.06.2013

[15] Introduction to the Google Maps Android API v2, developers.google.com, https://developers.google.com/maps/documentation/android/intro, Consultat la 17.06.2013

[16] Best Practices for Background Jobs, developers.google.com, https://developer.android.com/training/best-background.html, Consultat la 19.06.2013

[17] Android Design Patterns, developers.google.com, https://developer.android.com/design/patterns/index.html, Consultat la 20.06.2013

Similar Posts

  • Programul Matlab

    Introducere Lucrarea de față are drept scop studiul asupra posibilitaților de prelucrare și analiză a imaginilor cu ajutorul programului MATLAB. Prelucrarea si analiza imaginilor mai poate fi numită si pe scurt prelucrarea imaginilor, a luat naștere din cauza necesității si ideii de a înlocui observatorul uman printr-o mașină.Cel mai important de spus este faptul că…

  • Laborator Virtual In Cloud

    LABORATOR VIRTUAL IN CLOUD CUPRINS Introducere Capitolul 1 1. Cloud Computing 1.1 Ce este cloud computing 1.2 Caracteristicile cloud computing 1.3 Modele de servicii cloud 1.4 Modele de deployment Capitolul 2 2. Platforme Cloud Computing 2.1 Amazon cloud computing 2.2 Google cloud computing 2.3 Microsoft Windows Azure și serviciile online 2.4 Platforme software Open-source pentru…

  • Sistem Informatic de Localizare Geografica

    Introducere. Grafica interactivă este o ramură a informaticii aplicate, cu o largă răspândire în prezent, care se ocupă – in principal – cu comunicația om-sistem de calcul, prin intermediul desenelor și imaginilor (a graficii). În domeniul graficii interactive, sunt reunite două aplicații distincte ale informaticii : prelucrarea automată a graficelor (grafism) și sistemele interactive. Una…

  • Sub Sistem Informatic Privind Gestiunea Decontarilor CU Tertii

    CUPRINS Introducere …………………………………………………………………………………………………………. 4 Capitolul I Aspecte generale privind decontările cu terții ………………………………………… 5 Delimitări și structuri privind datoriile și creanțele …………………………………………….. 6 Evaluarea datoriilor și creanțelor ……………………………………………………………………… 8 Purtători primari de informații ……………………………………………………………………….. 10 Regimul juridic al decontărilor cu terții …………………………………………………………… 16 Capitolul II Contabilitatea decontărilor cu terții la S.C. Vastex S.A. Vaslui …………………

  • Tehnologii de Elaborare a Paginilor Web In Html Php Si Xml

    Introducere        Cu toate ca este cel mai popular mijloc de comunicare, în realitate Internetul este confuz si încurcat. Internetul este o rețea de rețele, prin intermediul căreia calculatoarele, și mai nou telefonia mobilă interacționeaza, folosindu-se de o serie de instrucțiuni cunoscute și ca protocoale. Aproape fiecare se poate conecta folosindu-și propriul computer,…

  • Servere de Baze de Date

    SERVERE DE BAZE DE DATE MANUAL UNIVERSITAR CUVÂNT ÎNAINTE Provocările din societatea contemporană impun existența unor sisteme electronice de calcul performante în cadrul fiecărei organizații. Nevoia de decizii rapide, asistate de calculator, impune prelucrarea unor volume mari de date, constituite în baze de date. Datele unei organizații trebuie să fie disponibile în timp util și…