Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
laboratoare:laborator04 [2015/03/16 05:24] Andrei Roșu-Cojocaru |
laboratoare:laborator04 [2015/03/16 14:37] (current) Andrei Roșu-Cojocaru |
||
|---|---|---|---|
| Line 1276: | Line 1276: | ||
| * ''postDelayed()'' - realizează o modificare la nivelul interfeței grafice cu o întârziere specificată ca parametru (exprimat în milisecunde); | * ''postDelayed()'' - realizează o modificare la nivelul interfeței grafice cu o întârziere specificată ca parametru (exprimat în milisecunde); | ||
| * ''postAtTime()'' - realizează o modificare la nivelul interfeței grafice la un moment de timp specificat ca parametru (exprimat ca număr de milisecunde ce au trecut de la 1 ianuarie 1970. | * ''postAtTime()'' - realizează o modificare la nivelul interfeței grafice la un moment de timp specificat ca parametru (exprimat ca număr de milisecunde ce au trecut de la 1 ianuarie 1970. | ||
| + | |||
| + | ==== Realizarea de Procesări prin Intermediul Alarmelor ==== | ||
| + | |||
| + | O alarmă reprezintă un mecanism de transmitere a unor intenții la momente predefinite de timp sau periodic, după trecerea unui anumit interval. Acestea există în afara domeniului de existență a unei aplicații Android, astfel încât acestea pot fi utilizate pentru a realiza anumite acțiuni chiar și în situația în care acestea nu mai există. Din acest motiv, alarmele reprezintă o metodă foarte utilă pentru a difuza intenții, pentru a porni servicii sau lansa în execuție activități, fără a fi necesar ca aplicația să se afle în execuție. Se asigură astfel și optimizarea cerințelor legate de resursele utilizate de aplicație. | ||
| + | |||
| + | Cele mai frecvente utilizări ale alarmelor sunt legate de planificarea unor actualizări bazate pe căutări în rețea, programarea unor operații (consumatoare de resurse) la momente de timp în care solicitările sunt mai reduse, organizarea unor noi încercări pentru operații care nu au putut fi realizate anterior. | ||
| + | |||
| + | <note tip>Evenimentele care pot fi produse doar pe parcursul ciclului de viață al unei aplicații Android trebuie tratate prin fire de execuție separate implementate de utilizator și sincronizate (manual) cu interfața grafică. Utilizarea de alarme trebuie limitată doar la evenimente programate în afara ferestrei temporale în care se desfășoară aplicația.</note> | ||
| + | |||
| + | <note>În Android, alarmele rămân active chiar și atunci când dispozitivul mobil se găsește într-o stare de latență (//eng.// sleep mode), putând fi utilizate pentru a-l scoate din aceasta. Totuși, ele devin inactive în momentul în care dispozitivul mobil este repornit.</note> | ||
| + | |||
| + | Operațiile cu alarme sunt realizate prin intermediul serviciului de sistem ''AlarmManager'' care poate fi accesat prin intermediul metodei ''getSystemService()'' care primește ca parametru argumentul ''Context.ALARM_SERVICE''. | ||
| + | |||
| + | Există mai multe tipuri de alarme: | ||
| + | * ''RTC_WAKEUP'' - scoate dispozitivul mobil din starea de latență prin transmiterea unei intenții în așteptare, la un anumit moment de timp specificat; | ||
| + | * ''RTC'' - transmite o intenție în așteptare, la un anumit moment de timp specificat, fără a scoate dispozitivul mobil din starea de latență; | ||
| + | * ''ELAPSED_REALTIME'' - transmite o intenție în așteptare, la un anumit interval de timp scurs de la momentul în care dispozitivul mobil a fost pornit, fără a-l scoate din starea de latență; | ||
| + | * ''ELAPSED_REALTIME_WAKEUP'' - scoate dispozitivul mobil din starea de latență prin transmiterea unei intenții în așteptare, la un anumit interval de timp scurs de la momentul în care acesta a fost pornit. | ||
| + | |||
| + | În funcție de aceste valori, parametrul furnizat metodei ''set()'' a obiectului de tip ''AlarmManager'' reprezintă un moment de timp sau un interval. | ||
| + | |||
| + | În momentul în care se declanșează, obiectul de tip ''PendingIntent'' este distribuit la nivelul tuturor componentelor sistemului de operare. | ||
| + | |||
| + | <note tip>Specificarea unei alte alarme folosind același obiect de tip ''PendingIntent'' o înlocuiește pe cea existentă.</note> | ||
| + | |||
| + | <code java> | ||
| + | AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); | ||
| + | alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, PendingIntent.getBroadcast(this, 0, new Intent("ALARM_ACTION"), 0)); | ||
| + | </code> | ||
| + | |||
| + | Anularea unei alarme se face prin intermediul metodei ''cancel()'' a obiectului de tip ''AlarmManager'' care primește ca parametru intenția în așteptare care nu mai trebuie transmisă. | ||
| + | |||
| + | <code java> | ||
| + | alarmManager.cancel(PendingIntent.getBroadcast(this, 0, new Intent("ALARM_ACTION"), 0)); | ||
| + | </code> | ||
| + | |||
| + | Utilizatorul are și posibilitatea de a indica anumite intervale de timp la care alarma este repetată, prin intermediul unor metode definite în clasa ''AlarmManager'': | ||
| + | * ''setRepeating()'' - utilizată când se dorește un control foarte exact asupra intervalului de timp la care alarma este repetată, exprimat la nivel de milisecunde; | ||
| + | * ''setInexactRepeating()'' - folosit pentru a economisi consumul de baterie realizat la scoaterea dispozitivului mobil din starea de latență de fiecare dată când este necesară realizarea unor sarcini planificate (care nu se suprapun); astfel, sistemul de operare Android va sincroniza mai multe alarme cu modul de repetare inexact, declanșându-le simultan; metoda primește ca parametru una dintre constantele: | ||
| + | * ''INTERVAL_FIFTEEN_MINUTES'' | ||
| + | * ''INTERVAL_HALF_HOUR'' | ||
| + | * ''INTERVAL_HOUR'' | ||
| + | * ''INTERVAL_HALF_DAY'' | ||
| + | * ''INTERVAL_DAY'' | ||
| + | Ambele metode primesc ca parametrii tipul de alarmă, un moment de timp la care alarma va fi declanșată inițial și o intenție în așteptare care va fi transmisă. | ||
| + | |||
| + | <code java> | ||
| + | AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); | ||
| + | alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, AlarmManager.INTERVAL_FIFTEEN_MINUTES, AlarmManager.INTERVAL_DAY, PendingIntent.getBroadcast(this, 0, new Intent("ALARM_ACTION"), 0)); | ||
| + | </code> | ||
| + | |||
| + | <note important>Impactul pe care alarmele recurente îl au asupra consumului de baterie poate fi semnificativ. De aceea, este recomandat ca frecvența de repetare a alarmei să fie cât mai mică, scoțând dispozitivul mobil din starea de latență numai atunci când este necesar și utilizând tipul de repetare inexact, dacă este posibil.</note> | ||
| + | |||
| + | Anularea unei alarme recurente se face tot prin intermediul metodei ''cancel()'' a obiectului de tip ''AlarmManager'' care primește ca parametru intenția în așteptare care nu mai trebuie transmisă. | ||
| ===== Activitate de Laborator ===== | ===== Activitate de Laborator ===== | ||
| - | ==== Intenții ==== | + | Se dorește implementarea unei aplicații Android, conținând o activitate conținând două fragmente, care să ofere utilizatorilor funcționalitatea necesară pentru a stoca un număr de telefon în agenda de contacte, specificând pentru acesta mai multe informații. |
| - | - Să se creeze încă o fereastră (activitate) pe care să se afișeze o imagine. Aceasta trebuie să apară pe ecran în momentul în care se apasă butonul //Fereastră Nouă//. | + | |
| - | - Să se adauge la fereastra creată anterior un buton de revenire. | + | {{ :laboratoare:laborator04:activitate_de_laborator01.png?nolink&300 }} |
| - | - Să se afișeze fereastra creată anterior și atunci când se apasă butonul //Inserați Fereastra//. Să se afișeze sub imagine, într-un câmp text, care a fost butonul ce a determinat invocarea ferestrei. | + | |
| - | - Să se adauge la fereastra creată anterior un buton prin intermediul căruia să se schimbe imaginea existentă cu o alta. | + | {{ :laboratoare:laborator04:activitate_de_laborator02.png?nolink&300 }} |
| + | |||
| + | **1.** În contul Github personal, să se creeze un depozit denumit 'Laborator04'. Acesta trebuie să conțină unui fișier ''README.md'', un fișier ''.gitignore'' specific unei aplicații Android și un fișier ''LICENSE'' care să descrie condițiile pentru utilizarea aplicației. | ||
| + | |||
| + | **2.** Să se cloneze într-un director de pe discul local conținutul depozitului la distanță astfel creat. În urma acestei operații, directorul Laborator04 va trebui să se conțină fișierele ''README.md'', ''.gitignore'' care indică tipurile de fișiere (extensiile) ignorate și ''LICENSE''. <code> | ||
| + | student@pdsd2015:~$ git clone https://www.github.com/perfectstudent/Laborator04 | ||
| + | </code> | ||
| + | |||
| + | **3.** În directorul Laborator04 de pe discul local, să se creeze un proiect Eclipse denumit //ContactsManager//. | ||
| + | |||
| + | Se utilizează următoarele detalii ale proiectului: | ||
| + | * **Application Name** - //Contacts Manager// | ||
| + | * **Project Name** - //ContactsManager// | ||
| + | * **Package Name** - ''ro.pub.cs.systems.pdsd.lab04.contactsmanager'' | ||
| + | * **Minimum Required SDK** - API 16: Android 4.1 (Jelly Bean) | ||
| + | * **Target SDK** - API 16: Android 4.1 (Jelly Bean) | ||
| + | * **Compile With** - API 16: Android 4.1 (Jelly Bean) | ||
| + | * **Theme** - Holo Light with Dark Action Bar | ||
| + | |||
| + | Ceilalți parametrii de configurare sunt impliciți: | ||
| + | * denumirea activității - ''ContactsManagerActivity''; | ||
| + | * denumirea fișierului XML din ''res/layout'' în care va fi construită interfața grafică - ''activity_contacts_manager''. | ||
| + | |||
| + | **4.** În fișierul ''activity_contacts_manager'' din directorul ''res/layout'' să se construiască interfața grafică folosind: | ||
| + | * editorul vizual (//Graphical Layout//) | ||
| + | * editorul XML (manual) | ||
| + | |||
| + | Acesta va fi format din două containere de tip ''FrameLayout'' în care vor fi plasate fragmentele, dispuse vertical. | ||
| + | |||
| + | **5.** Să se definească două fragmente: | ||
| + | * ''BasicDetailsFragment'' cu interfața grafică în fișierul ''fragment_basic_details.xml'' din directorul ''res/layout''; acesta va fi afișat în permanență în cadrul activității (pe metoda ''onCreate()'' a acesteia se adaugă o instanță a fragmentului la containerul <code java> | ||
| + | FragmentManager fragmentManager = getFragmentManager(); | ||
| + | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); | ||
| + | fragmentTransaction.add(R.id.containerTop, new BasicDetailsFragment()); | ||
| + | fragmentTransaction.commit(); | ||
| + | </code> | ||
| + | * ''AdditionalDetailsFragment'' cu interfața grafică în fișierul ''fragment_additional_details.xml'' din directorul ''res/layout''; acesta va fi atașat / detașat la activitate la accesarea butonului //Show Additional Fields//, respectiv //Hide Additional Fields//. | ||
| + | |||
| + | O clasă asociată unui fragment este derivată din ''android.app.Fragment'' și implementează metoda ''onCreateView()'' pe care se încarcă interfața grafică corespunzătoare: | ||
| + | |||
| + | <code java> | ||
| + | public class SomeFragment extends Fragment { | ||
| + | @Override | ||
| + | public View onCreateView(LayoutInflater layoutInflater, ViewGroup container, Bundle state) { | ||
| + | return layoutInflater.inflate(R.layout.fragment_some, container, false); | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | **6**. Să se implementeaze intefețele grafice ale fragmentelor, conținând următoarele controale: | ||
| + | * ''fragment_basic_details.xml'' conține mai multe elemente dispuse vertical și ocupând pe lățime întregul spațiu avut la dispoziție: | ||
| + | * un buton (''Button'') având mesajul //Show Additional Fields// în cazul în care celălalt fragment nu este afișat, respectiv mesajul //Hide Additional Fields// în cazul în care celălalt fragment este afișat, determinând atașarea / detașarea acestuia la activitate; | ||
| + | * patru controale de tip câmpuri text (''EditText'') prin care se introduc: | ||
| + | * numele; | ||
| + | * numărul de telefon - acest câmp este dezactivat (are proprietatea ''android:enabled="false"''), urmând ca valoarea sa să fie preluată din câmpul ''extra'' al unei intenții; | ||
| + | * adresa electronică; | ||
| + | * adresa poștală. | ||
| + | * ''fragment_additional_details.xml'' conține patru controale de tip câmpuri text dispuse vertical și ocupând pe lățime întregul spațiu avut la dispoziție, prin care se introduc: | ||
| + | * poziția ocupată; | ||
| + | * denumirea companiei; | ||
| + | * site-ul web; | ||
| + | * identificatorul pentru mesagerie instantanee. | ||
| + | |||
| + | **7.** Să se implementeaze interacțiunea cu utilizatorul a aplicației. | ||
| + | * în metoda ''onActivityCreated()'' a fragmentului ''BasicDetailsFragment'' se obțin referințe către butoanele //Show Additional Details// / //Hide Additional Details//, respectiv //Save// și //Cancel// prin intermediul metodei ''getActivity().findViewById(R.id....)''; | ||
| + | * se implementează o clasă ascultător pentru butoane, care implementează ''View.OnClickListener'' și (re)definește metoda ''onClick(View v)''; în funcție de identificatorul butonului care este transmis ca parametru al metodei, sunt realizate următoarele acțiuni: | ||
| + | * butonul //Show Additional Details// / //Hide Additional Details// - atașează / detașează fragmentul ''AdditionalDetailsFragment'' la activitate în funcție de existența / inexistența acestuia, modificând corespunzător textul afișat pe buton: <code> | ||
| + | FragmentManager fragmentManager = getActivity().getFragmentManager(); | ||
| + | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); | ||
| + | AdditionalDetailsFragment additionalDetailsFragment = (AdditionalDetailsFragment)fragmentManager.findFragmentById(R.id.containerBottom); | ||
| + | if (additionalDetailsFragment == null) { | ||
| + | fragmentTransaction.add(R.id.containerBottom, new AdditionalDetailsFragment()); | ||
| + | ((Button)v).setText(getActivity().getResources().getString(R.string.hide_additional_fields)); | ||
| + | fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_ENTER_MASK); | ||
| + | } else { | ||
| + | fragmentTransaction.remove(additionalDetailsFragment); | ||
| + | ((Button)v).setText(getActivity().getResources().getString(R.string.show_additional_fields)); | ||
| + | fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_EXIT_MASK); | ||
| + | } | ||
| + | fragmentTransaction.commit(); | ||
| + | </code> | ||
| + | * butonul //Save// - lansează în execuție aplicația Android nativă pentru stocarea unui contact în agenda telefonică, după ce în prealabil au fost preluate informațiile din controalele grafice: <code java> | ||
| + | Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION); | ||
| + | intent.setType(ContactsContract.RawContacts.CONTENT_TYPE); | ||
| + | if (name != null) { | ||
| + | intent.putExtra(ContactsContract.Intents.Insert.NAME, name); | ||
| + | } | ||
| + | if (phone != null) { | ||
| + | intent.putExtra(ContactsContract.Intents.Insert.PHONE, phone); | ||
| + | } | ||
| + | if (email != null) { | ||
| + | intent.putExtra(ContactsContract.Intents.Insert.EMAIL, email); | ||
| + | } | ||
| + | if (address != null) { | ||
| + | intent.putExtra(ContactsContract.Intents.Insert.POSTAL, address); | ||
| + | } | ||
| + | if (jobTitle != null) { | ||
| + | intent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobTitle); | ||
| + | } | ||
| + | if (company != null) { | ||
| + | intent.putExtra(ContactsContract.Intents.Insert.COMPANY, company); | ||
| + | } | ||
| + | ArrayList<ContentValues> contactData = new ArrayList<ContentValues>(); | ||
| + | if (website != null) { | ||
| + | ContentValues websiteRow = new ContentValues(); | ||
| + | websiteRow.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE); | ||
| + | websiteRow.put(ContactsContract.CommonDataKinds.Website.URL, website); | ||
| + | contactData.add(websiteRow); | ||
| + | } | ||
| + | if (im != null) { | ||
| + | ContentValues imRow = new ContentValues(); | ||
| + | imRow.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE); | ||
| + | imRow.put(ContactsContract.CommonDataKinds.Im.DATA, im); | ||
| + | contactData.add(imRow); | ||
| + | } | ||
| + | intent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData); | ||
| + | getActivity().startActivity(intent); | ||
| + | </code> Intenția pentru realizarea acestei operații are asociată acțiunea ''ContactsContract.Intents.Insert.ACTION'' și tipul ''ContactsContract.RawContacts.CONTENT_TYPE''. Informațiile care se doresc a fi completate sunt atașate în câmpul ''extra'' al acesteia, având cheile:\\ ✔ ''ContactsContract.Intents.Insert.NAME'';\\ ✔ ''ContactsContract.Intents.Insert.PHONE'';\\ ✔ ''ContactsContract.Intents.Insert.EMAIL'';\\ ✔ ''ContactsContract.Intents.Insert.POSTAL'';\\ ✔ ''ContactsContract.Intents.Insert.JOB_TITLE'';\\ ✔ ''ContactsContract.Intents.Insert.COMPANY'';\\ Pentru site-ul web și identificatorul de mesagerie instantanee, se folosește un tablou de elemente ''ContentValues'' în care se specifică înregistrări de tipul ''CommonDataKinds.Website.URL'', respectiv ''CommonDataKinds.Im.DATA'';\\ Pentru a putea gestiona agenda telefonică, este necesar ca în fișierul ''AndroidManifest.xml'' să fie specificate următoarele permisiuni: <code xml> | ||
| + | <uses-permission | ||
| + | android:name="android.permission.READ_CONTACTS" /> | ||
| + | <uses-permission | ||
| + | android:name="android.permission.WRITE_CONTACTS" /> | ||
| + | </code> | ||
| + | * butonul //Cancel// - termină aplicația Android: <code java> | ||
| + | getActivity().finish(); | ||
| + | </code> | ||
| + | * se înregistrează o instanță a clasei ascultător ca mecanism de tratare a evenimentelor de tip accesare a butoanelor din cadrul interfeței grafice, prin apelul metodei ''setOnClickListener()''. | ||
| + | |||
| + | **8.** Să se modifice aplicația Android [[https://github.com/pdsd2015/Laborator03/tree/master/labtaks/PhoneDialer|Phone Dialer]] astfel încât să conțină un buton suplimentar prin care este invocată aplicația //Contacts Manager// căreia îi transmite numărul de telefon format și așteptând un rezultat cu privire la stocarea contactului în agenda telefonică. | ||
| + | |||
| + | {{ :laboratoare:laborator04:activitate_de_laborator03.png?nolink&300 }} | ||
| + | |||
| + | {{ :laboratoare:laborator04:activitate_de_laborator04.png?nolink&500 }} | ||
| + | |||
| + | Metoda de tratare a evenimentului de tip accesare a butonului de stocare a numărului de telefon în agenda telefonică invocă o intenție asociată aplicației //Contacts Manager//, transmițând și numărul de telefon în câmpul ''extra'' asociat acesteia, identificabil prin intermediul unei chei. <code java> | ||
| + | if (phoneNumber.length() > 0) { | ||
| + | intent = new Intent("ro.pub.cs.systems.pdsd.lab04.contactsmanager.intent.action.ContactsManagerActivity"); | ||
| + | intent.putExtra("ro.pub.cs.systems.pdsd.lab04.contactsmanager.PHONE_NUMBER_KEY", phoneNumber); | ||
| + | startActivityForResult(intent, Constants.CONTACTS_MANAGER_REQUEST_CODE); | ||
| + | } else { | ||
| + | Toast.makeText(getApplication(), getResources().getString(R.string.phone_error), Toast.LENGTH_LONG).show(); | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | **9.** Să se modifice aplicația Android //Contacts Manager// astfel încât să poată fi lansată în execuție doar din contextul altei activități, prin intermediul unei intenții care conține în câmpul ''extra'' un număr de telefon, identificabil prin cheia ''ro.pub.cs.systems.pdsd.lab04.contactsmanager.PHONE_NUMBER_KEY'', acesta fiind plasat în câmpul text needitabil corespunzător. Totodată, va transmite înapoi rezultatul operației de stocare (''Activity.RESULT_OK'' sau ''Activity.RESULT_CANCELED''). | ||
| + | |||
| + | * în fișierul ''AndroidManifest.xml'' se modifică filtrul de intenții (acțiunea și categoria), astfel încât activitatea să poată fi rulată doar prin intermediul unei intenții <file xml AndroidManifest.xml> | ||
| + | <manifest ...> | ||
| + | <application ...> | ||
| + | <activity | ||
| + | android:name=".graphicuserinterface.ContactsManagerActivity" | ||
| + | android:label="@string/app_name" > | ||
| + | <intent-filter> | ||
| + | <action android:name="ro.pub.cs.systems.pdsd.lab04.contactsmanager.intent.action.ContactsManagerActivity" /> | ||
| + | <category android:name="android.intent.category.DEFAULT" /> | ||
| + | </intent-filter> | ||
| + | </activity> | ||
| + | </application> | ||
| + | </manifest> | ||
| + | </file> | ||
| + | * în metoda ''onActivityCreated()'' asociată fragmentului ''BasicDetailsFragment'' este verificată intenția cu care este pornită activitatea părinte, și în cazul în care aceasta nu este nulă, este preluată informația din secțiunea ''extra'', identificată prin cheia ''ro.pub.cs.systems.pdsd.lab04.contactsmanager.PHONE_NUMBER_KEY'', conținutul său fiind plasat în cadrul câmpului text corespunzător: <code java> | ||
| + | if (intent != null) { | ||
| + | String phone = intent.getStringExtra("ro.pub.cs.systems.pdsd.lab04.contactsmanager.PHONE_NUMBER_KEY"); | ||
| + | if (phone != null) { | ||
| + | phoneEditText.setText(phone); | ||
| + | } else { | ||
| + | Activity activity = getActivity(); | ||
| + | Toast.makeText(activity, activity.getResources().getString(R.string.phone_error), Toast.LENGTH_LONG).show(); | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| + | * pe metodele de tratare a evenimentelor de accesare a butoanelor: | ||
| + | * //Save// - este lansată în execuție aplicația nativă pentru gestiunea agendei telefonice, folosind un cod de cerere prin intermediul căruia se va verifica rezultatul furnizat: <code java> | ||
| + | getActivity().startActivityForResult(intent, Constants.CONTACTS_MANAGER_REQUEST_CODE); | ||
| + | </code> | ||
| + | * //Cancel// - se transmite înapoi rezultatul <code java> | ||
| + | getActivity().setResult(Activity.RESULT_CANCELED, new Intent()); | ||
| + | </code> | ||
| + | |||
| + | * în metoda ''onActivityResult()'' asociată activității ''ContactsManagerActivity'', în momentul în care s-a părăsit aplicația nativă pentru gestiunea agendei telefonice, se verifică codul de cerere și se transmite înapoi un rezultat: <code java> | ||
| + | public void onActivityResult(int requestCode, int resultCode, Intent intent) { | ||
| + | switch(requestCode) { | ||
| + | case Constants.CONTACTS_MANAGER_REQUEST_CODE: | ||
| + | setResult(resultCode, new Intent()); | ||
| + | finish(); | ||
| + | break; | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| - | ==== Fragmente ==== | + | **10.** Să se încarce modificările realizate în cadrul depozitului 'Laborator04' de pe contul Github personal, folosind un mesaj sugestiv. <code> |
| - | - Să se plaseze conținutul celor două ferestre create anterior în două fragmente aparținând aceleiași activități, afișându-se simultan pe ecran. | + | student@pdsd2015:~/Laborator04$ git add * |
| - | - Să se adauge un două butoane în cadrul primului fragment pentru atașarea, respectiv detașarea celui de-al doilea fragment de la activitate. | + | student@pdsd2015:~/Laborator04$ git commit -m "implemented taks for laboratory 04" |
| + | student@pdsd2015:~/Laborator04$ git push origin master | ||
| + | </code> | ||
| ===== Resurse Utile ===== | ===== Resurse Utile ===== | ||
