I del 3 fortsatte vi denne serien ved å forklare hvordan du legger til en helt ny kontakt. Vi diskuterte også hvordan du bruker Android Java API for å få tilgang til og manipulere kontakter i en Android-enhet. Denne opplæringen er den endelige avgiften i serien, og i det vil vi forklare hvordan du sletter og lagrer en kontakt ved hjelp av Android Java API. Vi vil også beskrive utviklingsmiljøet for søknaden, diskutere konfigurasjonsfiler for prosjektet, og gi individuelle skritt for import av prosjektet til Eclipse IDE.
Vi vil nå se på skriveoperasjoner om en kontakt. De er slett operasjon og lagre drift.
Følgende metode i ContactUtility
Klassen er ansvarlig for å slette en kontakt.
offentlig statisk tomt sletteKontakt (String id, ContentResolver contentResolver, String accountType) HashMapkontakter = getUsersFromAccount (accountType, contentResolver); String existingContactId = contacts.get (id); hvis (existingContactId == null) // Kontakten tilhører ikke kontoen tilbake; deleteContactInternal (id, contentResolver);
Som nevnt tidligere tillater vi ikke å slette eller endre en kontakt i denne opplæringsprogrammet, med mindre det er opprettet av selve applikasjonen. (Dette er rett og slett for å unngå utilsiktet skade på en kontakt i en ekte enhet, gitt at dette bare er en opplæringsapplikasjon.) For å oppdage om en kontakt er opprettet av dette programmet, er det tilstrekkelig å kontrollere om kontakt tilhører konto med den spesifikke kontotypen for dette programmet. De deleteContact ()
metode ovenfor først utfører en metode som heter getUsersFromAccount ()
som returnerer en liste over alle kontakt-ID-er for en gitt kontotype. Hvis kontakt-ID-en som ble bedt om å slette, er i den listen, så deleteContactInternal ()
Metoden kalles for å faktisk slette kontakten. Ellers, deleteContact ()
Metoden returnerer uten å slette kontakten.
De ContactUtility.getUsersFromAccount ()
Metoden er oppført nedenfor. Den bruker tabellen, hvor klausul og kolonneavn i spørringen "Kontakter knyttet til en konto" ovenfor.
importer java.util.HashMap ;? privat statisk HashMapGetUsersFromAccount (String accountType, ContentResolver contentResolver) Markørmarkør = contentResolver.query (ContactsContract.RawContacts.CONTENT_URI, null, ContactsContract.RawContacts.ACCOUNT_TYPE + "=?", ny String [] accountType, null); HashMap map = ny HashMap (); hvis (cursor.getCount ()> 0) mens (cursor.moveToNext ()) String contactId = cursor.getString (cursor.getColumnIndex (ContactsContract.RawContacts.CONTACT_ID)); map.put (kontaktId, kontaktId); returkort;
De ContactUtility.deleteContactInternal ()
Metoden er oppført nedenfor.
importer android.net.Uri ;? privat statisk tomt slettContactInternal (String id, ContentResolver contentResolver) Markørmarkør = contentResolver.query (ContactsContract.Contacts.CONTENT_URI, null, ContactsContract.Contacts._ID + "=?", ny String [] id, null); String oppslag = null; hvis (cursor.getCount ()> 0) while (cursor.moveToNext ()) lookup = cursor.getString (cursor.getColumnIndex (ContactsContract.Contacts.LOOKUP_KEY)); cursor.close (); Uri uri = Uri.withAppendedPath (ContactsContract.Contacts.CONTENT_LOOKUP_URI, oppslag); contentResolver.delete (uri, null, null);
Slette en kontakt fra databasen består av disse trinnene.
ContactsContract.Contacts.CONTENT_URI
som URI-basert representasjon av bordet.ContactsContract.Contacts.LOOKUP_KEY
som kolonnebeskrivelsen, få "oppslagstasten" for kontakten. Dette er en unik identifikator som skal brukes til å slette kontakten.android.net.Uri
objekt som konstruerer en URI-basert representasjon av kontaktens unike identifikator.ContentResolver.delete ()
metode med Uri
representasjon av kontakten for å slette den.Lagring av en kontakt skjer i to scenarier. Kontakten kan være en eksisterende i databasen, eller det kan være en helt ny kontakt for hvilken tilknyttede poster må settes inn fra bunnen av.
For å lagre en eksisterende kontakt, kan man bruke forskjellige strategier. Eksempelvis kan eksisterende poster oppdateres basert på rad-ID for disse postene. I denne opplæringsprogrammet, for enkelhet, bestemte vi oss for å lagre en eksisterende kontakt ved først å slette den og deretter sette tilbake som en helt ny kontakt. Dette er en enkel tilnærming fordi den benytter metodene som allerede er skrevet for å slette en eksisterende kontakt og lagre en helt ny kontakt. Tilleggskode med 'oppdatering' operasjoner ikke nødvendig.
De ContactUtility.saveOrUpdateContact ()
Metoden er oppført nedenfor. Den brukes til både nye og eksisterende kontakter.
offentlig statisk tomrom saveOrUpdateContact (Kontakt kontakt, ContentResolver contentResolver, String accountName, String accountType) if (kontakt == null || accountName == null || accountType == null) return; String id = contact.getContactId (); hvis (! "" er lik (erstattNull (id))) // Dette er eksisterende kontakt for å oppdatere HashMapkontakter = getUsersFromAccount (accountType, contentResolver); String existingContactId = contacts.get (id); hvis (existingContactId == null) // Dette er knyttet til en annen konto - kan ikke behandle retur; deleteContactInternal (id, contentResolver); saveContact (kontakt, contentResolver, accountName, accountType);
replaceNull ()
metode, oppført nedenfor, konverterer en null streng til en tom streng og er en del av de sunnhetskontrollene.getUsersFromAccount ()
Metoden har blitt vurdert ovenfor.) Hvis det ikke gjør det, må kontakten ikke endres, og metoden returnerer uten noen endring på kontoen.saveContact ()
Metoden kalles for å lagre kontakten. offentlig statisk String erstatteNull (String in) hvis (i == null) return ""; ellers return in;
De ContactUtility.saveContact ()
Metoden er oppført nedenfor. Det definerer en liste over android.content.ContentProviderOperation
forekomster for å sette inn individuelle poster og deretter samtaler ContentResolver.applyBatch ()
å utføre alle disse operasjonene samtidig.
com.jquerymobile.demo.contact
.ContentProviderOperation.newInsert ()
returnerer en forekomst av android.content.ContentProviderOperation.Builder
klassen, som vanligvis brukes til å definere parameterverdier for ContentProviderOperation
gjenstand. (Se følgende referanser for ContentProviderOperation
og Bygger
.) The Builder.withValue ()
operasjon returnerer samme forekomst av Bygger
slik at vi kan rekursivt passere kolonneverdier for den innførte posten.withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0)
klausul tillater kobling av hver innsatsrekord med den første innsatsrekorden der "rot" kontaktrekordet er satt inn.ContentResolver.applyBatch ()
kalles for å utføre batchinnsatsoperasjoner mot databasen.importere android.content.ContentProviderOperation ;? privat statisk tomt lagreKontakt (Kontakt kontakt, ContentResolver contentResolver, String accountName, String accountType) ArrayListoperasjoner = ny ArrayList (); // Ny kontaktoppføring med kontoinformasjon operations.add (ContentProviderOperation.newInsert (ContactsContract.RawContacts.CONTENT_URI) .withValue (ContactsContract.RawContacts.ACCOUNT_TYPE, accountType) .withValue (ContactsContract.RawContacts.ACCOUNT_NAME, accountName) .build ()); // For- og etternavn operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) .withValue (ContactsContract.CommonDataKinds.StructuredName .GIVEN_NAME, contact.getFirstName ()) .withValue (ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, contact.getLastName ()) .build ()); // Merk hvis (contact.getNote ()! = null) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds. Note.CONTENT_ITEM_TYPE) .withValue (ContactsContract.CommonDataKinds.Note.NOTE, contact.getNote (). GetText ()) .build ()); // Adresser Samling adresser = contact.getAddresses (); hvis (adresser! = null) for (adresse adresse: adresser) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, KontakterContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE) .withValue (ContactsContract.CommonDataKinds.StructuredPostal.TYPE, address.getType ()) .withValue (ContactsContract.CommonDataKinds.StructuredPostal.STREET, address.getStreet ()) .withValue (ContactsContract.CommonDataKinds.StructuredPostal .CITY, address.getCity ()) .withValue (ContactsContract.CommonDataKinds.StructuredPostal.REGION, address.getState ()) .withValue (ContactsContract.CommonDataKinds.StructuredPostal.POBOX, address.getPoBox ()) .withValue (ContactsContract.CommonDataKinds. StructuredPostal.POSTCODE, address.getZip ()) .withValue (ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY, address.getCountry ()) .build ()); // Organisasjoner Samling organisasjoner = contact.getOrganizations (); hvis (organisasjoner! = null) for (Organisasjonsorganisasjon: organisasjoner) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, KontakterContract.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 ()); // Emails Samling e-postadresser = contact.getEmails (); hvis (e-post! = null) for (e-postadresse: e-post) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, KontakterContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) .withValue (ContactsContract.CommonDataKinds.Email.TYPE, email.getType ()) .withValue (ContactsContract.CommonDataKinds.Email.DATA, email.getValue ()) .build ()); // IM Samling ims = contact.getIms (); hvis (ims! = null) for (Im im: ims) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, KontakterContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) .withValue (ContactsContract.CommonDataKinds.Im.PROTOCOL, im.getProtocol ()) .withValue (ContactsContract.CommonDataKinds.Im.DATA, im.getValue ()) .build ()); // Telefoner Samling telefoner = contact.getPhones (); hvis (telefoner = null) for (telefon telefon: telefoner) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) .withValue (ContactsContract.CommonDataKinds.Phone.TYPE, phone.getType ()) .withValue (ContactsContract.CommonDataKinds.Phone.NUMBER, phone.getNo ()) .build ()); prøv contentResolver.applyBatch (ContactsContract.AUTHORITY, drift); fangst (unntak e)
Etter å ha vurdert koden, la oss nå se på konfigurasjon og andre støttefiler for prosjektet.
Pakken = "com.jquerymobile.demo.contact" android: versionCode = "1" android: versionName = "1.0"> /> /> /> /> android: configChanges = "orientation | keyboardHidden" android: label = "@ streng / app_name"><service android: name =".Authentication.AuthenticationService" android: eksportert = "true"> service> ".ContactsActivity"
com.jquerymobile.demo.contact
, som er spesifisert på toppnivå manifest
element. Erklæringene .authentication.AuthenticationService
og .ContactsActivity
er i forhold til pakkenavnet.bruker-tillatelse
elementer.service
element i 'Opprett konto', del 2 i denne opplæringen.Kontakt
De strings.xml
lagrer konstante strenger som brukes i søknaden. Den eneste konstanten vi bruker er app_name
element som er navnet på søknaden. Verdien av den konstanten, "Kontakter", vises på forskjellige steder i Android-enheten, som vist i figuren nedenfor: Programmer-startskjermbildet (venstre), startskjermbildet (midten) og administrer programskjermbildet (høyre).
Lanseringsikonene for programmet er basert på Android GUI-elementene i http://www.matcheck.cz/androidguipsd/. Per Retningslinjer for Android-ikonet er tre ikonfiler opprettet som beskrevet nedenfor.
Mappenavn | Filnavn | Pixel størrelse |
res \ teikne-ldpi | icon.png | 36 x 36 |
res \ teikne-mdpi | icon.png | 48 x 48 |
res \ teikne-HDPI | icon.png | 72 x 72 |
Disse ikonene er vist i figuren under. Ikonet til venstre er 36x36 piksler, den i midten er 48x48 piksler og den til høyre er 72x72 piksler.
Vi vil nå diskutere hvordan du importerer den opprinnelige applikasjonen til Eclipse utviklingsmiljø. Prosjektfilene ble testet mot:
Prosjektet har blitt testet med Android platform 2.2 API nivå 8.
Før du importerer prosjektet til Eclipse-miljøet, må du kontrollere at Eclipse ADT-plugin peker på riktig sted for Android SDK i ditt lokale system. For å sjekke dette, gå til Eclipse-menyen Vinduet -> Innstillinger -> Android
. De SDK-plassering
Vinduet må settes til plasseringen av Android SDK. Når du er satt opp riktig, bør du se noe som ligner på under
Prosjektfilene leveres i en arkivfil som heter contacts.zip
. For å importere prosjektet, gå til Eclipse-menyen Fil -> Importer
og velg deretter fil importveiviseren Generelt -> Eksisterende prosjekter i arbeidsområdet
(se nedenfor).
På neste side av veiviseren velger du Velg arkivfil:
og bla til hvor contacts.zip
ligger i filsystemet ditt. De prosjekter
vinduet vil automatisk bli fylt der hvor ContactsDemo
prosjektet er allerede valgt. Dette er vist nedenfor. trykk Bli ferdig
knappen for å fullføre importen.
Eclipse vil bygge applikasjonen automatisk etter import. Nå bør du se ContactsDemo-prosjektet i prosjektutforskeren, som vist nedenfor.
Dette prosjektet er bygget og testet for Android OS 2.2-plattformen. For å bekrefte dette, velg ContactsDemo
prosjekt i prosjektutforsker og fra høyreklikkmeny velg Eiendommer
. På venstre side liste over egenskaper, velg Android
som eiendommen. De tilgjengelige byggemålene vises til høyre, som vist nedenfor. Du bør se at Android 2.2 er valgt.
En liste over filer i prosjektet er gitt nedenfor.
src
mappen lagrer Java-koden. Det er to pakker: com.jquerymobile.demo.contact
pakken inneholder Adresse
, Ta kontakt med
, ContactDisplay
, ContactGroup
, ContactsActivity
, ContactUtility
, e-post
, Jeg er
, Merk
, Organisasjon
og telefon
klasser.com.jquerymobile.demo.contact.authentication
pakken inneholder authentiseringstjenesten
klasse.gen
mappen inneholder forskjellige filer som automatisk genereres av Eclipse ADT.eiendeler
mappen lagrer HTML-filer, bildefiler som brukes i disse HTML-filene og jQuery Mobile / jQuery-biblioteker. Vi bruker jQuery Mobile versjon 1.0 Alpha 3, som var den siste utgivelsen da opplæringen ble skrevet. (En Alpha 4-utgivelse ble nylig laget med ulike feilrettinger. Se kunngjøringen.)lib
mappen lagrer Jackson JSON biblioteker.res
mappen lagrer ulike ressurser som kreves av søknaden. Det er ikonbildene og konfigurasjonsfilene strings.xml
og authenticator.xml
.default.properties
er en systemgenerert fil som definerer API-versjonen for Android-applikasjonen.proguard.cfg
filen opprettes automatisk av utviklingsmiljøet og brukes av ProGuard-verktøyet. Detaljer finner du i ProGuard Documentation. I denne opplæringen implementerte vi et Android-program der brukergrensesnittet er konstruert via HTML / JavaScript, og kjernens innfødte funksjonalitet er utviklet via Java. En fordel ved denne tilnærmingen er at webutviklere, som allerede har kjennskap til HTML og JavaScript, kan bruke sin kunnskap til å konstruere brukergrensesnittet uten å måtte lære Android-spesifikke APIer, UI-hendelseshåndteringsmodell og Java-programmeringsspråket. På den annen side kan utviklere med Java-kompetanse fokusere på å bygge den innfødte funksjonaliteten ved hjelp av Android Java API. På denne måten kan arbeidsinnsatsen deles mellom to eller flere utviklere basert på eksisterende ferdighetssett.
Et typisk design hensyn til en Android-applikasjon er at den visuelle aspekter og hendelseshåndteringsmodell av brukergrensesnittet må være konsekvent på tvers av ulike enheter der applikasjonen skal installeres. Disse enhetene kan ha forskjellige skjermdimensjoner og kjøre forskjellige sett med nettlesere med forskjellige nivåer av HTML-støtte. I den forbindelse er jQuery Mobile gunstig fordi den gir lett tilgjengelige brukergrensesnittkomponenter med en støttende hendelseshåndteringsmodell. Den har allerede blitt testet for konsistens på tvers av ulike enheter og nettlesere, noe som gjør utviklingen på tvers av plattformen lettere.
Til slutt, vær oppmerksom på at enkelte programmer ikke passer inn i modellen ovenfor. For eksempel: