/android/import-contacts

To get this branch, use:
bzr branch http://bzr.ed.am/android/import-contacts

« back to all changes in this revision

Viewing changes to src/am/ed/importcontacts/ContactsBackend.java

  • Committer: edam
  • Date: 2009-01-13 06:35:26 UTC
  • Revision ID: edam@waxworlds.org-20090113063526-l9t1s9git4bav60a
- new contact's phone numebrs and email addresses are added to the caches after those contacts are updated to account for the situation where the same contact is imported again from another file (or the contact exists twice in the same file!?)

Show diffs side-by-side

added added

removed removed

1
 
/*
2
 
 * ContactsBackend.java
3
 
 *
4
 
 * Copyright (C) 2012 Tim Marston <tim@ed.am>
5
 
 *
6
 
 * This file is part of the Import Contacts program (hereafter referred
7
 
 * to as "this program"). For more information, see
8
 
 * http://ed.am/dev/android/import-contacts
9
 
 *
10
 
 * This program is free software: you can redistribute it and/or modify
11
 
 * it under the terms of the GNU General Public License as published by
12
 
 * the Free Software Foundation, either version 3 of the License, or
13
 
 * (at your option) any later version.
14
 
 *
15
 
 * This program is distributed in the hope that it will be useful,
16
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
 * GNU General Public License for more details.
19
 
 *
20
 
 * You should have received a copy of the GNU General Public License
21
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 
 */
23
 
 
24
 
package am.ed.importcontacts;
25
 
 
26
 
import java.util.HashMap;
27
 
import java.util.HashSet;
28
 
import java.util.Iterator;
29
 
 
30
 
import am.ed.importcontacts.ContactsCache.CacheIdentifier;
31
 
import am.ed.importcontacts.Importer.ContactData;
32
 
import android.app.Activity;
33
 
import android.content.ContentUris;
34
 
import android.content.ContentValues;
35
 
import android.database.Cursor;
36
 
import android.net.Uri;
37
 
import android.provider.Contacts;
38
 
 
39
 
@SuppressWarnings( "deprecation" )
40
 
public class ContactsBackend implements Backend
41
 
{
42
 
        private Activity _activity = null;
43
 
 
44
 
        ContactsBackend( Activity activity )
45
 
        {
46
 
                _activity = activity;
47
 
        }
48
 
 
49
 
        @Override
50
 
        public void populateCache( ContactsCache cache )
51
 
        {
52
 
                Cursor cur;
53
 
 
54
 
                // set of contact ids that we have not yet added
55
 
                HashSet< Long > unadded_ids = new HashSet< Long >();
56
 
 
57
 
                // notes
58
 
                HashMap< Long, String > notes = new HashMap< Long, String >();
59
 
 
60
 
                // get all contacts
61
 
                cur = _activity.managedQuery( Contacts.People.CONTENT_URI,
62
 
                        new String[] {
63
 
                                Contacts.People._ID,
64
 
                                Contacts.People.NAME,
65
 
                                Contacts.People.NOTES,
66
 
                        }, null, null, null );
67
 
                while( cur.moveToNext() ) {
68
 
                        Long id = cur.getLong(
69
 
                                cur.getColumnIndex( Contacts.People._ID ) );
70
 
                        String name = cur.getString(
71
 
                                        cur.getColumnIndex( Contacts.People.NAME ) );
72
 
                        String note = cur.getString(
73
 
                                        cur.getColumnIndex( Contacts.People.NOTES ) );
74
 
 
75
 
                        // if we can, add a lookup for the contact id by name
76
 
                        CacheIdentifier cache_identifier = CacheIdentifier.factory(
77
 
                                CacheIdentifier.Type.NAME, name );
78
 
                        if( cache_identifier != null ) {
79
 
                                cache.addLookup( cache_identifier, id );
80
 
 
81
 
                                // add any associated notes (this would get done at the end but,
82
 
                                // since it is most common that contacts are identified by name,
83
 
                                // it is worth doing a special case here
84
 
                                cache.addAssociatedNote( id, note );
85
 
                        }
86
 
                        else
87
 
                        {
88
 
                                // record that a lookup for this contact's id still needs to be
89
 
                                // added by some other means
90
 
                                unadded_ids.add( id );
91
 
 
92
 
                                // store this contact's notes, so that they can be added to the
93
 
                                // cache at the end, after this contact has been added (by
94
 
                                // whatever identifying means)
95
 
                                if( note != null && note.length() > 0 )
96
 
                                        notes.put( id, note );
97
 
                        }
98
 
                }
99
 
 
100
 
                // get contact organisations, primary ones first
101
 
                cur = _activity.managedQuery( Contacts.Organizations.CONTENT_URI,
102
 
                        new String[] {
103
 
                                Contacts.Phones.PERSON_ID,
104
 
                                Contacts.Organizations.COMPANY,
105
 
                        }, null, null, Contacts.Organizations.ISPRIMARY + " DESC" );
106
 
                while( cur.moveToNext() ) {
107
 
                        Long id = cur.getLong( cur.getColumnIndex(
108
 
                                Contacts.Organizations.PERSON_ID ) );
109
 
                        String organisation = cur.getString(
110
 
                                cur.getColumnIndex( Contacts.Organizations.COMPANY ) );
111
 
 
112
 
                        // if this is an organisation name for a contact for whom we have
113
 
                        // not added a lookup, add a lookup for the contact id by
114
 
                        // organisation
115
 
                        if( unadded_ids.contains( id ) ) {
116
 
                                CacheIdentifier cache_identifier = CacheIdentifier.factory(
117
 
                                        CacheIdentifier.Type.ORGANISATION, organisation );
118
 
                                if( cache_identifier != null ) {
119
 
                                        cache.addLookup( cache_identifier, id );
120
 
                                        unadded_ids.remove( id );
121
 
                                }
122
 
                        }
123
 
 
124
 
                        // add associated data
125
 
                        cache.addAssociatedOrganisation( id, organisation );
126
 
                }
127
 
 
128
 
                // get all phone numbers, primary ones first
129
 
                cur = _activity.managedQuery( Contacts.Phones.CONTENT_URI,
130
 
                        new String[] {
131
 
                                Contacts.Phones.PERSON_ID,
132
 
                                Contacts.Phones.NUMBER,
133
 
                        }, null, null, Contacts.Phones.ISPRIMARY + " DESC" );
134
 
                while( cur.moveToNext() ) {
135
 
                        Long id = cur.getLong(
136
 
                                cur.getColumnIndex( Contacts.Phones.PERSON_ID ) );
137
 
                        String number = cur.getString(
138
 
                                cur.getColumnIndex( Contacts.Phones.NUMBER ) );
139
 
 
140
 
                        // if this is a number for a contact for whom we have not
141
 
                        // added a lookup, add a lookup for the contact id by phone
142
 
                        // number
143
 
                        if( unadded_ids.contains( id ) ) {
144
 
                                CacheIdentifier cache_identifier = CacheIdentifier.factory(
145
 
                                        CacheIdentifier.Type.PRIMARY_NUMBER, number );
146
 
                                if( cache_identifier != null ) {
147
 
                                        cache.addLookup( cache_identifier, id );
148
 
                                        unadded_ids.remove( id );
149
 
                                }
150
 
                        }
151
 
 
152
 
                        // add associated data
153
 
                        cache.addAssociatedNumber( id, number );
154
 
                }
155
 
 
156
 
                // now get all email addresses, primary ones first, and postal addresses
157
 
                cur = _activity.managedQuery( Contacts.ContactMethods.CONTENT_URI,
158
 
                        new String[] {
159
 
                                Contacts.ContactMethods.PERSON_ID,
160
 
                                Contacts.ContactMethods.DATA,
161
 
                                Contacts.ContactMethods.KIND,
162
 
                        }, Contacts.ContactMethods.KIND + " IN( ?, ? )",
163
 
                        new String[] {
164
 
                                "" + Contacts.KIND_EMAIL,
165
 
                                "" + Contacts.KIND_POSTAL,
166
 
                        }, Contacts.ContactMethods.ISPRIMARY + " DESC" );
167
 
                while( cur.moveToNext() ) {
168
 
                        Long id = cur.getLong(
169
 
                                cur.getColumnIndex( Contacts.ContactMethods.PERSON_ID ) );
170
 
                        int kind = cur.getInt(
171
 
                                cur.getColumnIndex( Contacts.ContactMethods.KIND ) );
172
 
                        if( kind == Contacts.KIND_EMAIL )
173
 
                        {
174
 
                                String email = cur.getString(
175
 
                                        cur.getColumnIndex( Contacts.ContactMethods.DATA ) );
176
 
 
177
 
                                // if this is an email address for a contact for whom we have
178
 
                                // not added a lookup, add a lookup for the contact id by email
179
 
                                // address
180
 
                                if( unadded_ids.contains( id ) ) {
181
 
                                        CacheIdentifier cache_identifier = CacheIdentifier.factory(
182
 
                                                CacheIdentifier.Type.PRIMARY_EMAIL, email );
183
 
                                        if( cache_identifier != null ) {
184
 
                                                cache.addLookup( cache_identifier, id );
185
 
                                                unadded_ids.remove( id );
186
 
                                        }
187
 
                                }
188
 
 
189
 
                                // add associated data
190
 
                                cache.addAssociatedEmail( id, email );
191
 
                        }
192
 
                        else if( kind == Contacts.KIND_POSTAL )
193
 
                        {
194
 
                                String address = cur.getString(
195
 
                                        cur.getColumnIndex( Contacts.ContactMethods.DATA ) );
196
 
 
197
 
                                // add associated data
198
 
                                cache.addAssociatedAddress( id, address );
199
 
                        }
200
 
                }
201
 
 
202
 
                // finally, add the notes that we stored earlier (we have to add these
203
 
                // at the end because we can't be sure which piece of contact data will
204
 
                // cause the contact to be added to the cache
205
 
                Iterator< Long > i = notes.keySet().iterator();
206
 
                while( i.hasNext() ) {
207
 
                        Long id = i.next();
208
 
                        cache.addAssociatedNote( id, notes.get( id ) );
209
 
                }
210
 
        }
211
 
 
212
 
        @Override
213
 
        public void deleteContact( Long id )
214
 
        {
215
 
                Uri contact_uri =
216
 
                        ContentUris.withAppendedId( Contacts.People.CONTENT_URI, id );
217
 
                _activity.getContentResolver().delete( contact_uri, null, null );
218
 
        }
219
 
 
220
 
        @Override
221
 
        public Long addContact( String name ) throws ContactCreationException
222
 
        {
223
 
                ContentValues values = new ContentValues();
224
 
                if( name != null )
225
 
                        values.put( Contacts.People.NAME, name );
226
 
                Uri contact_uri = _activity.getContentResolver().insert(
227
 
                        Contacts.People.CONTENT_URI, values );
228
 
                Long id = ContentUris.parseId( contact_uri );
229
 
                if( id == 0 )
230
 
                        throw new ContactCreationException();
231
 
 
232
 
                // try to add them to the "My Contacts" group
233
 
                try {
234
 
                        Contacts.People.addToMyContactsGroup(
235
 
                                _activity.getContentResolver(), id );
236
 
                }
237
 
                catch( IllegalStateException e ) {
238
 
                        // ignore any failure
239
 
                }
240
 
 
241
 
                return id;
242
 
        }
243
 
 
244
 
        private int convertTypeToBackendType( Class< ? > cls, int type )
245
 
                throws ContactCreationException
246
 
        {
247
 
                if( cls == Contacts.Phones.class )
248
 
                {
249
 
                        switch( type )
250
 
                        {
251
 
                        case ContactData.TYPE_HOME:
252
 
                                return Contacts.PhonesColumns.TYPE_HOME;
253
 
                        case ContactData.TYPE_WORK:
254
 
                                return Contacts.PhonesColumns.TYPE_WORK;
255
 
                        case ContactData.TYPE_MOBILE:
256
 
                                return Contacts.PhonesColumns.TYPE_MOBILE;
257
 
                        case ContactData.TYPE_FAX_HOME:
258
 
                                return Contacts.PhonesColumns.TYPE_FAX_HOME;
259
 
                        case ContactData.TYPE_FAX_WORK:
260
 
                                return Contacts.PhonesColumns.TYPE_FAX_WORK;
261
 
                        case ContactData.TYPE_PAGER:
262
 
                                return Contacts.PhonesColumns.TYPE_PAGER;
263
 
                        }
264
 
                }
265
 
                else if( cls == Contacts.ContactMethods.class )
266
 
                {
267
 
                        switch( type )
268
 
                        {
269
 
                        case ContactData.TYPE_HOME:
270
 
                                return Contacts.ContactMethodsColumns.TYPE_HOME;
271
 
                        case ContactData.TYPE_WORK:
272
 
                                return Contacts.ContactMethodsColumns.TYPE_WORK;
273
 
                        }
274
 
                }
275
 
 
276
 
                // still here?
277
 
                throw new ContactCreationException();
278
 
        }
279
 
 
280
 
        @Override
281
 
        public void addContactPhone( Long id, String number,
282
 
                ContactData.PreferredDetail data ) throws ContactCreationException
283
 
        {
284
 
                Uri contact_phones_uri = Uri.withAppendedPath(
285
 
                        ContentUris.withAppendedId( Contacts.People.CONTENT_URI, id ),
286
 
                        Contacts.People.Phones.CONTENT_DIRECTORY );
287
 
 
288
 
                ContentValues values = new ContentValues();
289
 
                values.put( Contacts.Phones.TYPE,
290
 
                        convertTypeToBackendType( Contacts.Phones.class,
291
 
                                data.getType() ) );
292
 
                values.put( Contacts.Phones.NUMBER, number );
293
 
                if( data.isPreferred() )
294
 
                        values.put( Contacts.Phones.ISPRIMARY, 1 );
295
 
 
296
 
                _activity.getContentResolver().insert( contact_phones_uri, values );
297
 
        }
298
 
 
299
 
        @Override
300
 
        public void addContactEmail( Long id, String email,
301
 
                ContactData.PreferredDetail data ) throws ContactCreationException
302
 
        {
303
 
                Uri contact_contact_methods_uri = Uri.withAppendedPath(
304
 
                        ContentUris.withAppendedId( Contacts.People.CONTENT_URI, id ),
305
 
                        Contacts.People.ContactMethods.CONTENT_DIRECTORY );
306
 
 
307
 
                ContentValues values = new ContentValues();
308
 
                values.put( Contacts.ContactMethods.KIND, Contacts.KIND_EMAIL );
309
 
                values.put( Contacts.ContactMethods.DATA, email );
310
 
                values.put( Contacts.ContactMethods.TYPE,
311
 
                        convertTypeToBackendType( Contacts.ContactMethods.class,
312
 
                                data.getType() ) );
313
 
                if( data.isPreferred() )
314
 
                        values.put( Contacts.ContactMethods.ISPRIMARY, 1 );
315
 
 
316
 
                _activity.getContentResolver().insert( contact_contact_methods_uri,
317
 
                        values );
318
 
        }
319
 
 
320
 
        @Override
321
 
        public void addContactAddresses( Long id, String address,
322
 
                ContactData.TypeDetail data ) throws ContactCreationException
323
 
        {
324
 
                Uri contact_contact_methods_uri = Uri.withAppendedPath(
325
 
                        ContentUris.withAppendedId( Contacts.People.CONTENT_URI, id ),
326
 
                        Contacts.People.ContactMethods.CONTENT_DIRECTORY );
327
 
 
328
 
                ContentValues values = new ContentValues();
329
 
                values.put( Contacts.ContactMethods.KIND, Contacts.KIND_POSTAL );
330
 
                values.put( Contacts.ContactMethods.DATA, address );
331
 
                values.put( Contacts.ContactMethods.TYPE,
332
 
                        convertTypeToBackendType( Contacts.ContactMethods.class,
333
 
                                data.getType() ) );
334
 
 
335
 
                _activity.getContentResolver().insert( contact_contact_methods_uri,
336
 
                        values );
337
 
        }
338
 
 
339
 
        @Override
340
 
        public void addContactOrganisation( Long id, String organisation,
341
 
                ContactData.ExtraDetail data ) throws ContactCreationException
342
 
        {
343
 
                ContentValues values = new ContentValues();
344
 
                values.put( Contacts.Organizations.PERSON_ID, id );
345
 
                values.put( Contacts.Organizations.COMPANY, organisation );
346
 
                values.put( Contacts.ContactMethods.TYPE,
347
 
                        Contacts.OrganizationColumns.TYPE_WORK );
348
 
                if( data.getExtra() != null )
349
 
                        values.put( Contacts.Organizations.TITLE, data.getExtra() );
350
 
 
351
 
                _activity.getContentResolver().insert(
352
 
                        Contacts.Organizations.CONTENT_URI, values );
353
 
        }
354
 
 
355
 
        @Override
356
 
        public void addContactNote( Long id, String note )
357
 
                throws ContactCreationException
358
 
        {
359
 
                ContentValues values = new ContentValues();
360
 
                values.put( Contacts.People.NOTES, note );
361
 
                _activity.getContentResolver().update(
362
 
                        ContentUris.withAppendedId( Contacts.People.CONTENT_URI, id ),
363
 
                        values, null, null );
364
 
        }
365
 
 
366
 
}