Creați o aplicație de contact cu jQuery Mobile și SDK-ul Android - Partea 4

În Partea 3, am continuat această serie explicând modul de adăugare a unui contact nou. Am discutat, de asemenea, cum să folosim API-ul Android Java pentru accesarea și manipularea contactelor într-un dispozitiv Android. Acest tutorial este ultima tranșă din seria și în care vom explica cum să ștergeți și să salvați un contact folosind API-ul Android Java. Vom descrie, de asemenea, mediul de dezvoltare pentru aplicație, vom discuta fișierele de configurare pentru proiect și vom da pași individuali pentru importul proiectului în Eclipse IDE.


Scrie operațiuni pentru contacte

Vom analiza acum operațiile de scriere referitoare la un contact. Acestea sunt operațiunea de ștergere și economisirea operațiunii.

Ștergerea unui contact

Următoarea metodă din ContactUtility clasa este responsabilă pentru ștergerea unui contact.

 public static void deleteContact (id șir, ContentResolver contentResolver, String accountType) HashMap contacte = getUsersFromAccount (contType, contentResolver); String existentContactId = contacts.get (id); if (existingContactId == null) // Contactul nu face parte din returul contului;  deleteContactInternal (id, contentResolver); 

Așa cum am menționat mai sus, nu permitem ștergerea sau modificarea unui contact în această aplicație tutorial decât dacă a fost creată de aplicația în sine. (Aceasta este pur și simplu pentru a evita deteriorarea accidentală a unui contact într-un dispozitiv real, dat fiind faptul că acesta este doar o aplicație tutorial.) Pentru a detecta dacă un contact a fost creat de această aplicație, este suficient să verificați dacă contactul aparține contul cu tipul de cont specific pentru această aplicație. deleteContact () metoda de mai sus execută mai întâi o metodă numită getUsersFromAccount () care returnează o listă a tuturor id-urilor de contact pentru un anumit tip de cont. Dacă ID-ul de contact solicitat pentru ștergere este în acea listă atunci deleteContactInternal () metoda este chemată să șterge efectiv contactul. In caz contrar, deleteContact () metoda revine fără ștergerea contactului.

ContactUtility.getUsersFromAccount () este prezentată mai jos. Utilizează tabelul, în cazul în care clauza și numele coloanelor din interogarea "Contactele asociate cu un cont" de mai sus.

 import java.util.HashMap ;? static HashMap static getUsersFromAccount (String accountType, ContentResolver contentResolver) Cursor cursor = contentResolver.query (ContacteContract.RawContacts.CONTENT_URI, null, ContactsContract.RawContacts.ACCOUNT_TYPE + "=?", noul String [] accountType, null); HashMap map = nou HashMap(); dacă (cursor.getCount ()> 0) în timp ce (cursor.moveToNext ()) String contactId = cursor.getString (cursor.getColumnIndex (ContactsContract.RawContacts.CONTACT_ID)); map.put (contactId, contactId);  retur hartă; 

ContactUtility.deleteContactInternal () este prezentată mai jos.

 import android.net.Uri ;? privat static privat deleteContactInternal (id de șir, contentResolver contentResolver) Cursor cursor = contentResolver.query (ContacteContract.Contacts.CONTENT_URI, null, ContactsContract.Contacts._ID + "=?", nou String [] id, null); String căutare = null; dacă (cursor.getCount ()> 0) în timp ce (cursor.moveToNext ())  căutare = cursor.getString (cursor.getColumnIndex (ContactsContract.Contacts.LOOKUP_KEY));   cursor.close (); Uri uri = Uri.withAppendedPath (ContacteContract.Contacts.CONTENT_LOOKUP_URI, căutare); contentResolver.delete (uri, null, null); 

Ștergerea unui contact din baza de date constă în acei pași.

  • Mai întâi, interogați baza de date pentru a obține înregistrarea de contacte utilizând ContactsContract.Contacts.CONTENT_URI ca reprezentare bazată pe URI a tabelului.
  • Utilizarea ContactsContract.Contacts.LOOKUP_KEY ca descriptor de coloană, obțineți "cheia de căutare" pentru contact. Acesta este un identificator unic care trebuie utilizat pentru ștergerea contactului.
  • Construiți a android.net.Uri obiect care construiește o reprezentare bazată pe URI a identificatorului unic al contactului.
  • Apel ContentResolver.delete () metoda cu uri reprezentare a contactului pentru ao șterge.

Salvarea unui contact

Salvarea unui contact are loc în două scenarii. Contactul poate fi unul existent în baza de date sau poate fi un contact nou, pentru care înregistrările asociate trebuie introduse de la zero.

Pentru a salva un contact existent, s-ar putea folosi strategii diferite. De exemplu, înregistrările existente pot fi actualizate pe baza id-ului rândului acelor înregistrări. În această aplicație tutorial, pentru simplitate, am decis să salvăm un contact existent ștergându-l mai întâi și apoi inserând înapoi ca un contact nou. Aceasta este o abordare simplă, deoarece utilizează metodele deja scrise pentru ștergerea unui contact existent și salvarea unui contact nou. Cod suplimentar cu operațiuni de "actualizare" nu este necesar.

ContactUtility.saveOrUpdateContact () este prezentată mai jos. Este utilizat atât pentru contactele noi, cât și pentru cele existente.

 static public void saveOrUpdateContact (contact de contact, ContentResolver contentResolver, nume contNet, String accountType) if (contact == null || contName == null || accountType == null) retur;  String id = contact.getContactId (); dacă ("" este egal (înlocuieșteNull (id))) // Acesta este contactul existent pentru a actualiza HashMap contacte = getUsersFromAccount (contType, contentResolver); String existentContactId = contacts.get (id); if (existingContactId == null) // Aceasta este asociată cu un alt cont - nu poate procesa returnarea;  deleteContactInternal (id, contentResolver);  saveContact (contact, contentResolver, accountName, accountType); 
  • Există mai multe controale sanitare, pentru a evita obiectele nulă sau trivială. replaceNull () , enumerate mai jos, transformă un șir nul într-un șir gol și face parte din acele verificări de sănătate.
  • Dacă id-ul nu este un șir gol, acesta trebuie să corespundă unui contact existent în baza de date. În acest caz, verificăm dacă aparține contului asociat cu această aplicație. (The getUsersFromAccount () metoda a fost examinată mai sus.) În caz contrar, contactul nu trebuie modificat și metoda revine fără nicio modificare în cont.
  • Dacă persoana de contact aparține contului asociat cu această aplicație, este șters.
  • In cele din urma, saveContact () metoda este chemată pentru a salva contactul.
 static public static replaceNull (String în) if (in == null) return "";  altceva return in; 

ContactUtility.saveContact () este prezentată mai jos. Definește o listă de android.content.ContentProviderOperation instanțe pentru introducerea înregistrărilor individuale și apoi a apelurilor ContentResolver.applyBatch () să efectueze simultan toate aceste operațiuni.

  • Prima operație asociază înregistrarea de contact nou creată cu numele contului și tipul de cont pentru această aplicație. Amintiți-vă că numele contului a fost specificat de utilizator atunci când contul a fost creat pentru prima dată, iar tipul contului este constanta com.jquerymobile.demo.contact.
  • Metoda ContentProviderOperation.newInsert () returnează o instanță de android.content.ContentProviderOperation.Builder clasa, care este de obicei folosită pentru a defini valorile parametrilor pentru ContentProviderOperation obiect. (Consultați următoarele referințe pentru ContentProviderOperation și Constructor.) Builder.withValue () operația returnează aceeași instanță a Constructor permițându-ne să trecem recursiv valorile coloanelor pentru înregistrarea inserată.
  • cuValueBackReference (ContacteContract.Data.RAW_CONTACT_ID, 0) clauza permite legarea fiecărei înregistrări inserate cu prima înregistrare a inserției în care este introdusă înregistrarea de contact "rădăcină".
  • În urma înregistrării primului insert, sunt definite înregistrări adiționale suplimentare pentru numele și prenumele, notele, adresele, organizațiile, e-mailurile, IM-urile și telefoanele persoanei de contact.
  • In cele din urma, ContentResolver.applyBatch () este chemat să efectueze operațiile de inserare a loturilor în baza de date.
 import android.content.ContentProviderOperation ;? private static void saveContact (contact de contact, ContentResolver contentResolver, nume contNet, String accountType) ArrayListoperațiuni = noul ArrayList(); // Informații noi despre contacte cu informații despre cont operațiuni.add (ContentProviderOperation.newInsert (ContactsContract.RawContacts.CONTENT_URI) .withValue (ContactsContract.RawContacts.ACCOUNT_TYPE, accountType) .withValue (ContactsContract.RawContacts.ACCOUNT_NAME, accountName) .build ()); // Numele si prenumele operațiuni.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContacteContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) .withValue (ContactsContract.CommonDataKinds.StructuredName .GIVEN_NAME, contact.getFirstName ()) .cuValue (ContacteContract.CommonDataKinds.StructuredName.FAMILY_NAME, contact.getLastName ()) .build ()); // Notă dacă (contact.getNote ()! = null) operații.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds. Notă.CONTENT_ITEM_TYPE) .cuValue (ContactsContract.CommonDataKinds.Note.NOTE, contact.getNote (). GetText ()) .build ());  // Adrese Colectie
adrese = contact.getAddresses (); dacă adresa (adresa! = null) pentru (adresa adresă: adrese) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContacteContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE) .cuValue (ContactsContract.CommonDataKinds.StructuredPostal.TYPE, address.getType ()) .withValue (ContactsContract.CommonDataKinds.StructuredPostal.STREET, address.getStreet ()) .withValue (ContactsContract.CommonDataKinds.StructuredPostal .CITY, address.getCity ()). Cu Valoare (ContactsContract.CommonDataKinds.StructuredPostal.REGION, address.getState ()) .withValue (ContactsContract.CommonDataKinds.StructuredPostal.POBOX, address.getPoBox ()) .withValue (ContactsContract.CommonDataKinds. StructuratPostal.POSTCODE, address.getZip ()). Cu Valoare (ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY, address.getCountry ()) .build ()); // Organizații Colectie organizații = contact.getOrganizations (); (organizații: organizații) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContacteContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE) .withValue (ContactsContract.CommonDataKinds.Organization.TYPE, organization.getType ()) .withValue (ContactsContract.CommonDataKinds.Organization.DATA, organization.getName ()) .withValue (ContactsContract.CommonDataKinds.Organization .TITLE, organization.getTitle ()) .build ()); // E-mailuri Colectie e-mailuri = contact.getEmails (); dacă (e-mailuri! = null) pentru (e-mail de email: e-mailuri) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContacteContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE). Cu Valoare (ContactsContract.CommonDataKinds.Email.TYPE, email.getType ()). Cu Valoare (ContactsContract.CommonDataKinds.Email.DATA, email.getValue ()) .build ()); // IMs Colectie ims = contact.getIms (); dacă (ims! = null) pentru (Im im: ims) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContacteContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE). Cu Valoare (ContactsContract.CommonDataKinds.Im.PROTOCOL, im.getProtocol ()). Cu Valoare (ContactsContract.CommonDataKinds.Im.DATA, im.getValue ()) .build ()); // Telefoane Colectie telefoane = contact.getPhones (); dacă (telefoane! = null) pentru (Telefon: telefoane) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContacteContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE). Cu Valoare (ContactsContract.CommonDataKinds.Phone.TYPE, phone.getType ()) .withValue (ContactsContract.CommonDataKinds.Phone.NUMBER, phone.getNo ()) .build ()); încerca contentResolver.applyBatch (ContactsContract.AUTHORITY, operațiuni); captură (Excepție e)

Configurarea proiectului și fișierele suport

După examinarea codului, examinați acum configurația și alte fișiere suport pentru proiect.

AndroidManifest.xml

  pachet = "com.jquerymobile.demo.contact" android: versionCode = "1" și Android: versionName = "1.0"> /> />  />  />  <serviciu android: name =".Authentication.AuthenticationService" Android: exportate = "true">     serviciu> ".ContactsActivity" android: configChanges = "orientare | tastaturăHidden" android: label = "@ string / app_name">       
  • Numele pachetului pentru aplicația noastră este com.jquerymobile.demo.contact, care este specificat la nivel superior manifesta element. Declarațiile .authentication.AuthenticationService și .ContactsActivity sunt relativ la numele pachetului.
  • Vom lista tipurile de permisiuni cerute de aplicație prin folosește-permisiune element.
  • Am discutat despre asta serviciu element în "Crearea contului", Partea 2 a acestui tutorial.

strings.xml

   Contacte 

strings.xml stochează șiruri constante folosite în aplicație. Singura constanta pe care o folosim este numele aplicatiei element care este numele aplicației. Valoarea acelei constante, "Persoane de contact", este afișată în diverse locații ale dispozitivului Android, după cum se arată în figura de mai jos: ecranul de lansare a aplicațiilor (stânga), ecranul de pornire (mijloc).

Figura 17. Numele aplicatiei.

Pictogramă de lansare a aplicației

Pictogramele de lansare pentru aplicație se bazează pe elementele GUI Android de pe http://www.matcheck.cz/androidguipsd/. Pe Ghidul de proiectare a pictogramelor Android, au fost create trei fișiere de pictograme, după cum este descris mai jos.

Numele fisierului Nume de fișier Dimensiunea pixelilor
res \ drawable-ldpi icon.png 36 x 36
res \ drawable-mdpi icon.png 48 x 48
res \ drawable-hdpi icon.png 72 x 72

Aceste icoane sunt prezentate în figura de mai jos. Pictograma din stânga este de 36x36 pixeli, cea din mijloc este de 48x48 pixeli, iar cea din partea dreaptă este de 72x72 pixeli.

Figura 18. Lansați pictograme.

Nativ mediul de dezvoltare a aplicațiilor Android

Vom discuta despre importul aplicației native în mediul de dezvoltare Eclipse. Fișierele proiectului au fost testate împotriva:

  • Versiunea Android SDK 8.
  • Eclipse IDE versiunea 3.5
  • Instrumente de dezvoltare Android (ADT), care este un plugin Eclipse, versiunea 8.0.1.

Proiectul a fost testat cu succes de platforma Android 2.2 API nivel 8.

Importul Proiectului

Înainte de a importa proiectul în mediul Eclipse, asigurați-vă că pluginul Eclipse ADT indică locația corectă a SDK-ului Android în sistemul dvs. local. Pentru a verifica acest lucru, în meniul Eclipse mergeți la Fereastră -> Preferințe -> Android. Locația SDK fereastra trebuie să fie setată la locația SDK Android. Odată setat corect, ar trebui să vedeți ceva similar celui de mai jos

Figura 19. Eclipse Preferințe.

Fișierele proiectului sunt furnizate într-un fișier de arhivă numit contacts.zip. Pentru a importa proiectul, în meniul Eclipse mergeți la Fișier -> Import apoi selectați din expertul de import fișier Generalități -> Proiecte existente în spațiul de lucru (Vezi mai jos).

Figura 20. Import de proiect.

În pagina următoare a expertului, alegeți Selectați fișierul de arhivă: și răsfoiți către unde contacts.zip este localizat în sistemul dvs. de fișiere. proiecte fereastra va fi automat populate acolo unde ContactsDemo proiectul este deja selectat. Acest lucru este prezentat mai jos. apasă pe finalizarea pentru a finaliza importul.

Figura 21. Selectarea fișierului de proiect.

Eclipse va construi aplicația automat după import. Acum, ar trebui să vedeți proiectul ContactsDemo în exploratorul de proiecte, după cum se arată mai jos.

Figura 22. Proiect Explorer.

Acest proiect a fost construit și testat pentru platforma Android OS 2.2. Pentru a verifica acest lucru, selectați ContactsDemo proiect în explorator de proiect și din meniul cu butonul din dreapta selectați Proprietăți. În lista din stânga a proprietăților, selectați Android ca proprietate. Obiectele de construcție disponibile sunt afișate în partea dreaptă, după cum se arată mai jos. Ar trebui să vedeți că Android 2.2 a fost selectat.

Figura 23. Android Build Target.

Afișarea fișierelor

O listă de fișiere din proiect este prezentată mai jos.

Figura 24. Afișarea fișierelor.
  • src folderul stochează codul Java. Există două pachete:
    • com.jquerymobile.demo.contact pachetul conține Adresa, a lua legatura, ContactDisplay, ContactGroup, ContactsActivity, ContactUtility, E-mail, Sunt, Notă, Organizare și Telefon clase.
    • com.jquerymobile.demo.contact.authentication pachetul conține AuthenticationService clasă.
  • gen folder conține diferite fișiere generate automat de Eclipse ADT.
  • bunuri folderul stochează fișiere HTML, fișiere imagine utilizate în acele fișiere HTML și jQuery Mobile / jQuery libraries. Utilizăm jQuery Mobile versiunea 1.0 Alpha 3, cea mai recentă versiune când a fost scris tutorialul. (A fost lansată recent o versiune Alpha 4 cu diferite corecții de erori. Vedeți anunțul.)
  • lib folderul stochează bibliotecile Jackson JSON.
  • res folderul stochează diverse resurse necesare aplicației. Acestea sunt imaginile cu pictograme și fișierele de configurare strings.xml și authenticator.xml.
  • default.properties este un fișier generat de sistem care definește versiunea API pentru aplicația Android.
  • proguard.cfg fișierul este creat automat de mediul de dezvoltare și este utilizat de instrumentul ProGuard. Detalii pot fi găsite în ProGuard Documentation.

concluzii

În acest tutorial am implementat o aplicație Android unde UI este construit prin HTML / JavaScript și funcționalitatea nativă de bază este dezvoltată prin Java. Un avantaj al acestei abordări îl reprezintă faptul că dezvoltatorii web, care deja cunosc HTML și JavaScript, își pot folosi cunoștințele pentru a construi UI fără a fi nevoie să învețe API specifice Android, modelul de manipulare a evenimentelor UI și limbajul de programare Java. Pe de altă parte, dezvoltatorii cu expertiză Java se pot concentra pe construirea funcționalității native utilizând API-ul Android Java. În acest fel, efortul de lucru poate fi împărțit între doi sau mai mulți dezvoltatori pe baza seturilor de competențe existente.

Un aspect tipic de proiectare pentru o aplicație Android este că aspectele vizuale și modelul de manipulare a evenimentelor din UI trebuie să fie consecvente pe diferite dispozitive în care aplicația va fi instalată. Aceste dispozitive pot avea dimensiuni diferite ale ecranului și pot rula diverse seturi de browsere web cu niveluri diferite de suport HTML. În acest sens, jQuery Mobile este benefic deoarece oferă componente de interfață cu utilizatorul ușor accesibile, cu un model de gestionare a evenimentului. Acesta a fost deja testat pentru consistență între diferite dispozitive și browsere, facilitând dezvoltarea platformelor.

În cele din urmă, rețineți că unele aplicații nu se încadrează în modelul de mai sus. De exemplu:

  • Anumite aplicații necesită componente UI sofisticate, de ex. animații complexe, care ar putea să nu fie fezabile pentru a construi folosind pagini HTML.
  • Se poate folosi un cadru de aplicații web, cum ar fi PhoneGap, pentru a accesa funcțiile native printr-un JavaScript API simplificat, în cazul în care API-ul este suficient pentru a satisface cerințele afacerii. În acest caz, interfața de utilizator poate fi construită în continuare cu jQuery Mobile, cu toate acestea, este posibil să nu fie nevoie să se dezvolte codul de back-end Java.
Cod