Error when read Android contacts - android

I've gotten this snippet from StackOverflow:
Cursor people = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
try{
while (people.moveToNext()) {
int nameFieldColumnIndex = people
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
String contact = people.getString(nameFieldColumnIndex);
int numberFieldColumnIndex = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String number = people.getString(numberFieldColumnIndex);
System.out.println(contact + "-" + number);
}
}catch(Exception e){
System.out.println(e);
}
people.close();
When I try to read phoneNum column I get an error using String number = people.getString(numberFieldColumnIndex). Checking the column index I find that numberFiledColomnIndex = -1.
How can I get this snippet working?

Per the documentation, getColumnIndex() returns -1 when the column doesn't exist.
Q: Are you passing the correct column name? Is the spelling correct?

Related

Android. Retrieve first name and last name from contact book by phone number

I am trying to get first name and last name in contact book by phone number.
Here is my code:
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = cResolver.query(uri, null, null, null, null);
if(cursor != null && cursor.moveToFirst()) {
int idColumnIndex = cursor.getColumnIndex(ContactsContract.Contacts._ID);
int firstNameIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
int lastNameIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
while (!cursor.isAfterLast()) {
long id = cursor.getLong(idColumnIndex);
contact = new MyContact();
contact.setId(id);
contact.setFirstName(cursor.getString(firstNameIndex));
contact.setLastName(cursor.getString(lastNameIndex));
}
cursor.close();
}
But firstNameIndex and lastNameIndex is always -1. What I am doing wrong ? Please help me.
PhoneLookup is a nice and quick way to get contact data by a phone number, but it returns a cursor limited to the columns mentioned in the docs.
You can see there's DISPLAY_NAME you can access, but not GIVEN_NAME, FAMILY_NAME.
GIVEN_NAME & FAMILY_NAME are fields stored in the Data table, which means you need to query that table separately to get to those fields.
So, you can just add another query using the contact ID you got from PhoneLookup (note that for each looked up phone there might be multiple contacts returned).
Here's a sample method to get first/last names from contact ID:
private void addNames(MyContact contact, long contactId) {
String[] projection = new String[] {StructuredName.GIVEN_NAME, StructuredName.FAMILY_NAME};
// filter to just StructuredName rows from the data table for the given contact
String selection = Data.CONTACT_ID + "=" + contactID + " AND " + Data.MIMETYPE + "=" + StructuredName.CONTENT_ITEM_TYPE;
Cursor cursor = getContentResolver().query(Data.CONTENT_URI, projection, selection, null, null);
if (cursor.next()) {
contact.setFirstName(cursor.getString(0));
contact.setLastName(cursor.getString(1));
}
cursor.close();
}

How to identify a local phone contact and an SYNC phone contact in android?

Can anybody guide me to find the solution for the following problem.
I have to identify whether the phone contact saved in locally or from Email ?(programatically)
i have read fromgoogle doc that ContactsContract.Groups, which contains information about raw contact groups such as Gmail contact groups. The current API does not support the notion of groups spanning multiple accounts.
Based on that i have tried the following code.
StringBuffer output = new StringBuffer();
final String[] GROUP_PROJECTION = new String[] {
ContactsContract.Groups._ID,
ContactsContract.Groups.TITLE,
ContactsContract.Groups.SUMMARY_WITH_PHONES
};
Cursor c = getContentResolver().query(
ContactsContract.Groups.CONTENT_URI, GROUP_PROJECTION, null,
null, ContactsContract.Groups.TITLE);
int IDX_ID = c.getColumnIndex(ContactsContract.Groups._ID);
int IDX_TITLE = c.getColumnIndex(ContactsContract.Groups.TITLE);
output.append("title"+IDX_TITLE+"\n");
Map<String,GroupInfo> m = new HashMap<String, GroupInfo>();
while (c.moveToNext()) {
output.append("test...\n");
GroupInfo g = new GroupInfo();
g.id = c.getString(IDX_ID);
g.title = c.getString(IDX_TITLE);
output.append("title"+c.getString(IDX_TITLE)+"\n");
int users = c.getInt(c.getColumnIndex(ContactsContract.Groups.SUMMARY_WITH_PHONES));
if (users>0) {
// group with duplicate name?
GroupInfo g2 = m.get(g.title);
if (g2==null) {
m.put(g.title, g);
output.append("title"+g.title+"\n");
groups.add(g);
} else {
g2.id+=","+g.id;
}
}
}
outputText.setText(output);
c.close();
but no hope.
I am posting this answer for future use. We can differentiate the local phone contacts and the sync contacts by using the field called RawContacts.SOURCE_ID
It is described here
SOURCE_ID
read/write
String that uniquely identifies this row to its source account. Typically it is set at the time the raw contact is inserted and never changed afterwards. The one notable exception is a new raw contact: it will have an account name and type (and possibly a data set), but no source id. This indicates to the sync adapter that a new contact needs to be created server-side and its ID stored in the corresponding SOURCE_ID field on the phone.
The sample code is follows, it gives the id for sync contacts and null for others.
private void testContact() {
StringBuffer output = new StringBuffer();
ContentResolver resolver = getContentResolver();
Cursor contacts = resolver.query(Contacts.CONTENT_URI, null,
Contacts.HAS_PHONE_NUMBER + " != 0", null, Contacts._ID
+ " ASC");
Cursor data = resolver.query(Data.CONTENT_URI, null, Data.MIMETYPE
+ "=? OR " + Data.MIMETYPE + "=?", new String[]{
Email.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE},
Data.CONTACT_ID + " ASC");
int idIndex = contacts.getColumnIndexOrThrow(Contacts._ID);
int nameIndex = contacts.getColumnIndexOrThrow(Contacts.DISPLAY_NAME);
int cidIndex = data.getColumnIndexOrThrow(Data.CONTACT_ID);
int data1Index = data.getColumnIndexOrThrow(Data.DATA1);
boolean hasData = data.moveToNext();
while (contacts.moveToNext()) {
long id = contacts.getLong(idIndex);
Uri rawContactUri =
ContentUris.withAppendedId(RawContacts.CONTENT_URI, id);
Uri entityUri =
Uri.withAppendedPath(rawContactUri, Entity.CONTENT_DIRECTORY);
Cursor c =
getContentResolver().query(
entityUri,
new String[] {
RawContacts.ACCOUNT_NAME,
RawContacts.SOURCE_ID, Entity.DATA_ID, Entity.MIMETYPE, Entity.DATA1},
null, null, null);
try {
while (c.moveToNext()) {
String sourceId = c.getString(0);
if (!c.isNull(1)) {
String source_id = c.getString(1);
try {
output.append(c.getString(4)+sourceId+" "+source_id+"\n");
//output.append(datas+ "Sync1 "+ c.getString(4)+" Sync2 "+ c.getString(5)+" Sync3"+ c.getString(6)+" Sync4 "+ c.getString(7)+"\n");
} catch (Exception e) {
e.printStackTrace();
}
//decide here based on mimeType, see comment later
}
}
} finally {
c.close();
}
}
outputText.setText(output);
}
Have a read through this and see if ACCOUNT_TYPE might be able to help you

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;
}

How to get contact name details for a particular contact

I want the Name of the Contact which includes (FAMILY_NAME, GIVEN_NAME,MIDDLE_NAME,PHONETIC_FAMILY_NAME,PHONETIC_GIVEN_NAME,PHONETIC_MIDDLE_NAME,PREFIX,SUFFIX).
I know that column names of the above data that starts with
android.provider.ContactsContract.CommonDataKinds.StructuredName
But i am unable to get the URI of the data.
I was working on device with api level 8 so i want to fetch these details using
android.provider.ContactsContract
I have searched about this in commumnity but i can't get the desired result.
I am working for 4 hours on this.
Any help will be appreciated.
I was using this code
Cursor cursor = activity.managedQuery(android.provider.ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cursor != null)
{
if (cursor.moveToFirst())
{
int rows = cursor.getCount();
int cols = cursor.getColumnCount();
do
{
int _id = cursor.getInt(cursor.getColumnIndex("_id"));
int times_contacted = cursor.getInt(cursor.getColumnIndex("times_contacted"));
int has_phone_number = cursor.getInt(cursor.getColumnIndex("has_phone_number"));
int send_to_voicemail = cursor.getInt(cursor.getColumnIndex("send_to_voicemail"));
int starred = cursor.getInt(cursor.getColumnIndex("starred"));
// Here i want the contact names But i dont know what column name i have to pass to get them
}
while (cursor.moveToNext());
}
cursor.close();
}
Thanks in advance.
Ok, Try this, and let me know what happen,
Look at ContactsContract.CommonDataKinds.StructuredName class. You can find there all columns you are looking for.
String whereName = ContactsContract.Data.MIMETYPE + " = ?";
String[] whereNameParams = new String[] { ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE };
Cursor nameCur = contentResolver.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));
}
nameCur.close();
Look at this SO question How to get the firstname and lastname from android contacts?
EDIT: Look at this complete example for working with android contacts Working With Android Contacts, Now if you want to get more info from any contacts then add a particular column on that cursor. For more columns look at ContactsContract.CommonDataKinds.

Getting random contact numbers in Android

I'm trying to use the following code to grab a random mobile phone number from the contacts:
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, "DISPLAY_NAME = '" + "NAME" + "'", null, null);
cursor.moveToFirst();
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phones = cr.query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + " = " + contactId, null, null);
List numbers = new ArrayList();
while (phones.moveToNext()) {
String number = phones.getString(phones.getColumnIndex(Phone.NUMBER));
int type = phones.getInt(phones.getColumnIndex(Phone.TYPE));
switch (type) {
case Phone.TYPE_MOBILE:
numbers.add(number);
break;
}
}
Random randGen = new Random();
return (String) numbers.get(randGen.nextInt(numbers.size()));
However, running this code produces a crash on line 4, with a message saying "CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0". The crash seems to be caused by the cursor.getString() method. Does anyone know where I'm going wrong? This is using the ContactsContract in Android 2.1. Eclipse gives no errors.
Thanks!
The moveToFirst() method returns a boolean. It returns true if it was able to move to the first row and false otherwise, indicating that the query returned an empty set.
When using a cursor, you should follow something like:
if (cursor.moveToFirst()) {
do {
// do some stuff
} while (cursor.moveToNext());
}
cursor.close();

Categories

Resources