I am working on a project where I need to list down all the contacts. I am following this article.
My AndroidManifest.xml contains below, so i can read the contacts:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
Code is here:
private void getContacts() {
try {
// Form an array specifying which columns to return.
String[] projection = new String[] {
People._ID,
People._COUNT,
People.NAME,
People.NUMBER};
// Get the base URI for the People table in the Contacts content provider.
Uri contacts = People.CONTENT_URI;
// Make the query.
Cursor managedCursor = managedQuery(contacts,
projection, // Which columns to return
null, // Which rows to return (all rows)
null, // Selection arguments (none)
// Put the results in ascending order by name
People.NAME + " ASC");
printContacts(managedCursor);
}
catch(Exception ex) {
Log.d("Contacts",ex.toString());
}
}
private void printContacts(Cursor cur){
if (cur.moveToFirst()) {
String name;
String phoneNumber;
int nameColumn = cur.getColumnIndex(People.NAME);
int phoneColumn = cur.getColumnIndex(People.NUMBER);
String imagePath;
do {
// Get the field values
name = cur.getString(nameColumn);
phoneNumber = cur.getString(phoneColumn);
Log.d("Contacts","Name: "+ name + " **** Phone: "+ phoneNumber);
} while (cur.moveToNext());
}
}
When I run it on the Emulator(2.3.3) it throws below error:
java.lang.IllegalArgumentException: Invalid column _count
Can someone fix it?
Great thanks for your valuable time & help.
If you remove the string People._COUNT everything works
See also: Android SDK - List All Users
Android People class is deprecated. You should use ContactsContract instead.
Since you run it on Emulator API level 10, and the class is deprecated since API level 5, there's no reason to keep using People.
Related
I am very new to app development. I am trying to read contact info without having to request permission to contacts (so I am using intents).
I get a URI with the following code in my main activity:
Intent selectContactIntent = new Intent(Intent.ACTION_PICK);
selectContactIntent.setType(ContactsContract.Contacts.CONTENT_TYPE);
if (selectContactIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(selectContactIntent, REQUEST_CODE_SELECT_CONTACT);
}
else {
showContactRequiredMessage(view);
}
In another (sub)activity, I do the following:
contactUri = intent.getParcelableExtra(MainActivity.CONTACT_URI);
String[] projection = new String[] {
ContactsContract.Contacts.Data._ID,
ContactsContract.Contacts.Data.MIMETYPE,
ContactsContract.Contacts.Data.DATA1,
ContactsContract.Contacts.Data.DATA2,
ContactsContract.Contacts.Data.DATA3,
ContactsContract.Contacts.Data.DATA4,
ContactsContract.Contacts.Data.DATA5,
ContactsContract.Contacts.Data.DATA6,
ContactsContract.Contacts.Data.DATA7,
ContactsContract.Contacts.Data.DATA8,
ContactsContract.Contacts.Data.DATA9,
ContactsContract.Contacts.Data.DATA10,
ContactsContract.Contacts.Data.DATA11,
ContactsContract.Contacts.Data.DATA12,
ContactsContract.Contacts.Data.DATA13,
ContactsContract.Contacts.Data.DATA14,
ContactsContract.Contacts.Data.DATA15
};
Cursor contactResults = getContentResolver().query(contactUri, projection, null, null, null);
The last line throws the exception java.lang.IllegalArgumentException: Invalid column <any column after _ID>
My app doesn't require all of the data in reality I just want to see what is available, I will most likely need first name, last name, phone, and email.
My issue is the MIME type that I set on the intent when I request the contact info. The documentation states ContactsContract.Contacts.CONTENT_TYPE should be used. However, if I use, something like ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE, I can get display name and phone number. I am not sure if this means I will need to make multiple queries to get everything (the information shown in the contact picker changes when changing the type requested).
TL;DR: Used the "wrong" content type when creating the intent to select a contact.
As mentioned in my comment to your answer, you should be able to get the information expected without using a specific CONTENT_TYPE like CommonDataKinds.Phone.CONTENT_TYPE.
The problem I see in your code is that you're trying to access Data table info from a Contacts table uri.
The ContactsContract api stored info on 3 main tables: Contacts, RawContacts and Data.
You were given a contactUri which points to an entry in the Contacts table, use the following code to read Data entries related to that contact:
long contactId = ContentUris.parseId(contactUri);
String projection = String[] { Data.MIMETYPE, Data.DISPLAY_NAME, Data.DATA1 };
String selection = Data.CONTACT_ID + " = " + contactId;
Cursor cursor = getContentResolver().query(Data.CONTENT_URI, projection, selection, null, null);
while (cursor != null && cursor.moveToNext()) {
String mime = cursor.getString(0);
String name = cursor.getString(1);
String info = cursor.getString(2);
if (mime.equals(CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
Log.d(TAG, name + ": email = " + info;
}
if (mime.equals(CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
Log.d(TAG, name + ": phone = " + info;
}
// Add more mimetypes here if needed...
}
if (cursor != null) {
cursor.close();
}
I'm new to android and i'm working with native contact.
So my app is let user put contact display name and their number for edit/delete.
In case the contact have more that one number.
I tried a lot but still have no luck, the app still doesn't update the number or it crashes.
What I'm going to do as my understanding is:
Find name in contact that matched name user inserted and use that to get contact_id that represent this contact datagroup.
Use contact_id in 1. and the number user input to find ._ID that represent the specific row id.
Do task with ._ID we get from 2.
This is 1. code to get contact_id:
public String getPeopleUniqueID(String name, Context context) {
String s = null;
String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" like'%" + name +"%'";
String[] projection = new String[] {ContactsContract.Data.CONTACT_ID};
Cursor c = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, selection, null, null);
if(c.moveToFirst()) {
s = c.getString(c.getColumnIndex(ContactsContract.Data.CONTACT_ID));
}
c.close();
return s;
}
This is 2. code to get ._ID (num is number user inserted and name is from 1. > the contact_id)
public String checkPhoneNumber(String num, String name, Context context) {
String s = null;
String selection = ContactsContract.CommonDataKinds.Phone.NUMBER + "=?" + " AND "+ContactsContract.Data.CONTACT_ID+ "=?";
String[] projection = new String[] {ContactsContract.Data._ID};
Cursor c = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, selection, new String[]{u,name}, null);
if(c.moveToFirst()) {
s=c.getString(c.getColumnIndex(ContactsContract.Data._ID));
}
c.close();
if (s==null){
s = "null";
}
return s;
}
To do something like editing (num is _.ID we get from 2. and newnum is new number user want to change into).
public void editNumber(String num , String newnum) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
.withSelection(Data._ID + "=? AND " +
Data.MIMETYPE + "='" +
CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'",
new String[]{num})
.withValue(Data.DATA1, newnum)
.build());
try{
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);}
catch (RemoteException e){e.printStackTrace();}catch (OperationApplicationException e) {e.printStackTrace();}
}
And well it crashes when I call editNumber().
Can you help me fix my code and my understanding?
And another question, can I edit/insert group for the contact programatically, like I want to add this contact to family friend or co-worker group (the default group that we can set at contact edit page)?
Use ContactsContract.Contacts.CONTENT_FILTER_URI for searching a contact based on name - to get Id or anything else. The like operator cannot handle all cases which the CONTENT_FILTER_URI does handle - For various languages, special characters etc.
http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html#CONTENT_FILTER_URI
Use following uri to lookup a contact from phone number - you can get person id or anything else :
Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(phoneNumber));
In the set query you can also use contactId in the condition
For groups you can use custom mimetypes if the default one does not suit you (which is still very primitive for groups across different account types)
I want to get contact number via contact name I am creating android app in which user just enter contact-name and it automatically fetch the number from contact-list
For example I have 2 text-box contact-name and contact-number when I enter name in contact-name it automatically match name in contact list if match found display its number in contact-number....
how I can do it in ANDROID please help me.
Take name as input in EditText1 and call getb(name,MainActivity.this) on click event. you will get your answer. In android manifest.xml file. add
<uses-permission android:name="android.permission.READ_CONTACTS" />
enter code here
public String getb(String name, Context context) {
String ret = null;
String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" like'%" + name +"%'";
String[] projection = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor c = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, selection, null, null);
if (c.moveToFirst()) {
ret = c.getString(0);
editText2.setText(""+ret);
}
c.close();
if(ret==null)
ret = "Unsaved";
return ret;
}
}
Maybe this helps: Contacts-Provider
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;
}
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.