i'm doing some tests to figure out how the provider works with events etc.
I'm trying to get all contacts of specific accounts, then read details of each contact to get the birthday if present.
I firstly tried to do it in 1 go but I didn't have enough knowledge of the provider so I'm trying to do it in 2 steps for know just to see if I can get to it.
I get Invalid column on this line:
Cursor cursor = cr.query(uri, projection, [...]
The contact_id is the problem here. How can I improve the second query to get the data I want? I tried various mods on the code getting nowhere.
Thanks.
The code I use:
private void readContacts(){
Cursor contByAccCursor = getContactsByAccounts();
getContactsBirthdays(contByAccCursor);
}
private Cursor getContactsByAccounts() {
Uri uri = ContactsContract.RawContacts.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.RawContacts.CONTACT_ID,
ContactsContract.RawContacts.ACCOUNT_TYPE
};
String where = ContactsContract.RawContacts.ACCOUNT_TYPE + " IN ('com.google', 'vnd.sec.contact.phone', 'com.skype.contacts.sync')";
return activity.getContentResolver().query(uri,
projection,
where,
null,
null);
}
private void getContactsBirthdays(Cursor filteredContacts) {
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] {
//ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.CommonDataKinds.Event.CONTACT_ID,
ContactsContract.CommonDataKinds.Event.START_DATE
};
String where =
ContactsContract.Data.MIMETYPE + "= ? AND " +
ContactsContract.CommonDataKinds.Event.TYPE + "=" +
ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY + " AND " +
ContactsContract.CommonDataKinds.Event.CONTACT_ID + "= ?";
String[] selectionArgs;
String sortOrder = null;
StringBuffer sb = new StringBuffer();
ContentResolver cr = activity.getContentResolver();
int accTypeCol = filteredContacts.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE);
while(filteredContacts.moveToNext()){
selectionArgs = new String[] {
ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE,
filteredContacts.getString(filteredContacts.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID))
};
Cursor cursor = cr.query(uri,
projection,
where,
selectionArgs,
sortOrder);
if(cursor.moveToNext()){
String dName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY));
String bDay = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE));
String accType = filteredContacts.getString(accTypeCol);
sb.append(dName + "("+accType+")" + " - " + bDay);
sb.append("\n");
}
}
Log.d(TAG, sb.toString());
}
Ok I feel so stupid now. The error is the second content_uri, I was getting the wrong one, must be tired...
This is the correct uri to get the right data:
private void getContactsBirthdays(Cursor filteredContacts) {
Uri uri = ContactsContract.Data.CONTENT_URI;
Related
I try to implement a live search over the users contacts, and I want to get the name, thumbnail and address (if there is one) of each matching contact.
The live search is running while the user is typing.
So he types ma and will get 'martin', 'matthews'...
He'll continue with mat and will only see 'matthews'
I try to achieve this with a single query like the following, but I always get the contact number in the FORMATTED_ADRESS field. I guess I have a JOIN problem, because I'm using ContactsContract.CommonDataKinds and ContactsContract.Contacts in the same query?
public static List<ContactModel> getContactsForQuery(Context context, String query) {
String[] projection = new String[] {
ContactsContract.Contacts.DISPLAY_NAME,
Contacts.PHOTO_THUMBNAIL_URI,
ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS
};
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String selection = ContactsContract.Contacts.DISPLAY_NAME + " LIKE '%" + query + "%'";
Cursor cursor = context.getContentResolver().query(uri, projection, selection, null,null);
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(0);
String thumbail = cursor.getString(1);
String formattedADress = cursor.getString(2);
}
while (cursor.moveToNext());
}
I actually solved my issue, with
querying for Contacts._ID, Contacts.DISPLAY_NAME
start a second query with the Contacts._ID like the following
Cursor detailCursor = context.getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[]{
CommonDataKinds.StructuredPostal.STREET,
CommonDataKinds.StructuredPostal.CITY,
CommonDataKinds.StructuredPostal.POSTCODE
},
ContactsContract.Data.CONTACT_ID + "=? AND "
+ CommonDataKinds.StructuredPostal.MIMETYPE + "=?",
new String[]{
String.valueOf(contactID),
CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE
},
null);
but this will start a second query for every contact, which might not be the best approach.
So my final question is: is it possible to get this work with the first query?
Mmmh, very sad, that no one was able to answer my question and grab the bounty points ;-(
For the record, here's my working example. It solves the issue but I still think it's producing a big overload. On every user entry (afterTextchange) I call the getContactsDetailsQuery which first gets all users with their ID containing the query in their name (cursor) and afterwards I start another query (detailCursor) for every user to get the adress. To prevent the overload, i added an limit..
public static List<SearchModel> getContactDetailsForQuery(Context context, String query, int limit) {
final int CONTACT_ID_INDEX = 0;
final int CONTACT_NAME_INDEX = 1;
final int CONTACT_THUMBNAIL_INDEX = 2;
//my custom model to hold my results
List<SearchModel> results = new ArrayList<SearchModel>();
final String[] selectUser = new String[]{
Contacts._ID,
Contacts.DISPLAY_NAME,
Contacts.PHOTO_THUMBNAIL_URI};
String selection = Contacts.DISPLAY_NAME + " LIKE ?";
String[] selectionArgs = new String[]{"%" + query + "%"};
String sortOrder = Contacts.DISPLAY_NAME + " ASC";
Cursor cursor = context.getContentResolver().query(Contacts.CONTENT_URI, selectUser, selection, selectionArgs, sortOrder, null);
int contactCounter = 0;
if (cursor != null && cursor.moveToFirst()) {
do {
String contactID = cursor.getString(CONTACT_ID_INDEX);
String displayName = cursor.getString(CONTACT_NAME_INDEX);
String thumbnail = cursor.getString(CONTACT_THUMBNAIL_INDEX);
//get user details with user id (this is the query i wanted to change in my question!!)
Cursor detailCursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
new String[]{
CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS},
ContactsContract.Data.CONTACT_ID + "=? AND " +
CommonDataKinds.StructuredPostal.MIMETYPE + "=?",
new String[]{String.valueOf(contactID), CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE},
null);
if (detailCursor != null && detailCursor.moveToFirst()) {
//special case: user has several address, query all of them
do {
String formattedAddress = detailCursor.getString(detailCursor.getColumnIndex(CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS));
//user has serveral adress -> init model for each adress
SearchModel contact = new SearchModel();
results.add(contact);
contactCounter++;
} while (detailCursor.moveToNext() && contactCounter < limit);
} else {
//user has no adress -> init model
SearchModel contact = new SearchModel();
results.add(contact);
contactCounter++;
}
detailCursor.close();
} while (cursor.moveToNext() && contactCounter < limit);
}
cursor.close();
return results;
}
I am able to fetch other information (Display name,organisation,phone no and email_id) of a contact, but not able to fetch birthday and anniversary of that contact.
Here is the code i am using for birthday. It does fetch the data, but gives me wrong data, i.e repeats the same data for all the contacts.
private String getBDate(String id) {
String bday = null;
ContentResolver cr = getContentResolver();
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Event.CONTACT_ID,
ContactsContract.CommonDataKinds.Event.START_DATE };
String where = ContactsContract.Data.MIMETYPE + "= ? AND "
+ ContactsContract.CommonDataKinds.Event.TYPE + "="
+ ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY;
String[] selectionArgs = new String[] { ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE };
String sortOrder = null;
Cursor cur = cr.query(uri, projection, where, selectionArgs, sortOrder);
while (cur.moveToNext()) {
bday = cur
.getString(cur
.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE));
Log.v("Birthday", bday);
}
cur.close();
return bday;
}
Same is the case with anniversary, here is the code for it. In some case anniversary is not added but it still shows the data from other contact.
private String getAnnv(String id) {
String annv = null;
ContentResolver cr = getContentResolver();
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Event.CONTACT_ID,
ContactsContract.CommonDataKinds.Event.START_DATE };
String where = ContactsContract.Data.MIMETYPE + "= ? AND "
+ ContactsContract.CommonDataKinds.Event.TYPE + "="
+ ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY;
String[] selectionArgs = new String[] { ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE };
// String sortOrder = null;
Cursor cur = cr.query(uri, projection, where, selectionArgs, null);
while (cur.moveToNext()) {
annv = cur
.getString(cur
.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE));
Log.v("Anniversary", annv);
}
cur.close();
return annv;
}
you are not using String id perameter in where condition so please check again.
E,g private String getAnnv(String id) function has input for ID but that seems to be not used withing function so please put that ID in condition check and this should work.
e.g
ContactsContract.CommonDataKinds.Event.CONTACT_ID + "= " + ID
AND ContactsContract.Data.MIMETYPE + "= ? AND "
Hy everybody.
I need to get the email contact that I have in android by id of contact. But it returns a null value. Don't return nothing and i don't know where I'm failed.
public Cursor cursorEmailByContactId(long contactId) {
Uri uri = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Email.DATA,
ContactsContract.CommonDataKinds.Email.TYPE,
ContactsContract.CommonDataKinds.Email.LABEL,
};
String where = ContactsContract.CommonDataKinds.Email.CONTACT_ID
+ " = ? ";
String[] whereParams = new String[] { String.valueOf(contactId) };
String order = ContactsContract.CommonDataKinds.Email.IS_PRIMARY
+ " DESC, " + ContactsContract.CommonDataKinds.Email.DATA
+ " COLLATE LOCALIZED ASC";
return ctx.getContentResolver().query(uri, projection, where,
whereParams, order);
}
Cursor cursorEmail = null;
cursorEmail = sds.cursorEmailByContactId(idContacto);
correioElectr = (EditText)findViewById(R.id.sfe_etEmail);
try{
if(cursorEmail.moveToFirst())
do{
sEmail = cursorEmail.getString(cursorEmail.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
}while(cursorEmail.moveToNext());
}finally{
if(cursorEmail != null && !cursorEmail.isClosed())
cursorEmail.close();
}
correioElectr.setText(sEmail);
And i don't get nothing in the correioElectr editText.
Someone can help me?
Thanks
try with XMPP like this
https://stackoverflow.com/questions/9885154/how-to-get-images-from-xmpp-in-android-application/10272947#10272947
I am working on an android application for which I need to match the birthday of each contact against current date and if positive, process some business logic, which needs the complete contact details.
I have found ways to read birthdays of contacts or the contacts themselves separately, but am confused as to how to combine both. Can somebody please provide some direction.
Thanks
Found the answer after some looking out on the web. The way this has to be done is :
Get list of contacts
For each contact, get contactId
Get birthday using the contactid
Following is the code snippet :
ContentResolver cr = getContentResolver(); //getContnetResolver()
String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME };
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, projection, null, null,
ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
while (cur.moveToNext()) {
Map<String, String> contactInfoMap = new HashMap<String, String>();
String contactId = cur.getString(cur.getColumnIndex(ContactsContract.Data._ID));
String displayName = cur.getString(cur.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
String columns[] = {
ContactsContract.CommonDataKinds.Event.START_DATE,
ContactsContract.CommonDataKinds.Event.TYPE,
ContactsContract.CommonDataKinds.Event.MIMETYPE,
};
String where = Event.TYPE + "=" + Event.TYPE_BIRTHDAY +
" and " + Event.MIMETYPE + " = '" + Event.CONTENT_ITEM_TYPE + "' and " + ContactsContract.Data.CONTACT_ID + " = " + contactId;
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME;
Cursor birthdayCur = cr.query(ContactsContract.Data.CONTENT_URI, columns, where, selectionArgs, sortOrder);
if (birthdayCur.getCount() > 0) {
while (birthdayCur.moveToNext()) {
String birthday = birthdayCur.getString(birthdayCur.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE));
}
}
birthdayCur.close();
}
cur.close();
Friends I want Contacts which have email and also sort in ascending order..
any one know how to get this list and sort..
Please help me and thanks in advance.
I am using this code.
MatrixCursor matCur = new MatrixCursor(new String[] { Contacts._ID,
Contacts.DISPLAY_NAME, "photo_id", "starred" });
Cursor cEmail = WP7Main.this.managedQuery(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
cEmail.moveToFirst();
if (cEmail.moveToFirst())
{
// String name =
// cursor.getString(cursor.getColumnIndexOrThrow(People.NAME));
String contactId = cEmail.getString(cEmail.getColumnIndex(ContactsContract.Contacts._ID));
Cursor emails = WP7Main.this.getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,ContactsContract.CommonDataKinds.Email.CONTACT_ID+ " = " + contactId, null, null);
String emailAddress = "";
while (emails.moveToNext())
{
// This would allow you get several email addresses
if (emails.getString(emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)) != null)
{
String[] columnValues = {
cEmail.getString(cEmail
.getColumnIndex("_id")),
cEmail.getString(cEmail
.getColumnIndex("display_name")),
cEmail.getString(cEmail
.getColumnIndex("photo_id")),
cEmail.getString(cEmail
.getColumnIndex("starred")) };
matCur.addRow(columnValues);
}
}
emails.close();
}
Try this:
/**
* #return A managed cursor of email contacts for the given activity.
*/
public static Cursor buildFilteredEmailCursor(Activity activity) {
final String my_sort_order = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
String my_selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'";
String[] eproj = new String[]{
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Email.DATA};
Uri uri = android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI;
return activity.managedQuery(uri, eproj, my_selection, null, my_sort_order);
}
Use this query :
Cursor c = getContentResolver().query(Data.CONTENT_URI,
new String[]{Data.CONTACT_ID, Data.DISPLAY_NAME, Email.ADDRESS},
Data.MIMETYPE + "=?", new String[] {Email.CONTENT_TYPE}, Data.DISPLAY_NAME /* use Email.ADDRESS if you want to sort it using that*/);