Invata Sistemul de Operare Android – Partea 7

Bine ati venit pe ItAssistant. Aceasta noua serie de tutoriale isi propune sa va familiarizeze cu Sistemul de Operare Android astfel incat sa puteti sa scrieti singuri aplicatii pentru propriul SmartPhone, si de ce nu, aplicatia sa ajunga in top pe Android Market.

Inainte de a incepe trebuie sa cunoasteti destul de bine limbajul de programare Java si conceptele Programarii Orientata Obiect; puteti sa aruncati o privire peste tutorialele noastre avansate: Invata Java

Android Intents

Android este o platforma mobila bazate pe o arhitectura orientata pe servicii. Aplicatiile sunt compuse din componente independente care isi ofera servicii una alteia. Legatura dintre aceste componente se face prin Intent-uri. Acestea sunt de fapt obiecte ce sunt serializate si trimise catre sistem. Sistemul le analizeaza, hotareste care este cea mai buna componenta de destinatie, porneste componenta, si trimite Intent-ul mai departe acesteia.

Propietatiile

Fiecare Intent are urmatoarele propietati:

  • action:String – denumeste actiunea ce trebuie efectuata. Nu poate lipsi.
  • data:Uri – datele asupra carora trebuie efectuata actiunea. Nu poate lipsi.
  • category:String[] – o lista de informatii suplimentare ce definesc actiunea
  • component:String/class – componenta care sa efectueze actiunea
  • type:String – tipul datelor
  • extra:Bundle – date suplimentare trimise componentei de destinatie

Action

Acesta propietate defineste actiunea ce se doreste a fi indeplinita. Exemple de actiuni sunt:

  • ACTION_SEND
  • ACTION_CALL
  • ACTION_VIEW
  • ACTION_EDIT
  • ACTION_MAIN

Din punct de vedere al Java, actiunea este stocata sub forma unui String.

Acesta propietate nu poate lipsi.

Exemplu

// crearea Intent-ului
Intent intent = new Intent ();
 
// setarea unei actiuni predefinite in Android
intent.setAction (Intent.ACTION_EDIT);
 
// setarea unei actiuni definite de catre programator
intent.setAction ("actiunea mea");

Data

Acesta propietate reprezinta datele asupra carora sa se efectueze actiunea. Din punct de vedere Java, datele sunt stocate sub forma unui Uri. Exemple ar fi:

  • tel:071334434
  • file:///sdcard/fisierul.txt
  • content://contacts/un_nume_de_contact

Acesta propietate nu poate lipsi.

Se poate face urmatoarea analogie: daca intent-ul reprezinta o cerere HTTP, actiunea este metoda din HTTP iar datele sunt URL-ul.

Spre exemplu:

HTTP

GET /index.html HTTP/1.1
Host: www.android.com

Intent

{action=android.intent.action.VIEW; data=http://www.android.com/index.html}

Exemplu

// crearea Intent-ului
Intent intent = new Intent ();
// setarea unei actiuni predefinite in Android
intent.setAction (Intent.ACTION_VIEW);
 
// setarea datelor, in cazul de fata pagina www.android.com
intent.setData (Uri.parse ("http://www.android.com");

Category

Categoriile sunt memorate sub forma unui sir de String-uri. Acestea reprezinta informatii suplimentare despre actiunea ce trebui indeplinita. Cu ajutorul acestora, sistemul poate identifica mai bine cea mai buna componenta care sa efectueze actiunea. Exemple de categorii sunt:

  • CATEGORY_LAUNCHER
  • CATEGORY_HOME
  • CATEGORY_DEFAULT

Spre exemplu, componentele care pot efectua actiunea ACTION_MAIN sunt componentele de intrare intr-o aplicatie (in analogie cu programele standard, sunt clasele ce contin functia main). In functie de categorie, componentele sunt (lista este departe de a fi completa):

  • plasate in meniul principal al telefonului (CATEGORY_LAUNCHER)
  • pornite cand se apasa butonul Home (CATEGORY_HOME)

Exemplu

// crearea Intent-ului
Intent intent = new Intent ();
 
// setarea categoriilor carora le este destinate Intent-ul
intent.addCategory (Intent.CATEGORY_DEFAULT);
intent.addCategory ("categorie nestandard");

Component

Acesta propietate permite specificare exacta a componentei care trebuie sa efectueze actiunea. In general, componenta nu este speficicata ci este dedusa dupa analizarea celorlalte propietati. In cazul in care se specifica o componenta, sistemul o va porni direct, fara sa mai analizeze propietatiile celelalte.

Spre exemplu, daca dorim sa trimitem un email, vom specifica actiunea ACTION_SEND, adresa de destinatie si textul email-ului. Sistemul va determina automat care este programul de email predefinit si ne va deschide fereastra de editare a email-ului. In alanogie cu HTTP, avem acolo adresele mailto:nume@adresa.de.email.

In cazul in care dorim sa trimitem un email cu un anumit program, vom specifica actiunea ACTION_SEND si vom seta drept componenta de destinatie clasa din programul dorit.

Exemplu

// crearea Intent-ului
Intent intent = new Intent ();
 
// setarea componente, in cazul in care este in aceelasi pachet cu componenta ce va emite evenimentul
// this reprezinta Contextul
intent.setClass (this, NumeClasa.class);
 
// daca componenta este in alta aplicatie (alt APK)
intent.setClassName ("un.pachet", "NumeClasa");

Type

Acesta propietate este un String ce specifica tipul datelor din Intent. Daca nu este explicit specificat, tipul este dedus din Uri-ul datelor. Exemple

image/jpeg
audio/mp3
text/html>

Exemplu

// crearea unui Intent
Intent intent = new Intent ();
 
// setarea tipului
intent.setType ("image/jpg");

Extra

Acesta este un parametru de tip Bundle cu ajutorul caruia putem atasa parametrii Intent-ului. Acest Bundle este trimis componentei de destinatie. Functiile puse la dispozitie sunt:

void putExtra (String key, String value);
void putExtra (String key, int value);
void putExtra (String key, double value);
void putExtra (String key, long value);
void putExtra (String key, boolean value);
void putExtra (String key, String[] value);
void putExtra (String key, byte value);
void putExtra (String key, byte[] value);
// etc.
 
String getStringExtra (String key);
String[] getStringArrayExtra (String key);
double getDoubleExtra (String key, double defaultValue);
int getIntExtra (String key, int defaultValue);
long getLongExtra (String key, long defaultValue);
boolean getBooleanExtra (String key, boolean defaultValue);
ArrayList<String> getStringArrayListExtra (String key);
// etc.

Functiile get…Extra(…) intorc null in cazul in care parametru nu exista. Functiile care intorc tipuri primare (long, int, float, double, boolean, byte etc.) nu pot intoarce null (null este valid doar pentru obiecte), si astfel intoc valoarea lui defaultValue in cazul in care parametru nu exista.

Exemple de utilizare

In functie de tipul componentei de destinatie, pentru a emite un Intent, se folosesc una din functii:

// daca componenta este o activitate
void startActivity (Intent intent);
 
// daca componenta este o activitate si acesta trebuie sa intoarce o valoare
void startActivityForResult (Intent intent, int requestCode);
 
// daca componenta este un serviciu
void startService (Intent intent);

Pornirea unei componente

Unul din cele mai simple exemple de utilizare a unui Intent este pornirea unei alte componente din aceelasi pachet (program). Deoarece cunoastem exact ce componente dorim sa pornim, vom seta direct parametru component. Dearece componenta este o clasa, vom folosi functia setClass in loc de setComponent.

// construim un Intent
Intent intent = new Intent ();
 
// setam componenta de destinatie (activitatea implmentata in clasa ActivitateDePornit)
intent.setClass(this, ActivitateDePornit.class);
 
// componenta de destinatie stim ca este o activitate, deci emitem Intent-ul cu startActivity
// atentie, functia startActivity intoarce imediat, urmand ca sistemul sa porneasca la un moment dat fereastra
startActivity (intent);

Pasarea de parametrii cartre alta componenta

Din cauza modului de pornire a unei noi componente (o porneste sistemul, nu noi), ne este imposibil sa pasam direct parametrii. Nu avem nici o referinta (pointer) catre noua componenta. Astfel, pasarea parametrilor se face prin intermediul propietatii extre din intent-ul de pornire. Vom modifica in continuare exemplul de mai sus pentru a trimite un parametru ferestrei noi create:

// construim un Intent
Intent intent = new Intent ();
 
// setam componenta de destinatie (activitatea implmentata in clasa ActivitateDePornit)
intent.setClass(this, ActivitateDePornit.class);
 
// setam parametrul doi parametrii, un String cu numele "nume" si un numar cu numele "numar"
intent.putExtra("nume", "un nume");
intent.putExtra("numar", 10);
 
// componenta de destinatie stim ca este o activitate, deci emitem Intent-ul cu startActivity
// atentie, functia startActivity intoarce imediat, urmand ca sistemul sa porneasca la un moment dat fereastra
startActivity (intent);

In activitatea pornita, preluam parametrii in felul urmator:

// preluam Intent-ul care ne-a pornit
Intent intent = getIntent ();
 
// preluam parametrii
String nume = intent.getStringExtra("nume");
int numar = intent.getIntExtra("numar", 0);
 
// afisam in log parametrii primiti
Log.d ("intent", "nume: "+nume);
Log.d ("intent", "nume: "+numar);

Asteptarea unui raspuns

De multe ori apar situatii in care o fereastra trebuie sa intoarca niste date ferestrei care a pornit-o. De exemplu, avem un program ce pastreaza o lista de filme.

Dorim sa adaugam un film nou, dar cum formularul de adaugare este mai mare, dorim sa cream o fereastra noua. Astfel, utilizatorul apasa pe butonul Adaugare, se deschide o fereatsra nou, utilizatorul completeaza datele noului film si apasa Adauga. Fereastra cu formularul se inchide si trimite datele inapoi fereastrei cu lista. Actiunea acestea se face in felul urmator:

Codul pentru butonul Adaugare din lista de filme:

Intent adauga = new Intent ();
 
// stim excat cine este componenta de destinatie
adauga.setClass (ListaFilme.this, FormularAdaugare.class);
 
// pronim activitatea si specificam ca dorim un raspuns
// numarul 100 reprezinta un numar definit de noi
startActivityForResult (adauga, 100);

Intoarcerea datelor se face prin intermediul unui obiect de tip Intent. Astfel, fereastra cu formularul va crea un nou Intent si il va trimit drept raspuns fereastrei cu lista.

Codul pentru butonul Adauga din formular este:

// cream obiectul de raspuns
Intent raspuns = new Intent ();
 
// setam parametrii
raspuns.putExtra ("nume", nume.getText().toString());
raspuns.putExtra ("an", Integer.parseInt (an.getText().toString()));
raspuns.putExtra ("regizor", regizor.getText().toString());
 
// setam raspunsul, numarul 1 reprezinta un cod numeric al raspuinsului, definit de catre noi
// in cazul nostru reprezinta butonul apasat 
// 1 - pentru Adauga
// 0 - pentru renunte (vezi exemplul urmator)
setResult (1, raspuns);
 
// inchidem formularul
finish ();

Vom presupune ca formularul nostru are si un buton de renunta. Codul pentru acest buton este:

// in cazul acesta nici nu mai trimitem un Intent, nu are rost 
// deoarece nu trimitem nici o informatie despre vreun film
setResult (0);
 
// inchidem formularul
finish ();

In activitatea cu lista de filme, vom suprascrie functie onActivityResult(…). Functia este apelata pentru orice activitate care intoarce un rezultat catre lista de filme (formular de adaugare, formular de modficare etc.), iar selectia se face dupa requestCode.

    @Override
    public void onActivityResult (int requestCode, int responseCode, Intent data)
    {
    	// raspunsul vine de la formularul de adaugare
    	// acolo am cerut raspunsul cu nr 100
    	if (requestCode == 100)
    	{
    		// s-a apasat butonul Adauga
    		if (responseCode==1)
    		{
    			String nume = data.getStringExtra("nume");
    			int an = data.getIntExtra("an", 0);
    			String regizor = data.getStringExtra("regizor");
 
    			// adaptor.adaugaFilm (nume, an, regizor);
    		}
    		// s-a apasat butonul Renunta
    		else if (responseCode==0)
    		{
    		}
    	}
    }
Android Intents

Android – Filtre de Intent-uri

Fiecare componenta trebuie sa declare (in manifest) la ce Intent-uri raspunde, practic cu ce Intent-uri poate fi pornita. Astfel, fiecare componenta trebuie/poate declara:

  • actiunea
  • categorie
  • tipul

Exemplul urmator ilustreaza o activitate ce raspunde la actiunile EDIT si VIEW pentru tipul image/jpeg din categoria DEFAULT.

        <activity android:name=".ImageActivity"
                  android:label="Image Activity">
            <intent-filter>
                <action android:name="android.intent.action.EDIT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:nameType="image/jpeg"/>
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:nameType="image/jpeg"/>
            </intent-filter>
        </activity>

Related posts:

  1. Invata Sistemul de Operare Android – Partea 9
  2. Invata Sistemul de Operare Android – Partea 12
  3. Invata Sistemul de Operare Android – Partea 6
  4. Invata Sistemul de Operare Android – Partea 5
  5. Invata Sistemul de Operare Android – Partea 13
Tags: , , , , , , ,

V-a placut acest tutorial? Aveti anumite sugestii pentru urmatoarele tutoriale video? Lasati un comentariu! Feedback-ul vostru este foarte important pentru noi.

Pentru intrebari mai elaborate, cu caracter general, va rugam folositi forumul si in cel mai scurt timp veti primi un raspuns. Astfel ii vom ajuta si pe ceilalti sa invete din eventualele probleme.