I need to fetch the members for a specific group in android contacts.
I have the contact group names and their ID's
Can anyone provide me how to query the contacts provider for members in a particular group ?
Try this method:
private Cursor getContacts(String groupID) {
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Data.CONTACT_ID,
ContactsContract.Data.DISPLAY_NAME
};
String selection = null;
String[] selectionArgs = null;
if(groupID != null && !"".equals(groupID)) {
selection = ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID
+ " = ?";
selectionArgs = new String[] { groupID };
}
else
selection = "1) GROUP BY (" + ContactsContract.Data.CONTACT_ID;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC ";
return getContentResolver().query(uri, projection,
selection, selectionArgs, sortOrder);
}
This works on Android 2.3.3 and lower, but doesn't work on Android 4+ and I don't currently know why.
UPD.
Adding custom string parameter "GROUP BY" to SQL query is denied in Android 4+, so I've founded this workaround:
private Cursor getContacts(String groupID) {
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Data.CONTACT_ID,
ContactsContract.Data.DISPLAY_NAME
};
String selection = null;
String[] selectionArgs = null;
if(groupID != null && !"".equals(groupID)) {
selection = ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID
+ " = ?";
selectionArgs = new String[] { groupID };
}
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC ";
Cursor cursor = getContentResolver().query(uri, projection,
selection, selectionArgs, sortOrder);
MatrixCursor result = new MatrixCursor(projection);
Set<Long> seen = new HashSet<Long>();
while (cursor.moveToNext()) {
long raw = cursor.getLong(1);
if (!seen.contains(raw)) {
seen.add(raw);
result.addRow(new Object[] { cursor.getLong(0),
cursor.getLong(1), cursor.getString(2) });
}
}
return result;
Related
I have gotten the group id from cursor. Let's say groupID as '59'. I want to get all contacts from the groups where Group_ID is 59. I have manipulated projection, selection and cursor with different classes of ContactsContract but no use. Here is what my code for getting member contacts looks like.
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection22 = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Data.CONTACT_ID,
ContactsContract.Data.DISPLAY_NAME
};
String selection = null;
String[] selectionArgs = null;
if(groupID != null && !"".equals(groupID)) {
selection = ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID
+ " = ?";
selectionArgs = new String[] { groupID };
}
String sortOrder = null;
Cursor cursor = getContentResolver().query(uri, projection22,
selection, selectionArgs, sortOrder);
Now the cursor returns zero count. Please get me through to use the cursor in a proper way.
public void getSampleContactList(int groupID) {
contactList = new ArrayList<ConatctData>();
Uri groupURI = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.GroupMembership.CONTACT_ID };
Cursor c = getContentResolver().query(
groupURI,
projection,
ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID
+ "=" + groupID, null, null);
while (c.moveToNext()) {
String id = c
.getString(c
.getColumnIndex(ContactsContract.CommonDataKinds.GroupMembership.CONTACT_ID));
Cursor pCur = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[] { id }, null);
while (pCur.moveToNext()) {
ConatctData data = new ConatctData();
data.name = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
data.phone = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contactList.add(data);
}
pCur.close();
}
}
class ConatctData {
String phone, name;
}
original post
I have a SearchView in which if I type a name, it shows a autocomplete list of names matching it. However contacts like Facebook ambulance and AL Cricket also come in these results. How to exclude such results and only get those contacts that are of actual people?
Code I am using to get display name is this :
private String getDisplayNameForContact(Intent intent) {
Cursor phoneCursor = getContentResolver().query(intent.getData(), null, null, null, null);
phoneCursor.moveToFirst();
int idDisplayName = phoneCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
String name = phoneCursor.getString(idDisplayName);
phoneCursor.close();
return name;
}
You need to add a selection and selection arguments to your contentResolver.query.
The arguments you want are:
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = ?";
String[] selectionArgs = {"1"};
You add them like so:
ContentResolver contentResolver = getActivity().getContentResolver();
Cursor contactsCursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, selection, selectionArgs, ContactsContract.Contacts.DISPLAY_NAME_PRIMARY);
The constant ContactsContract.Contacts.IN_VISIBLE_GROUP determines what subgroup of contacts you are querying.
As you can see, when you call - query(intent.getData(), null, null, null, null) - get all list data. Where is null, theare is your selections parameters. It remains only to choose the appropriate options. Try my example, and swith different values (ContactsContract.CommonDataKinds.SomethingElse).
I hope this helps.
private static Cursor allContactsQuery(Context context) {
final String[] CONTACTS = new String[]{
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.LABEL,
ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,
ContactsContract.Contacts.LOOKUP_KEY,
};
String SELECTION = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY +
"<>''" + " AND " + ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1" +
" AND " + ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1";
final String[] SELECTION_ARGS = null;
final String SORT_ORDER = ContactsContract.Contacts.SORT_KEY_PRIMARY;
Cursor cursor = context.getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
CONTACTS,
SELECTION,
SELECTION_ARGS,
SORT_ORDER);
return cursor;
}
For a given number from my address book, I need to look-up if the number has whatsapp enabled.
(The idea is to choose SMS/WhatsApp for initiating a text intent)
Lets say, I have two numbers under a contact, And I need to know which one has whatsapp enabled.
The "People" app on the Nexus 4 shows both contact numbers,
And also a little below has a CONNECTIONS section, which shows only the WhatsApp possible contact.
Is there a way to look up(like how People app does) ?
If you want to know if this contact has WhatsApp:
String[] projection = new String[] { RawContacts._ID };
String selection = ContactsContract.Data.CONTACT_ID + " = ? AND account_type IN (?)";
String[] selectionArgs = new String[] { "THE_CONTACT_DEVICE_ID", "com.whatsapp" };
Cursor cursor = activity.getContentResolver().query(RawContacts.CONTENT_URI, projection, selection, selectionArgs, null);
boolean hasWhatsApp = cursor.moveToNext();
if (hasWhatsApp){
String rowContactId = cursor.getString(0);
}
And to find to which number of this contact has WhatsApp
projection = new String[] { ContactsContract.Data.DATA3 };
selection = ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.Data.RAW_CONTACT_ID + " = ? ";
selectionArgs = new String[] { "vnd.android.cursor.item/vnd.com.whatsapp.profile", rawContactId };
cursor = CallAppApplication.get().getContentResolver().query(ContactsContract.Data.CONTENT_URI, projection, selection, selectionArgs, "1 LIMIT 1");
String phoneNumber = null;
if (cursor.moveToNext()) {
phoneNumber = cursor.getString(0);
}
Using #idog's method, I improved code to work easier. contactID is a string variable to be passed. If contact hasn't WhatsApp returns null, otherwise returns with contactID which has been passed as variable.
public String hasWhatsapp(String contactID) {
String rowContactId = null;
boolean hasWhatsApp;
String[] projection = new String[]{ContactsContract.RawContacts._ID};
String selection = ContactsContract.Data.CONTACT_ID + " = ? AND account_type IN (?)";
String[] selectionArgs = new String[]{contactID, "com.whatsapp"};
Cursor cursor = getActivity().getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, selectionArgs, null);
if (cursor != null) {
hasWhatsApp = cursor.moveToNext();
if (hasWhatsApp) {
rowContactId = cursor.getString(0);
}
cursor.close();
}
return rowContactId;
}
public int hasWhatsApp(String contactID) {
int whatsAppExists = 0;
boolean hasWhatsApp;
String[] projection = new String[]{ContactsContract.RawContacts._ID};
String selection = ContactsContract.Data.CONTACT_ID + " = ? AND account_type IN (?)";
String[] selectionArgs = new String[]{contactID, "com.whatsapp"};
Cursor cursor = getActivity().getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, selectionArgs, null);
if (cursor != null) {
hasWhatsApp = cursor.moveToNext();
if (hasWhatsApp) {
whatsAppExists = 1;
}
cursor.close();
}
return whatsAppExists;
}
I am able to fetch other information (Display name,organisation,phone no and email_id) of a contact, but not able to fetch birthday and anniversary of that contact.
Here is the code i am using for birthday. It does fetch the data, but gives me wrong data, i.e repeats the same data for all the contacts.
private String getBDate(String id) {
String bday = null;
ContentResolver cr = getContentResolver();
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Event.CONTACT_ID,
ContactsContract.CommonDataKinds.Event.START_DATE };
String where = ContactsContract.Data.MIMETYPE + "= ? AND "
+ ContactsContract.CommonDataKinds.Event.TYPE + "="
+ ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY;
String[] selectionArgs = new String[] { ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE };
String sortOrder = null;
Cursor cur = cr.query(uri, projection, where, selectionArgs, sortOrder);
while (cur.moveToNext()) {
bday = cur
.getString(cur
.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE));
Log.v("Birthday", bday);
}
cur.close();
return bday;
}
Same is the case with anniversary, here is the code for it. In some case anniversary is not added but it still shows the data from other contact.
private String getAnnv(String id) {
String annv = null;
ContentResolver cr = getContentResolver();
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Event.CONTACT_ID,
ContactsContract.CommonDataKinds.Event.START_DATE };
String where = ContactsContract.Data.MIMETYPE + "= ? AND "
+ ContactsContract.CommonDataKinds.Event.TYPE + "="
+ ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY;
String[] selectionArgs = new String[] { ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE };
// String sortOrder = null;
Cursor cur = cr.query(uri, projection, where, selectionArgs, null);
while (cur.moveToNext()) {
annv = cur
.getString(cur
.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE));
Log.v("Anniversary", annv);
}
cur.close();
return annv;
}
you are not using String id perameter in where condition so please check again.
E,g private String getAnnv(String id) function has input for ID but that seems to be not used withing function so please put that ID in condition check and this should work.
e.g
ContactsContract.CommonDataKinds.Event.CONTACT_ID + "= " + ID
AND ContactsContract.Data.MIMETYPE + "= ? AND "
Friends I want Contacts which have email and also sort in ascending order..
any one know how to get this list and sort..
Please help me and thanks in advance.
I am using this code.
MatrixCursor matCur = new MatrixCursor(new String[] { Contacts._ID,
Contacts.DISPLAY_NAME, "photo_id", "starred" });
Cursor cEmail = WP7Main.this.managedQuery(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
cEmail.moveToFirst();
if (cEmail.moveToFirst())
{
// String name =
// cursor.getString(cursor.getColumnIndexOrThrow(People.NAME));
String contactId = cEmail.getString(cEmail.getColumnIndex(ContactsContract.Contacts._ID));
Cursor emails = WP7Main.this.getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,ContactsContract.CommonDataKinds.Email.CONTACT_ID+ " = " + contactId, null, null);
String emailAddress = "";
while (emails.moveToNext())
{
// This would allow you get several email addresses
if (emails.getString(emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)) != null)
{
String[] columnValues = {
cEmail.getString(cEmail
.getColumnIndex("_id")),
cEmail.getString(cEmail
.getColumnIndex("display_name")),
cEmail.getString(cEmail
.getColumnIndex("photo_id")),
cEmail.getString(cEmail
.getColumnIndex("starred")) };
matCur.addRow(columnValues);
}
}
emails.close();
}
Try this:
/**
* #return A managed cursor of email contacts for the given activity.
*/
public static Cursor buildFilteredEmailCursor(Activity activity) {
final String my_sort_order = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
String my_selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'";
String[] eproj = new String[]{
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Email.DATA};
Uri uri = android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI;
return activity.managedQuery(uri, eproj, my_selection, null, my_sort_order);
}
Use this query :
Cursor c = getContentResolver().query(Data.CONTENT_URI,
new String[]{Data.CONTACT_ID, Data.DISPLAY_NAME, Email.ADDRESS},
Data.MIMETYPE + "=?", new String[] {Email.CONTENT_TYPE}, Data.DISPLAY_NAME /* use Email.ADDRESS if you want to sort it using that*/);