Cum trimit un SMS in Android

@uthors: Octav Dospinescu & Marian Perca

O categorie foarte interesantã a aplicaţiilor mobile o constituie cea care foloseşte atributele oferite de tehnologia GSM, foarte popularã în rândul utilizatorilor de telefonie mobilã. Ne propunem ca în cadrul acestui capitol sã dezvoltãm o mini-aplicaţie ce va fi capabilã sã realizeze urmãtoarele operaţiuni:

  • preluarea unui mesaj de tip text de la utilizatorul dispozitivului mobil;
  • trimiterea unui mesaj de tip SMS (Short Message Service) cãtre un destinatar mobil;
  • informarea utilizatorului cu privire la mesajul trimis;
  • informarea utilizatorului cu privire la eventualele erori apãrute în timpul transmisiei.

De fapt, ne dorim sã implementãm o aplicaţie care sã ruleze pe un emulator şi sã trimitã mesaje SMS cãtre alt emulator. Din fericire, acest lucru nu este foarte dificil deoarece necesitã doar cunoştinţe minime de Android, cunoştinţe pe care aţi avut ocazia sã le asimilaţi în capitolele anterioare. În cazul în care reuşim sã realizãm o astfel de implementare, ne propunem ca spre final sã dezvoltãm şi un modul capabil sã „intercepteze” mesajele primite pe telefonul mobil. Aceastã operaţiune are drept scop prelucrarea explicitã a datelor pe care le conţine un mesaj SMS pe care îl primim pe telefonul mobil: numãrul expeditorului şi mesajul propriu-zis.

            3.1 Trimiterea unui mesaj SMS

Pentru început, vom începe cu o operaţiune absolut necesarã, şi anume crearea unui nou emulator, astfel încât în mediul Eclipse sã avem douã emulatoare care pot rula simultan. Ideea este cã unul dintre emulatoare va fi folosit drept „gazdã” pentru aplicaţia noastrã, iar cel de-al doilea va fi folosit drept „destinatar” sau „primitor” de mesaje SMS. Definirea unui nou emulator se face prin apelarea meniului Window, opţiunea Android SDK and AVD Manager. Prin acţionarea butonului New din fereastra care apare, pe lângã emulatorul cu numele dispozitivOctav, mai definim şi emulatorul cu numele destinatie, conform figurii urmãtoare.

Figura nr.  1 – Definirea a douã emulatoare în cadrul mediului Eclipse

Deşi nu este cazul chiar în acest moment, este bine de ştiut cã pentru a porni cele douã emulatoare trebuie sã ne poziţionãm pe rând pe denumirea fiecãruia şi apoi sã acţionãm butonul Start. Pentru ca utilizatorul sã poatã folosi aplicaţia noastrã, construim în cadrul unui nou proiect (appSMStavy) o interfaţã graficã ce va avea 3 elemente simple: un text informativ (TextView – Introduceti mesajul dvs.), o casetã de text în care utilizatorul va putea sã-şi tasteze mesajul dorit (EditText) şi un buton prin care se va declanşa operaţiunea de trimitere a unui sms (Button). Pe scurt, la finalul acestei etape de design, mediul Eclipse va arãta cam în felul urmãtor.

Figura nr.  2 – Elementele principale de design ale formularului

                Nu insistãm foarte mult asupra proprietãţilor fiecãrui control grafic, însã reţinem faptul cã am modificat id-urile aferente: lblEticheta, txtMesaj şi btnTrimiteSMS. Aceste id-uri vor fi utilizate în codul Java pentru a instanţia obiectele pe care le vom folosi mai departe. În demersul nostru ne vom folosi de clasa SmsManager din pachetul android.telephony. Recomandãm importul explicit al acestui pachet prin folosirea directivei import android.telephony.SmsManager;. Clasa SmsManager are rolul de a permite gestionarea mesajelor de tip sms în ceea ce priveşte trimiterea lor cãtre un destinatar. Obţinem obiecte din clasa SmsManager prin apelul metodei statice SmsManager.getDefault(). Metoda care ne intereseazã la acest moment se numeşte sendTextMessageşi are urmãtoarea listã de parametri:

  • destinationAddress: reprezintã numãrul destinatarului, exprimat în format String;
  • scAddress: reprezintã numãrul centrului de servicii, în format String. În mod implicit, acest numãr este deja cunoscut de cãtre dispozitivul mobil şi ca urmare putem folosi valoarea null pentru a beneficia de numãrul implicit.
  • text: reprezintã mesajul care va fi trimis cãtre destinationAddress, folosind centrul de servicii scAddress. Este foarte important sã menţionãm faptul cã dacã acest text are mai mult de 160 de caractare (lungimea maximã a unui mesaj SMS standard), atunci va fi generatã o excepţie ce va trebui tratatã.
  • sentIntent şi deliveryIntent au rolul de a capta coduri rezultate în urma trimiterii şi livrãrii mesajelor. Recomandãm pentru început folosirea valorilor null în cazul acestor ultimi 2 parametri.

Metoda sendTextMessagegenereazã o excepţie IllegalArgumentException dacã destinationAddress sau text sunt vide. La modul simplist, utilizarea clasei SmsManager se poate face pe baza urmãtoarelor secvenţe de cod, înlocuind cu valori valide numarDestinatar şi mesajSMS.

SmsManager sms; sms = SmsManager.getDefault(); sms.sendTextMessage(numarDestinatar, null, mesajSMS, null, null);

Implementarea efectivã şi completã a aplicaţiei noastre este realizatã în secvenţa de mai jos.

</pre>
package smsTavy.com;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class AppSMStavyActivity extends Activity implements OnClickListener {
 /** Called when the activity is first created. */
//declaram butonul de trimitere sms Button btnSMS;
//declaram caseta de text in care vom tasta mesajul ce va fi trimis TextView txtMesaj;
//definim o variabila de tip Toast pe care o vom folosi la afisarea notificarilor
Toast notificare;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//instantiem butonul de trimitere
sms btnSMS = (Button) findViewById(R.id.btnTrimiteSMS);
//instantiem caseta de text de unde vom prelua mesajul tastat de user
txtMesaj = (TextView) findViewById(R.id.txtMesaj);
//"ascultam" evenimentul "click"
btnSMS.setOnClickListener(this);
 }

 @Override public void onClick(View v) {
 // TODO Auto-generated method stub if(v==btnSMS) {
//adica s-a apasat butonul de trimitere SMS
//generam un nou manager pentru trimitere
 SMS SmsManager sms;
sms = SmsManager.getDefault();
 //stabilim numarul destinatarului
 String numarDestinatar;
 numarDestinatar="5556";
 //preluam mesajul introdus de user pe formular
 String mesajSMS;
 mesajSMS=this.txtMesaj.getText().toString();
 try {
 //trimitem efectiv SMS-ul
 sms.sendTextMessage(numarDestinatar, null, mesajSMS, null, null);
//realizam un mesaj pentru a instiinta utilizatorul
notificare = Toast.makeText(getApplicationContext(), "Mesajul a fost trimis",Toast.LENGTH_LONG);
 //afisam mesajul notificare.show();
}
 catch (Exception eroare)
 {
//in caz de esec, afisam mesajul de eroare
 notificare = Toast.makeText(getApplicationContext(), "Eroare:" + eroare.getMessage(), Toast.LENGTH_LONG); notificare.show();
 }
 }
 }
 }
<pre>

Este foarte posibil ca atunci când vom încerca sã rulãm aceastã aplicaţie, sã primim un mesaj de eroare care ne avertizeazã cã nu avem dreptul sã efectuãm o operaţiune de tip SEND_SMS. Acest lucru este explicat de faptul cã fiecare aplicaţie are o serie de permisiuni (Permissions)care sunt stabilite în cadrul fişierului AndroidManifest.xml. Pentru a rezolva problema, tehnica de lucru este urmãtoarea:

  • intrãm în fişierul AndroidManifest.xml (acţionãm dublu click pe denumirea lui care apare în PackageExplorer, în lista componentelor proiectului);
  • în partea de jos a ferestrei care apare, selectãm fila Permissions;
  • acţionãm butonul Add… şi selectãm din lista de permisiuni pe care care are numele android.permissions.SEND_SMS;
  • închidem fila şi confirmãm salvarea modificãrilor efectuate.

Figura nr.  3 – Setarea permisiunii SEND_SMS pentru aplicaţie

                Aceastã operaţiune va reprezenta la un moment dat o protecţie pentru beneficiarul final al unei astfel de aplicaţii; gândiţi-vã în perspectivã la posibilitatea de a „planta” o astfel de aplicaţie în telefonul unui coleg şi sã setãm aplicaţia sã trimitã periodic SMS-uri la un numãr cu suprataxã, fãrã ca acel coleg sã ştie acest lucruL. În urma adãugãrii acestei permisiuni pentru aplicaţia noastrã, fişierul AndroidManifest.xml a reţinut acest aspect într-o linie specificã, pe baza tag-ului uses-permission.

<?xml version=“1.0” encoding=“utf-8”?> <manifest xmlns:android=“http://schemas.android.com/apk/res/android” package=“smsTavy.com” android:versionCode=“1” android:versionName=“1.0”> <uses-sdk android:minSdkVersion=“8” />     <uses-permission android:name=“android.permission.SEND_SMS”></uses-permission> <application android:icon=“@drawable/icon” android:label=“@string/app_name”> <activity android:name=“.AppSMStavyActivity” android:label=“@string/app_name”> <intent-filter> <action android:name=“android.intent.action.MAIN” /> <category android:name=“android.intent.category.LAUNCHER” /> </intent-filter> </activity> </application> </manifest>

În acest moment putem spune cã am parcurs toate etapele de dezvoltare pentru aceastã aplicaţie simplã. Mai rãmâne sã o testãm şi vom porni ambele emulatoare (dispozitivOctav şi destinatie). Apoi vom lansa în execuţie aplicaţia pe dispozitivOctav şi vom completa un mesaj în caseta de text, având grijã sã fie vizibile simultan suprafeţele ambelor emulatoare pe ecran.

Figura nr.  4 – Emulatorul “sursã” în stânga şi emulatorul “destinatar” în dreapta

                Fiecare dispozitiv are câte un ID (5554, 5556) atribuite implicit de cãtre mediul de lucru Eclipse. De alfel, am folosit acest numãr în linia de cod numarDestinatar=“5556”;. În cazul unei aplicaţii reale, va trebui sã avem grijã sã preluãm tot de la utilizator numãrul destinatarului (eventual din agenda telefonicã a dispozitivului mobil). În urma apãsãrii butonului de trimitere a SMS-ului, vom observa cã foarte rapid se modificã o parte din elementele de pe ecran: în dispozitivul sursã apare un mesaj de confirmare, iar în emulatorul destinaţie apare o notã informativã în partea de sus cu referire la mesajul care tocmai a fost primit.

Figura nr.  5 – Confirmarea trimiterii (stânga jos) şi notificare primirii (dreapta sus)

                Ca rezultat final, putem sã accesãm lista de mesaje din emulatorul destinatie şi sã ne convingem de faptul cã acest dispozitiv a primit mesajul SMS trimis din aplicaţia noastrã.

Figura nr.  6 – Mesajul primit de emulatorul cu numãrul 5556 de la emulatorul cu numãrul 5554

                Având în vedere cã secvenţa principalã de cod a fost inclusã într-un bloc try…catch de tratare a excepţiilor, vã recomandãm sã realizaţi urmãtoarele teste pentru a „forţa” aplicaţia:

  • eliminaţi temporar permisiunea SEND_SMS din AndroidManifest.xml;
  • acţionaţi butonul de trimitere SMS fãrã sã fi scris nimic în caseta de text (încercaţi trimiterea unui SMS vid);
  • completaţi în caseta de text un mesaj cu mai mult de 160 de caractere şi apoi încercaţi trimiterea mesajului.

Veţi constata cã fiecare dintre aceste operaţiuni genereazã excepţii specifice care vor fi afişate pe ecranul emulatorului sursã. Încercãm sã încheiem aceastã secvenţã într-o notã optimistã şi vã recomandãm sã vã gândiţi la posibilitatea de a trimite „fluxuri” de SMS-uri. Mai exact, pornind de la acest model de aplicaţie, dezvoltaţi o nouã aplicaţie care sã trimitã SMS-uri personalizate unei liste de destinatari; recomandãm ca lista sã fie memoratã într-un fişier text, într-un format de tip numarDestinar:mesajPersonalizat. În felul acesta, utilizatorul are posibilitatea sã trimitã un set întreg de SMS-uri unei liste de persoane, prin încãrcarea fişierului respectiv. Aplicabilitatea imediatã a acestei aplicaţii poate fi regãsitã în campaniile de informare în masã realizate de marile lanţuri comerciale prin intermediul mesajelor SMS.

O categorie foarte interesantã a aplicaţiilor mobile o constituie cea care foloseşte atributele oferite de tehnologia GSM, foarte popularã în rândul utilizatorilor de telefonie mobilã. Ne propunem ca în cadrul acestui capitol sã dezvoltãm o mini-aplicaţie ce va fi capabilã sã realizeze urmãtoarele operaţiuni:

·         preluarea unui mesaj de tip text de la utilizatorul dispozitivului mobil;

·         trimiterea unui mesaj de tip SMS (Short Message Service) cãtre un destinatar mobil;

·         informarea utilizatorului cu privire la mesajul trimis;

·         informarea utilizatorului cu privire la eventualele erori apãrute în timpul transmisiei.

De fapt, ne dorim sã implementãm o aplicaţie care sã ruleze pe un emulator şi sã trimitã mesaje SMS cãtre alt emulator. Din fericire, acest lucru nu este foarte dificil deoarece necesitã doar cunoştinţe minime de Android, cunoştinţe pe care aţi avut ocazia sã le asimilaţi în capitolele anterioare.

În cazul în care reuşim sã realizãm o astfel de implementare, ne propunem ca spre final sã dezvoltãm şi un modul capabil sã „intercepteze” mesajele primite pe telefonul mobil. Aceastã operaţiune are drept scop prelucrarea explicitã a datelor pe care le conţine un mesaj SMS pe care îl primim pe telefonul mobil: numãrul expeditorului şi mesajul propriu-zis.

 

(c) Marian Perca & Octav Dospinescu

Prima mea aplicatie Android

@uthors: Marian Perca & Octav Dospinescu

Pentru a descoperi minunata lume a aplicațiilor mobile vom începe cu un exemplu simplu în care:

  • Vom crea un nou proiect Android;
  • Vom defini layout-ul Activității într-un fișier XML;
  • Vom asimila acest layout unei Activități;
  • Vom afișa un mesaj de notificare introdus de utilizator.

Astfel, vom diseca aplicația și o vom explica pas cu pas pentru a înțelege cât mai bine modul în care lucrează platforma Android.

Crearea unui proiect

Pentru a crea un nou proiect trebuie să deschidem mediul de lucru Eclipse și să accesăm din meniul File -> Meniu -> Project… opțiunea Android Project. În fereastra care se va deschide va trebui să configurăm noul nostru proiect.

Elementele principale de care trebuie să ţinem cont atunci când completăm această fereastră sunt:

Project Name – Acesta este numele proiectului Eclipse, cât şi a directorului în care vom găsi aplicaţia noastră.

Application Name – Acesta este numele aplicaţiei care va apărea în dispozitivul mobil.

Package Name – pentru a defini numele pachetului din care vor face parte clase pe care le vom defini, vom urma aceleaşi reguli de definire a pachetelor ca în cazul unui proiect Java. Acesta trebuie să fie unic în tot sistemul Android în care este instalată aplicaţia noastră, de aceea este recomandat să folosim un nume de domeniu, în cazul nostru ro.uaic.feaa.helloworld.

Create Activity – Acesta este numele clasei exemplu care va fi generată la crearea proiectului. Aceasta va fi o subclasă a clasei Activity din Android, fiind punctul nostru de pornire în crearea aplicaţiei, deoarece acest tip de clasă reprezintă fundaţia unei aplicaţii. Putem păstra aceasta clasa generată, sau putem crea noi alta.

Min SDK Version – Această valoare indică nivelul minim API pentru care creăm aplicaţia. Este indicat să proiectăm aplicaţia noastră pentru un nivel cât mai scăzut, pentru a acoperi o plajă cât mai largă de dispozitive mobile.

Structura proiectului

Un proiect Android are la bază un sistem de directoare ierarhizate, la fel ca și un proiect Java. Cu toate acestea, particularitățile sunt unice pentru Android. Pentru a crea o aplicație trebuie să înțelegem modul în care este structurat acesta:

  • src – este directorul în care vom găsi codul Java aferent proiectului nostru;
  • gen – în acest director, Android va stoca codul generat pentru rularea proiectului;
  • assets – conține toate fișierele pe care dorim să le includem în proiect;
  • res – este un director care conține resursele aplicației precum: elemente grafice, designul aplicației sau descrierea unor elemente din aplicație. Acesta este împărțit la rândul său în mai multe directoare:
    • res/drawables/ – pentru imagini;
    • res/layout/  – pentru fișiere XML care descriu interfața utilizator;
    • res/menu/ – specificațiile XML pentru meniurile din aplicație;
    • res/values/ – pentru șiruri de caractere, matrici sau alte elemente asemănătoare;

În funcție de particularitățile proiectului, putem adăuga în acest director orice elemente de care avem nevoie în aplicație.

  • AndroidManifest.xmlacest fișier XML conține descrierea aplicației, ce activități, servicii include sau ce permisiuni necesită aplicația pentru a rula.

În momentul în care compilăm proiectul prin intermediul Eclipse sau orice alt IDE[1], fișierele rezultate în urma acestei acțiuni le vom găsi în directorul bin/ din rădăcina proiectului nostru, după cum urmează:

  • bin/namespace/clasele Java compilate, unde namespace reprezintă numele pachetului specificat la crearea proiectului;
  • bin/classes.dexreprezintă un fișier executabil creat din clasele compilate;
  • bin/resources.ap_acest fișier este o arhivă a resurselor aplicației noastre;
  • bin/NumeAplicatie.apkaceast fișier este aplicația noastră, care va fi instalată pe dispozitivul mobil.

Crearea interfeței utilizator

În acest moment am creat proiectul HelloWorld, iar Android ne-a creat toate fișierele necesare pentru a putea începe să construim aplicația noastră. În continuare, ne propunem să creăm o aplicație care să conțină un câmp în care putem scrie orice dorim, iar acest text să fie afișat ca un mesaj de notificare când apăsăm butonul “Afișează notificare”. Pentru a realiza toate acestea, trebuie să modificăm layoutul aplicației și să introducem linii de cod în activitatea generată.

Să analizăm un pic structura fișierului generat la crearea proiectului și anume HelloWord.java

public class HelloWorld extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

După cum putem observa această clasă extinde clasa Activity și suprascrie o metodă din aceasta: onCreate().  Această metodă este apelată la pornirea Activității. Ceea ce ne propunem pentru început este modificarea designului aplicației, iar pentru a realiza aceast lucru, avem la dispoziție două metode:

  • declararea elementelor din interfață într-un fișier XML;
  • instanțierea elementelor din interfață în momentul rulării aplicației. Pentru aceasta va trebui să manipulăm elementele într-un mod programatic (cod Java).

Platforma Android ne oferă o mare flexibilitate în construirea interfeței utilizator. Putem folosi doar una din cele două metode sau le putem combina pentru a realiza exact ceea ce ne dorim. Spre exemplu, putem defini structura de bază a interfeței în fișierul XML, iar apoi putem adăuga cod în aplicația noastră pentru a adăuga noi obiecte, sau pentru a le modifica pe cele deja definite în fişierul XML.

Avantajul definirii elementelor unei interfețe prin metoda XML este separarea interfeței de codul care controlează elementele definite. Asta înseamnă că implementarea aplicaţiei este mult mai logică şi mai uşor de urmat, ori de câte ori va fi nevoie să modificăm un element din interfaţă nu va trebui decât să îi ajustăm proprietăţile din fişierul XML. Un lucru foarte la îndemână în platforma Android este sintaxa XML pentru definirea elementelor UI[2]. Acestea respectă aceleaşi reguli de definire ca şi clasele sau metodele din cod, unde numele clasei corespunde cu numele obiectului iar numele metodei corespunde cu atributele pe care le acceptă obiectul.

În cadrul capitolelor ce urmează vom prezenta exemple de implementări pentru ambele metode, dar în principal vom folosi fișierele XML pentru a introduce şi aranja elementele de care avem nevoie în aplicaţiile noastre.

În cadrul platformei Android pentru a defini interfața utilizator pentru o Activitate trebuie să folosim o structură care să conţină noduri de tip ViewGroup sau simple View-uri. Aceasta poate fi cât de complexă sau simplă dorim şi o putem crea folosim widget-uri şi layout-uri predefinite sau putem crea noi înșine view-uri particularizate.

Pentru a atribui un asemenea layout unei activități trebuie să inserăm următoarea linie de cod în metoda onCreate():

setContentView(R.layout.<em>main</em>);

În sistemul Android aceste fişiere XML sunt percepute ca fiind resurse ale aplicației, aşadar le vom găsi în directorul res/layout în cadrul proiectului nostru. Fiecare fişier de acest gen conţine o structură ierarhică de widget-uri şi containere care descriu modul în care va arăta un anumit ecran din aplicaţia noastră. XML se aseamănă destul de mult cu HTML deoarece structura sa este ușor de urmărit și înțeles.

Fișierul care conține layout-ul nostru se numește main.xml și este structurat astfel:

<?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"
    android:gravity="right"
    android:padding="5dip">
	<TextView
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:text="@string/titlu_aplicatie"
	    android:textSize="16dip"
	    android:paddingBottom="10dip"/>

    <EditText
    	android:id="@+id/notificare"
    	android:layout_width="fill_parent"
    	android:layout_height="wrap_content"
    	android:hint="@string/hint_notificare" />

    <Button
    	android:id="@+id/afiseaza_mesaj"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:text="@string/text_afiseaza_notificare" />
</LinearLayout>

În acest prim proiect s-a utilizat un layout de tip liniar. Acesta poziționează toate elementele pe care le conține în linie sau pe coloană. Pentru a defini orientarea trebuie îi adăugăm atributul android:orientation. Acesta poate primi 2 valori: vertical pentru a aranja elementele în coloană și horizontal pentru a aranja elementele în linie. Dorim ca layout-ul nostru să se extindă pe întregul ecran, astfel vom adăuga atributele android:layout_width și android:layout_height cu valoarea fill_parent.

După cum putem observa, elementul LiniarLayout conține trei elemente TextView, EditText și Button, acestea fiind obiectele cu care utilizatorul va interacționa. Cu ajutorul elementului TextView vom afișa un titlu; de obicei cu ajutorul elementelor de acest gen vom afișa porțiuni informative de text; EditText este special creat pentru text editabil, astfel încât vom plasa un element de acest tip în layoutul nostru pentru a capta textul care va fi afișat în mesajul de notificare; Button reprezintă butonul care va declanșa afișarea mesajului de notificare.

Elementele EditText și Button au un atribut mai special și anume android:id. Multe dintre widget-urile, containerele sau obiectele pe care le utilizăm în crearea layout-ului XML nu vor fi manipulate din codul Java, spre exemplu elementele de tip TextView care nu reprezintă altceva decât text static. Nu va fi necesar decât să le poziționăm prin intermediul atributelor din fișierul XML. Pentru toate celelalte elemente pe care dorim să le utilizăm în fișierele Java va trebui să le adăugăm atributul android:id. Există o convenție pentru definirea acestor id-uri și anume să folosim @+id/denumireId unde denumireId reprezintă numele unic pe care îl atribuim elementului. În exemplul nostru, pentru elementul EditText am utilizat atributul android:id=”@+id/notificare”, astfel încât îl putem apela din Java cu ajutorul id-ului notificare.

Lăţimea şi înălţimea pentru elementul EditText au fost stabilite cu ajutorul atributelor:

  • android:layout_width=”fill_parent” – datorită valorii fill_parent va avea aceeași lăţime ca şi elementul părinte, în cazul nostru LinearLayout care se întinde pe întreaga lățime a ecranului;
  • android:layout_height=”wrap_content” – prin acest atribut cu valoarea wrap_content definim ca înălțimea elementului să fie variabilă în funcție de textul pe care îl cuprinde. Astfel, pe măsură ce vom scrie, înălțimea se va ajusta în mod automat.

Pentru a da un aspect mai plăcut interfeței am adăugat atributele:

  • android:gravity=”right” – prin intermediul acestui atribut am aliniat toate elementele din LinearLayout la dreapta;
  • android:padding=”5dip” – cu ajutorul acestui atribut am adăugat un spațiu între marginile elementului LinearLayout și elementele care le conține.

În continuare, pentru a manipula obiectele din interfața creată, trebuie să le instanţiem în activitatea noastră: HelloWorld.java. În cele din urmă, aceasta va arăta astfel:

package ro.uaic.feaa.helloworld;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class HelloWorld extends Activity implements OnClickListener{
    /** Called when the activity is first created. */
    @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Button btnNotificare = (Button)findViewById(R.id.afiseaza_mesaj);
btnNotificare.setOnClickListener(this);
}

	@Override
public void onClick(View v) {
		EditText textNotificare = (EditText)findViewById(R.id.notificare);

		Toast toast = Toast.makeText(getApplicationContext(), textNotificare.getText(), Toast.LENGTH_SHORT);
		toast.show();
	}
}

În această aplicație va trebui să afișăm un mesaj atunci când apăsăm pe butonul ”Afișează notificare”, de aceea trebuie să implementăm interfața OnClickListener pentru a putea capta evenimentul click. Din această interfața trebuie să suprascriem metoda onClick().

În metoda onCreate() vom crea o variabilă de tip Button, care va fi o referință a elementului creat în XML și pe care îl putem identifica prin id-ul atribuit: ”afiseaza_mesaj”. Pentru a realiza acest lucru vom folosi metoda (Button)findViewById(R.id.afiseaza_mesaj). După ce am creat butonul vom ”asculta” evenimentul ”click”.

În funcția onClick() vom afișa mesajul de notificare. În primul rând, va trebui să preluăm mesajul din căsuța de text afișată. Pentru aceasta, trebuie să creăm un obiect de tipul EditText care va face referire către elementul de același tip creat în XML:

EditText textNotificare = (EditText)findViewById(R.id.notificare);

Apoi, vom crea un obiect de tip Toast pe care îl vom folosi pentru a afișa mesajul nostru. Cu acest tip de obiect Toast putem crea mesaje tranzitorii, care vor apărea şi vor dispărea fără a fi nevoie de interacţiunea utilizatorului. Vom discuta mai multe aspecte despre acest tip de mesaj în capitolele următoare.

Metoda makeText() acceptă trei parametri printre care vor fi textul afișat, precum şi durata de afişare. Pentru a prelua textul din obiectul de tip EditText, avem la dispoziție metoda getText(), iar pentru a stabili timpul de afișare folosim constanta Toast.LENGTH_SHORT. Mesajul de notificare îl vom afișa folosind metoda show() a obiectului de tip Toast.

Crearea unui emulator

Deși suntem nerăbdători să rulăm aplicația noastră, trebuie mai întâi să creăm un dispozitiv virtual pe care să ruleze. În Android acesta se numește AVD –Android Virtual Device. Desigur, dacă avem un dispozitiv fizic pe care să rulăm aplicația, nu mai este necesar să crem unul virtual.

AVD reprezintă un emulator pe care îl putem particulariza alegând componentele hardware și software pe care Android le va emula. Pentru a crea un AVD, cea mai simpla metodă este utilizarea managerului AVD. Pentru a-l porni vom accesa Android SDK and AVD Manager din meniul Window al Eclipse. Alternativa este linia de comandă, folosind comanda androidcu opțiunile pe care le dorim pentru a-l particulariza.

android create avd -n <name> -t <targetID> [-<option> <value>] …

Dacă folosim AVD Manager, din fereastra care ni se va deschide vom alege New… pentru a crea un AVD nou:

În fereastra cu detalii ni se va cere să completăm numele pe care dorim să îl atribuim AVD-ului, nivelul API (Target) pentru care va fi creat, dimensiunea SD cardului, dimensiunea ecranului şi o listă în care vom putea specifica suportul hardware pe care îl va oferi emulatorul.

Putem crea oricâte AVD-uri avem nevoie, în funcție de tipul de dispozitiv mobil pe care vrem să-l emulăm. Pentru a testa aplicația cât mai bine trebuie să creăm câte un AVD pentru fiecare dispozitiv din piața noastră țintă (diferite dimensiuni ale ecranului și platforme). În configurarea AVD-ului trebuie să acordăm o mare importanță nivelului API, deoarece nu trebuie să fie mai mic decât cel specificat la crearea proiectului Android. Trebuie să ţinem cont de faptul că aplicaţia noastră nu va putea rula pe un dispozitiv cu un nivel API mai mic. Ideal este ca aplicația să rule pe toate dispozitivele mobile indiferent de platformă, dimensiunea ecranului sau caracteristicile hardware. Acest lucru este dificil de realizat întrucât periodic apar noi versiuni ale platformei Android, telefoane de dimensiuni diferite. Soluția ar fi să testăm aplicația pe cât mai multe emulatoare, astfel încât utilizatorii să nu întâmpine probleme în rularea aplicației, indiferent de dispozitivul mobil pe care îl folosesc.

Cu toate acestea, testarea aplicaţiei pe un AVD nu poate înlocui testarea pe un dispozitiv fizic. Emulatoarele ne permit să testăm aplicația noastră pe o gamă largă de dispozitive, chiar și pe cele care încă nu există pe piață. Totuși, aplicația ar trebui testată pe cel puțin un dispozitiv Android, deoarece cele două nu se pot compara, atât din privința vitezei de răspuns cât și a senzației oferite de interfața utilizator.

Dacă suntem obişnuiţi deja cu AVD-urile, atunci ştim cât de greu pot porni. Cei de la Android au venit cu o nouă facilitate pentru a îmbunătăți timpul de pornire al emulatorului, şi anume Snapshot. Dacă bifăm această opţiune, atunci când se creează un nou AVD, Android va realiza o imagine a emulatorul atunci când îl vom închide. Astfel, atunci când dorim să pornim emulatorul se va deschide aproape instantaneu pe baza imaginii create.

După ce am creat emulatorul nu ne rămâne decât să rulăm aplicația. Pentru a realiza aceasta din meniul Run > Run as, vom alege Android Application. Aplicația va trebui să arate ca cea din figura de mai jos:

(c) Marian Perca & Octav Dospinescu