Postat de la Nov 14, 2012 in Tutoriale | 0 comentarii

@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