I'm trying to write an Android program which can identify if a given contact number is associated with WhatsApp or not. I managed to find out if a particular contact name has WhatsApp account or not. How can I find out which contact corresponding to that contact name has WhatsApp? Currently I'm using the following code:
public void identifyWhatsappContact() {
Cursor c = ctx.getContentResolver().query(
RawContacts.CONTENT_URI,
new String[] { RawContacts.CONTACT_ID, RawContacts.DISPLAY_NAME_PRIMARY },
RawContacts.ACCOUNT_TYPE + "= ? AND " + StructuredName.DISPLAY_NAME_PRIMARY + " = ?",
new String[] { "com.whatsapp", "John Doe" },
null);
ArrayList<String> myWhatsappContacts = new ArrayList<String>();
int contactNameColumn = c.getColumnIndex(RawContacts.DISPLAY_NAME_PRIMARY);
while (c.moveToNext())
{
myWhatsappContacts.add(c.getString(contactNameColumn));
Log.v("WHATSAPP", c.getString(contactNameColumn)+"");
}
}
I'm able to identify if "John Doe" has WhatsApp or not, but I can't figure out which phone number of "John Doe" has WhatsApp (assuming the contact has multiple phone numbers). Can anybody please help me? I've already tried the solution here, but it's not working for me.
This example extract all the WhatsApp numbers of a contact name:
public void getWhatsAppNumbers(String contactName) {
Cursor cursor1 = getContentResolver().query(
ContactsContract.RawContacts.CONTENT_URI,
new String[]{ContactsContract.RawContacts._ID},
ContactsContract.RawContacts.ACCOUNT_TYPE + "= ? AND " + ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME_PRIMARY + " = ?",
new String[]{"com.whatsapp", contactName},
null);
while (cursor1.moveToNext()) {
String rawContactId = cursor1.getString(cursor1.getColumnIndex(ContactsContract.RawContacts._ID));
Cursor cursor2 = getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[]{ContactsContract.Data.DATA3},
ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.Data.RAW_CONTACT_ID + " = ? ",
new String[]{"vnd.android.cursor.item/vnd.com.whatsapp.profile", rawContactId},
null);
while (cursor2.moveToNext()) {
String phoneNumber = cursor2.getString(0);
if (TextUtils.isEmpty(phoneNumber))
continue;
if (phoneNumber.startsWith("Message "))
phoneNumber = phoneNumber.replace("Message ", "");
Log.d("whatsapp", String.format("%s - %s", contactName, phoneNumber));
}
}
}
Related
I am getting only name & birthday using the code below. But I need phone number & email also. It would be great if anyone can help me out. Thanks.
private void getContacts() {
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[]{
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Event.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Email.DATA,
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;
ContentResolver contentResolver = this.getActivity().getContentResolver();
Cursor cursor = contentResolver.query(uri, projection, where, selectionArgs, sortOrder);
int nameColumn = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
int numberColumn = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int emailColumn = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
int bithDayColumn = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE);
while (cursor.moveToNext()) {
String name = cursor.getString(nameColumn);
String number = cursor.getString(numberColumn);
String email = cursor.getString(emailColumn);
String birthDay = cursor.getString(bithDayColumn);
Log.d(TAG, "Birthday: " + birthDay);
}
}
In your projection you're limiting your query to rows of MIMETYPE CommonDataKinds.Event.CONTENT_ITEM_TYPE only, so you'll only get birthdays.
You need to ask for emails and phones mimetypes, but note that these additional information will come in separate rows for the same contact.
For example, for contact A that has 2 phones, 3 emails and a birthday, you'll get 6 results in your cursor. So you need to group them all together using the CONTACT_ID field.
Here's simple code to get you started, print the resulting HashMap and you'll get for each contact all his/hers name, emails, phones and birthday:
Map<Long, List<String>> contacts = new HashMap<Long, List<String>>();
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 + "', '" + Event.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 / birthday / email)
String data = cur.getString(3); // the actual info, e.g. +1-212-555-1234
String kind = "unknown";
switch (mime) {
case Phone.CONTENT_ITEM_TYPE:
kind = "phone";
break;
case Event.CONTENT_ITEM_TYPE:
kind = "birthday";
break;
case Email.CONTENT_ITEM_TYPE:
kind = "email";
break;
}
Log.d(TAG, "got " + id + ", " + name + ", " + kind + " - " + data);
// add info to existing list if this contact-id was already found, or create a new list in case it's new
List<String> infos;
if (contacts.containsKey(id)) {
infos = contacts.get(id);
} else {
infos = new ArrayList<String>();
infos.add("name = " + name);
contacts.put(id, infos);
}
infos.add(kind + " = " + data);
}
I'm trying to get the given name, family name etc of a specific contact on android but can't seem to be able to. I've been banging my head on this for hours, basically if (nameCur.moveNext()) is always false! This code is originally by #perborin (How to get the first name and last name from Android contacts?). Please help!
P.S. I've added <uses-permission android:name="android.permission.READ_CONTACTS"/> in the AndroidManifest, so that is not the problem.
// A contact ID is fetched from ContactList
Uri resultUri = data.getData();
Cursor cont = getContentResolver().query(resultUri, null, null, null, null);
if (!cont.moveToNext()) {
Toast.makeText(this, "Cursor contains no data", Toast.LENGTH_LONG).show();
return;
}
int columnIndexForId = cont.getColumnIndex(ContactsContract.Contacts._ID);
String contactId = cont.getString(columnIndexForId);
// Fetch contact name with a specific ID
String whereName = ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " = " + contactId;
String[] whereNameParams = new String[] { ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE };
Cursor nameCur = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, whereName, whereNameParams, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
while (nameCur.moveToNext()) {
String given = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
String family = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
String display = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
Toast.makeText(this, "Name: " + given + " Family: " + family + " Displayname: " + display, Toast.LENGTH_LONG).show();
}
nameCur.close();
cont.close();
Solved by referring to user3717188 answer at Get first and last name of a contact rather than single display name?.
Cursor phone_cursor = cr.query(ContactsContract.CommonDataKinds.
Phone.CONTENT_URI, null, null, null, null);
while (phone_cursor.moveToNext()) {
try {
int id = Integer.parseInt(phone_cursor.getString(phone_cursor.getColumnIndex
(ContactsContract.CommonDataKinds.Phone.CONTACT_ID)));
Cursor name_cursor = cr.query(ContactsContract.Data.CONTENT_URI,null,
ContactsContract.Data.CONTACT_ID + " = " + id, null, null);
String name = phone_cursor.getString(phone_cursor.getColumnIndex
(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String first_name ="";
String last_name = "";
while (name_cursor.moveToNext()) {
if(name_cursor.getString(name_cursor.getColumnIndex
(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME))!=null){
first_name = name_cursor.getString(name_cursor.getColumnIndex
(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
last_name = name_cursor.getString(name_cursor.getColumnIndex
(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
}}
name_cursor.close();
String phoneNumber = phone_cursor.getString(phone_cursor.getColumnIndex
(ContactsContract.CommonDataKinds.Phone.NUMBER));
} catch (Exception e) {
}
}
phone_cursor.close();
Hi I am currently trying to implement WhatsApp with an application I am working on. I want to be able to display all the WhatsApp contacts that a user has along with their phone number. So far I have been able to grab the name of their WhatsApp contact but I have not been able to grab the phone number of their WhatsApp contact, here is the code that I am using to get the list of a users WhatsApp contacts.
cursor = cr.query(ContactsContract.RawContacts.CONTENT_URI, new String[] {
ContactsContract.RawContacts.CONTACT_ID, ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY
}, ContactsContract.RawContacts.ACCOUNT_TYPE + "= ?", new String[] {
"com.whatsapp"
}, null);
int contactNameColumn = cursor.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID);
while (cursor.moveToNext()) {
String name = cursor.getString(contactNameColumn);
System.out.println(name);
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] {
Integer.toString(contactNameColumn)
}, null);
while (pCur.moveToNext()) {
String phonenumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
System.out.println("PHONE: " + phonenumber);
}
pCur.close();
}
cursor.close();
When I print out the name it prints it out correctly, I then use that id to query the data table in order to get their phone number, but that always returns null, can anyone help me out please.
Thanks
Use following code to get WhatsApp contacts from Phonebook with associated whatsApp number :
private void displayWhatsAppContacts() {
final String[] projection = {
ContactsContract.Data.CONTACT_ID,
ContactsContract.Data.DISPLAY_NAME,
ContactsContract.Data.MIMETYPE,
"account_type",
ContactsContract.Data.DATA3,
};
final String selection = ContactsContract.Data.MIMETYPE + " =? and account_type=?";
final String[] selectionArgs = {
"vnd.android.cursor.item/vnd.com.whatsapp.profile",
"com.whatsapp"
};
ContentResolver cr = getContentResolver();
Cursor c = cr.query(
ContactsContract.Data.CONTENT_URI,
projection,
selection,
selectionArgs,
null);
while (c.moveToNext()) {
String id = c.getString(c.getColumnIndex(ContactsContract.Data.CONTACT_ID));
String number = c.getString(c.getColumnIndex(ContactsContract.Data.DATA3));
String name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Log.v("WhatsApp", "name " +name + " - number - "+number);
}
Log.v("WhatsApp", "Total WhatsApp Contacts: " + c.getCount());
c.close();
}
Change your pCur like this
if (name != null) {
Cursor pCur = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{name}, null);
//Iterate cursor here...
}
And it is better to use proper naming conventions for variables. Why because here the varible name represents the id of the conatact.
I'm creating a contact app in android and I'm adding contacts to a specific account. How can I select all Data rows for all RawContacts belonging to this account in one query?
I know I can first select all RawContacts belonging to the account and then foreach _ID I could select all Data entries. But first of all that's really slow, but most important I want to get a cursor for all those Data rows so that I can provide this cursor to a CursorAdapter.
Cursor rawCursor = context.getContentResolver().query(
RawContacts.CONTENT_URI,
new String[] {
RawContacts.CONTACT_ID,
RawContacts._ID,
},
RawContacts.ACCOUNT_TYPE + " = ? AND " + RawContacts.ACCOUNT_NAME + " = ? ",
new String[] {account_type, account_name},
null);
while (rawCursor.moveToNext()) {
long rawContactID = rawCursor.getLong(rawCursor.getColumnIndex(RawContacts._ID));
Cursor dataCursor = mContext.getContentResolver().query(
Data.CONTENT_URI,
new String[] {
Data._ID,
Data.MIMETYPE,
Data.IS_SUPER_PRIMARY,
Data.DATA1,
Data.DATA2,
Data.DATA3,
},
Data.RAW_CONTACT_ID + " = ?",
new String[] {String.valueOf(rawContactID)},
null);
}
For now I solved this by first querying all raw_contacts and then using an IN statement in the selection. like:
ArrayList<String> ids = new ArrayList<String>();
Cursor idCursor = getRawContactsCursor(context, new String[]{RawContacts._ID}, account_name);
try {
while (idCursor.moveToNext()) {
ids.add(idCursor.getString(idCursor.getColumnIndex(RawContacts._ID)));
}
} finally {
idCursor.close();
}
String idSql = "?";
for (int i = 1; i < ids.size(); i++) {
idSql += ",?";
}
String whereSQL = Data.RAW_CONTACT_ID + " IN (" + idSql + ")";
String[] whereArgs = null;
if (!TextUtils.isEmpty(mimetype)) {
whereSQL += " AND " + Data.MIMETYPE + " = ? ";
ids.add(mimetype);
}
whereArgs = ids.toArray(new String[ids.size()]);
Cursor cursor = context.getContentResolver().query(
Data.CONTENT_URI,
projection,
whereSQL,
whereArgs,
Data.RAW_CONTACT_ID);
return cursor;
I just wonder what will happen when the number of raw_contacts becomes large enough. I'm guessing that having a thousand or more raw_contact id's will break stuff.
I am working on an android application for which I need to match the birthday of each contact against current date and if positive, process some business logic, which needs the complete contact details.
I have found ways to read birthdays of contacts or the contacts themselves separately, but am confused as to how to combine both. Can somebody please provide some direction.
Thanks
Found the answer after some looking out on the web. The way this has to be done is :
Get list of contacts
For each contact, get contactId
Get birthday using the contactid
Following is the code snippet :
ContentResolver cr = getContentResolver(); //getContnetResolver()
String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME };
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, projection, null, null,
ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
while (cur.moveToNext()) {
Map<String, String> contactInfoMap = new HashMap<String, String>();
String contactId = cur.getString(cur.getColumnIndex(ContactsContract.Data._ID));
String displayName = cur.getString(cur.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
String columns[] = {
ContactsContract.CommonDataKinds.Event.START_DATE,
ContactsContract.CommonDataKinds.Event.TYPE,
ContactsContract.CommonDataKinds.Event.MIMETYPE,
};
String where = Event.TYPE + "=" + Event.TYPE_BIRTHDAY +
" and " + Event.MIMETYPE + " = '" + Event.CONTENT_ITEM_TYPE + "' and " + ContactsContract.Data.CONTACT_ID + " = " + contactId;
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME;
Cursor birthdayCur = cr.query(ContactsContract.Data.CONTENT_URI, columns, where, selectionArgs, sortOrder);
if (birthdayCur.getCount() > 0) {
while (birthdayCur.moveToNext()) {
String birthday = birthdayCur.getString(birthdayCur.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE));
}
}
birthdayCur.close();
}
cur.close();