/android/import-contacts

To get this branch, use:
bzr branch http://bzr.ed.am/android/import-contacts
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
1
/*
2
 * ContactsBackend.java
3
 *
95 by Tim Marston
added suopport for birthdays
4
 * Copyright (C) 2012 to 2013 Tim Marston <tim@ed.am>
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
5
 *
6
 * This file is part of the Import Contacts program (hereafter referred
93 by Tim Marston
minor style tweaks
7
 * to as "this program").  For more information, see
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
26
import java.util.HashMap;
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
27
import java.util.HashSet;
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
28
import java.util.Iterator;
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
39
@SuppressWarnings( "deprecation" )
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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
57 by edam
cleanup; fixed some typos; updated TODO
55
		HashSet< Long > unadded_ids = new HashSet< Long >();
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
56
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
57
		// notes
58
		HashMap< Long, String > notes = new HashMap< Long, String >();
59
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
60
		// get all contacts
83 by edam
stop using managedQuery(), which isn't cleaning up my queries
61
		cur = _activity.getContentResolver().query(
62
			Contacts.People.CONTENT_URI,
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
63
			new String[] {
64
				Contacts.People._ID,
65
				Contacts.People.NAME,
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
66
				Contacts.People.NOTES,
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
67
			}, null, null, null );
68
		while( cur.moveToNext() ) {
69
			Long id = cur.getLong(
70
				cur.getColumnIndex( Contacts.People._ID ) );
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
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
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
88
			{
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
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 );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
98
			}
99
		}
83 by edam
stop using managedQuery(), which isn't cleaning up my queries
100
		cur.close();
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
101
102
		// get contact organisations, primary ones first
83 by edam
stop using managedQuery(), which isn't cleaning up my queries
103
		cur = _activity.getContentResolver().query(
104
			Contacts.Organizations.CONTENT_URI,
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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 ) );
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
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 );
57 by edam
cleanup; fixed some typos; updated TODO
123
					unadded_ids.remove( id );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
124
				}
125
			}
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
126
127
			// add associated data
128
			cache.addAssociatedOrganisation( id, organisation );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
129
		}
83 by edam
stop using managedQuery(), which isn't cleaning up my queries
130
		cur.close();
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
131
132
		// get all phone numbers, primary ones first
83 by edam
stop using managedQuery(), which isn't cleaning up my queries
133
		cur = _activity.getContentResolver().query(
134
			Contacts.Phones.CONTENT_URI,
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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 ) );
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
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 );
57 by edam
cleanup; fixed some typos; updated TODO
153
					unadded_ids.remove( id );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
154
				}
155
			}
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
156
157
			// add associated data
158
			cache.addAssociatedNumber( id, number );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
159
		}
83 by edam
stop using managedQuery(), which isn't cleaning up my queries
160
		cur.close();
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
161
162
		// now get all email addresses, primary ones first, and postal addresses
83 by edam
stop using managedQuery(), which isn't cleaning up my queries
163
		cur = _activity.getContentResolver().query(
164
			Contacts.ContactMethods.CONTENT_URI,
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
165
			new String[] {
166
				Contacts.ContactMethods.PERSON_ID,
167
				Contacts.ContactMethods.DATA,
168
				Contacts.ContactMethods.KIND,
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
169
			}, Contacts.ContactMethods.KIND + " IN( ?, ? )",
170
			new String[] {
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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
			{
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
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 );
57 by edam
cleanup; fixed some typos; updated TODO
192
						unadded_ids.remove( id );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
193
					}
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
194
				}
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
195
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
196
				// add associated data
197
				cache.addAssociatedEmail( id, email );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
198
			}
199
			else if( kind == Contacts.KIND_POSTAL )
200
			{
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
201
				String address = cur.getString(
202
					cur.getColumnIndex( Contacts.ContactMethods.DATA ) );
203
204
				// add associated data
205
				cache.addAssociatedAddress( id, address );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
206
			}
207
		}
83 by edam
stop using managedQuery(), which isn't cleaning up my queries
208
		cur.close();
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
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
		}
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
229
	public Long addContact( String name ) throws ContactCreationException
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
230
	{
231
		ContentValues values = new ContentValues();
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
232
		if( name != null )
233
			values.put( Contacts.People.NAME, name );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
234
		Uri contact_uri = _activity.getContentResolver().insert(
235
			Contacts.People.CONTENT_URI, values );
236
		Long id = ContentUris.parseId( contact_uri );
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
237
		if( id == 0 )
238
			throw new ContactCreationException();
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
239
240
		// try to add them to the "My Contacts" group
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
241
		try {
242
			Contacts.People.addToMyContactsGroup(
243
				_activity.getContentResolver(), id );
244
		}
245
		catch( IllegalStateException e ) {
246
			// ignore any failure
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
247
		}
248
57 by edam
cleanup; fixed some typos; updated TODO
249
		return id;
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
250
	}
251
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
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:
77 by edam
fixed some column valuesa dn a broken check to contatinate name parts with spaces
260
				return Contacts.PhonesColumns.TYPE_HOME;
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
261
			case ContactData.TYPE_WORK:
77 by edam
fixed some column valuesa dn a broken check to contatinate name parts with spaces
262
				return Contacts.PhonesColumns.TYPE_WORK;
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
263
			case ContactData.TYPE_MOBILE:
77 by edam
fixed some column valuesa dn a broken check to contatinate name parts with spaces
264
				return Contacts.PhonesColumns.TYPE_MOBILE;
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
265
			case ContactData.TYPE_FAX_HOME:
77 by edam
fixed some column valuesa dn a broken check to contatinate name parts with spaces
266
				return Contacts.PhonesColumns.TYPE_FAX_HOME;
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
267
			case ContactData.TYPE_FAX_WORK:
77 by edam
fixed some column valuesa dn a broken check to contatinate name parts with spaces
268
				return Contacts.PhonesColumns.TYPE_FAX_WORK;
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
269
			case ContactData.TYPE_PAGER:
77 by edam
fixed some column valuesa dn a broken check to contatinate name parts with spaces
270
				return Contacts.PhonesColumns.TYPE_PAGER;
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
271
			}
272
		}
273
		else if( cls == Contacts.ContactMethods.class )
274
		{
275
			switch( type )
276
			{
277
			case ContactData.TYPE_HOME:
77 by edam
fixed some column valuesa dn a broken check to contatinate name parts with spaces
278
				return Contacts.ContactMethodsColumns.TYPE_HOME;
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
279
			case ContactData.TYPE_WORK:
77 by edam
fixed some column valuesa dn a broken check to contatinate name parts with spaces
280
				return Contacts.ContactMethodsColumns.TYPE_WORK;
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
281
			}
282
		}
283
284
		// still here?
285
		throw new ContactCreationException();
286
	}
287
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
288
	@Override
289
	public void addContactPhone( Long id, String number,
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
290
		ContactData.PreferredDetail data ) throws ContactCreationException
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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();
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
297
		values.put( Contacts.Phones.TYPE,
298
			convertTypeToBackendType( Contacts.Phones.class,
299
				data.getType() ) );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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,
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
309
		ContactData.PreferredDetail data ) throws ContactCreationException
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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 );
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
318
		values.put( Contacts.ContactMethods.TYPE,
319
			convertTypeToBackendType( Contacts.ContactMethods.class,
320
				data.getType() ) );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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,
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
330
		ContactData.TypeDetail data ) throws ContactCreationException
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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 );
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
339
		values.put( Contacts.ContactMethods.TYPE,
340
			convertTypeToBackendType( Contacts.ContactMethods.class,
341
				data.getType() ) );
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
342
343
		_activity.getContentResolver().insert( contact_contact_methods_uri,
344
			values );
345
	}
346
347
	@Override
348
	public void addContactOrganisation( Long id, String organisation,
61 by edam
made contacts backend throw exceptions when it can't create contacts on the device; specified Locale in lower/upper case conversions; stripped old Contacts types from Importer (and replaced with our own types, which are now converted in the backend; switched using Integer() constructors to Integer.valueOf(); rewrote the main importer routine a bit
349
		ContactData.ExtraDetail data ) throws ContactCreationException
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
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
65 by edam
added support for notes; rewrote backends so that all normalising of data is now done within the contacts cache; made the vCard unescape routine slightly more acceptant of non-standard escaped characters
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
	}
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
373
95 by Tim Marston
added suopport for birthdays
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
	}
53 by edam
abstracted the android contacts API in to an interface, ready to be switched to
380
}