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. 开发者_Python百科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);
}
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...
- The Contacts database is divided into 3 tables contacts, raw contacts, and data.
- Each table contains column (_ID) which is an auto incremented primary key.
- data table contains all the contact info like phone number, mail id, address etc.
- The raw contacts points to the actual contact created. Hence we use the raw contacts while adding a contact.
- The user cannot add any data in the contacts table. The data in this table is populated internally due to aggregation of contacts.
- 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
精彩评论