Search code examples
androidcontactsandroid-contentprovidercontactscontract

Inserting contact with android and querying the result uri returns no entries


Im developing an application which is dealing with the android contacts API. I implemented methods to insert, update and query contacts. So far everything worked (writing and reading contacts).

At one point in my project Im experiencing a strange behaviour.

  1. I insert a contact using batch mode. I receive the URI to the RawContact. I do this in a background thread.
    ArrayList<ContentProviderOperation> ops = new  ArrayList<ContentProviderOperation>();      
                    int rawContactInsertIndex = ops.size();  
                    // create rawContact  
                    ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
                                        .withValue(RawContacts.ACCOUNT_TYPE, ConstantsContract.ACCOUNT_TYPE)
                                        .withValue(RawContacts.ACCOUNT_NAME, accountName).build());
                    ops.add(createInsertOperation().withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex)
                                    .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
                                    .withValue(StructuredName.DISPLAY_NAME, displayName).withValue(StructuredName.GIVEN_NAME, firstName)
                                    .withValue(StructuredName.FAMILY_NAME, lastName).build());      

        ContentProviderResult[] results = context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
if (results.length > 0) {
    result = results[0];
}
  1. Then i request and store the lookup uri
RawContacts.getContactLookupUri(this.getContentResolver(), myContantRawContactUri);
  1. I am able to query the contact using the rawContactUri directly after inserting it (in the same thread). The lookup uri returns null.
    Uri rawContactUri = appUser.getRawContactUri(ctx);
    if (rawContactUri == null) {
                return null;
            }

String lastPathSegment = rawContactUri.getLastPathSegment();
                long rawContactId = Long.decode(lastPathSegment);
                if (rawContactUri != null) {
                    contact = readContactWithID(rawContactId, ContactsContract.Data.RAW_CONTACT_ID);
  1. In a different place in the project I want to query the contact i inserted by the stored lookup uri or raw contact uri. Both return no rows from the content provider. I tried it in the main thread and in another background thread.
ctx.getContentResolver().query(ContactsContract.Data.CONTENT_URI, null,   ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " =   ?", new String[] { contactID + "",   ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE }, null);

My first thought was that it could be related to the context.getContentResolver(). But the android documentation states, that the ContentResolver objects scope is the application's package, so you have on ContentResolver for the whole app. Am I right?

What am I doing wrong? Why does the same rawContactUri return the contact at one place and does not on another place? And why do I get a lookup uri from a raw contact, which is not working at all?

Update: I analyzed the database using sqlite. When I insert the contact, the rows in raw_contacts and contacts are created. The deleted flag is set to 0, so it is not marked for deletion. If I then read the contact in another place in the application, it returns null. The database dump at this point of time does not contain the rows for the contact anymore.

Update 2: I tested my app with the emulator in versions 2.3.3, 4.0, and 4.1. The described behavior only appears with 4.1 Jelly Bean.


Solution

  • Ok, i found the solution. It was actually my own fault. I added a contact before i added my custom account to the AccountManager. This obviously deleted the contact because it had the same account type set.