I added some raw contacts to an account I created.
Does anyone knows how can I access its data fields?
This is how I added the contact:
Log.i(TAG, "Adding contact: " + username);
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
// create the contact
ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
builder.withValue(RawContacts.ACCOUNT_NAME, account.name);
builder.withValue(RawContacts.ACCOUNT_TYPE, account.type);
builder.withValue(RawContacts.SYNC1, username);
operationList.add(builder.build());
// set display name
builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
operationList.add(builder.build());
// set profile data
builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.net.myapp.android.profile");
builder.withValue(ContactsContract.Data.DATA1, username);
builder.withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name) + " Profile");
builder.withValue(ContactsContract.Data.DATA3, "View profile");
operationList.add(builder.build());
The cursor I use to get my contacts is:
private Cursor getContactsCursor(CharSequence constraint) {
Uri uri = RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(RawContacts.ACCOUNT_NAME, getString(R.string.app_name)).appendQueryParameter(RawContacts.ACCOUNT_TYPE, getString(R.string.ACCOUNT_TYPE)).build();
String[] projection = null;//new String[] { ContactsContract.Contacts.DISPLAY_NAME };
String selection = null;
if (constraint != null && constraint.length() > 0)
selection = ContactsContract.Contacts.DISPLAY_NAME + " LIKE '%" + constraint + "%'" ;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
Cursor cursor = getContentResolver().query(uri, projection, selection, null , sortOrder);
return cursor;
}
Unfortunately, I need Data1 field, which is not one of the cursor columns.
I guess that the problem is with RawContacts.CONTENT_URI Uri.
What should I use instead?
Related
This code is working fine for fetching name and phone but i don't know how to get email from this code. Here is my code :
public static ArrayList<ContentValues> getContactDetails(final Context mContext){
ArrayList<ContentValues> contactList = new ArrayList<ContentValues>();
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor managedCursor = mContext.getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, order);
int _number = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int _name = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int _id = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);
while (managedCursor.moveToNext()) {
ContentValues values = new ContentValues();
Contact mContact = new Contact();
values.put(ContactClass.CONTACT_NAME, managedCursor.getString(_name));
values.put(ContactClass.CONTACT_MOBILE_NUMBER, managedCursor.getString(_number).replaceAll("\\s+",""));
mContact.setPhNo(managedCursor.getString(_number).replaceAll("\\s+",""));
mContact.setName(managedCursor.getString(_name));
contactList.add(values);
serverContactList.add(mContact);
}
}
return contactList;
}
here i want to get email and add to serverContactList list.
I edited your code, add rest of your code in 2 todos.
public static ArrayList<ContentValues> getContactDetails(final Context mContext) {
// todo rest of things
int _id = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);
while (managedCursor.moveToNext()) {
// we will get emails for a contact id
String id = managedCursor.getString(_id);
Cursor cur1 = mContext.getContentResolver().query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{id}, null);
if (cur1 != null) {
while (cur1.moveToNext()) {
//to get the contact names
String name = cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
Log.e("Name :", name);
String email = cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
Log.e("Email", email);
}
}
cur1.close();
// todo rest of things
}
return contactList;
}
Don't use managedCursor, ever.
Query over Data.CONTENT_URI instead of Phone.CONTENT_URI to get access to all Data items (including Phone and Email and others if needed)
Limit the query by MIMETYPE to just the items you need
Map<Long, Contact> contacts = new HashMap<>();
String[] projection = {Data.CONTACT_ID, Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1, Data.DATA2, Data.DATA3};
// query only emails/phones/events
String selection = Data.MIMETYPE + " IN ('" + Phone.CONTENT_ITEM_TYPE + "', '" + Email.CONTENT_ITEM_TYPE + "')";
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);
while (cur != null && cur.moveToNext()) {
long id = cur.getLong(0);
String name = cur.getString(1); // full name
String mime = cur.getString(2); // type of data (phone / email)
String data = cur.getString(3); // the actual info, e.g. +1-212-555-1234
Log.d(TAG, "got " + id + ", " + name + " - " + data);
// add info to existing list if this contact-id was already found, or create a new list in case it's new
Contact contact;
if (contacts.containsKey(id)) {
contact = contacts.get(id);
} else {
contact = new Contact();
contacts.put(id, contact);
contact.setName(name);
}
if (mime == Phone.CONTENT_ITEM_TYPE) {
contact.setPhNo(data);
} else {
contact.setEmail(data);
}
}
I'd like to create an app which syncs contacts from a given server. To identify those contacts, I'd like to store a identifier in the android contact in a hidden field.
I've found the field SYNC1 which seems to appropriate for that, but I've no idea how to use this field correctly.
I tried setting it in the following way:
ArrayList<ContentProviderOperation> ops =
new ArrayList<>();
int rawContactInsertIndex = ops.size();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
.withValue(ContactsContract.RawContacts.SYNC1, "myInternalId")
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, rawContactInsertIndex)
.withValue(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "Test User")
.build());
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
The issue is now, that the batch insert runs through, but the field isn't set in the contact, because it is empty when I try to read it afterwards:
ContentResolver cr = this.getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(
ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME));
String sync1 = null;
int sync1Index = cur.getColumnIndex(ContactsContract.RawContacts.SYNC1);
if (sync1Index >= 0) {
sync1 = cur.getString(sync1Index);
}
System.out.println("Contact id=" + id + " name=" + name + " sync1=" + sync1);
}
}
cur.close();
If I want to set it in the raw contact, so in the second batch, I get an exception.
The way you insert the value seems correct, but the method that reads the value isn't.
You can't query Contacts.CONTENT_URI and get fields from the RawContacts table.
To read back your value, try this:
ContentResolver cr = this.getContentResolver();
String[] projection = new String[] { RawContacts._ID, RawContacts.CONTACT_ID, RawContacts.SYNC1 }
String selection = RawContacts.ACCOUNT_TYPE + " = '" + accountType + "' AND " + RawContacts.ACCOUNT_NAME + " = '" + accountName + "'";
Cursor cur = cr.query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, null, null);
while (cur.moveToNext()) {
Long rawId = cur.getLong(0);
Long contactId = cur.getLong(1);
String sync1 = cur.getString(2);
System.out.println("Contact id=" + contactId + " raw-id=" + rawId + " sync1=" + sync1);
}
cur.close();
I am trying to update existing contact with custom fields of MIME type defined for my app. This gets added to Contact available in Contacts app but it's not visible there. I am not sure what I am missing, Please suggest if you find anything wrong with below code -
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
ContentProviderOperation.Builder builder = ContentProviderOperation
.newInsert(RawContacts.CONTENT_URI);
builder.withValue(RawContacts.ACCOUNT_NAME, AccountGeneral.ACCOUNT_NAME);
builder.withValue(RawContacts.ACCOUNT_TYPE, AccountGeneral.ACCOUNT_TYPE);
operationList.add(builder.build());
operationList
.add(ContentProviderOperation
.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(
ContactsContract.Data.RAW_CONTACT_ID, contactId)
.withValue(
ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
"Display Name")
.build());
builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
// builder =
// ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID,
contactId);
builder.withValue(ContactsContract.Data.MIMETYPE, MIMETYPE);
builder.withValue(ContactsContract.Data.DATA1, contact.getId());
builder.withValue(ContactsContract.Data.DATA2, "Test Action");
builder.withValue(ContactsContract.Data.DATA3, "Test Action");
operationList.add(builder.build());
I am using same MIME type defined in contacts.xml file which is used for SyncAdapter.
Please help...
You can use below snippet to modify contact:
public void update()
{
int id = 1;
String firstname = "Contact's first name";
String lastname = "Last name";
String number = "000 000 000";
String photo_uri = "android.resource://com.my.package/drawable/default_photo";
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
// Name
Builder builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
builder.withSelection(ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?", new String[]{String.valueOf(id), ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE});
builder.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, lastname);
builder.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, firstname);
ops.add(builder.build());
// Number
builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
builder.withSelection(ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?"+ " AND " + ContactsContract.CommonDataKinds.Organization.TYPE + "=?", new String[]{String.valueOf(id), ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_HOME)});
builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, number);
ops.add(builder.build());
// Picture
try
{
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), Uri.parse(photo_uri));
ByteArrayOutputStream image = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG , 100, image);
builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
builder.withSelection(ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?", new String[]{String.valueOf(id), ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE});
builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, image.toByteArray());
ops.add(builder.build());
}
catch (Exception e)
{
e.printStackTrace();
}
// Update
try
{
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
}
catch (Exception e)
{
e.printStackTrace();
}
}
I use following code for new contacts added to phone.
private static void addContact(Account account, String name, String username,String phone,String email) {
Log.i(TAG, "Adding contact: " + name);
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
builder.withValue(RawContacts.ACCOUNT_NAME, account.name);
builder.withValue(RawContacts.ACCOUNT_TYPE, account.type);
builder.withValue(RawContacts.SYNC1, username);
operationList.add(builder.build());
//NAME adding area
builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
operationList.add(builder.build());
// Phone Number adding area
builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
builder.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK);
operationList.add(builder.build());
}
This code work fine for adding a new contact.
I want to update my contacts from server to phone. So I need contact id for updating purpose.
Can I get contact id from above code?. If anybody known share your answer.
If any questions or comments also welcome. Thanks for your answers.
Try this code,
ContentProviderResult[] res = getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
Uri myContactUri = res[0].uri;
int lastSlash = myContactUri.toString().lastIndexOf("/");
int length = myContactUri.toString().length();
int contactID = Integer.parseInt((String) myContactUri.toString().subSequence(lastSlash+1, length));
I hope this code help you..
The bulk insert that you do with the operation list will return a list of results (URIs I think, but it's been a few months since I did this), I believe you can get the ID you want from the first of these results
long rawContactId = ContentUris.parseId(rawContactUri);
After Applying the badge and receive the last segment you receive:
ContactsContract.RawContacts._ID
If you want to get Contact_id you should make this query:
(rowId - is the last segment you received before)
String[] projections = new String[]{ContactsContract.RawContacts.CONTACT_ID};
String select = ContactsContract.RawContacts._ID + "= ?";
String[] selectionArgs = new String[]{rowId};
Cursor cursor = context.getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, projections, select, selectionArgs, null);
String contactId = null;
if (cursor.getCount() == 0) {
Log.d("aaa","Couldn't find row: " + rowId);
return null;
}
if (cursor.moveToNext()) {
int columnIndex;
columnIndex = cursor.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID);
if (columnIndex == -1) {
Log.d("aaa","Couldn't get contact id");
} else {
contactId = cursor.getString(columnIndex);
}
}
cursor.close();
return contactId;
I am trying to birthday information to a contact. I use lookupkey to identify my contacts (as it is safer than just relying on contactId). In order to be able to insert the Event into the database i need a raw_contact_id ... so i'm trying to get this id:
String where = ContactsContract.Data.LOOKUP_KEY + " = ? AND "
+ ContactsContract.Data.MIMETYPE + " = ?";
String[] params = new String[] { lookupKey,
ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE };
Cursor cursor = contentResolver.query(
ContactsContract.Data.CONTENT_URI, null, where, params, null);
if (cursor.moveToFirst()) {
birthdayRow = cursor.getInt(idIdx);
long rawContactId = cursor.getLong(cursor
.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID));
}
The problem is that if there is not birthday event set for a contact then this cursor i receive is empty ... and i don't know how to insert this event without a raw_contact_id. In order to insert the event i do the folowing:
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Event.START_DATE,
birthdayStartDate);
values.put(ContactsContract.CommonDataKinds.Event.TYPE,
ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY);
values.put(ContactsContract.CommonDataKinds.Event.START_DATE,
context.getString(R.string.birthday_label));
if (birthdayRow >= 0) {
int result = contentResolver.update(
ContactsContract.Data.CONTENT_URI, values,
ContactsContract.Data._ID + " = " + birthdayRow, null);
Log.i("ContactList", "update result: " + result);
} else {
Uri result = contentResolver.insert(
ContactsContract.Data.CONTENT_URI, values);
Log.i("ContactList", "update result: " + result);
}
So please advice what shall i do, is there any way to add this event to the ContactData whitout a raw_contact id? Also i find strange the fact that for other ContactData like nickname i am doing the same thing and i dont get an empty cursor for the params
String[] params = new String[] { String.valueOf(lookupKey),
ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE };
even if the contact has no nickname.
Use this to get the raw contact id before performing the insert.
long rawContactId = -1;
String[] projection = new String[]{ContactsContract.CommonDataKinds.Event.RAW_CONTACT_ID};
String selection = ContactsContract.CommonDataKinds.Event.CONTACT_ID + "=?";
String[] selectionArgs = new String[]{
String.valueOf(bdayContact.getId()) };
Cursor c = getContentResolver().query(ContactsContract.Data.CONTENT_URI, projection, selection, selectionArgs, null);
try {
if (c.moveToFirst()) {
rawContactId = c.getLong(0);
}
} finally {
c.close();
}