Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - New Data record is added to the wrong contact

I'm trying to add Data record to an already exist contact, I find the contact using phone lookup, i take the contact _id field, and add a new data with raw_contact_id set to the _id field. on some contacts it just doesn't work, it match the data to different contact. (I think it relates to contacts that are stored on the sim card)

Please advice, maybe you have a different way to add the data

code sample:

LinkedList<Long> lcv = new LinkedList<Long>();
    ContentResolver cr = getContentResolver();
    Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
    Cursor c = cr.query(uri, null, null, null, null);
    try {
        while (c.moveToNext()) {
            Uri lookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
                    c.getString(c.getColumnIndex(PhoneLookup.LOOKUP_KEY)));
            Cursor c2 = getContentResolver().query(lookupUri, new String[] { Contacts._ID, Contacts.DISPLAY_NAME },
                    null, null, null);
            try {
                if (c2.moveToNext()) {
                    Log.i(TAG, "found: " + c2.getLong(c2.getColumnIndex(Contacts._ID)) + ", " + c2.getString(c2.getColumnIndex(Contacts.DISPLAY_NAME)));
                    lcv.add(c2.getLong(c2.getColumnIndex(Contacts._ID)));
                } else {
                    Log.e(TAG, "failed to lookup");
                }
            } finally {
                c2.close();
            }
        }
    } finally {
        c.close();
    }

    for (Long rawid : lcv) {
                        Cursor c3 = cr.query(RawContacts.CONTENT_URI, null, RawContacts.CONTACT_ID + "=?", new String[] {rawid+""}, null);
                        if (c3.moveToNext()) {
                            Log.e(TAG,"aaaa: " + c3.getString(c3.getColumnIndex(Contacts.DISPLAY_NAME)));
                        } else {
                            Log.e(TAG,"errrrror");
                        }

                        ContentValues cv = new ContentValues();
                        cv.put(Data.RAW_CONTACT_ID, rawid + "");
                        cv.put(Data.MIMETYPE, MyMime.MIMETYPE);
                        cv.put(Data.DATA1, "mydata");
                        cv.put(Data.SYNC1, syncvalue);
                        Uri newIns = cr.insert(ContactsContract.Data.CONTENT_URI, cv);
                        Log.i(TAG, "insert: " + newIns + ", " + name);
                    }

like image 922
alvin Avatar asked Mar 01 '11 08:03

alvin


Video Answer


1 Answers

The problem lies when you select the Contacts._ID and use this id to populate the data in the LinkedList lcv .

 Cursor c2 = getContentResolver().query(lookupUri, new String[] { Contacts._ID, Contacts.DISPLAY_NAME },
                    null, null, null);

You actually need a RAW_CONTACT_ID here.

The DISPLAY_NAME can be fetched either from Contacts database/ContactsContract.Data' OR 'database/ContactsContract.CommonDataKinds.StructuredName' OR 'database/RawContactsEntity. In the later 2 cases you will be able to fetch the DISPLAY_NAME using RAW_CONTACT_ID

Couple of Key pointers:

  • Contacts._ID = Data.CONTACT_ID
  • RawContacts._ID = Data.RAW_CONTACT_ID
  • RawContacts.CONTACT_ID = Contacts._ID
  • RawContactsEntity._ID = RawContacts._ID

Sounds confusing?? Let me try...

  1. The Contacts database is divided into 3 tables contacts, raw contacts, and data.
  2. Each table contains column (_ID) which is an auto incremented primary key.
  3. data table contains all the contact info like phone number, mail id, address etc.
  4. The raw contacts points to the actual contact created. Hence we use the raw contacts while adding a contact.
  5. The user cannot add any data in the contacts table. The data in this table is populated internally due to aggregation of contacts.
  6. The reason your logic worked for some of the contacts is: _ID for contacts, raw contacts remains same until there is any contact aggregation taking place. Lets say you add two contacts with same name abc. Here the _ID for raw contacts increments twice while _ID for contacts increments only once as these two contacts gets merged due to the aggregation of contacts

Refer this for more details.

The best approach to fetch the info in your case is by using ContactsContract.RawContactsEntity ( an outer join of the raw_contacts table with the data table)

Reference: http://developer.android.com/reference/android/provider/ContactsContract.RawContactsEntity.html

like image 178
Manish Khot Avatar answered Dec 07 '22 18:12

Manish Khot