/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/org/waxworlds/importcontacts/Importer.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
 * Importer.java
 
3
 *
 
4
 * Copyright (C) 2009 Tim Marston <edam@waxworlds.org>
 
5
 *
 
6
 * This file is part of the Import Contacts program (hereafter referred
 
7
 * to as "this program"). For more information, see
 
8
 * http://www.waxworlds.org/edam/software/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
 
1
24
package org.waxworlds.importcontacts;
2
25
 
3
26
import java.util.HashMap;
17
40
 
18
41
public class Importer extends Thread
19
42
{
20
 
        public final static int MESSAGE_FINISHED = 0;
21
 
        public final static int MESSAGE_FINISHED_BACK = 1;
22
 
        public final static int MESSAGE_ERROR = 2;
23
 
        public final static int MESSAGE_CONTINUEORABORT = 3;
24
 
        public final static int MESSAGE_SETPROGRESSMESSAGE = 4;
25
 
        public final static int MESSAGE_SETMAXPROGRESS = 5;
26
 
        public final static int MESSAGE_SETTMPPROGRESS = 6;
27
 
        public final static int MESSAGE_SETPROGRESS = 7;
28
 
        public final static int MESSAGE_MERGEPROMPT = 8;
29
 
        public final static int MESSAGE_CONTACTOVERWRITTEN = 9;
30
 
        public final static int MESSAGE_CONTACTCREATED = 10;
31
 
        public final static int MESSAGE_CONTACTMERGED = 11;
32
 
        public final static int MESSAGE_CONTACTSKIPPED = 12;
 
43
        public final static int ACTION_GOBACK = 0;
 
44
        public final static int ACTION_ABORT = 1;
 
45
        public final static int ACTION_ALLDONE = 2;
33
46
 
34
47
        public final static int RESPONSE_NEGATIVE = 0;
35
48
        public final static int RESPONSE_POSITIVE = 1;
46
59
        private int _mergeSetting;
47
60
        private int _lastMergeDecision;
48
61
        private boolean _abort = false;
 
62
        private boolean _isFinished = false;
49
63
 
50
64
        public class ContactData
51
65
        {
151
165
                        onImport();
152
166
 
153
167
                        // done!
154
 
                        finish();
 
168
                        finish( ACTION_ALLDONE );
155
169
                }
156
170
                catch( AbortImportException e )
157
171
                {}
 
172
 
 
173
                // flag as finished to prevent interrupts
 
174
                setIsFinished();
 
175
        }
 
176
 
 
177
        synchronized private void setIsFinished()
 
178
        {
 
179
                _isFinished = true;
158
180
        }
159
181
 
160
182
        protected void onImport() throws AbortImportException
178
200
                notify();
179
201
        }
180
202
 
181
 
        synchronized public void setAbort()
 
203
        synchronized public boolean setAbort()
182
204
        {
183
 
                _abort = true;
 
205
                if( !_isFinished && !_abort ) {
 
206
                        _abort = true;
 
207
                        notify();
 
208
                        return true;
 
209
                }
 
210
                return false;
184
211
        }
185
212
 
186
213
        protected SharedPreferences getSharedPreferences()
198
225
        {
199
226
                checkAbort();
200
227
                _doit._handler.sendMessage( Message.obtain(
201
 
                                _doit._handler, MESSAGE_ERROR, message ) );
 
228
                                _doit._handler, Doit.MESSAGE_ERROR, message ) );
202
229
                try {
203
230
                        wait();
204
231
                }
205
232
                catch( InterruptedException e ) { }
206
 
                finish( true );
 
233
                // no need to check if an abortion happened during the wait, we are
 
234
                // about to finish anyway!
 
235
                finish( ACTION_ABORT );
207
236
        }
208
237
 
209
238
        protected void showFatalError( int res ) throws AbortImportException
216
245
        {
217
246
                checkAbort();
218
247
                _doit._handler.sendMessage( Message.obtain(
219
 
                                _doit._handler, MESSAGE_ERROR, message ) );
 
248
                                _doit._handler, Doit.MESSAGE_ERROR, message ) );
220
249
                try {
221
250
                        wait();
222
251
                }
223
252
                catch( InterruptedException e ) { }
224
 
                finish( false );
 
253
                // no need to check if an abortion happened during the wait, we are
 
254
                // about to finish anyway!
 
255
                finish( ACTION_ABORT );
225
256
        }
226
257
 
227
258
        protected boolean showContinue( int res ) throws AbortImportException
234
265
        {
235
266
                checkAbort();
236
267
                _doit._handler.sendMessage( Message.obtain(
237
 
                                _doit._handler, MESSAGE_CONTINUEORABORT, message ) );
 
268
                                _doit._handler, Doit.MESSAGE_CONTINUEORABORT, message ) );
238
269
                try {
239
270
                        wait();
240
271
                }
241
272
                catch( InterruptedException e ) { }
 
273
 
 
274
                // check if an abortion happened during the wait
 
275
                checkAbort();
 
276
 
242
277
                return _response == RESPONSE_POSITIVE;
243
278
        }
244
279
 
246
281
        {
247
282
                checkAbort();
248
283
                _doit._handler.sendMessage( Message.obtain( _doit._handler,
249
 
                                MESSAGE_SETPROGRESSMESSAGE, getText( res ) ) );
 
284
                                Doit.MESSAGE_SETPROGRESSMESSAGE, getText( res ) ) );
250
285
        }
251
286
 
252
287
        protected void setProgressMax( int maxProgress )
254
289
        {
255
290
                checkAbort();
256
291
                _doit._handler.sendMessage( Message.obtain(
257
 
                                _doit._handler, MESSAGE_SETMAXPROGRESS,
 
292
                                _doit._handler, Doit.MESSAGE_SETMAXPROGRESS,
258
293
                                new Integer( maxProgress ) ) );
259
294
        }
260
295
 
262
297
        {
263
298
                checkAbort();
264
299
                _doit._handler.sendMessage( Message.obtain(
265
 
                                _doit._handler, MESSAGE_SETTMPPROGRESS,
 
300
                                _doit._handler, Doit.MESSAGE_SETTMPPROGRESS,
266
301
                                new Integer( tmpProgress ) ) );
267
302
        }
268
303
 
270
305
        {
271
306
                checkAbort();
272
307
                _doit._handler.sendMessage( Message.obtain(
273
 
                                _doit._handler, MESSAGE_SETPROGRESS,
 
308
                                _doit._handler, Doit.MESSAGE_SETPROGRESS,
274
309
                                new Integer( progress ) ) );
275
310
        }
276
311
 
277
 
        protected void finish() throws AbortImportException
 
312
        protected void finish( int action ) throws AbortImportException
278
313
        {
279
 
                finish( false );
280
 
        }
 
314
                // update UI to reflect action
 
315
                int message;
 
316
                switch( action )
 
317
                {
 
318
                case ACTION_GOBACK:             message = Doit.MESSAGE_FINISHED_GOBACK; break;
 
319
                case ACTION_ALLDONE:    message = Doit.MESSAGE_FINISHED_ALLDONE; break;
 
320
                default:        // fall through
 
321
                case ACTION_ABORT:              message = Doit.MESSAGE_FINISHED; break;
 
322
                }
 
323
                _doit._handler.sendEmptyMessage( message );
281
324
 
282
 
        protected void abort() throws AbortImportException
283
 
        {
284
 
                finish( true );
 
325
                // stop
 
326
                throw new AbortImportException();
285
327
        }
286
328
 
287
329
        protected CharSequence getText( int res )
296
338
                return isImportRequired( name, _mergeSetting );
297
339
        }
298
340
 
299
 
        synchronized private boolean isImportRequired( String name, int mergeSetting )
 
341
        synchronized private boolean isImportRequired( String name,
 
342
                        int mergeSetting ) throws AbortImportException
300
343
        {
301
344
                _lastMergeDecision = mergeSetting;
302
345
 
314
357
 
315
358
                        // ok, it exists, so do prompt
316
359
                        _doit._handler.sendMessage( Message.obtain(
317
 
                                        _doit._handler, MESSAGE_MERGEPROMPT, name ) );
 
360
                                        _doit._handler, Doit.MESSAGE_MERGEPROMPT, name ) );
318
361
                        try {
319
362
                                wait();
320
363
                        }
321
364
                        catch( InterruptedException e ) { }
322
365
 
 
366
                        // check if an abortion happened during the wait
 
367
                        checkAbort();
 
368
 
323
369
                        // if "always" was selected, make choice permenant
324
370
                        if( _responseExtra == RESPONSEEXTRA_ALWAYS )
325
371
                                _mergeSetting = _response;
336
382
        protected void skipContact() throws AbortImportException
337
383
        {
338
384
                checkAbort();
339
 
                _doit._handler.sendEmptyMessage( MESSAGE_CONTACTSKIPPED );
 
385
                _doit._handler.sendEmptyMessage( Doit.MESSAGE_CONTACTSKIPPED );
340
386
        }
341
387
 
342
388
        protected void importContact( ContactData contact )
344
390
        {
345
391
                checkAbort();
346
392
 
347
 
                if( !showContinue( "====[ IMPORTING ]====\n: " + contact._name ) )
348
 
                        abort();
 
393
//              if( !showContinue( "====[ IMPORTING ]====\n: " + contact._name ) )
 
394
//                      finish( ACTION_ABORT );
349
395
 
350
396
                ContentValues values = new ContentValues();
351
397
                boolean uiInformed = false;
368
414
                                contactUri = null;
369
415
 
370
416
                                // upate the UI
371
 
                                _doit._handler.sendEmptyMessage( MESSAGE_CONTACTOVERWRITTEN );
 
417
                                _doit._handler.sendEmptyMessage( Doit.MESSAGE_CONTACTOVERWRITTEN );
372
418
                                uiInformed = true;
373
419
 
374
420
                                // update cache
397
443
 
398
444
                        // update UI
399
445
                        if( !uiInformed ) {
400
 
                                _doit._handler.sendEmptyMessage( MESSAGE_CONTACTCREATED );
 
446
                                _doit._handler.sendEmptyMessage( Doit.MESSAGE_CONTACTCREATED );
401
447
                                uiInformed = true;
402
448
                        }
403
449
                }
404
450
 
405
451
                // update UI
406
452
                if( !uiInformed )
407
 
                        _doit._handler.sendEmptyMessage( MESSAGE_CONTACTMERGED );
 
453
                        _doit._handler.sendEmptyMessage( Doit.MESSAGE_CONTACTMERGED );
408
454
 
409
455
                // import contact parts
410
456
                if( contact._phones != null )
419
465
                Long contactId = ContentUris.parseId( contactUri );
420
466
                Uri contactPhonesUri = Uri.withAppendedPath( contactUri,
421
467
                                Contacts.People.Phones.CONTENT_DIRECTORY );
422
 
 
423
 
                // add phone numbers
424
468
                Set phonesKeys = phones.keySet();
 
469
 
 
470
                // add phone numbers
425
471
                Iterator i = phonesKeys.iterator();
426
472
                while( i.hasNext() ) {
427
473
                        ContactData.PhoneData phone = phones.get( i.next() );
445
491
                        if( phone._isPreferred ) values.put( Contacts.Phones.ISPRIMARY, 1 );
446
492
                        _doit.getContentResolver().insert( contactPhonesUri, values );
447
493
                }
 
494
 
 
495
                // now add those phone numbers to the cache to prevent the addition of
 
496
                // duplicate data from another file
 
497
                i = phonesKeys.iterator();
 
498
                while( i.hasNext() ) {
 
499
                        ContactData.PhoneData phone = phones.get( i.next() );
 
500
 
 
501
                        String number = sanitisePhoneNumber( phone._number );
 
502
                        if( number != null ) {
 
503
                                HashSet< String > numbers = _contactNumbers.get( contactId );
 
504
                                if( numbers == null ) {
 
505
                                        _contactNumbers.put( contactId, new HashSet< String >() );
 
506
                                        numbers = _contactNumbers.get( contactId );
 
507
                                }
 
508
                                numbers.add( number );
 
509
                        }
 
510
                }
448
511
        }
449
512
 
450
513
        private void importContactEmails( Uri contactUri,
453
516
                Long contactId = ContentUris.parseId( contactUri );
454
517
                Uri contactContactMethodsUri = Uri.withAppendedPath( contactUri,
455
518
                                Contacts.People.ContactMethods.CONTENT_DIRECTORY );
456
 
 
457
 
                // add phone numbers
458
519
                Set emailsKeys = emails.keySet();
 
520
 
 
521
                // add email addresses
459
522
                Iterator i = emailsKeys.iterator();
460
523
                while( i.hasNext() ) {
461
524
                        ContactData.EmailData email = emails.get( i.next() );
477
540
                        _doit.getContentResolver().insert( contactContactMethodsUri,
478
541
                                        values );
479
542
                }
480
 
        }
481
 
 
482
 
        synchronized private void finish( boolean offerBack )
483
 
                        throws AbortImportException
484
 
        {
485
 
                // notify Doit that we're finished
486
 
                _doit._handler.sendEmptyMessage(
487
 
                                offerBack? MESSAGE_FINISHED_BACK : MESSAGE_FINISHED );
488
 
 
489
 
                // stop
490
 
                throw new AbortImportException();
491
 
        }
492
 
 
493
 
        synchronized private void checkAbort() throws AbortImportException
 
543
 
 
544
                // now add those email addresses to the cache to prevent the addition of
 
545
                // duplicate data from another file
 
546
                i = emailsKeys.iterator();
 
547
                while( i.hasNext() ) {
 
548
                        ContactData.EmailData email = emails.get( i.next() );
 
549
 
 
550
                        String address = sanitiseEmailAddress( email.getAddress() );
 
551
                        if( address != null ) {
 
552
                                HashSet< String > addresses = _contactEmails.get( contactId );
 
553
                                if( addresses == null ) {
 
554
                                        _contactEmails.put( contactId, new HashSet< String >() );
 
555
                                        addresses = _contactEmails.get( contactId );
 
556
                                }
 
557
                                addresses.add( address );
 
558
                        }
 
559
                }
 
560
        }
 
561
 
 
562
        synchronized protected void checkAbort() throws AbortImportException
494
563
        {
495
564
                if( _abort ) {
496
565
                        // stop