/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/edam/importcontacts/Importer.java

  • Committer: edam
  • Date: 2011-03-24 06:46:40 UTC
  • Revision ID: edam@waxworlds.org-20110324064640-wr3sxbonxk6gvx7a
- updated TODO

Show diffs side-by-side

added added

removed removed

24
24
package org.waxworlds.edam.importcontacts;
25
25
 
26
26
import java.util.HashMap;
 
27
import java.util.HashSet;
27
28
import java.util.Iterator;
28
29
import java.util.Set;
29
30
import java.util.regex.Matcher;
32
33
import android.content.ContentUris;
33
34
import android.content.ContentValues;
34
35
import android.content.SharedPreferences;
 
36
import android.database.Cursor;
35
37
import android.net.Uri;
36
38
import android.os.Message;
37
39
import android.provider.Contacts;
51
53
        private Doit _doit;
52
54
        private int _response;
53
55
        private int _responseExtra;
 
56
        private HashMap< String, Long > _contacts;
 
57
        private HashMap< Long, HashSet< String > > _contactNumbers;
 
58
        private HashMap< Long, HashSet< String > > _contactEmails;
 
59
        private HashMap< Long, HashSet< String > > _contactAddresses;
54
60
        private int _mergeSetting;
55
61
        private int _lastMergeDecision;
56
62
        private boolean _abort = false;
57
63
        private boolean _isFinished = false;
58
 
        private ContactsCache _contactsCache = null;
59
64
 
60
65
        public class ContactData
61
66
        {
183
188
        {
184
189
                try
185
190
                {
186
 
                        // update UI
187
 
                        setProgressMessage( R.string.doit_caching );
188
 
 
189
 
                        // build a cache of existing contacts
190
 
                        _contactsCache = new ContactsCache();
191
 
                        _contactsCache.buildCache( _doit );
 
191
                        // cache current contact names
 
192
                        buildContactsCache();
192
193
 
193
194
                        // do the import
194
195
                        onImport();
378
379
                {
379
380
                case Doit.ACTION_KEEP:
380
381
                        // if we keep contacts on duplicate, we better check for one
381
 
                        return !_contactsCache.exists( name );
 
382
                        return !_contacts.containsKey( name );
382
383
 
383
384
                case Doit.ACTION_PROMPT:
384
385
                        // if we are prompting on duplicate, we better check for one
385
 
                        if( !_contactsCache.exists( name ) )
 
386
                        if( !_contacts.containsKey( name ) )
386
387
                                return true;
387
388
 
388
389
                        // ok, it exists, so do prompt
429
430
                // does contact exist already?
430
431
                Uri contactUri = null;
431
432
                Long id;
432
 
                if( ( id = (Long)_contactsCache.getId( contact._name ) ) != null )
 
433
                if( ( id = (Long)_contacts.get( contact._name ) ) != null )
433
434
                {
434
435
                        // should we skip this import altogether?
435
436
                        if( _lastMergeDecision == Doit.ACTION_KEEP ) return;
449
450
                                uiInformed = true;
450
451
 
451
452
                                // update cache
452
 
                                _contactsCache.remove( contact._name );
 
453
                                _contacts.remove( contact._name );
453
454
                        }
454
455
                }
455
456
 
474
475
                        }
475
476
 
476
477
                        // update cache
477
 
                        _contactsCache.put( id, contact._name );
 
478
                        _contacts.put( contact._name, id );
478
479
 
479
480
                        // update UI
480
481
                        if( !uiInformed ) {
518
519
                        // anyway, so it's not a problem).
519
520
                        String number = sanitisePhoneNumber( phone._number );
520
521
                        if( number == null ) continue;
521
 
                        if( _contactsCache.hasNumber( contactId, number ) ) continue;
 
522
                        HashSet< String > cache = _contactNumbers.get( contactId );
 
523
                        if( cache != null && cache.contains( number ) ) continue;
522
524
 
523
525
                        // add phone number
524
526
                        ContentValues values = new ContentValues();
529
531
 
530
532
                        // and add this address to the cache to prevent a addition of
531
533
                        // duplicate date from another file
532
 
                        _contactsCache.addNumber( contactId, number );
 
534
                        if( cache == null ) {
 
535
                                cache = new HashSet< String >();
 
536
                                _contactNumbers.put( contactId, cache );
 
537
                        }
 
538
                        cache.add( number );
533
539
                }
534
540
        }
535
541
 
550
556
                        // we would introduce duplicates.
551
557
                        String address = sanitiseEmailAddress( email.getAddress() );
552
558
                        if( address == null ) continue;
553
 
                        if( _contactsCache.hasEmail( contactId, address ) ) continue;
 
559
                        HashSet< String > cache = _contactEmails.get( contactId );
 
560
                        if( cache != null && cache.contains( address ) ) continue;
554
561
 
555
562
                        // add phone number
556
563
                        ContentValues values = new ContentValues();
564
571
 
565
572
                        // and add this address to the cache to prevent a addition of
566
573
                        // duplicate date from another file
567
 
                        _contactsCache.addEmail( contactId, address );
 
574
                        if( cache == null ) {
 
575
                                cache = new HashSet< String >();
 
576
                                _contactEmails.put( contactId, cache );
 
577
                        }
 
578
                        cache.add( address );
568
579
                }
569
580
        }
570
581
 
584
595
                        // we don't want to add this address if it exists already or we
585
596
                        // would introduce duplicates
586
597
                        if( address == null ) continue;
587
 
                        if( _contactsCache.hasAddress( contactId, address.getAddress() ) )
 
598
                        HashSet< String > cache = _contactAddresses.get( contactId );
 
599
                        if( cache != null && cache.contains( address.getAddress() ) )
588
600
                                continue;
589
601
 
590
602
                        // add postal address
597
609
 
598
610
                        // and add this address to the cache to prevent a addition of
599
611
                        // duplicate date from another file
600
 
                        _contactsCache.addAddress( contactId, address.getAddress() );
 
612
                        if( cache == null ) {
 
613
                                cache = new HashSet< String >();
 
614
                                _contactAddresses.put( contactId, cache );
 
615
                        }
 
616
                        cache.add( address.getAddress() );
601
617
                }
602
618
        }
603
619
 
609
625
                }
610
626
        }
611
627
 
612
 
        static public String sanitisePhoneNumber( String number )
 
628
        private void buildContactsCache() throws AbortImportException
 
629
        {
 
630
                // update UI
 
631
                setProgressMessage( R.string.doit_caching );
 
632
 
 
633
                String[] cols;
 
634
                Cursor cur;
 
635
 
 
636
                // init contacts caches
 
637
                _contacts = new HashMap< String, Long >();
 
638
                _contactNumbers = new HashMap< Long, HashSet< String > >();
 
639
                _contactEmails = new HashMap< Long, HashSet< String > >();
 
640
                _contactAddresses = new HashMap< Long, HashSet< String > >();
 
641
 
 
642
                // query and store map of contact names to ids
 
643
                cols = new String[] { Contacts.People._ID, Contacts.People.NAME };
 
644
                cur = _doit.managedQuery( Contacts.People.CONTENT_URI,
 
645
                        cols, null, null, null);
 
646
                if( cur.moveToFirst() ) {
 
647
                        int idCol = cur.getColumnIndex( Contacts.People._ID );
 
648
                        int nameCol = cur.getColumnIndex( Contacts.People.NAME );
 
649
                        do {
 
650
                                _contacts.put( cur.getString( nameCol ), cur.getLong( idCol ) );
 
651
                        } while( cur.moveToNext() );
 
652
                }
 
653
 
 
654
                // query and store map of contact ids to sets of phone numbers
 
655
                cols = new String[] { Contacts.Phones.PERSON_ID,
 
656
                                Contacts.Phones.NUMBER };
 
657
                cur = _doit.managedQuery( Contacts.Phones.CONTENT_URI,
 
658
                        cols, null, null, null);
 
659
                if( cur.moveToFirst() ) {
 
660
                        int personIdCol = cur.getColumnIndex( Contacts.Phones.PERSON_ID );
 
661
                        int numberCol = cur.getColumnIndex( Contacts.Phones.NUMBER );
 
662
                        do {
 
663
                                Long id = cur.getLong( personIdCol );
 
664
                                String number = sanitisePhoneNumber(
 
665
                                                cur.getString( numberCol ) );
 
666
                                if( number != null ) {
 
667
                                        HashSet< String > numbers = _contactNumbers.get( id );
 
668
                                        if( numbers == null ) {
 
669
                                                numbers = new HashSet< String >();
 
670
                                                _contactNumbers.put( id, numbers );
 
671
                                        }
 
672
                                        numbers.add( number );
 
673
                                }
 
674
                        } while( cur.moveToNext() );
 
675
                }
 
676
 
 
677
                // query and store map of contact ids to sets of email addresses
 
678
                cols = new String[] { Contacts.ContactMethods.PERSON_ID,
 
679
                                Contacts.ContactMethods.DATA };
 
680
                cur = _doit.managedQuery( Contacts.ContactMethods.CONTENT_URI,
 
681
                                cols, Contacts.ContactMethods.KIND + " = ?",
 
682
                                new String[] { "" + Contacts.KIND_EMAIL }, null );
 
683
                if( cur.moveToFirst() ) {
 
684
                        int personIdCol = cur.getColumnIndex(
 
685
                                Contacts.ContactMethods.PERSON_ID );
 
686
                        int addressCol = cur.getColumnIndex(
 
687
                                Contacts.ContactMethods.DATA );
 
688
                        do {
 
689
                                Long id = cur.getLong( personIdCol );
 
690
                                String address = sanitiseEmailAddress(
 
691
                                        cur.getString( addressCol ) );
 
692
                                if( address != null ) {
 
693
                                        HashSet< String > addresses = _contactEmails.get( id );
 
694
                                        if( addresses == null ) {
 
695
                                                addresses = new HashSet< String >();
 
696
                                                _contactEmails.put( id, addresses );
 
697
                                        }
 
698
                                        addresses.add( address );
 
699
                                }
 
700
                        } while( cur.moveToNext() );
 
701
                }
 
702
 
 
703
                // query and store map of contact ids to sets of postal addresses
 
704
                cols = new String[] { Contacts.ContactMethods.PERSON_ID,
 
705
                        Contacts.ContactMethods.DATA };
 
706
                cur = _doit.managedQuery( Contacts.ContactMethods.CONTENT_URI,
 
707
                        cols, Contacts.ContactMethods.KIND + " = ?",
 
708
                        new String[] { "" + Contacts.KIND_POSTAL }, null );
 
709
                if( cur.moveToFirst() ) {
 
710
                        int personIdCol = cur.getColumnIndex(
 
711
                                Contacts.ContactMethods.PERSON_ID );
 
712
                        int addressCol = cur.getColumnIndex(
 
713
                                Contacts.ContactMethods.DATA );
 
714
                        do {
 
715
                                Long id = cur.getLong( personIdCol );
 
716
                                String address = cur.getString( addressCol );
 
717
                                if( address != null ) {
 
718
                                        HashSet< String > addresses = _contactAddresses.get( id );
 
719
                                        if( addresses == null ) {
 
720
                                                addresses = new HashSet< String >();
 
721
                                                _contactAddresses.put( id, addresses );
 
722
                                        }
 
723
                                        addresses.add( address );
 
724
                                }
 
725
                        } while( cur.moveToNext() );
 
726
                }
 
727
        }
 
728
 
 
729
        private String sanitisePhoneNumber( String number )
613
730
        {
614
731
                number = number.replaceAll( "[-\\(\\) ]", "" );
615
732
                Pattern p = Pattern.compile( "^[\\+0-9#*]+" );
618
735
                return null;
619
736
        }
620
737
 
621
 
        static public String sanitiseEmailAddress( String address )
 
738
        private String sanitiseEmailAddress( String address )
622
739
        {
623
740
                address = address.trim();
624
741
                Pattern p = Pattern.compile(