/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

21
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
22
 */
23
23
 
24
 
package org.waxworlds.edam.importcontacts;
 
24
package org.waxworlds.importcontacts;
25
25
 
26
26
import java.util.HashMap;
27
27
import java.util.HashSet;
40
40
 
41
41
public class Importer extends Thread
42
42
{
 
43
        public final static int ACTION_GOBACK = 0;
43
44
        public final static int ACTION_ABORT = 1;
44
45
        public final static int ACTION_ALLDONE = 2;
45
46
 
131
132
                        if( _phones == null ) _phones = new HashMap< String, PhoneData >();
132
133
                        if( !_phones.containsKey( number ) )
133
134
                                _phones.put( number,
134
 
                                        new PhoneData( number, type, isPreferred ) );
 
135
                                                new PhoneData( number, type, isPreferred ) );
135
136
                }
136
137
 
137
138
                protected void addEmail( String email, int type, boolean isPreferred )
142
143
                }
143
144
        }
144
145
 
145
 
        @SuppressWarnings("serial")
146
146
        protected class AbortImportException extends Exception { };
147
147
 
148
148
        public Importer( Doit doit )
150
150
                _doit = doit;
151
151
 
152
152
                SharedPreferences prefs = getSharedPreferences();
153
 
                _mergeSetting = prefs.getInt( "merge_setting", Doit.ACTION_PROMPT );
 
153
                _mergeSetting = prefs.getInt( "merge_setting", 0 );
154
154
        }
155
155
 
156
156
        @Override
225
225
        {
226
226
                checkAbort();
227
227
                _doit._handler.sendMessage( Message.obtain(
228
 
                        _doit._handler, Doit.MESSAGE_ERROR, message ) );
 
228
                                _doit._handler, Doit.MESSAGE_ERROR, message ) );
229
229
                try {
230
230
                        wait();
231
231
                }
232
232
                catch( InterruptedException e ) { }
233
 
 
234
233
                // no need to check if an abortion happened during the wait, we are
235
234
                // about to finish anyway!
236
235
                finish( ACTION_ABORT );
246
245
        {
247
246
                checkAbort();
248
247
                _doit._handler.sendMessage( Message.obtain(
249
 
                        _doit._handler, Doit.MESSAGE_ERROR, message ) );
 
248
                                _doit._handler, Doit.MESSAGE_ERROR, message ) );
250
249
                try {
251
250
                        wait();
252
251
                }
253
252
                catch( InterruptedException e ) { }
254
 
 
255
253
                // no need to check if an abortion happened during the wait, we are
256
254
                // about to finish anyway!
257
255
                finish( ACTION_ABORT );
267
265
        {
268
266
                checkAbort();
269
267
                _doit._handler.sendMessage( Message.obtain(
270
 
                        _doit._handler, Doit.MESSAGE_CONTINUEORABORT, message ) );
 
268
                                _doit._handler, Doit.MESSAGE_CONTINUEORABORT, message ) );
271
269
                try {
272
270
                        wait();
273
271
                }
283
281
        {
284
282
                checkAbort();
285
283
                _doit._handler.sendMessage( Message.obtain( _doit._handler,
286
 
                        Doit.MESSAGE_SETPROGRESSMESSAGE, getText( res ) ) );
 
284
                                Doit.MESSAGE_SETPROGRESSMESSAGE, getText( res ) ) );
287
285
        }
288
286
 
289
287
        protected void setProgressMax( int maxProgress )
291
289
        {
292
290
                checkAbort();
293
291
                _doit._handler.sendMessage( Message.obtain(
294
 
                        _doit._handler, Doit.MESSAGE_SETMAXPROGRESS,
295
 
                        new Integer( maxProgress ) ) );
 
292
                                _doit._handler, Doit.MESSAGE_SETMAXPROGRESS,
 
293
                                new Integer( maxProgress ) ) );
296
294
        }
297
295
 
298
296
        protected void setTmpProgress( int tmpProgress ) throws AbortImportException
299
297
        {
300
298
                checkAbort();
301
299
                _doit._handler.sendMessage( Message.obtain(
302
 
                        _doit._handler, Doit.MESSAGE_SETTMPPROGRESS,
303
 
                        new Integer( tmpProgress ) ) );
 
300
                                _doit._handler, Doit.MESSAGE_SETTMPPROGRESS,
 
301
                                new Integer( tmpProgress ) ) );
304
302
        }
305
303
 
306
304
        protected void setProgress( int progress ) throws AbortImportException
307
305
        {
308
306
                checkAbort();
309
307
                _doit._handler.sendMessage( Message.obtain(
310
 
                        _doit._handler, Doit.MESSAGE_SETPROGRESS,
311
 
                        new Integer( progress ) ) );
 
308
                                _doit._handler, Doit.MESSAGE_SETPROGRESS,
 
309
                                new Integer( progress ) ) );
312
310
        }
313
311
 
314
312
        protected void finish( int action ) throws AbortImportException
317
315
                int message;
318
316
                switch( action )
319
317
                {
320
 
                case ACTION_ALLDONE:    message = Doit.MESSAGE_ALLDONE; break;
 
318
                case ACTION_GOBACK:             message = Doit.MESSAGE_FINISHED_GOBACK; break;
 
319
                case ACTION_ALLDONE:    message = Doit.MESSAGE_FINISHED_ALLDONE; break;
321
320
                default:        // fall through
322
 
                case ACTION_ABORT:              message = Doit.MESSAGE_ABORT; break;
 
321
                case ACTION_ABORT:              message = Doit.MESSAGE_FINISHED; break;
323
322
                }
324
323
                _doit._handler.sendEmptyMessage( message );
325
324
 
347
346
                // handle special cases
348
347
                switch( mergeSetting )
349
348
                {
350
 
                case Doit.ACTION_KEEP:
 
349
                case R.id.merge_keep:
351
350
                        // if we keep contacts on duplicate, we better check for one
352
351
                        return !_contacts.containsKey( name );
353
352
 
354
 
                case Doit.ACTION_PROMPT:
 
353
                case R.id.merge_prompt:
355
354
                        // if we are prompting on duplicate, we better check for one
356
355
                        if( !_contacts.containsKey( name ) )
357
356
                                return true;
358
357
 
359
358
                        // ok, it exists, so do prompt
360
359
                        _doit._handler.sendMessage( Message.obtain(
361
 
                                _doit._handler, Doit.MESSAGE_MERGEPROMPT, name ) );
 
360
                                        _doit._handler, Doit.MESSAGE_MERGEPROMPT, name ) );
362
361
                        try {
363
362
                                wait();
364
363
                        }
371
370
                        if( _responseExtra == RESPONSEEXTRA_ALWAYS )
372
371
                                _mergeSetting = _response;
373
372
 
374
 
                        // recurse, with our new merge setting
 
373
                        // recurse, with out new merge setting
375
374
                        return isImportRequired( name, _response );
376
375
                }
377
376
 
403
402
                if( ( id = (Long)_contacts.get( contact._name ) ) != null )
404
403
                {
405
404
                        // should we skip this import altogether?
406
 
                        if( _lastMergeDecision == Doit.ACTION_KEEP ) return;
 
405
                        if( _lastMergeDecision == R.id.merge_keep ) return;
407
406
 
408
407
                        // get contact's URI
409
408
                        contactUri = ContentUris.withAppendedId(
410
 
                                Contacts.People.CONTENT_URI, id );
 
409
                                        Contacts.People.CONTENT_URI, id );
411
410
 
412
411
                        // should we destroy the existing contact before importing?
413
 
                        if( _lastMergeDecision == Doit.ACTION_OVERWRITE ) {
 
412
                        if( _lastMergeDecision == R.id.merge_overwrite ) {
414
413
                                _doit.getContentResolver().delete( contactUri, null, null );
415
414
                                contactUri = null;
416
415
 
417
 
                                // update the UI
418
 
                                _doit._handler.sendEmptyMessage(
419
 
                                                Doit.MESSAGE_CONTACTOVERWRITTEN );
 
416
                                // upate the UI
 
417
                                _doit._handler.sendEmptyMessage( Doit.MESSAGE_CONTACTOVERWRITTEN );
420
418
                                uiInformed = true;
421
419
 
422
420
                                // update cache
431
429
                        // create a new contact
432
430
                        values.put( Contacts.People.NAME, contact._name );
433
431
                        contactUri = _doit.getContentResolver().insert(
434
 
                                Contacts.People.CONTENT_URI, values );
 
432
                                        Contacts.People.CONTENT_URI, values );
435
433
                        id = ContentUris.parseId( contactUri );
436
434
                        if( id <= 0 ) return;   // shouldn't happen!
437
435
 
438
 
                        // try to add them to the "My Contacts" group
439
 
                        try {
440
 
                                Contacts.People.addToMyContactsGroup(
441
 
                                        _doit.getContentResolver(), id );
442
 
                        }
443
 
                        catch( IllegalStateException e ) {
444
 
                                // ignore any failure
445
 
                        }
 
436
                        // add them to the "My Contacts" group
 
437
                        Contacts.People.addToGroup(
 
438
                                        _doit.getContentResolver(), id,
 
439
                                        Contacts.Groups.GROUP_MY_CONTACTS );
446
440
 
447
441
                        // update cache
448
442
                        _contacts.put( contact._name, id );
471
465
                Long contactId = ContentUris.parseId( contactUri );
472
466
                Uri contactPhonesUri = Uri.withAppendedPath( contactUri,
473
467
                                Contacts.People.Phones.CONTENT_DIRECTORY );
474
 
                Set< String > phonesKeys = phones.keySet();
 
468
                Set phonesKeys = phones.keySet();
475
469
 
476
470
                // add phone numbers
477
 
                Iterator< String > i = phonesKeys.iterator();
 
471
                Iterator i = phonesKeys.iterator();
478
472
                while( i.hasNext() ) {
479
473
                        ContactData.PhoneData phone = phones.get( i.next() );
480
474
 
522
516
                Long contactId = ContentUris.parseId( contactUri );
523
517
                Uri contactContactMethodsUri = Uri.withAppendedPath( contactUri,
524
518
                                Contacts.People.ContactMethods.CONTENT_DIRECTORY );
525
 
                Set< String > emailsKeys = emails.keySet();
 
519
                Set emailsKeys = emails.keySet();
526
520
 
527
521
                // add email addresses
528
 
                Iterator< String > i = emailsKeys.iterator();
 
522
                Iterator i = emailsKeys.iterator();
529
523
                while( i.hasNext() ) {
530
524
                        ContactData.EmailData email = emails.get( i.next() );
531
525
 
544
538
                        if( email.isPreferred() )
545
539
                                values.put( Contacts.ContactMethods.ISPRIMARY, 1 );
546
540
                        _doit.getContentResolver().insert( contactContactMethodsUri,
547
 
                                values );
 
541
                                        values );
548
542
                }
549
543
 
550
544
                // now add those email addresses to the cache to prevent the addition of
589
583
                // query and store map of contact names to ids
590
584
                cols = new String[] { Contacts.People._ID, Contacts.People.NAME };
591
585
                cur = _doit.managedQuery( Contacts.People.CONTENT_URI,
592
 
                        cols, null, null, null);
 
586
                                cols, null, null, null);
593
587
                if( cur.moveToFirst() ) {
594
588
                        int idCol = cur.getColumnIndex( Contacts.People._ID );
595
589
                        int nameCol = cur.getColumnIndex( Contacts.People.NAME );
602
596
                cols = new String[] { Contacts.Phones.PERSON_ID,
603
597
                                Contacts.Phones.NUMBER };
604
598
                cur = _doit.managedQuery( Contacts.Phones.CONTENT_URI,
605
 
                        cols, null, null, null);
 
599
                                cols, null, null, null);
606
600
                if( cur.moveToFirst() ) {
607
601
                        int personIdCol = cur.getColumnIndex( Contacts.Phones.PERSON_ID );
608
602
                        int numberCol = cur.getColumnIndex( Contacts.Phones.NUMBER );
629
623
                                new String[] { "" + Contacts.KIND_EMAIL }, null );
630
624
                if( cur.moveToFirst() ) {
631
625
                        int personIdCol = cur.getColumnIndex(
632
 
                                Contacts.ContactMethods.PERSON_ID );
 
626
                                        Contacts.ContactMethods.PERSON_ID );
633
627
                        int addressCol = cur.getColumnIndex(
634
 
                                Contacts.ContactMethods.DATA );
 
628
                                        Contacts.ContactMethods.DATA );
635
629
                        do {
636
630
                                Long id = cur.getLong( personIdCol );
637
631
                                String address = sanitiseEmailAddress(
638
 
                                        cur.getString( addressCol ) );
 
632
                                                cur.getString( addressCol ) );
639
633
                                if( address != null ) {
640
634
                                        HashSet< String > addresses = _contactEmails.get( id );
641
635
                                        if( addresses == null ) {
651
645
        private String sanitisePhoneNumber( String number )
652
646
        {
653
647
                number = number.replaceAll( "[-\\(\\) ]", "" );
654
 
                Pattern p = Pattern.compile( "^[\\+0-9#*]+" );
 
648
                Pattern p = Pattern.compile( "^\\+?[0-9]+" );
655
649
                Matcher m = p.matcher( number );
656
650
                if( m.lookingAt() ) return m.group( 0 );
657
651
                return null;
661
655
        {
662
656
                address = address.trim();
663
657
                Pattern p = Pattern.compile(
664
 
                        "^[^ @]+@[a-zA-Z]([-a-zA-Z0-9]*[a-zA-z0-9])?(\\.[a-zA-Z]([-a-zA-Z0-9]*[a-zA-z0-9])?)+$" );
 
658
                                "^[^ @]+@[a-zA-Z]([-a-zA-Z0-9]*[a-zA-z0-9])?(\\.[a-zA-Z]([-a-zA-Z0-9]*[a-zA-z0-9])?)+$" );
665
659
                Matcher m = p.matcher( address );
666
660
                if( m.matches() ) {
667
661
                        String[] bits = address.split( "@" );