I would like to query on phonenumber to obtain the rawcontactID.
The only thing I know of the contact is the given phonenumber, but for my function I need to have the rawcontactID. I got a working code but now I did use 2 seperate queries. What I would like to have is 1 query that can do both just to save some query time.
my code:
Uri uri = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
String[] columns = new String[]{Phone.CONTACT_ID, Phone.DISPLAY_NAME, Phone.NUMBER, Phone._ID };
Cursor cursor = contentResolver.query(uri, columns, null, null, null);
if(cursor!=null) {
int clenght = cursor.getCount();
while(cursor.moveToNext()){
//contactName = cursor.getString(cursor.getColumnIndexOrThrow(PhoneLookup.DISPLAY_NAME));
id = cursor.getString(cursor.getColumnIndex(Phone.CONTACT_ID));
}
cursor.close();
}
Cursor pCur = contentResolver.query(ContactsContract.Data.CONTENT_URI, new String[]{ContactsContract.Data.RAW_CONTACT_ID}, ContactsContract.Data.CONTACT_ID+" = "+ id, null, null);
if(pCur!=null) {
int clenght = pCur.getCount();
while(pCur.moveToNext()){
//contactName = cursor.getString(cursor.getColumnIndexOrThrow(PhoneLookup.DISPLAY_NAME));
id = pCur.getString(pCur.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID));
}
pCur.close();
}
thanks in advance
Edit:
My code above works fine, but I am still looking for increasing speed for large number of contacts. Therefore I will give a bounty if someone comes with a solution to combine my queries.
private String[] getRawContactIdFromNumber(String givenNumber){
List<String> rawIds = new ArrayList<String>();
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID},ContactsContract.CommonDataKinds.Phone.NUMBER + "='"+ givenNumber +"'",null, ContactsContract.CommonDataKinds.Phone.NUMBER);
while (phones.moveToNext())
{
rawIds.add( phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID)));
Log.v("contacts","Given Number: " + givenNumber + "Raw ID: " +rawIds.get(rawIds.size() - 1));
}
phones.close();
String[] ret = new String[0];
return rawIds.toArray(ret);
}
Edited to only include the raw id in the cursor for efficiency. Also changed return type to array in case multiple contacts have the same number.
Please try
String phonenumber = "input your phone number";
Cursor pCur = getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[] { ContactsContract.Data.RAW_CONTACT_ID,
Phone.CONTACT_ID }, Phone.NUMBER + " = " + phonenumber,
null, null);
if (pCur != null) {
while (pCur.moveToNext()) {
String contactID = pCur.getString(pCur
.getColumnIndex(Phone.CONTACT_ID));
String Rowid = pCur.getString(pCur
.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID));
Log.e("RAW_CONTACT_ID", Rowid);
Log.e("CONTACT_ID", contactID);
}
pCur.close();
}
Now you can get Both CONTACT_ID & RAW_CONTACT_ID in single query.
Related
I am using the below code to fetch the local phone contacts. It is working fine and also fetching the contacts very fast.
But the problem comes here, in my contact list there are few contacts that are having multiple Emails and multiple phone numbers.
In case of multiple phone or emails address it repeats the name of the same person multiple times.
And if i change
ContactsContract.CommonDataKinds.Email.CONTENT_URI
to ContactsContract.CommonDataKinds.Phone.CONTENT_URI then it will repeat name according to the number of phone number exists for a contact. Please help
private static final String[] PROJECTION = new String[]{
ContactsContract.CommonDataKinds.Email.CONTACT_ID,
ContactsContract.CommonDataKinds.Nickname.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Email.DATA,
ContactsContract.CommonDataKinds.Phone.NUMBER,
};
ContentResolver cr = mContext.getContentResolver();
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, PROJECTION, null, null, null);
if (cursor != null) {
try {
final int contactIdIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.CONTACT_ID);
final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
final int emailIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
final int phoneIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
long contactId;
String displayName, email, phone, photo;
while (cursor.moveToNext()) {
mNK_UserModel = new NK_Contact();
contactId = cursor.getLong(contactIdIndex);
displayName = cursor.getString(displayNameIndex);
//Adding display name
mNK_UserModel.setFirstName(displayName);
Util.DEBUG_LOG(1, "contact", "contact id :" + contactId);
al_PhoneContacts.add(mNK_UserModel);
}
} finally {
cursor.close();
}
}
If i had to guess i would say you are missing a "break" in your while-loop. Since the cursor tries to fetch the next available column entry. But have a look at my solution which worked for me in the past.
It uses a seperate cursor for each row which gives you more control over the data.
Map<String, String> contactDataMap = new HashMap<String, String>();
Uri contactData = data.getData();
Cursor cursor = getContentResolver().query(contactData, null, null, null, null);
cursor.moveToFirst();
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
String id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
contactDataMap.put(NAME, (name != null)?name:"");
if (Integer.parseInt(cursor.getString(
cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id},
null);
while (pCur.moveToNext()) {
String number = pCur.getString(pCur.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
contactDataMap.put(PHONE, (number != null)?number:"");
break;
}
pCur.close();
}
Cursor emailCur = getContentResolver().query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{id}, null);
while (emailCur.moveToNext()) {
String email = emailCur.getString(
emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
contactDataMap.put(MAIL, (email != null)?email:"");
break;
}
emailCur.close();
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 want to select unique contacts from android only that contacts which have phone numbers. i am using this code
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, ContactsContract.Contacts.DISPLAY_NAME);
// Find the ListView resource.
mainListView = (ListView) findViewById(R.id.mainListView);
// When item is tapped, toggle checked properties of CheckBox and
// Planet.
mainListView
.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View item,
int position, long id)
{
ContactsList planet = listAdapter.getItem(position);
planet.toggleChecked();
PlanetViewHolder viewHolder = (PlanetViewHolder) item
.getTag();
viewHolder.getCheckBox().setChecked(planet.isChecked());
}
});
// Create and populate planets.
planets = (ContactsList[]) getLastNonConfigurationInstance();
// planets = new Planet[10];
// planets.Add("asdf");
ArrayList<ContactsList> planetList = new ArrayList<ContactsList>();
String phoneNumber = null;
String phoneType = null;
count = cur.getCount();
contacts = new ContactsList[count];
if (planets == null)
{
if (cur.getCount() > 0)
{
planets = new ContactsList[cur.getCount()];
int i = 0;
//
while (cur.moveToNext())
{
String id = cur.getString(cur
.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur
.getString(cur
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer
.parseInt(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
// Query phone here. Covered next
Cursor pCur = cr
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?", new String[]
{ id }, null);
// WHILE WE HAVE CURSOR GET THE PHONE NUMERS
while (pCur.moveToNext())
{
// Do something with phones
phoneNumber = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA));
phoneType = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
Log.i("Pratik", name + "'s PHONE :" + phoneNumber);
Log.i("Pratik", "PHONE TYPE :" + phoneType);
}
pCur.close();
}
planets = new ContactsList[]
{ new ContactsList(name, phoneNumber) };
contacts[i] = planets[0];
planetList.addAll(Arrays.asList(planets));
i++;
}
}
this code retrieve all the contacts and put the into a list. but i want unique contacts and only that which have phone no. how can i do this?? is there any method to pass some argument in query to select unique contacts only???
I think you mean you got duplicate record for some contacts. So you must add condition for your query. The essential part is contacts must be in visible group and have phone number.
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '"
+ ("1") + "'";
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";
cur = context.getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, projection, selection
+ " AND " + ContactsContract.Contacts.HAS_PHONE_NUMBER
+ "=1", null, sortOrder);// this query only return contacts which had phone number and not duplicated
Update 20/05/2020
suspend fun fetchContacts(): ArrayList<FriendItem> {
val list = ArrayList<FriendItem>()
val uri: Uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
val selection = ContactsContract.Contacts.HAS_PHONE_NUMBER
val cursor: Cursor? = context.contentResolver.query(
uri,
arrayOf(
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.Contacts._ID
),
selection,
null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"
)
cursor?.let {
val nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)
val phoneIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
while (cursor.moveToNext()) {
val info = FriendItem(
friendName = cursor.getString(nameIndex),
friendPhoneNumber = cursor.getString(phoneIndex)
)
list.add(info)
}
cursor.close()
}
return list
}
This is working for me to get contact with phone number. Here we are querying Data table, and using CONTACT_ID contact provider documentation
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
final String ORDER_BY = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " ASC";
final String[] PROJECTION = {
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
return new CursorLoader(
context,
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
PROJECTION,
null,
null,
ORDER_BY
);
}
easy way to get phonenumbers and contact names
// set as global
Set<string> phonenumbersList = new HashSet<string>();
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//contact has name number and phonenumber does not exists in list
if ( phoneNumber != null && name != null && !phonenumbersList.contains(phoneNumber)){
planets = new ContactsList[]{ new ContactsList(name, phoneNumber) };
phonenumbersList.add(phoneNumber);
planetList.addAll(Arrays.asList(planets));
planetList.Add(phoneNumber, name);
}
}
phones.close();
I want to have my application which gets values from contact book from Android Phone.
I have tried People, ContactContracts.Data, ContactContracts.Contact.Data and
ContactsContract.CommonDataKinds to read value of NOTE value from Phone book.
But Can't get successed .Please help me.
Use below Code for Get Note Value from Contacts.
Cursor cursor = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
cursor.moveToFirst();
for (int i=0; i<cursor.getCount(); i++){
System.out.println("Hello");
String contactId = cursor.getString(
cursor.getColumnIndex(ContactsContract.Contacts._ID));
String note = null;
String[] columns = new String[] { ContactsContract.CommonDataKinds.Note.NOTE };
String where = ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " +
ContactsContract.Data.MIMETYPE + " = ?";
String[] whereParameters = new String[] {
contactId, ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE };
Cursor contacts = getContentResolver().query(
ContactsContract.Data.CONTENT_URI, columns, where,
whereParameters, null);
if (contacts.moveToFirst()) {
String rv = contacts.getString(0);
note = rv;
} else{
String rv = contacts.getString(i);
note = rv;
}
contacts.close();
System.out.println("Note is: " + note);
cursor.moveToNext();
}
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();
}