Adding contacts to a ListView - android

Alright so I'm just learning how to work with contacts and such. I would like to have my contacts listed out in a ListView, with custom adapter (I think thats what it is called, where I can have ImageViews, TextViews, all that such, in one ListView entry). How would I be able to do that with the following code that I have?
Cursor cursor = getContentResolver().query(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 (Boolean.parseBoolean(hasPhone)) {
// You know have the number so now query it like this
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
phones.close();
}
}
cursor.close();

Check out ContactManager samplecode. It explains exactly how to do what you are looking for:
http://developer.android.com/resources/samples/ContactManager/index.html

Related

Show only a certain number of contacts

I have developed a program that shows a list of contacts from my phone book.
For this I use the following code:
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,
null,
ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '1'",
null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(id));
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id,
null,
null);
if (phones != null) {
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contactList.add(new Contact(name, phoneNumber, id));
}
phones.close();
}
}
cursor.close();
}
adapter = new ContactAdapter(contactList, R.layout.contacts_list_item, getApplicationContext());
recyclerView.setAdapter(adapter);
Everything works, and the program displays all contacts from my phone book, but I want a certain number of contacts to be displayed. For example:
I open the program and load the first 50 contacts from the phone book, after scrolling, the next 50 contacts are loaded to the end of the list. and so on
Use below code that has limit cause. Replace your code with below
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,
null,
ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '1' ",
null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC LIMIT 10");
It will get first 10 records. And in pull to refresh implementation, get more records on call back event of pull to refresh. Hope this will help you
I assume the reason you want this is because loading all contacts is very slow.
The reason it's very slow is because you currently have 1 query per contact, so if a user has 500 contacts, you'll need to run 500 queries.
You can reduce the number of queries to just one, then I assume you won't need the limit thing.
String[] projection = { Phone.CONTACT_ID, Phone.DISPLAY_NAME, Phone.NUMBER };
Cursor phones = getContentResolver().query(Phone.CONTENT_URI, projection, null, null, Phone.DISPLAY_NAME + " ASC");
while (phones.moveToNext()) {
String name = phones.getString(1);
String phone = phones.getString(2);
Long id = phones.getLong(0);
contactList.add(new Contact(name, phone, id));
}
phones.close();
If you want to display only one item per contact, and not per phone, you can change your contactList field to be a HashMap<Long, Contact> instead of a List, and add newly found phones to an existing Contact object if it already exists in the Map.
Something like:
Contact contact = allContacts.get(id);
if (contact == null) {
contact = new Contact(name, phone, id);
allContacts.put(id, contact);
} else {
contact.addPhone(phone); // you'll need to implement this
}

Wrong reference to Contacts table from sms inbox

I am trying to find the contact details corresponding to an sms from the phone's sms inbox. From my understanding the person column is a foreign key to the _id column of ContactsContract.Contacts.
My problem is that I am getting wrong values for the person value from the sms query. Some person ids don't exist in the contact table and some are pointing to totally different contact.
Below is the code that I use for fetching the list of person values, Can anyone tell me if I missed something or faced a similar problem.
Tested with Nexus S running Android 4.1.2
Uri parsedUri = Uri.parse("content://sms/inbox");
String[] projection = new String[] { "_id", "address", "person" };
Cursor cursor = contentResolver.query(parsedUri, projection, null, null, null);
Log.d(TAG, "Total Count " + cursor.getCount());
if (cursor.getCount() > 0) {
// String address;
int person;
int personIndex = cursor.getColumnIndex("person");
if (cursor.moveToFirst())
do {
person = cursor.getInt(personIndex);
if (person > 0) {
// Add this id to a list
}
} while (cursor.moveToNext());
}
cursor.close();
Update: I was looking at some documentation from the Android Developer Portal (http://developer.android.com/guide/topics/providers/contacts-provider.html), Is it possible that the person id that is retrieved from the sms inbox is referring to the ContactsContract.RawContacts instead of ContactsContract.Contacts as I have done.
Indeed the person column in the sms inbox refers to a RawContacts entry's id. By querying the RawContacts table you can find the contact_id for the Contacts table for the specific user.
You can try this code to get the contact id from the RawContacts table..
long contactId = 0;
Uri uri = ContactsContract.RawContacts.CONTENT_URI;
String[] projection = new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.CONTACT_ID };
Cursor cursor = contentResolver.query(uri, projection,
ContactsContract.RawContacts._ID + " = ?",
new String[] { rawContactId }, null);
if (cursor.moveToFirst()) {
int contactIdIndex = cursor.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID);
contactId = cursor.getLong(contactIdIndex);
}
cursor.close();
This should solve your problem for fetching the correct contact details by reading an sms row in Android. However as the sms data provider is not documented and phone manufacturers may use them differently, there is chance that this approach may not work on phones other than pure android.
You first check that person number is exits in contact list or not.if yes then match both id.
Cursor cursor=managedQuery(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 (Boolean.parseBoolean(hasPhone)) {
// You know have the number so now query it like this
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,
null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(
phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
phones.close();
}
}

Get all phone numbers from contacts

I use the following code to retrieve all phone number from contacts.
Cursor c = context.getContentResolver().query(
Data.CONTENT_URI,
new String[] { Phone.NUMBER },
Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE
+ "'", null, null);
It works perfectly in my Android phone.
But some users say my app doesn't get all phone numbers from contacts and just part of them. I can't figure out the reason.. why?
This will get the cursor holding base contact data, and will loop through the phone numbers the contact has, can have multiple.
Uri uri = data.getData();
Cursor cursor=ctx.getContentResolver().query(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 (Boolean.parseBoolean(hasPhone)) {
// You know have the number so now query it like this
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,
null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(
phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
phones.close();
}
}

how to get android contact list data on my seperate listview in android 2.1?

i have created one listview.now i want to show data(contact no.,name) from contactlist of android(Phonebook) on my listview.
i got it for android 1.5 but i want to do it for android2.1updated.
How to do it?can any one guide me or give some sample code?
Thanks in advance---
If you have achieved it in 1.5 then there can be a small difference of URI. You should go for updated/changed URI of Contacts in 2.1. For further understanding here is a sample code for 2.1updated:
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (cur.moveToNext())
{
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
//---------------------------------------- Contact Names
//------------------------------------------------------
String DisplayName = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Cursor names = cr.query(ContactsContract.Data.CONTENT_URI, null,ContactsContract.Data.CONTACT_ID + " = " + id, null, null);
names.moveToNext();
String GivenName = names.getString(names.getColumnIndex(ContactsContract.Data.DATA2));
String FamilyName = names.getString(names.getColumnIndex(ContactsContract.Data.DATA3));
String MiddleName = names.getString(names.getColumnIndex(ContactsContract.Data.DATA5));
names.close();
//----------------------------------------- Phone Numbers
//-------------------------------------------------------
String hasPhoneNumber = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if (hasPhoneNumber.equals("1"))
{
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id,null, null);
while (phones.moveToNext())
{
......
}
}
} // AND SO ON.... Get which ever data you need.
so above is just a sample code that I used for my task. You can get what you need by making changes accordingly. I hope it helps.
This will help you getting contacts.
Cursor contactList = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null,null, null);
For getting phone number of a particular contact,you need to use:
String id = contactList.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phoneCursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER},
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
new String[]{id}, null);

Android get contacts name and number query

I'm trying to retrieve both the display names and the phone numbers of all my contacts but I want it to return only the rows that have a number.
Currently I have it like this and it works:
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,null, null, ContactsContract.Contacts.DISPLAY_NAME+ " COLLATE NOCASE");
while (cur.moveToNext())
{
if ( Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contacts[index] = name;
Cursor pCur = cr.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null);
pCur.moveToFirst();
numbers[index] = pCur.getString( pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
index++;
pCur.close();
}
The thing is that it takes something like 4-5 seconds to load as it is running the cr.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null); like 400 times.
Now my understanding is that the name and number of a contact are held in different tables and you need the id of the name in order to get the number.
Can this be done in any other way faster?
Thanks in advance
#mixkat
I have figured out one more solution.
It is possible to get Name and Phone data using just one query.
Here is the code:
String WHERE_CONDITION = ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'";
String[] PROJECTION = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.Data.DATA1};
String SORT_ORDER = ContactsContract.Data.DISPLAY_NAME;
Cursor cur = context.getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
PROJECTION,
WHERE_CONDITION,
null,
SORT_ORDER);
In this case you query not Contact provider but Data provider directly.
I have the same problem. I resolved it by saving contacts in db first time user open app. And than I update data (it is up to you when app should update contacts).
So application uses contacts from my db table where name and number are in one row. It takes much less time.

Categories

Resources