0

In my application i need to create a great amount of contacts.

The code I currenly use:

        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
        ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, accounts[0].type)
                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, accounts[0].name)
                .build());
        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE,
                        ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                        .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
                        .build());
        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE,
                        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                        .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, number)
                        .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_HOME)
                        .build());
        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE,
                        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                        .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, number)
                        .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
                        .build());


        try {
            cr.applyBatch(ContactsContract.AUTHORITY, ops);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (OperationApplicationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

For some amounts of contacts the code works perfect, but if I create large amount then this code workt to slow. Therefore my question: Whats the fastest way to create large numbers of contacts?

Thanks in advance, any suggestions of idea's are welcome.

Greezer
  • 515
  • 2
  • 4
  • 18

1 Answers1

0

If you can sync with gmail, you could import contacts in gmail.com (as CSV) and sync them to the phone.

Or just see this similar question: Insertion of thousands of contact entries using applyBatch is slow

Community
  • 1
  • 1
Paweł Nadolski
  • 8,296
  • 2
  • 42
  • 32
  • These would ofc also be added to the ContactsProvider (using batches) by the Google sync adapter for ContactsContract. No real speed improvement there. – Jens May 24 '12 at 11:26
  • @Jens, the speed improvement is in developing solution time, generating large CSV is trivial and sync algorithm made by google should be optimal. – Paweł Nadolski May 24 '12 at 11:32
  • however, his question involved "`code workt (sic) to slow`" - and, as shown in his pasted example - he already has the `ContentProviderOperation`s required to insert new contacts into an arbitrary account. The sync operation by google would most likely be a delta sync - i.e. changes since last sync, i.e. **at best** the same operations he's trying to perform but with the added overhead of HTTP, protocol & parsing. – Jens May 24 '12 at 11:35
  • Added also link to similar questions which should give some hints how to do it in code. – Paweł Nadolski May 24 '12 at 11:49
  • Right-oh. Just a fyi for @Greezer - in "more recent versions" (e.g. ICS) `bulkInsert` will also yield in the same manner as `applyBatch` after you've reached a predefined constant number of operations in your bulk/batch. – Jens May 24 '12 at 11:57
  • thanks for your replies. @Paweł Nadolski i want to add like 600 contacts with multiple numbers which needs to be merged with the native android contacts. I also looked at you link but I did not find the name of the native database for the contacts. I Also find some example on other website but same question how to add the native database to the example: http://eshyu.wordpress.com/2010/08/15/using-sqlite-transactions-with-your-contentprovider/ – Greezer May 24 '12 at 13:49
  • @jens So in ICS it doesn’t matter if I use either the applyBatch or the BulkInsert. But what’s the speed difference for earlier versions of android? – Greezer May 24 '12 at 13:55
  • 1
    Well, bulkInsert in ICS has a harder limit than batches - i.e. it will yield even more often. You're probably better of trying to do reasonably sized applyBatches (of **max** 500 ops) in the background. Why do you need to fill the address book with ludicrous amounts of contacts? Testing purposes? – Jens May 25 '12 at 08:32
  • @Jens I am now using the applyBatch in small numbers, but it is very slow. Therefore I will test your suggestion to update in larger numbers. I am making custom fields for native contacts therefore I need to add/update large numbers of contacts. Is there a way to adjust the contacts2.db directly with own provider, or is this not possible (permissions)? – Greezer May 25 '12 at 10:53
  • @Greezer - correct, it's not possible to directly access the SQLite database. – Jens May 25 '12 at 10:54
  • @Jens, I tried your solution and its it way faster as before. I now got some time loss in my query’s for obtaining the needed data. Thanks for your advice. If you post it under answer then I can mark the your answer as the solution. – Greezer May 29 '12 at 10:25