Fast reading contacts android - android

Is there a faster method for reading contacts in android? For example my method with cursor take 3-5 seconds for reading 30-50 contacts. It's very long.
Cursor cursor = managedQuery(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (cursor.moveToNext())
{
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if ( hasPhone.equalsIgnoreCase("1"))
hasPhone = "true";
else
hasPhone = "false" ;
if (Boolean.parseBoolean(hasPhone))
{
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,null, null);
while (phones.moveToNext())
{
names.add(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)));
numbers.add(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
}
phones.close();
}
}
Any ideas?

your question is interesting....
reading a fast contacts because it take time to read contacts data from ContactsContract..
i don't know about another way then the one you use, but still u can increase the performance by providing a String[] projection parameter to managedQuery...
fetch only those data which u require from contactsContract, because by providing null value it fetches all the columns of the record.

Sorry for my bad english. I have created the similar but with different style using HashMap. I will paste my approach.
//Create a hashMap, Key => Raw Contact ID and value => Object of customClass
HashMap<Long, ContactStructure> mFinalHashMap = new HashMap<Long, ContactStructure>();
//Run IN query in data table. example
select mimetype_id, raw_contact_id, data1 to data14 from data where raw_contact_id IN (select _id from raw_contacts where deleted <> 1 and account_type = "phone" and account_name = "bla bla") and mimetype_id = (select _id from mimetypes where mimetype = "vnd.something.phone");
Now Create a class which will have all the data of contact.
while accessing the cursor.
while (cursor.moveToNext()) {
ContactStructure contactStructure = mFinalHashMap.get(rawContactID);
//It will return the previous instance of object, If we already put
if(rawContactStructure == null) {
contactStructure = ContactStructure.provideInstance();
}
//Now check for your required mimeType
case MIMETYPE_PHONE:
contactStructure.hasPhoneNo = true;
contactStructure.phoneNumbers.add(addDetail); //add the data1 .. to data14
break;
}
/*Demo class for saving the details*/
public class ContactMetaData {
static classContactStructure {
boolean hasPhoneNo;
List<List<String>> phoneNumbers;
public static ContactStructure provideInstance() {
contact.phoneNumbers = new ArrayList<List<String>>();
ContactStructure contact = new RawContactStructure();
return contact
}
}
use this approach, I tried with 3000 contacts with all the data, It was fast. coz its not easy to get all the contacts and their all data with in sec..

For reading contacts faster you need to use the concept of the projection
where you specify only columns which you need to fetch.
cursor.moveToFirst();
while (cursor.isAfterLast() == false) {
String contactNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
int phoneContactID = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID));
int contactID = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Log.d("con ", "name " + contactName + " " + " PhoeContactID " + phoneContactID + " ContactID " + contactID)
cursor.moveToNext();
}
This will help you to reduce the timing by 90% for complete tutorial i used this site http://www.blazin.in/2016/02/loading-contacts-fast-from-android.html

Related

How to fetch all contacts from local phonebook and google contacts together?

I am trying to fetch contacts from the phonebook in my Android application. But it fetches the contacts that are present only in the local phone storage. I need to fetch all the contacts including the ones synced to the device using various accounts like Google. That is currently not happening. I am using a RecyclerView to display the contacts fetched.
I have tried using https://github.com/mirrajabi/rx-contacts2 library for fetching asynchronously. But that doesn't include Google contacts as well. Then I tried using Android's built-in CotentResolver
Contact contact;
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
if (cursor != null) {
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
if (hasPhoneNumber > 0) {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contact = new Contact(Long.parseLong(id));
contact.setDisplayName(name);
Cursor phoneCursor = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id},
null);
if (phoneCursor != null) {
if (phoneCursor.moveToNext()) {
String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Set<String> phoneNumbers = new HashSet<>();
phoneNumbers.add(phoneNumber);
contact.setPhoneNumbers(phoneNumbers);
}
phoneCursor.close();
}
Cursor emailCursor = contentResolver.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{id}, null);
if (emailCursor != null) {
while (emailCursor.moveToNext()) {
String emailId = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
}
emailCursor.close();
}
listContacts.add(contact);
}
}
}
cursor.close();
}
Currently, I am trying to fetch the contacts synchronously and it hangs up the main thread. It would be really helpful if you could suggest some ways to do that asynchronously. When doing so I also require a trigger to know when the task is completed.
Your code should work on all contacts synced to the device, including Google contacts (assuming the Google account is installed, and the contacts sync is enabled).
However, your code has some bugs, and can be greatly improved, currently for a device with 500 contacts, you are doing ~1000 queries.
All the data you need is on a single table called Data so you can get everything in a single quick query, see here:
Map<Long, Contact> contacts = new HashMap<>();
String[] projection = {Data.CONTACT_ID, Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1};
String selection = Data.MIMETYPE + " IN ('" + Phone.CONTENT_ITEM_TYPE + "', '" + Email.CONTENT_ITEM_TYPE + "')";
Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);
while (cur.moveToNext()) {
long id = cur.getLong(0);
String name = cur.getString(1);
String mime = cur.getString(2); // email / phone
String data = cur.getString(3); // the actual info, e.g. +1-212-555-1234
// get the Contact class from the HashMap, or create a new one and add it to the Hash
Contact contact;
if (contacts.containsKey(id)) {
contact = contacts.get(id);
} else {
contact = new Contact(id);
contact.setDisplayName(name);
// start with empty Sets for phones and emails
contact.setPhoneNumbers(new HashSet<>());
contact.setEmails(new HashSet<>());
contacts.put(id, contact);
}
switch (mime) {
case Phone.CONTENT_ITEM_TYPE:
contact.getPhoneNumbers().add(data);
break;
case Email.CONTENT_ITEM_TYPE:
contact.getEmails().add(data);
break;
}
}
cur.close();
Notes:
I've changed your listContacts to a HashMap called contacts so we can quickly find an existing contact
I've added setEmails, getPhoneNumbers and getEmails to your Contact class

Retrieve Contact info from Android Contact Provider

I'm trying to retrieve data from the Contact provider but the data shows seems not query correctly. The code I use is just below:
mCursor = mContext.getContentResolver().query(
ContactsContract.Data.CONTENT_URI, null, null, null, null);
if(mCursor == null){
mListener.onRetrieveError();
return;
}
for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext()) {
String contact_f = mCursor.getString(mCursor
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
String contact_m = mCursor.getString(mCursor
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME));
String contact_l = mCursor.getString(mCursor
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
String phone_type = mCursor.getString(mCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
String email_type = mCursor.getString(mCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
Log.d(TAG, "|" + contact_l + ", " + contact_f + " " + contact_m + " | " + phone_type + " | " + email_type);
}
The Log shows for example :
Log: |LastName, FirstName | FirstName | FirstName
Log: |null, 3 null | 3 | 3
I was expecting :
Log: |LastName, FirstName MiddleName | PhoneType| EmailType
I want to be able to get the firstname, lastname, middle name, email type (home/work...) - and all email types listed and also the phone type.
The goal is to for example get for a contact his lastname, firstname middle name and also saying that we got is home and work phone or email
The result I got seems a mix.
Any ideas.
Regards
That's not how it works. The Data table contains one row per contact value field (phone number, email address, structured name ...). Each row has a mimetype value that tells you how to interpret the columns of that row.
For example, if the mimetype column has the value Phone.CONTENT_ITEM_TYPE you must use the Phone column mapping to access the data.
So if a contact has one phone number and one email address there are at least 3 rows for this contact in the Data table. One for the StructuredName (this one is required exactly once for each RawContact), one for the Phone number and one for the Email address.
Each row also has a RAW_CONTACT_ID that contains the row id of the RawContact the value belongs to.
When you query the Data table, you actually read from a view that joins the real Data table with the RawContacts table, so each row also contains the CONTACT_ID of the contact the row belongs to. That means if two rows have the same CONTACT_ID they belong to the same contact.
I hope that explains it. I don't really know what you're trying to achieve in the end, so I can't give any helpful code snippets.
Update
The key to this is to check the mimetype of each row before you decide how to interpret the values. Also you need to read the CONTACT_ID or RAW_CONTACT_ID to be able to aggregate the data correctly. If you order the result by CONTACT_ID you can assume that all rows belonging to a contact have been read when the CONTACT_ID value changes.
The (untested) code snippet below should point you to the right direction. The point is, you can not get all the data of a contact in a single row. You always need to read multiple rows and aggregate them in some way.
mCursor = mContext.getContentResolver().query(
ContactsContract.Data.CONTENT_URI, null, null, null, ContactsContract.Data.CONTACT_ID);
if(mCursor == null){
mListener.onRetrieveError();
return;
}
colIdxContactId = mCursor.getColumnIndex(ContactsContract.Data.CONTACT_ID);
colIdxMimetype = mCursor.getColumnIndex(ContactsContract.Data.MIMETYPE);
long lastContactId = -1L;
for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext())
// this is the contact Id the current row belongs to
long contactId = mCursor.getLong(colIdxContactId);
if (lastContactId != contactId) {
// the previous contact is complete, the following data belong to a new contact
// handle this case ...
lastContactId = contactId;
}
// the mimetype column tells us how to interpret the current row:
switch(mCursor.getString(colIdxMimetype)) {
case ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE: {
// this row is a structured name
String contact_f = mCursor.getString(mCursor
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
String contact_m = mCursor.getString(mCursor
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME));
String contact_l = mCursor.getString(mCursor
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
// store names somewhere ...
break;
}
case ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE: {
// this row represents a phone number
int phone_type = mCursor.getInt(mCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
// store phone_type somewhere ...
break;
}
case ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE: {
// this row represents an email address
int email_type = mCursor.getInt(mCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
// store email_type somewhere ...
break;
}
}
}
You can use this
public void getAllContacts(){
Cursor cursor = null;
ContactPerson contact;
try {
cursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
int nameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int phoneNumberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int emailAddressIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
cursor.moveToFirst();
do {
contact = new ContactPerson(cursor.getString(nameIdx),cursor.getString(phoneNumberIdx),cursor.getString(emailAddressIdx));
cpList.add(contact);
// Toast.makeText(getActivity(),cursor.getString(nameIdx)+" "+ cursor.getString(phoneNumberIdx),Toast.LENGTH_SHORT).show();
} while (cursor.moveToNext());
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getActivity(),e.getMessage(), Toast.LENGTH_LONG).show();
Log.d("Error",e.getMessage());
} finally {
if (cursor != null) {
cursor.close();
}
}
}
I think the URI you are using is wrong.
Try using ContactsContract.Contacts.CONTENT_URI instead of ContactsContract.Data.CONTENT_URI (this is what I use).

How to display numbers taken from contact and Have Uri

I am trying to create an app which selects the contact from the contacts and display the name and number on the screen. Till now I have created activity to select the contact and the activity is successfully returning the contacts. It is successful in showing the Contact name. Now I have problem in showing the numbers in it. There are variety of solutions and I want the simplest one. All of them goes through complex methods which is hard for me to understand. I am unable to find a simple function that can display the number like ContactsContract.Contacts.DISPLAY_NAME
Here is my code!
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_contact);
Intent viewContact = getIntent();
String tempViewContact = viewContact.getStringExtra(MainActivity.contactUri);
Uri contactUri = Uri.parse(tempViewContact);
Cursor cursor;
cursor = getContentResolver().query(contactUri,null,null,null,null);
cursor.moveToFirst();
int indexName = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
int indexID = cursor.getColumnIndex(ContactsContract.Contacts._ID);
//Shows Contact name
String contactName = cursor.getString(indexName);
contact_name = (TextView) findViewById(R.id.contact_name);
contact_name.setText(contactName);
contact_num = (TextView) findViewById(R.id.contact_number);
//Now what to do ????
}
Here is a small snippet on how to collect contacts from the device
// Getting Content Resolver to Access Contact Details
ContentResolver cr = c.getContentResolver();
// Getting Cursor
Cursor cur1 = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
// Checking CURSOR HAS DATA
if (cur1.getCount() > 0) {
// LOOPING THROUGH EVERY CONTACT
while (cur1.moveToNext()) {
// GETTING CONTACT ID
String id = cur1.getString(cur1
.getColumnIndex(ContactsContract.Contacts._ID));
// GETTING CONTACT NAME
String contactName = cur1
.getString(cur1
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String contactNumber = "";
// Ensuring number availablity
if (Integer
.parseInt(cur1.getString(cur1
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
// Phone numbers are stored in another table
// Cursor for Phone Numbers
Cursor pCur = cr
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?", new String[] { id },
null);
// Has Number in Cursor - CHECK + LOOP
while (pCur.moveToNext()) {
// Checking Number Count for A SINGLE
// CONTACT
if (pCur.getCount() > 1) {
contactNumber = contactNumber
+ ","
+ pCur.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
} else {
contactNumber = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
}
}
// LOGGING
Log.d("X", "ID:" + id + "\nName:" + contactName
+ "\nNumber:" + contactNumber);
Log.i("X", "--------------------------------");
include the below permission in the manifest
<uses-permission android:name="android.permission.READ_CONTACTS" />
If you want to show the name and the contact number in a list, then follow the below steps
1) Build a model class with two fields name and contact say ContactModel
2) Make a ContactModel List and add each model into the list.
3) Finally attach the data to the listView using a custom adapter.

Get contact name and family name from Android contacts

I'm building an app that needs to pick a contact from Android contacts. I do it and I use the following code in my app for retrieve name and family name form chosen contact (in onActivityResult).
Cursor namesc = getContentResolver().query( ContactsContract.Data.CONTENT_URI, null, ContactsContract.Data.CONTACT_ID + " = " + id,null, null);
if (namesc.moveToFirst()) {
String name = namesc.getString(namesc.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
String family = namesc.getString(namesc
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
String middle = namesc.getString(namesc
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME));
It works well in HTC phones and some other phones but in many of SE Xperia models and some Samsung devices it can't give me name and family and returns null. Can anybody help me?
Here is the code I use:
String structuredNameWhere = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
String[] structuredNameWhereParams = new String[]{id, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE};
cursor = resolver.query(ContactsContract.Data.CONTENT_URI, null, structuredNameWhere, structuredNameWhereParams, null);
if (cursor.moveToFirst())
{
String StructuredNameId = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName._ID));
String prefix = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.PREFIX));
String givenName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
String middleName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME));
String familyName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
String suffix = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.SUFFIX));
}
The only difference I really see is I added mime-type to the where parameters and I am retrieving data slightly differently.
Android Contacts has just been REBORN! Using the Contacts, Reborn API, the answer to the original question,
I use the following code in my app for retrieve name and family name form chosen contact... it can't give me name and family and returns null. Can anybody help me?
is the following...
In Java,
public void printContactFullName(Context context, Long contactId) {
Contacts contactsApi = ContactsFactory.create(context);
Contact contact = contactsApi
.query()
.include(Fields.Name.getAll())
.where(WhereKt.equalTo(Fields.Contact.Id, contactId))
.find()
.get(0);
// Assuming this contact only have 1 RawContact...
Name name = ContactDataKt.nameList(contact).get(0);
Log.d(
"Contact",
"Prefix: " + name.getPrefix() +
", Given name: " + name.getGivenName() +
", Middle name: " + name.getMiddleName() +
", Family name: " + name.getFamilyName() +
", Suffix: " + name.getSuffix()
);
}
In Kotlin,
fun printContactFullName(context: Context, contactId: Long) {
Contacts(context)
.query()
.include(Fields.Name.all)
.where(Fields.Contact.Id equalTo contactId)
.find()
.first().let { contact ->
// Assuming this contact only have 1 RawContact...
val name = contact.names().first()
Log.d(
"Contact",
"""
Prefix: ${name.prefix}
Given name: ${name.givenName}
Middle name: ${name.middleName}
Family name: ${name.familyName}
Suffix: ${name.suffix}
""".trimIndent()
)
}
}
Do keep in mind, however, that not all Contacts have to have proper names. Users can create contacts without a name. This is the behavior in the native Contacts app.
You can do a lot more than this using the Contacts, Reborn API. You can even build your own full-fledged Contacts application that can stand toe-to-toe with the one that comes with almost every copy of Android.
/* Return all contacts and show each contact data in android monitor console as debug info. */ private List<ContactDTO> getAllContacts() {
List<ContactDTO> ret = new ArrayList<ContactDTO>();
// Get all raw contacts id list.
List<Integer> rawContactsIdList = getRawContactsIdList();
int contactListSize = rawContactsIdList.size();
ContentResolver contentResolver = getContentResolver();
// Loop in the raw contacts list.
for(int i=0;i<contactListSize;i++)
{
// Get the raw contact id.
Integer rawContactId = rawContactsIdList.get(i);
Log.d(TAG_ANDROID_CONTACTS, "raw contact id : " + rawContactId.intValue());
// Data content uri (access data table. )
Uri dataContentUri = ContactsContract.Data.CONTENT_URI;
// Build query columns name array.
List<String> queryColumnList = new ArrayList<String>();
// ContactsContract.Data.CONTACT_ID = "contact_id";
queryColumnList.add(ContactsContract.Data.CONTACT_ID);
// ContactsContract.Data.MIMETYPE = "mimetype";
queryColumnList.add(ContactsContract.Data.MIMETYPE);
queryColumnList.add(ContactsContract.Data.DATA1);
queryColumnList.add(ContactsContract.Data.DATA2);
queryColumnList.add(ContactsContract.Data.DATA3);
queryColumnList.add(ContactsContract.Data.DATA4);
queryColumnList.add(ContactsContract.Data.DATA5);
queryColumnList.add(ContactsContract.Data.DATA6);
queryColumnList.add(ContactsContract.Data.DATA7);
queryColumnList.add(ContactsContract.Data.DATA8);
queryColumnList.add(ContactsContract.Data.DATA9);
queryColumnList.add(ContactsContract.Data.DATA10);
queryColumnList.add(ContactsContract.Data.DATA11);
queryColumnList.add(ContactsContract.Data.DATA12);
queryColumnList.add(ContactsContract.Data.DATA13);
queryColumnList.add(ContactsContract.Data.DATA14);
queryColumnList.add(ContactsContract.Data.DATA15);
// Translate column name list to array.
String queryColumnArr[] = queryColumnList.toArray(new String[queryColumnList.size()]);
// Build query condition string. Query rows by contact id.
StringBuffer whereClauseBuf = new StringBuffer();
whereClauseBuf.append(ContactsContract.Data.RAW_CONTACT_ID);
whereClauseBuf.append("=");
whereClauseBuf.append(rawContactId);
// Query data table and return related contact data.
Cursor cursor = contentResolver.query(dataContentUri, queryColumnArr, whereClauseBuf.toString(), null, null);
/* If this cursor return database table row data.
If do not check cursor.getCount() then it will throw error
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0.
*/
if(cursor!=null && cursor.getCount() > 0)
{
StringBuffer lineBuf = new StringBuffer();
cursor.moveToFirst();
lineBuf.append("Raw Contact Id : ");
lineBuf.append(rawContactId);
long contactId = cursor.getLong(cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID));
lineBuf.append(" , Contact Id : ");
lineBuf.append(contactId);
do{
// First get mimetype column value.
String mimeType = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
lineBuf.append(" \r\n , MimeType : ");
lineBuf.append(mimeType);
List<String> dataValueList = getColumnValueByMimetype(cursor, mimeType);
int dataValueListSize = dataValueList.size();
for(int j=0;j < dataValueListSize;j++)
{
String dataValue = dataValueList.get(j);
lineBuf.append(" , ");
lineBuf.append(dataValue);
}
}while(cursor.moveToNext());
Log.d(TAG_ANDROID_CONTACTS, lineBuf.toString());
}
Log.d(TAG_ANDROID_CONTACTS, "=========================================================================");
}
return ret; }

How to check if a particular CallerID is in Contact List?

I am trying to find out if the caller id is in the contacts list. So the code I am using for that:
ContentResolver resolver = this.service.getContentResolver();
String number = PhoneLookup.NUMBER;
String[] projections = { number };
String selectionClause = number + " = ?";
String[] selectionClauseArgs = { callerId };
Cursor people = resolver.query(
ContactsContract.Contacts.CONTENT_URI, projections,
selectionClause, selectionClauseArgs, null);
return people.getCount() > 0 ? true : false;
I am giving the filtering functionality to the ContentResolver itself instead of fetching everything, iterating over them and checking one by one.
But I receive the following error for something reason (There are many codes but they are working just fine, since they are just subscribing to the telephony events in order to receive caller id when some one is calling!")
08-28 19:20:05.903: E/AndroidRuntime(737): java.lang.IllegalArgumentException: Invalid column number
I don't what is invalid. I am using right column name which is PhoneLookup.NUMBER constant. A similar question was asked here before: How to read contacts on Android 2.0 which I followed.
There's no phone numbers in this table. You should query it from another place.
Here's fast scratch (I belive there's better way to do it):
boolean hasPhoneNumber = (people.getInt(people.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0);
if (hasPhoneNumber) {
String id = people.getString(people.getColumnIndex(ContactsContract.Contacts._ID));
String num = getNumber(id);
}
public String getNumber(String id) {
String number = null;
String name = null;
Cursor pCur = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { id }, null);
if (pCur.moveToFirst()) {
number = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
name = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
}
pCur.close();
return number;
}

Categories

Resources