Nella parte 3, abbiamo continuato questa serie spiegando come aggiungere un contatto nuovo di zecca. Abbiamo anche discusso su come usare l'API Java di Android per accedere e manipolare i contatti in un dispositivo Android. Questo tutorial è l'ultimo capitolo della serie e in esso spiegheremo come eliminare e salvare un contatto utilizzando l'API Java di Android. Descriveremo anche l'ambiente di sviluppo per l'applicazione, discuteremo i file di configurazione per il progetto e forniremo i singoli passaggi per importare il progetto nell'IDE di Eclipse.
Vedremo ora le operazioni di scrittura relative a un contatto. Quelli sono operazione di cancellazione e operazione di salvataggio.
Il seguente metodo in ContactUtility
la classe è responsabile dell'eliminazione di un contatto.
pubblico static void deleteContact (String id, ContentResolver contentResolver, String accountType) HashMapcontacts = getUsersFromAccount (accountType, contentResolver); String existingContactId = contacts.get (id); if (existingContactId == null) // Il contatto non appartiene al ritorno dell'account; deleteContactInternal (id, contentResolver);
Come accennato in precedenza, non è consentito eliminare o modificare un contatto in questa applicazione di esercitazione a meno che non sia stato creato dall'applicazione stessa. (Questo è semplicemente per evitare danni accidentali a un contatto in un dispositivo reale, dato che si tratta semplicemente di un'applicazione tutorial.) Per rilevare se un contatto è stato creato da questa applicazione, è sufficiente verificare se il contatto appartiene al account con il tipo di account specifico per questa applicazione. Il deleteContact ()
il metodo sopra prima esegue un metodo chiamato getUsersFromAccount ()
che restituisce un elenco di tutti gli ID dei contatti per un determinato tipo di account. Se l'ID del contatto richiesto per l'eliminazione è in quell'elenco allora deleteContactInternal ()
il metodo viene chiamato per eliminare effettivamente il contatto. Altrimenti, deleteContact ()
il metodo ritorna senza eliminare il contatto.
Il ContactUtility.getUsersFromAccount ()
il metodo è elencato di seguito. Utilizza la tabella, dove i nomi delle clausole e delle colonne nella query "Contatti associati a un account" sopra.
importare java.util.HashMap ;? HashMap statico privatogetUsersFromAccount (String accountType, ContentResolver contentResolver) Cursore cursor = contentResolver.query (ContactsContract.RawContacts.CONTENT_URI, null, ContactsContract.RawContacts.ACCOUNT_TYPE + "=?", new String [] accountType, null); HashMap map = new HashMap (); if (cursor.getCount ()> 0) while (cursor.moveToNext ()) String contactId = cursor.getString (cursor.getColumnIndex (ContactsContract.RawContacts.CONTACT_ID)); map.put (contactId, contactId); restituisce la mappa;
Il ContactUtility.deleteContactInternal ()
il metodo è elencato di seguito.
importare android.net.Uri ;? private static void deleteContactInternal (String id, ContentResolver contentResolver) Cursore cursor = contentResolver.query (ContactsContract.Contacts.CONTENT_URI, null, ContactsContract.Contacts._ID + "=?", new String [] id, null); String lookup = null; if (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, lookup); contentResolver.delete (uri, null, null);
L'eliminazione di un contatto dal database consiste in questi passaggi.
ContactsContract.Contacts.CONTENT_URI
come la rappresentazione basata sulla URI della tabella.ContactsContract.Contacts.LOOKUP_KEY
come descrittore di colonne, ottenere la "chiave di ricerca" per il contatto. Questo è un identificatore univoco da utilizzare per eliminare il contatto.android.net.Uri
oggetto che costruisce una rappresentazione basata su URI dell'identificatore univoco del contatto.ContentResolver.delete ()
metodo con il Uri
rappresentazione del contatto per eliminarlo.Il salvataggio di un contatto avviene in due scenari. Il contatto potrebbe essere esistente nel database o potrebbe essere un nuovo contatto per cui i record associati devono essere inseriti da zero.
Per salvare un contatto esistente, è possibile utilizzare strategie diverse. Ad esempio, i record esistenti possono essere aggiornati in base all'ID di riga di tali record. In questa applicazione tutorial, per semplicità, abbiamo deciso di salvare un contatto esistente eliminandolo e inserendolo nuovamente come nuovo contatto. Questo è un approccio semplice perché utilizza i metodi già scritti per eliminare un contatto esistente e salvare un contatto nuovo di zecca. Codice aggiuntivo con operazioni di 'aggiornamento' non necessarie.
Il ContactUtility.saveOrUpdateContact ()
il metodo è elencato di seguito. Viene utilizzato sia per i contatti nuovi che esistenti.
pubblico static void saveOrUpdateContact (Contatto di contatto, ContentResolver contentResolver, String accountName, String accountType) if (contact == null || accountName == null || accountType == null) return; String id = contact.getContactId (); if (! "". equals (replaceNull (id))) // Questo è un contatto esistente per aggiornare HashMapcontacts = getUsersFromAccount (accountType, contentResolver); String existingContactId = contacts.get (id); if (existingContactId == null) // Questo è associato a un altro account - non può elaborare il reso; deleteContactInternal (id, contentResolver); saveContact (contact, contentResolver, accountName, accountType);
replaceNull ()
metodo, elencato di seguito, converte una stringa nulla in una stringa vuota e fa parte di quei controlli di integrità.getUsersFromAccount ()
metodo è stato rivisto in precedenza.) In caso contrario, il contatto non dovrebbe essere modificato e il metodo ritorna senza alcuna modifica sull'account.saveContact ()
il metodo è chiamato per salvare il contatto. public static String replaceNull (String in) if (in == null) return ""; else return in;
Il ContactUtility.saveContact ()
il metodo è elencato di seguito. Definisce una lista di android.content.ContentProviderOperation
istanze per l'inserimento di singoli record e quindi chiamate ContentResolver.applyBatch ()
per eseguire tutte quelle operazioni contemporaneamente.
com.jquerymobile.demo.contact
.ContentProviderOperation.newInsert ()
restituisce un'istanza di android.content.ContentProviderOperation.Builder
classe, che viene in genere utilizzata per definire i valori dei parametri per ContentProviderOperation
oggetto. (Vedi i seguenti riferimenti per ContentProviderOperation
e Costruttore
.) Il Builder.withValue ()
operazione restituisce la stessa istanza di Costruttore
permettendoci di passare in modo ricorsivo i valori delle colonne per il record inserito.withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0)
la clausola consente il collegamento di ciascun record di inserimento con il primo record di inserimento in cui è inserito il record di contatto 'root'.ContentResolver.applyBatch ()
viene chiamato per eseguire le operazioni di inserimento batch rispetto al database.import android.content.ContentProviderOperation ;? private static void saveContact (Contatto di contatto, ContentResolver contentResolver, String accountName, String accountType) ArrayListoperations = new ArrayList (); // Nuovo record di contatto con informazioni sull'account operations.add (ContentProviderOperation.newInsert (ContactsContract.RawContacts.CONTENT_URI) .withValue (ContactsContract.RawContacts.ACCOUNT_TYPE, accountType) .withValue (ContactsContract.RawContacts.ACCOUNT_NAME, accountName) .build ()); // Nome e cognome 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 ()); // Nota if (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 ()); // Indirizzi Collezione indirizzi = contact.getAddresses (); if (indirizzi! = null) per (indirizzo: indirizzi) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContactsContract.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 ()); // Organizzazioni Collezione organizzazioni = contact.getOrganizations (); if (organizzazioni! = null) for (Organizzazione organizzazione: organizzazioni) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContactsContract.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 ()); // Email Collezione email = contact.getEmails (); if (email! = null) for (Email email: email) operations.add (ContentProviderOperation.newInsert (ContactsContract.Data.CONTENT_URI) .withValueBackReference (ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue (ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) .withValue (ContactsContract.CommonDataKinds.Email.TYPE, email.getType ()) .withValue (ContactsContract.CommonDataKinds.Email.DATA, email.getValue ()) .build ()); // Io sono S Collezione ims = contact.getIms (); if (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, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) .withValue (ContactsContract.CommonDataKinds.Im.PROTOCOL, im.getProtocol ()) .withValue (ContactsContract.CommonDataKinds.Im.DATA, im.getValue ()) .build ()); // telefoni Collezione phones = contact.getPhones (); if (phones! = null) for (Telefono: telefoni) 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 ()); provare contentResolver.applyBatch (ContactsContract.AUTHORITY, operazioni); catch (Exception e)
Dopo aver esaminato il codice, esaminiamo ora la configurazione e altri file di supporto per il progetto.
package = "com.jquerymobile.demo.contact" android: versionCode = "1" android: versionName = "1.0"> /> /> /> /> android: configChanges = "orientation | keyboardHidden" android: label = "@ string / nome_app"><servizio android: name =".Authentication.AuthenticationService" Android: esportato = "true"> servizio> ".ContactsActivity"
com.jquerymobile.demo.contact
, che è specificato nel livello superiore manifesto
elemento. Le dichiarazioni .authentication.AuthenticationService
e .ContactsActivity
sono relativi al nome del pacchetto.usa-permessi
elementi.servizio
elemento in 'Crea account', parte 2 di questo tutorial.Contatti
Il strings.xml
memorizza stringhe costanti utilizzate nell'applicazione. L'unica costante che usiamo è il nome dell'applicazione
elemento che è il nome dell'applicazione. Il valore di tale costante, "Contatti", viene visualizzato in vari punti del dispositivo Android, come mostrato nella figura seguente: schermata di avvio delle applicazioni (a sinistra), schermata iniziale (al centro) e schermata delle applicazioni di gestione (a destra).
Le icone di avvio dell'applicazione sono basate sugli elementi della GUI di Android in http://www.matcheck.cz/androidguipsd/. Per le Linee guida per la progettazione di icone Android, sono stati creati tre file di icone come descritto di seguito.
Nome della cartella | Nome del file | Dimensione del pixel |
res \ drawable-ldpi | icon.png | 36 x 36 |
res \ drawable-MDPI | icon.png | 48 x 48 |
res \ drawable-hdpi | icon.png | 72 x 72 |
Quelle icone sono mostrate nella figura sotto. L'icona a sinistra è 36x36 pixel, quella al centro è 48x48 pixel e quella a destra è 72x72 pixel.
Ora discuteremo come importare l'applicazione nativa nell'ambiente di sviluppo Eclipse. I file di progetto sono stati testati contro:
Il progetto è stato testato con successo contro la piattaforma Android 2.2 API livello 8.
Prima di importare il progetto nel tuo ambiente Eclipse, assicurati che il plug-in di Eclipse ADT indichi la posizione corretta di Android SDK nel tuo sistema locale. Per verificare questo, nel menu Eclipse vai a Finestra -> Preferenze -> Android
. Il Posizione SDK
la finestra deve essere impostata sulla posizione di Android SDK. Una volta impostato correttamente, dovresti vedere qualcosa di simile a sotto
I file di progetto sono forniti in un file di archivio chiamato contacts.zip
. Per importare il progetto, nel menu Eclipse vai a File -> Importa
e quindi nel wizard di importazione dei file selezionare Generale -> Progetti esistenti nello spazio di lavoro
(vedi sotto).
Nella pagina successiva della procedura guidata, scegliere Seleziona il file di archivio:
e vai a dove contacts.zip
si trova nel tuo file system. Il progetti
finestra verrà popolata automaticamente dove il ContactsDemo
progetto è già selezionato. Questo è mostrato sotto. premi il finire
pulsante per completare l'importazione.
Eclipse costruirà l'applicazione automaticamente dopo l'importazione. Ora, dovresti vedere il progetto ContactsDemo in Project Explorer, come mostrato di seguito.
Questo progetto è stato costruito e testato per la piattaforma Android OS 2.2. Per verificare ciò, selezionare il ContactsDemo
progetto in Project Explorer e dal menu di scelta rapida scegli Proprietà
. Nell'elenco a sinistra delle proprietà, selezionare androide
come la proprietà. I target di build disponibili sono visualizzati a destra, come mostrato di seguito. Dovresti vedere che Android 2.2 è stato selezionato.
Di seguito è riportato un elenco di file nel progetto.
src
la cartella memorizza il codice Java. Ci sono due pacchetti: com.jquerymobile.demo.contact
il pacchetto contiene Indirizzo
, Contatto
, ContactDisplay
, ContactGroup
, ContactsActivity
, ContactUtility
, E-mail
, Sono
, Nota
, Organizzazione
e Telefono
classi.com.jquerymobile.demo.contact.authentication
il pacchetto contiene il AuthenticationService
classe.gen
la cartella contiene vari file generati automaticamente da Eclipse ADT.risorse
la cartella archivia i file HTML, i file di immagine utilizzati in quei file HTML e nelle librerie jQuery Mobile / jQuery. Usiamo jQuery Mobile versione 1.0 Alpha 3, che era l'ultima versione quando è stato scritto il tutorial. (Una versione di Alpha 4 è stata recentemente realizzata con varie correzioni di bug. Vedi l'annuncio.)lib
cartella memorizza le librerie Jackson JSON.res
la cartella memorizza le varie risorse necessarie all'applicazione. Quelle sono le immagini delle icone e i file di configurazione strings.xml
e authenticator.xml
.default.properties
è un file generato dal sistema che definisce la versione dell'API per l'applicazione Android.proguard.cfg
il file viene creato automaticamente dall'ambiente di sviluppo e viene utilizzato dallo strumento ProGuard. Dettagli possono essere trovati in Documentazione ProGuard. In questo tutorial, abbiamo implementato un'applicazione Android in cui l'interfaccia utente è costruita tramite HTML / JavaScript e la funzionalità core nativa viene sviluppata tramite Java. Un vantaggio di tale approccio è il fatto che gli sviluppatori web, già in possesso di familiarità con HTML e JavaScript, possono utilizzare le loro conoscenze per costruire l'interfaccia utente senza dover imparare API specifiche di Android, il modello di gestione degli eventi dell'interfaccia utente e il linguaggio di programmazione Java. D'altra parte, gli sviluppatori con competenze Java possono concentrarsi sulla creazione della funzionalità nativa utilizzando l'API Java di Android. In questo modo, lo sforzo di lavoro può essere suddiviso tra due o più sviluppatori sulla base di set di competenze esistenti.
Una tipica considerazione di progettazione per un'applicazione Android è che gli aspetti visivi e il modello di gestione degli eventi dell'interfaccia utente devono essere coerenti tra i vari dispositivi su cui verrà installata l'applicazione. Questi dispositivi possono avere dimensioni dello schermo diverse e possono eseguire diversi set di browser Web con diversi livelli di supporto HTML. A tale proposito, jQuery Mobile è utile perché fornisce componenti dell'interfaccia utente prontamente disponibili con un modello di gestione degli eventi di supporto. È già stato testato per coerenza tra diversi dispositivi e browser, rendendo più facile lo sviluppo multipiattaforma.
Infine, tieni presente che alcune applicazioni non si adattano al modello precedente. Per esempio: