/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 to 2013 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.getContentResolver().query(
62
 
                        Contacts.People.CONTENT_URI,
63
 
                        new String[] {
64
 
                                Contacts.People._ID,
65
 
                                Contacts.People.NAME,
66
 
                                Contacts.People.NOTES,
67
 
                        }, null, null, null );
68
 
                while( cur.moveToNext() ) {
69
 
                        Long id = cur.getLong(
70
 
                                cur.getColumnIndex( Contacts.People._ID ) );
71
 
                        String name = cur.getString(
72
 
                                        cur.getColumnIndex( Contacts.People.NAME ) );
73
 
                        String note = cur.getString(
74
 
                                        cur.getColumnIndex( Contacts.People.NOTES ) );
75
 
 
76
 
                        // if we can, add a lookup for the contact id by name
77
 
                        CacheIdentifier cache_identifier = CacheIdentifier.factory(
78
 
                                CacheIdentifier.Type.NAME, name );
79
 
                        if( cache_identifier != null ) {
80
 
                                cache.addLookup( cache_identifier, id );
81
 
 
82
 
                                // add any associated notes (this would get done at the end but,
83
 
                                // since it is most common that contacts are identified by name,
84
 
                                // it is worth doing a special case here
85
 
                                cache.addAssociatedNote( id, note );
86
 
                        }
87
 
                        else
88
 
                        {
89
 
                                // record that a lookup for this contact's id still needs to be
90
 
                                // added by some other means
91
 
                                unadded_ids.add( id );
92
 
 
93
 
                                // store this contact's notes, so that they can be added to the
94
 
                                // cache at the end, after this contact has been added (by
95
 
                                // whatever identifying means)
96
 
                                if( note != null && note.length() > 0 )
97
 
                                        notes.put( id, note );
98
 
                        }
99
 
                }
100
 
                cur.close();
101
 
 
102
 
                // get contact organisations, primary ones first
103
 
                cur = _activity.getContentResolver().query(
104
 
                        Contacts.Organizations.CONTENT_URI,
105
 
                        new String[] {
106
 
                                Contacts.Phones.PERSON_ID,
107
 
                                Contacts.Organizations.COMPANY,
108
 
                        }, null, null, Contacts.Organizations.ISPRIMARY + " DESC" );
109
 
                while( cur.moveToNext() ) {
110
 
                        Long id = cur.getLong( cur.getColumnIndex(
111
 
                                Contacts.Organizations.PERSON_ID ) );
112
 
                        String organisation = cur.getString(
113
 
                                cur.getColumnIndex( Contacts.Organizations.COMPANY ) );
114
 
 
115
 
                        // if this is an organisation name for a contact for whom we have
116
 
                        // not added a lookup, add a lookup for the contact id by
117
 
                        // organisation
118
 
                        if( unadded_ids.contains( id ) ) {
119
 
                                CacheIdentifier cache_identifier = CacheIdentifier.factory(
120
 
                                        CacheIdentifier.Type.ORGANISATION, organisation );
121
 
                                if( cache_identifier != null ) {
122
 
                                        cache.addLookup( cache_identifier, id );
123
 
                                        unadded_ids.remove( id );
124
 
                                }
125
 
                        }
126
 
 
127
 
                        // add associated data
128
 
                        cache.addAssociatedOrganisation( id, organisation );
129
 
                }
130
 
                cur.close();
131
 
 
132
 
                // get all phone numbers, primary ones first
133
 
                cur = _activity.getContentResolver().query(
134
 
                        Contacts.Phones.CONTENT_URI,
135
 
                        new String[] {
136
 
                                Contacts.Phones.PERSON_ID,
137
 
                                Contacts.Phones.NUMBER,
138
 
                        }, null, null, Contacts.Phones.ISPRIMARY + " DESC" );
139
 
                while( cur.moveToNext() ) {
140
 
                        Long id = cur.getLong(
141
 
                                cur.getColumnIndex( Contacts.Phones.PERSON_ID ) );
142
 
                        String number = cur.getString(
143
 
                                cur.getColumnIndex( Contacts.Phones.NUMBER ) );
144
 
 
145
 
                        // if this is a number for a contact for whom we have not
146
 
                        // added a lookup, add a lookup for the contact id by phone
147
 
                        // number
148
 
                        if( unadded_ids.contains( id ) ) {
149
 
                                CacheIdentifier cache_identifier = CacheIdentifier.factory(
150
 
                                        CacheIdentifier.Type.PRIMARY_NUMBER, number );
151
 
                                if( cache_identifier != null ) {
152
 
                                        cache.addLookup( cache_identifier, id );
153
 
                                        unadded_ids.remove( id );
154
 
                                }
155
 
                        }
156
 
 
157
 
                        // add associated data
158
 
                        cache.addAssociatedNumber( id, number );
159
 
                }
160
 
                cur.close();
161
 
 
162
 
                // now get all email addresses, primary ones first, and postal addresses
163
 
                cur = _activity.getContentResolver().query(
164
 
                        Contacts.ContactMethods.CONTENT_URI,
165
 
                        new String[] {
166
 
                                Contacts.ContactMethods.PERSON_ID,
167
 
                                Contacts.ContactMethods.DATA,
168
 
                                Contacts.ContactMethods.KIND,
169
 
                        }, Contacts.ContactMethods.KIND + " IN( ?, ? )",
170
 
                        new String[] {
171
 
                                "" + Contacts.KIND_EMAIL,
172
 
                                "" + Contacts.KIND_POSTAL,
173
 
                        }, Contacts.ContactMethods.ISPRIMARY + " DESC" );
174
 
                while( cur.moveToNext() ) {
175
 
                        Long id = cur.getLong(
176
 
                                cur.getColumnIndex( Contacts.ContactMethods.PERSON_ID ) );
177
 
                        int kind = cur.getInt(
178
 
                                cur.getColumnIndex( Contacts.ContactMethods.KIND ) );
179
 
                        if( kind == Contacts.KIND_EMAIL )
180
 
                        {
181
 
                                String email = cur.getString(
182
 
                                        cur.getColumnIndex( Contacts.ContactMethods.DATA ) );
183
 
 
184
 
                                // if this is an email address for a contact for whom we have
185
 
                                // not added a lookup, add a lookup for the contact id by email
186
 
                                // address
187
 
                                if( unadded_ids.contains( id ) ) {
188
 
                                        CacheIdentifier cache_identifier = CacheIdentifier.factory(
189
 
                                                CacheIdentifier.Type.PRIMARY_EMAIL, email );
190
 
                                        if( cache_identifier != null ) {
191
 
                                                cache.addLookup( cache_identifier, id );
192
 
                                                unadded_ids.remove( id );
193
 
                                        }
194
 
                                }
195
 
 
196
 
                                // add associated data
197
 
                                cache.addAssociatedEmail( id, email );
198
 
                        }
199
 
                        else if( kind == Contacts.KIND_POSTAL )
200
 
                        {
201
 
                                String address = cur.getString(
202
 
                                        cur.getColumnIndex( Contacts.ContactMethods.DATA ) );
203
 
 
204
 
                                // add associated data
205
 
                                cache.addAssociatedAddress( id, address );
206
 
                        }
207
 
                }
208
 
                cur.close();
209
 
 
210
 
                // finally, add the notes that we stored earlier (we have to add these
211
 
                // at the end because we can't be sure which piece of contact data will
212
 
                // cause the contact to be added to the cache
213
 
                Iterator< Long > i = notes.keySet().iterator();
214
 
                while( i.hasNext() ) {
215
 
                        Long id = i.next();
216
 
                        cache.addAssociatedNote( id, notes.get( id ) );
217
 
                }
218
 
        }
219
 
 
220
 
        @Override
221
 
        public void deleteContact( Long id )
222
 
        {
223
 
                Uri contact_uri =
224
 
                        ContentUris.withAppendedId( Contacts.People.CONTENT_URI, id );
225
 
                _activity.getContentResolver().delete( contact_uri, null, null );
226
 
        }
227
 
 
228
 
        @Override
229
 
        public Long addContact( String name ) throws ContactCreationException
230
 
        {
231
 
                ContentValues values = new ContentValues();
232
 
                if( name != null )
233
 
                        values.put( Contacts.People.NAME, name );
234
 
                Uri contact_uri = _activity.getContentResolver().insert(
235
 
                        Contacts.People.CONTENT_URI, values );
236
 
                Long id = ContentUris.parseId( contact_uri );
237
 
                if( id == 0 )
238
 
                        throw new ContactCreationException();
239
 
 
240
 
                // try to add them to the "My Contacts" group
241
 
                try {
242
 
                        Contacts.People.addToMyContactsGroup(
243
 
                                _activity.getContentResolver(), id );
244
 
                }
245
 
                catch( IllegalStateException e ) {
246
 
                        // ignore any failure
247
 
                }
248
 
 
249
 
                return id;
250
 
        }
251
 
 
252
 
        private int convertTypeToBackendType( Class< ? > cls, int type )
253
 
                throws ContactCreationException
254
 
        {
255
 
                if( cls == Contacts.Phones.class )
256
 
                {
257
 
                        switch( type )
258
 
                        {
259
 
                        case ContactData.TYPE_HOME:
260
 
                                return Contacts.PhonesColumns.TYPE_HOME;
261
 
                        case ContactData.TYPE_WORK:
262
 
                                return Contacts.PhonesColumns.TYPE_WORK;
263
 
                        case ContactData.TYPE_MOBILE:
264
 
                                return Contacts.PhonesColumns.TYPE_MOBILE;
265
 
                        case ContactData.TYPE_FAX_HOME:
266
 
                                return Contacts.PhonesColumns.TYPE_FAX_HOME;
267
 
                        case ContactData.TYPE_FAX_WORK:
268
 
                                return Contacts.PhonesColumns.TYPE_FAX_WORK;
269
 
                        case ContactData.TYPE_PAGER:
270
 
                                return Contacts.PhonesColumns.TYPE_PAGER;
271
 
                        }
272
 
                }
273
 
                else if( cls == Contacts.ContactMethods.class )
274
 
                {
275
 
                        switch( type )
276
 
                        {
277
 
                        case ContactData.TYPE_HOME:
278
 
                                return Contacts.ContactMethodsColumns.TYPE_HOME;
279
 
                        case ContactData.TYPE_WORK:
280
 
                                return Contacts.ContactMethodsColumns.TYPE_WORK;
281
 
                        }
282
 
                }
283
 
 
284
 
                // still here?
285
 
                throw new ContactCreationException();
286
 
        }
287
 
 
288
 
        @Override
289
 
        public void addContactPhone( Long id, String number,
290
 
                ContactData.PreferredDetail data ) throws ContactCreationException
291
 
        {
292
 
                Uri contact_phones_uri = Uri.withAppendedPath(
293
 
                        ContentUris.withAppendedId( Contacts.People.CONTENT_URI, id ),
294
 
                        Contacts.People.Phones.CONTENT_DIRECTORY );
295
 
 
296
 
                ContentValues values = new ContentValues();
297
 
                values.put( Contacts.Phones.TYPE,
298
 
                        convertTypeToBackendType( Contacts.Phones.class,
299
 
                                data.getType() ) );
300
 
                values.put( Contacts.Phones.NUMBER, number );
301
 
                if( data.isPreferred() )
302
 
                        values.put( Contacts.Phones.ISPRIMARY, 1 );
303
 
 
304
 
                _activity.getContentResolver().insert( contact_phones_uri, values );
305
 
        }
306
 
 
307
 
        @Override
308
 
        public void addContactEmail( Long id, String email,
309
 
                ContactData.PreferredDetail data ) throws ContactCreationException
310
 
        {
311
 
                Uri contact_contact_methods_uri = Uri.withAppendedPath(
312
 
                        ContentUris.withAppendedId( Contacts.People.CONTENT_URI, id ),
313
 
                        Contacts.People.ContactMethods.CONTENT_DIRECTORY );
314
 
 
315
 
                ContentValues values = new ContentValues();
316
 
                values.put( Contacts.ContactMethods.KIND, Contacts.KIND_EMAIL );
317
 
                values.put( Contacts.ContactMethods.DATA, email );
318
 
                values.put( Contacts.ContactMethods.TYPE,
319
 
                        convertTypeToBackendType( Contacts.ContactMethods.class,
320
 
                                data.getType() ) );
321
 
                if( data.isPreferred() )
322
 
                        values.put( Contacts.ContactMethods.ISPRIMARY, 1 );
323
 
 
324
 
                _activity.getContentResolver().insert( contact_contact_methods_uri,
325
 
                        values );
326
 
        }
327
 
 
328
 
        @Override
329
 
        public void addContactAddresses( Long id, String address,
330
 
                ContactData.TypeDetail data ) throws ContactCreationException
331
 
        {
332
 
                Uri contact_contact_methods_uri = Uri.withAppendedPath(
333
 
                        ContentUris.withAppendedId( Contacts.People.CONTENT_URI, id ),
334
 
                        Contacts.People.ContactMethods.CONTENT_DIRECTORY );
335
 
 
336
 
                ContentValues values = new ContentValues();
337
 
                values.put( Contacts.ContactMethods.KIND, Contacts.KIND_POSTAL );
338
 
                values.put( Contacts.ContactMethods.DATA, address );
339
 
                values.put( Contacts.ContactMethods.TYPE,
340
 
                        convertTypeToBackendType( Contacts.ContactMethods.class,
341
 
                                data.getType() ) );
342
 
 
343
 
                _activity.getContentResolver().insert( contact_contact_methods_uri,
344
 
                        values );
345
 
        }
346
 
 
347
 
        @Override
348
 
        public void addContactOrganisation( Long id, String organisation,
349
 
                ContactData.ExtraDetail data ) throws ContactCreationException
350
 
        {
351
 
                ContentValues values = new ContentValues();
352
 
                values.put( Contacts.Organizations.PERSON_ID, id );
353
 
                values.put( Contacts.Organizations.COMPANY, organisation );
354
 
                values.put( Contacts.ContactMethods.TYPE,
355
 
                        Contacts.OrganizationColumns.TYPE_WORK );
356
 
                if( data.getExtra() != null )
357
 
                        values.put( Contacts.Organizations.TITLE, data.getExtra() );
358
 
 
359
 
                _activity.getContentResolver().insert(
360
 
                        Contacts.Organizations.CONTENT_URI, values );
361
 
        }
362
 
 
363
 
        @Override
364
 
        public void addContactNote( Long id, String note )
365
 
                throws ContactCreationException
366
 
        {
367
 
                ContentValues values = new ContentValues();
368
 
                values.put( Contacts.People.NOTES, note );
369
 
                _activity.getContentResolver().update(
370
 
                        ContentUris.withAppendedId( Contacts.People.CONTENT_URI, id ),
371
 
                        values, null, null );
372
 
        }
373
 
 
374
 
        @Override
375
 
        public void addContactBirthday( Long id, String birthday )
376
 
                throws ContactCreationException
377
 
        {
378
 
                // this contacts API doesn't support birthdays, so just ignore them
379
 
        }
380
 
}