/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/ContactsContractBackend.java

  • Committer: edam
  • Date: 2012-12-19 17:51:35 UTC
  • Revision ID: tim@ed.am-20121219175135-1cpuafp76jg1ib1p
added preliminary (buggy) ContactsContract backend

Show diffs side-by-side

added added

removed removed

1
1
/*
2
2
 * ContactsBackend.java
3
3
 *
4
 
 * Copyright (C) 2012 to 2013 Tim Marston <tim@ed.am>
 
4
 * Copyright (C) 2012 Tim Marston <tim@ed.am>
5
5
 *
6
6
 * This file is part of the Import Contacts program (hereafter referred
7
 
 * to as "this program").  For more information, see
 
7
 * to as "this program"). For more information, see
8
8
 * http://ed.am/dev/android/import-contacts
9
9
 *
10
10
 * This program is free software: you can redistribute it and/or modify
57
57
                // build a set of aggregate contact ids that haven't been added to the
58
58
                // cache yet
59
59
                HashSet< Long > unadded_ids = new HashSet< Long >();
60
 
                cur = _activity.getContentResolver().query(
61
 
                        ContactsContract.Contacts.CONTENT_URI,
 
60
                cur = _activity.managedQuery( ContactsContract.Contacts.CONTENT_URI,
62
61
                        new String[] {
63
62
                                ContactsContract.Contacts._ID,
64
63
                        }, null, null, null );
67
66
                                cur.getColumnIndex( ContactsContract.Contacts._ID ) );
68
67
                        unadded_ids.add( id );
69
68
                }
70
 
                cur.close();
71
69
 
72
70
                // build a mapping of the ids of raw contacts to the ids of their
73
71
                // aggregate contacts
74
72
                HashMap< Long, Long > raw_to_aggregate_ids =
75
73
                        new HashMap< Long, Long >();
76
 
                cur = _activity.getContentResolver().query(
77
 
                        ContactsContract.RawContacts.CONTENT_URI,
 
74
                cur = _activity.managedQuery( ContactsContract.RawContacts.CONTENT_URI,
78
75
                        new String[] {
79
76
                                ContactsContract.RawContacts._ID,
80
77
                                ContactsContract.RawContacts.CONTACT_ID,
81
 
                        }, ContactsContract.RawContacts.DELETED + " = 0", null, null );
 
78
                        }, ContactsContract.RawContacts.DELETED + " != 0", null, null );
82
79
                while( cur.moveToNext() ) {
83
80
                        Long raw_id = cur.getLong(
84
81
                                cur.getColumnIndex( ContactsContract.RawContacts._ID ) );
86
83
                                cur.getColumnIndex( ContactsContract.RawContacts.CONTACT_ID ) );
87
84
                        raw_to_aggregate_ids.put( raw_id, id );
88
85
                }
89
 
                cur.close();
90
86
 
91
87
                // get structured names, primary ones first
92
 
                cur = _activity.getContentResolver().query(
93
 
                        ContactsContract.Data.CONTENT_URI,
 
88
                cur = _activity.managedQuery( ContactsContract.Data.CONTENT_URI,
94
89
                        new String[] {
95
90
                                ContactsContract.Data.RAW_CONTACT_ID,
96
91
                                CommonDataKinds.StructuredName.DISPLAY_NAME,
102
97
                        Long raw_id = cur.getLong( cur.getColumnIndex(
103
98
                                ContactsContract.Data.RAW_CONTACT_ID ) );
104
99
                        Long id = raw_to_aggregate_ids.get( raw_id );
105
 
                        if( id != null )
 
100
                        String name = ContactsCache.normaliseName(
 
101
                                cur.getString( cur.getColumnIndex(
 
102
                                        CommonDataKinds.StructuredName.DISPLAY_NAME ) ) );
 
103
                        if( name != null && id != null )
106
104
                        {
107
 
                                String name = cur.getString( cur.getColumnIndex(
108
 
                                        CommonDataKinds.StructuredName.DISPLAY_NAME ) );
109
 
 
110
105
                                // if this is a name for a contact for whom we have not added a
111
106
                                // lookup, add a lookup for the contact id by name
112
107
                                if( unadded_ids.contains( id ) ) {
113
 
                                        CacheIdentifier cache_identifier = CacheIdentifier.factory(
114
 
                                                CacheIdentifier.Type.NAME, name );
115
 
                                        if( cache_identifier != null ) {
116
 
                                                cache.addLookup( cache_identifier, id );
117
 
                                                unadded_ids.remove( id );
118
 
                                        }
 
108
                                        cache.addLookup( new CacheIdentifier(
 
109
                                                CacheIdentifier.Type.NAME, name ), id );
 
110
                                        unadded_ids.remove( id );
119
111
                                }
120
112
                        }
121
113
                }
122
 
                cur.close();
123
114
 
124
115
                // get contact organisations, primary ones first
125
 
                cur = _activity.getContentResolver().query(
126
 
                        ContactsContract.Data.CONTENT_URI,
 
116
                cur = _activity.managedQuery( ContactsContract.Data.CONTENT_URI,
127
117
                        new String[] {
128
118
                                ContactsContract.Data.RAW_CONTACT_ID,
129
119
                                CommonDataKinds.Organization.COMPANY,
135
125
                        Long raw_id = cur.getLong( cur.getColumnIndex(
136
126
                                ContactsContract.Data.RAW_CONTACT_ID ) );
137
127
                        Long id = raw_to_aggregate_ids.get( raw_id );
138
 
                        if( id != null )
 
128
                        String organisation = ContactsCache.normaliseOrganisation(
 
129
                                cur.getString( cur.getColumnIndex(
 
130
                                        CommonDataKinds.Organization.COMPANY ) ) );
 
131
                        if( organisation != null && id != null )
139
132
                        {
140
 
                                String organisation = cur.getString( cur.getColumnIndex(
141
 
                                        CommonDataKinds.Organization.COMPANY ) );
142
 
 
143
133
                                // if this is an organisation name for a contact for whom we
144
134
                                // have not added a lookup, add a lookup for the contact id
145
135
                                // by organisation
146
136
                                if( unadded_ids.contains( id ) ) {
147
 
                                        CacheIdentifier cache_identifier = CacheIdentifier.factory(
148
 
                                                CacheIdentifier.Type.ORGANISATION, organisation );
149
 
                                        if( cache_identifier != null ) {
150
 
                                                cache.addLookup( cache_identifier, id );
151
 
                                                unadded_ids.remove( id );
152
 
                                        }
 
137
                                        cache.addLookup( new CacheIdentifier(
 
138
                                                CacheIdentifier.Type.ORGANISATION, organisation ), id );
 
139
                                        unadded_ids.remove( id );
153
140
                                }
154
141
 
155
142
                                // add associated data
156
143
                                cache.addAssociatedOrganisation( id, organisation );
157
144
                        }
158
145
                }
159
 
                cur.close();
160
146
 
161
147
                // get all phone numbers, primary ones first
162
 
                cur = _activity.getContentResolver().query(
163
 
                        ContactsContract.Data.CONTENT_URI,
 
148
                cur = _activity.managedQuery( ContactsContract.Data.CONTENT_URI,
164
149
                        new String[] {
165
150
                                ContactsContract.Data.RAW_CONTACT_ID,
166
151
                                CommonDataKinds.Phone.NUMBER,
172
157
                        Long raw_id = cur.getLong( cur.getColumnIndex(
173
158
                                ContactsContract.Data.RAW_CONTACT_ID ) );
174
159
                        Long id = raw_to_aggregate_ids.get( raw_id );
175
 
                        if( id != null )
 
160
                        String number = ContactsCache.normalisePhoneNumber(
 
161
                                cur.getString( cur.getColumnIndex(
 
162
                                        CommonDataKinds.Phone.NUMBER ) ) );
 
163
                        if( number != null && id != null )
176
164
                        {
177
 
                                String number = cur.getString( cur.getColumnIndex(
178
 
                                        CommonDataKinds.Phone.NUMBER ) );
179
 
 
180
165
                                // if this is a number for a contact for whom we have not
181
166
                                // added a lookup, add a lookup for the contact id by phone
182
167
                                // number
183
168
                                if( unadded_ids.contains( id ) ) {
184
 
                                        CacheIdentifier cache_identifier = CacheIdentifier.factory(
185
 
                                                CacheIdentifier.Type.PRIMARY_NUMBER, number );
186
 
                                        if( cache_identifier != null ) {
187
 
                                                cache.addLookup( cache_identifier, id );
188
 
                                                unadded_ids.remove( id );
189
 
                                        }
 
169
                                        cache.addLookup( new CacheIdentifier(
 
170
                                                CacheIdentifier.Type.PRIMARY_NUMBER, number ), id );
 
171
                                        unadded_ids.remove( id );
190
172
                                }
191
173
 
192
174
                                // add associated data
193
175
                                cache.addAssociatedNumber( id, number );
194
176
                        }
195
177
                }
196
 
                cur.close();
197
178
 
198
179
                // get all email addresses, primary ones first
199
 
                cur = _activity.getContentResolver().query(
200
 
                        ContactsContract.Data.CONTENT_URI,
 
180
                cur = _activity.managedQuery( ContactsContract.Data.CONTENT_URI,
201
181
                        new String[] {
202
182
                                ContactsContract.Data.RAW_CONTACT_ID,
203
183
                                CommonDataKinds.Email.DATA,
209
189
                        Long raw_id = cur.getLong( cur.getColumnIndex(
210
190
                                ContactsContract.Data.RAW_CONTACT_ID ) );
211
191
                        Long id = raw_to_aggregate_ids.get( raw_id );
212
 
                        if( id != null )
 
192
                        String email = ContactsCache.normaliseEmailAddress(
 
193
                                cur.getString( cur.getColumnIndex(
 
194
                                        CommonDataKinds.Email.DATA ) ) );
 
195
                        if( email != null && id != null )
213
196
                        {
214
 
                                String email = cur.getString( cur.getColumnIndex(
215
 
                                        CommonDataKinds.Email.DATA ) );
216
 
 
217
197
                                // if this is an email address for a contact for whom we have
218
198
                                // not added a lookup, add a lookup for the contact id by email
219
199
                                // address
220
200
                                if( unadded_ids.contains( id ) ) {
221
 
                                        CacheIdentifier cache_identifier = CacheIdentifier.factory(
222
 
                                                CacheIdentifier.Type.PRIMARY_EMAIL, email );
223
 
                                        if( cache_identifier != null ) {
224
 
                                                cache.addLookup( cache_identifier, id );
225
 
                                                unadded_ids.remove( id );
226
 
                                        }
 
201
                                        cache.addLookup( new CacheIdentifier(
 
202
                                                CacheIdentifier.Type.PRIMARY_EMAIL, email ), id );
 
203
                                        unadded_ids.remove( id );
227
204
                                }
228
205
 
229
206
                                // add associated data
230
207
                                cache.addAssociatedEmail( id, email );
231
208
                        }
232
209
                }
233
 
                cur.close();
234
210
 
235
211
                // get all postal addresses, primary ones first
236
 
                cur = _activity.getContentResolver().query(
237
 
                        ContactsContract.Data.CONTENT_URI,
 
212
                cur = _activity.managedQuery( ContactsContract.Data.CONTENT_URI,
238
213
                        new String[] {
239
214
                                ContactsContract.Data.RAW_CONTACT_ID,
240
215
                                CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS,
241
216
                        },
242
217
                        ContactsContract.Data.MIMETYPE + " = '" +
243
 
                                CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE + "'",
 
218
                                CommonDataKinds.Organization.CONTENT_ITEM_TYPE + "'",
244
219
                        null, ContactsContract.Data.IS_PRIMARY + " DESC" );
245
220
                while( cur.moveToNext() ) {
246
221
                        Long raw_id = cur.getLong( cur.getColumnIndex(
247
222
                                ContactsContract.Data.RAW_CONTACT_ID ) );
248
223
                        Long id = raw_to_aggregate_ids.get( raw_id );
249
 
                        if( id != null )
 
224
                        String address = ContactsCache.normaliseAddress(
 
225
                                cur.getString( cur.getColumnIndex(
 
226
                                        CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS ) ) );
 
227
                        if( address != null && id != null )
250
228
                        {
251
 
                                String address = cur.getString( cur.getColumnIndex(
252
 
                                        CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS ) );
253
 
 
254
229
                                // add associated data
255
230
                                cache.addAssociatedAddress( id, address );
256
231
                        }
257
232
                }
258
 
                cur.close();
259
 
 
260
 
                // get all notes
261
 
                cur = _activity.getContentResolver().query(
262
 
                        ContactsContract.Data.CONTENT_URI,
263
 
                        new String[] {
264
 
                                ContactsContract.Data.RAW_CONTACT_ID,
265
 
                                CommonDataKinds.Note.NOTE,
266
 
                        },
267
 
                        ContactsContract.Data.MIMETYPE + " = '" +
268
 
                                CommonDataKinds.Note.CONTENT_ITEM_TYPE + "'",
269
 
                        null, null );
270
 
                while( cur.moveToNext() ) {
271
 
                        Long raw_id = cur.getLong( cur.getColumnIndex(
272
 
                                ContactsContract.Data.RAW_CONTACT_ID ) );
273
 
                        Long id = raw_to_aggregate_ids.get( raw_id );
274
 
                        if( id != null )
275
 
                        {
276
 
                                String note = cur.getString( cur.getColumnIndex(
277
 
                                        CommonDataKinds.Note.NOTE ) );
278
 
 
279
 
                                // add associated data
280
 
                                cache.addAssociatedNote( id, note );
281
 
                        }
282
 
                }
283
 
                cur.close();
284
 
 
285
 
                // get all birthdays
286
 
                cur = _activity.getContentResolver().query(
287
 
                        ContactsContract.Data.CONTENT_URI,
288
 
                        new String[] {
289
 
                                ContactsContract.Data.RAW_CONTACT_ID,
290
 
                                CommonDataKinds.Event.START_DATE,
291
 
                        },
292
 
                        ContactsContract.Data.MIMETYPE + " = '" +
293
 
                                CommonDataKinds.Event.CONTENT_ITEM_TYPE + "' AND " +
294
 
                                CommonDataKinds.Event.TYPE + " = '" +
295
 
                                CommonDataKinds.Event.TYPE_BIRTHDAY + "'",
296
 
                        null, null );
297
 
                while( cur.moveToNext() ) {
298
 
                        Long raw_id = cur.getLong( cur.getColumnIndex(
299
 
                                ContactsContract.Data.RAW_CONTACT_ID ) );
300
 
                        Long id = raw_to_aggregate_ids.get( raw_id );
301
 
                        if( id != null )
302
 
                        {
303
 
                                String birthday = cur.getString( cur.getColumnIndex(
304
 
                                        CommonDataKinds.Event.START_DATE ) );
305
 
 
306
 
                                // add associated data
307
 
                                cache.addAssociatedBirthday( id, birthday );
308
 
                        }
309
 
                }
310
 
                cur.close();
311
233
        }
312
234
 
313
235
        @Override
343
265
                        ContentUris.withAppendedId(
344
266
                                ContactsContract.RawContacts.CONTENT_URI, raw_id ),
345
267
                        ContactsContract.RawContacts.Entity.CONTENT_DIRECTORY );
346
 
                Cursor cur = _activity.getContentResolver().query( contact_uri,
 
268
                Cursor cur = _activity.managedQuery( contact_uri,
347
269
                        new String[] {
348
270
                                ContactsContract.RawContacts.CONTACT_ID,
349
271
                        }, null, null, null );
351
273
                if( cur.moveToNext() )
352
274
                        id = cur.getLong(
353
275
                                cur.getColumnIndex( ContactsContract.RawContacts.CONTACT_ID ) );
354
 
                cur.close();
355
276
                if( id == null || id == 0 )
356
277
                {
357
278
                        // we didn't find an aggregate contact id, so try to clean up (by
370
291
         * Obtain the raw contact id for the phone-only raw contact that is
371
292
         * associated with the aggregate contact id.  One will be created if
372
293
         * necessary.
373
 
         *
374
294
         * @param id the aggregate contact id
375
295
         * @return the raw contact id
376
296
         * @throws ContactCreationException
382
302
                if( raw_id != null ) return raw_id;
383
303
 
384
304
                // find a corresponding raw contact that has no account name/type
385
 
                Cursor cur = _activity.getContentResolver().query(
 
305
                Cursor cur = _activity.managedQuery(
386
306
                        ContactsContract.RawContacts.CONTENT_URI,
387
307
                        new String[] {
388
308
                                ContactsContract.RawContacts._ID,
389
 
                                ContactsContract.RawContacts.ACCOUNT_NAME,
390
309
                        },
391
 
                        ContactsContract.RawContacts.DELETED + " = 0 AND " +
392
 
                                ContactsContract.RawContacts.CONTACT_ID + " = ? AND " +
 
310
                        ContactsContract.RawContacts.DELETED + " != 0 AND " +
393
311
                                "IFNULL( " + ContactsContract.RawContacts.ACCOUNT_NAME +
394
312
                                        ", '' ) = '' AND " +
395
313
                                "IFNULL( " + ContactsContract.RawContacts.ACCOUNT_TYPE +
396
314
                                        ", '' ) = ''",
397
 
                        new String[] {
398
 
                                String.valueOf( id ),
399
 
                        }, null );
 
315
                        null, null );
400
316
                if( cur.moveToNext() )
401
317
                        raw_id = cur.getLong(
402
318
                                cur.getColumnIndex( ContactsContract.RawContacts._ID ) );
403
 
                cur.close();
404
319
 
405
320
                // if one wasn't found, we'll need to create one
406
321
                if( raw_id == null ) {
540
455
                _activity.getContentResolver().insert(
541
456
                        ContactsContract.Data.CONTENT_URI, values );
542
457
        }
543
 
 
544
 
        @Override
545
 
        public void addContactNote( Long id, String note )
546
 
                throws ContactCreationException
547
 
        {
548
 
                ContentValues values = new ContentValues();
549
 
                values.put( ContactsContract.Data.RAW_CONTACT_ID,
550
 
                        obtainRawContact( id ) );
551
 
                values.put( ContactsContract.Data.MIMETYPE,
552
 
                        CommonDataKinds.Note.CONTENT_ITEM_TYPE );
553
 
                values.put(
554
 
                        CommonDataKinds.Note.NOTE, note );
555
 
 
556
 
                _activity.getContentResolver().insert(
557
 
                        ContactsContract.Data.CONTENT_URI, values );
558
 
        }
559
 
 
560
 
        @Override
561
 
        public void addContactBirthday( Long id, String birthday )
562
 
                throws ContactCreationException
563
 
        {
564
 
                ContentValues values = new ContentValues();
565
 
                values.put( ContactsContract.Data.RAW_CONTACT_ID,
566
 
                        obtainRawContact( id ) );
567
 
                values.put( ContactsContract.Data.MIMETYPE,
568
 
                        CommonDataKinds.Event.CONTENT_ITEM_TYPE );
569
 
                values.put(
570
 
                        CommonDataKinds.Event.TYPE, CommonDataKinds.Event.TYPE_BIRTHDAY );
571
 
                values.put(
572
 
                        CommonDataKinds.Event.START_DATE, birthday );
573
 
                _activity.getContentResolver().insert(
574
 
                        ContactsContract.Data.CONTENT_URI, values );
575
 
        }
576
458
}