CursorAdapter with search string as either contact name or number - android

Hi I am developing an app to search a contact. The search string can be either a number or the contact name. I am able to search the list based on the contact name. Not sure how to search the same if the user enters the number of a contact. This is the code I am using
Cursor contacts = getContacts2(null);
startManagingCursor(contacts);
TestForCursorAdapter adapter = new TestForCursorAdapter(this, contacts);
mTxtPhoneNo.setAdapter(adapter);
mTxtPhoneNo.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Cursor cursor = (Cursor) arg0.getItemAtPosition(arg2);
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
mTxtPhoneNo.setText(number);
}
});
public Cursor getContacts2(String where)
{
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor people = this.getContentResolver().query(uri, projection, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
return people;
}
public class TestForCursorAdapter extends CursorAdapter implements Filterable
{
ImageView imageAvatar;
ContentResolver contentResolver;
LayoutInflater layoutInflater;
ArrayList<String> arrofnumberfrominbuiltsms = new ArrayList<String>();
ArrayList<String> arrofnumbettocomapreandbold = new ArrayList<String>();
String recipient_ids;
String r_address;
String contactName;
String contactID;
String bold= "false";
private String snippet;
private long timestamp;
private String dateString;
private String timeString;
String threadid;
private String phoneNumber;
private String numberType;
private ContentResolver mContext;
#SuppressWarnings("deprecation")
public TestForCursorAdapter(Context context, Cursor people)
{
super(context, people);
layoutInflater = LayoutInflater.from(context);
mContext = context.getContentResolver();
}
#Override
public View newView(Context context, Cursor people, ViewGroup parent)
{
final LayoutInflater mInflater = LayoutInflater.from(context);
final View ret = mInflater.inflate(R.layout.custcontview, null);
return ret;
}
#SuppressLint("SimpleDateFormat")
#Override
public void bindView(View vi, Context context, Cursor cursor)
{
TextView cname = (TextView)vi.findViewById(R.id.ccontName);
TextView cnumber = (TextView)vi.findViewById(R.id.ccontNo);
TextView ctype = (TextView)vi.findViewById(R.id.ccontType);
int nameIdx = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
int numberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String name = cursor.getString(nameIdx);
int type = cursor.getInt(typeIdx);
String number = cursor.getString(numberIdx);
cname.setText(name);
if (type == 1)
{
ctype.setText("Home");
}
else if (type == 2)
{
ctype.setText("Mobile");
}
else if (type == 3)
{
ctype.setText("Work");
}
else
{
ctype.setText("Other");
}
cnumber.setText(number);
}
#Override
public String convertToString(Cursor cursor)
{
int nameCol = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
String name = cursor.getString(nameCol);
return name;
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint)
{
// this is how you query for suggestions
// notice it is just a StringBuilder building the WHERE clause of a cursor which is the used to query for results
if (getFilterQueryProvider() != null)
{
return getFilterQueryProvider().runQuery(constraint);
}
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.NUMBER};
if (( constraint).toString().matches("[0-9]+") && constraint.length() > 2)
{//This is what I want to try
return mContext.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection,
"UPPER(" + ContactsContract.CommonDataKinds.Phone.NUMBER + ") LIKE '" + constraint.toString().toUpperCase() + "%'", null,
ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
else
{
return mContext.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection,
"UPPER(" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") LIKE '" + constraint.toString().toUpperCase() + "%'", null,
ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
}
}
Please Help. Thanks

You just need to use
Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, searchString);
Android does a good job with lookup urls like this

Related

Android cursor return empty contacts

I need to get all contacts that have at least a phone number. Android contacts may be picked from many accounts like gmail,skype,vibe etc. I made the classes i need to get the contacts i need. My problem that it gets anyway contacts that don't have at least 1 phone number and shows just their name and avatar. Can any1 say what I am doing wrong in my code? My code source is shared below.
ContactsActivity.class
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
selectionString = edtSearch.getText().toString();
String[] selectionArgs = {"%" + selectionString + "%", selectionString + "%", "%" + selectionString};
String selection = ContactsContract.Contacts.DISPLAY_NAME + " LIKE ? OR "
+ ContactsContract.Contacts.DISPLAY_NAME + " LIKE ? OR "
+ ContactsContract.Contacts.DISPLAY_NAME + " LIKE ? AND "
+ ContactsContract.Contacts.HAS_PHONE_NUMBER + "=='1'";
return new CursorLoader(this,
ContactsContract.Contacts.CONTENT_URI, // URI
null, // projection fields
selection, // the selection criteria
selectionArgs, // the selection args
ContactsContract.Contacts.DISPLAY_NAME + " ASC" // the sort order
);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
ContactsAdapter.createCheckedContacts(data.getCount());
contactsAdapter.setCursor(data);
contactsAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
contactsAdapter.swapCursor(null);
}
ContactsAdapter.class
public class ContactsAdapter extends CursorAdapter {
static boolean status = true;
private static boolean[] checkedContacts;
private static Context context;
private static Cursor cursor;
public ContactsAdapter(Context context, Cursor c) {
super(context, c, 0);
this.context = context;
}
public static void setCursor(Cursor cursor) {
ContactsAdapter.cursor = cursor;
}
public static void createCheckedContacts(int count) {
checkedContacts = new boolean[count];
}
public static void saveSelectedContacts(ClientDao contactDao) {
for (int i = 0; i < checkedContacts.length; i++) {
if (checkedContacts[i]) {
cursor.moveToPosition(i);
DatabaseHelper.getInstance().saveClient(ContactUtils.cursorToContact(cursor, context), status);
status = !status;
}
}
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View convertView = ((Activity) context).getLayoutInflater().inflate(R.layout.contact_item, parent, false);
ViewHolder holder = new ViewHolder(convertView);
convertView.setTag(holder);
return convertView;
}
#Override
public void bindView(View convertView, final Context context, final Cursor cursor) {
final ViewHolder holder = (ViewHolder) convertView.getTag();
final Contact contact = ContactUtils.cursorToContact(cursor, context);
holder.tvName.setText(contact.getDisplayName());
if (isFirst(cursor)) {
holder.tvLetter.setVisibility(View.VISIBLE);
String letter = String.valueOf(Character.toUpperCase(contact.getDisplayName().charAt(0)));
holder.tvLetter.setText(letter);
} else {
holder.tvLetter.setVisibility(View.INVISIBLE);
}
convertView.setTag(convertView.getId(), contact);
if (!TextUtils.isEmpty(contact.getPhotoUri())) {
new ImageLoaderUtils.ContactImage(contact, convertView, holder.ivUserImage, context).execute();
} else {
holder.ivUserImage.setImageResource(R.drawable.ic_profile);
}
holder.inviteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, ContactInvitationActivity_.class);
intent.putExtra("contact", contact);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
}
});
}
private boolean isFirst(Cursor cursor) {
Contact c1 = ContactUtils.cursorToContact(cursor, context);
if (cursor.getPosition() == 0)
return true;
cursor.moveToPrevious();
Contact c2 = ContactUtils.cursorToContact(cursor, context);
if (c1.getDisplayName() == null || c2.getDisplayName() == null)
return false;
if (Character.toUpperCase(c1.getDisplayName().charAt(0)) != Character.toUpperCase(c2.getDisplayName().charAt(0)))
return true;
return false;
}
private static class ViewHolder {
TextView tvName;
TextView tvLetter;
ImageView ivUserImage;
Button inviteBtn;
RelativeLayout rlContact;
private ViewHolder(View convertView) {
tvName = (TextView) convertView.findViewById(R.id.tvContactsName);
tvLetter = (TextView) convertView.findViewById(R.id.tvLetter);
ivUserImage = (ImageView) convertView.findViewById(R.id.ivUserIcon);
inviteBtn = (Button) convertView.findViewById(R.id.inviteBtn);
rlContact = (RelativeLayout) convertView.findViewById(R.id.rlContact);
}
}
}
ContactUtil.class
public class ContactUtils {
public static Contact cursorToContact(Cursor c, Context context) {
if (c == null || c.getPosition() < 0) return null;
Contact contactObj = new Contact();
try {
contactObj.setID(c.getString(c.getColumnIndex(ContactsContract.Contacts._ID)));
contactObj.setDisplayName(c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
contactObj.setPhotoUri(c.getString(c.getColumnIndex(ContactsContract.Contacts.PHOTO_URI)));
contactObj.setPhoneNumber("");
contactObj.setEmail("");
setPhoneNumber(c, contactObj, context);
setEmail(contactObj, context);
} catch (Exception e) {
e.printStackTrace();
}
return contactObj;
}
public static void setPhoneNumber(Cursor c, Contact contactObj, Context context) {
if (Integer.parseInt(c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
// Query phone here. Covered next
Cursor phones = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactObj.getID(), null, null);
phones.moveToFirst();
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i("Number", phoneNumber);
contactObj.setPhoneNumber(phoneNumber);
phones.close();
}
}
public static void setEmail(Contact contactObj, Context context) {
Cursor emailCur = context.getContentResolver().query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{contactObj.getID()}, null);
while (emailCur.moveToNext()) {
// This would allow you get several email addresses
// if the email addresses were stored in an array
String email = emailCur.getString(
emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
String emailType = emailCur.getString(
emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
contactObj.setEmail(email);
}
emailCur.close();
}
}

Get phone number by contact name

I’m trying to get phone number from contacts by providing the phone number. what I've done so far:
public static String getPhone(Context context, String displayName) {
ContentResolver cr = context.getContentResolver();
Uri uri = CommonDataKinds.Phone.CONTENT_URI;
String selection = CommonDataKinds.Phone.DISPLAY_NAME+" LIKE '%" + displayName + "&'";
Cursor cursor = cr.query(uri, new String[]{CommonDataKinds.Phone._ID,CommonDataKinds.Phone.DISPLAY_NAME,CommonDataKinds.Phone.NUMBER}, selection, null, null);
if (cursor == null) {
return null;
}
String contactName = null;
if(cursor.moveToFirst()) {
contactName = cursor.getString(cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER));
}
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
//Log.d("Contact",contactName.toString());
return contactName;
}
Try this code out. You will need to set the permission in the manifest "android.permission.READ_CONTACTS" on true.
public String getPhoneNumber(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);
}
c.close();
if(ret==null)
ret = "Unsaved";
return ret;
}
UPDATE:
This code snippet will allow you to read all messages from a particular contact:
StringBuilder smsBuilder = new StringBuilder();
final String SMS_URI_INBOX = "content://sms/inbox";
final String SMS_URI_ALL = "content://sms/";
try {
Uri uri = Uri.parse(SMS_URI_INBOX);
String[] projection = new String[] { "_id", "address", "person", "body", "date", "type" };
Cursor cur = getContentResolver().query(uri, projection, "address='123456789'", null, "date desc");
if (cur.moveToFirst()) {
int index_Address = cur.getColumnIndex("address");
int index_Person = cur.getColumnIndex("person");
int index_Body = cur.getColumnIndex("body");
int index_Date = cur.getColumnIndex("date");
int index_Type = cur.getColumnIndex("type");
do {
String strAddress = cur.getString(index_Address);
int intPerson = cur.getInt(index_Person);
String strbody = cur.getString(index_Body);
long longDate = cur.getLong(index_Date);
int int_Type = cur.getInt(index_Type);
smsBuilder.append("[ ");
smsBuilder.append(strAddress + ", ");
smsBuilder.append(intPerson + ", ");
smsBuilder.append(strbody + ", ");
smsBuilder.append(longDate + ", ");
smsBuilder.append(int_Type);
smsBuilder.append(" ]\n\n");
} while (cur.moveToNext());
if (!cur.isClosed()) {
cur.close();
cur = null;
}
} else {
smsBuilder.append("no result!");
} // end if
}
} catch (SQLiteException ex) {
Log.d("SQLiteException", ex.getMessage());
}

Android - Custom AutoCompleteTextView CursorAdaptor - Suggestion Behavior

I am trying to implement a custom AutoCompleteTextView for choosing a contact's phone number from a list of suggestions that display the contact name, phone number type, and phone number. I created a custom CursorAdapter that defines and sets my Layout and TextViews for each suggestion and queries contacts based on the user-entered text via runQueryOnBackgroundThread. I'm running into an issue where the suggestions seem correct for the first two values entered (e.g. "ab" suggests "abcd" and "abyz") but not for anything beyond that (e.g. "abc" suggests "abyz"). For the latter, when the "abyz" suggestion is selected, the values for "abcd" are returned.
Code for the main activity:
final ContactInfo cont = new ContactInfo(ctx);
Cursor contacts = cont.getContacts2(null);
startManagingCursor(contacts);
ContactsAutoCompleteCursorAdapter adapter = new ContactsAutoCompleteCursorAdapter(this, contacts);
mPersonText.setAdapter(adapter);
mPersonText.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Cursor cursor = (Cursor) arg0.getItemAtPosition(arg2);
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
mPersonNum.setText(number);
}
});
Code for my contacts class that returns a cursor for all contacts:
public Cursor getContacts2(String where)
{
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor people = ctx.getContentResolver().query(uri, projection, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
return people;
}
Code for my CursorAdapter:
public class ContactsAutoCompleteCursorAdapter extends CursorAdapter implements Filterable {
private TextView mName, mType, mNumber;
private ContentResolver mContent;
public ContactsAutoCompleteCursorAdapter(Context context, Cursor c) {
super(context, c);
mContent = context.getContentResolver();
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater mInflater = LayoutInflater.from(context);
final View ret = mInflater.inflate(R.layout.contacts_auto_list, null);
mName = (TextView) ret.findViewById(R.id.name);
mType = (TextView) ret.findViewById(R.id.phonetype);
mNumber = (TextView) ret.findViewById(R.id.phonenum);
return ret;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
int nameIdx = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
int numberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String name = cursor.getString(nameIdx);
int type = cursor.getInt(typeIdx);
String number = cursor.getString(numberIdx);
mName.setText(name);
if (type == 1) {mType.setText("Home");}
else if (type == 2) {mType.setText("Mobile");}
else if (type == 3) {mType.setText("Work");}
else {mType.setText("Other");}
mNumber.setText(number);
}
#Override
public String convertToString(Cursor cursor) {
int nameCol = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
String name = cursor.getString(nameCol);
return name;
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
// this is how you query for suggestions
// notice it is just a StringBuilder building the WHERE clause of a cursor which is the used to query for results
if (getFilterQueryProvider() != null) { return getFilterQueryProvider().runQuery(constraint); }
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.NUMBER};
return mContent.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection,
"UPPER(" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") LIKE '" + constraint.toString().toUpperCase() + "%'", null,
ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
}
As I said above, when the user enters "ab" into the AutoCompleteTextView the suggestions are "abcd" and "abyz", however when the user types "abc" the suggestion is just "abyz". When the user selects "abyz" in that case, the values for "abcd" are returned. Here are two screenshots that show what I'm trying to describe:
I've read every question I could find here and elsewhere but can't seem to figure this out. I'm fairly new to Android development so I apologize in advance if my mistake is a simple one. Thanks in advance!
I seem to have answered my own question after more research. Moving the setting of the views for my textViews from the newView function to the bindView function seems to have done the trick, which I think makes sense...
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater mInflater = LayoutInflater.from(context);
final View ret = mInflater.inflate(R.layout.contacts_auto_list, null);
return ret;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
int nameIdx = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
int numberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String name = cursor.getString(nameIdx);
int type = cursor.getInt(typeIdx);
String number = cursor.getString(numberIdx);
mName = (TextView) view.findViewById(R.id.name);
mType = (TextView) view.findViewById(R.id.phonetype);
mNumber = (TextView) view.findViewById(R.id.phonenum);
mName.setText(name);
if (type == 1) {mType.setText("Home");}
else if (type == 2) {mType.setText("Mobile");}
else if (type == 3) {mType.setText("Work");}
else {mType.setText("Other");}
mNumber.setText(number);
}
you have already public Cursor runQueryOnBackgroundThread function in your adapter so you do not need call second time cursor in activity
you do not need to use getContacts2 function
Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sms_send);
Cursor contacts = null;
mAdapter= new ContactsAutoCompleteCursorAdapter(this, contacts);
mTxtPhoneNo = (AutoCompleteTextView) findViewById(R.id.mmWhoNo);
mTxtPhoneNo.setAdapter(mAdapter);
mTxtPhoneNo.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Cursor cursor = (Cursor) arg0.getItemAtPosition(arg2);
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
mTxtPhoneNo.setText(number);
}
});
}
Adapter
public class ContactsAutoCompleteCursorAdapter extends CursorAdapter implements Filterable {
private TextView mName, mType, mNumber;
private ContentResolver mContent;
public ContactsAutoCompleteCursorAdapter(Context context, Cursor c) {
super(context, c);
mContent = context.getContentResolver();
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater mInflater = LayoutInflater.from(context);
final View ret = mInflater.inflate(R.layout.custcontview, null);
return ret;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
int nameIdx = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
int numberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String name = cursor.getString(nameIdx);
int type = cursor.getInt(typeIdx);
String number = cursor.getString(numberIdx);
mName = (TextView) view.findViewById(R.id.ccontName);
mType = (TextView) view.findViewById(R.id.ccontType);
mNumber = (TextView) view.findViewById(R.id.ccontNo);
mName.setText(name);
if (type == 1) {mType.setText("Home");}
else if (type == 2) {mType.setText("Mobile");}
else if (type == 3) {mType.setText("Work");}
else {mType.setText("Other");}
mNumber.setText(number);
}
#Override
public String convertToString(Cursor cursor) {
int nameCol = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
String name = cursor.getString(nameCol);
return name;
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
// this is how you query for suggestions
// notice it is just a StringBuilder building the WHERE clause of a cursor which is the used to query for results
if (constraint==null)
return null;
if (getFilterQueryProvider() != null) { return getFilterQueryProvider().runQuery(constraint); }
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.NUMBER};
return mContent.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection,
"UPPER(" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") LIKE '%" + constraint.toString().toUpperCase() + "%' or UPPER(" + ContactsContract.CommonDataKinds.Phone.NUMBER + ") LIKE '%" + constraint.toString().toUpperCase() + "%' ", null,
ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
}
i also add query for phone number search in query

How can I read the favorites contacts inside service?

I am looking for a way to get the contacts in the favorites list inside service from phone number or from name it dose not matter. Can any one help me with this?
It's not important to use any code related to this code
I found in the developer.android.com something like this (IN_VISIBLE_GROUP).
How to use this variable in my case?
case (PICK_CONTACT):
if (resultCode == Activity.RESULT_OK) {
Uri contactData = data.getData();
Cursor c = managedQuery(contactData, null, null, null, null);
ContentResolver cr = getContentResolver();
if (c.moveToFirst()) {
String name = c.getString(c.getColumnIndexOrThrow(People.NAME));
String id =c.getString(c.getColumnIndexOrThrow(People._ID));
Cursor phones = cr.query(Phone.CONTENT_URI, null,
Phone.CONTACT_ID + " = " + id, null, null);
}
Lets assume that you are searching a contact by name..
If you want to get Favourite value of all the possible contacts , drop the selection parameter in the given code.
//First get the contact ID from a display name as:-
String displayName = "Albert Einstein";
Uri contacts = ContactsContract.Contacts.CONTENT_URI;
cur = cr.query(contacts, null, ContactsContract.Contacts.DISPLAY_NAME +"="+displayName,null, null);
int contactIdIndex = cur.getColumnIndex(ContactsContract.PhoneLookup._ID);
int contactId = cur.getInt(contactIdIndex);
//Make a query to get the Starred value:-
Cursor starred = cr.query(ContactsContract.Contacts.CONTENT_URI,
new String[] { ContactsContract.Contacts.STARRED },
ContactsContract.Contacts._ID + " = " + contactId,
null, null);
if (starred != null && starred.moveToFirst())
{
int fav = starred.getInt(0);
}
if (starred != null)
starred.close();
}
You can drop the step of getting Contact ID and then querying for Starred value and directly query based on Display name
Something like this?
final private static class DataQuery {
public static final int COLUMN_MIMETYPE = 1;
public static final int COLUMN_PHONE = 2;
public static final int COLUMN_RAWCONTACT_ID = 3;
public static final int COLUMN_PHONE_NUMBER = COLUMN_DATA1;
public static final String[] PROJECTION = new String[] { Data._ID, Data.MIMETYPE, Data.DATA1, Data.RAW_CONTACT_ID };
public static final String SELECTION_PHONE = Data.DATA1 + "=?";
}
long findContact(Context context, String number) {
long rawContactId = -1;
final Cursor cursor = context.getContentResolver().query(Data.CONTENT_URI, DataQuery.PROJECTION, DataQuery.SELECTION_PHONE, new String[] { number }, null);
try {
if (cursor.moveToFirst()) {
rawContactId = cursor.getLong(DataQuery.COLUMN_RAWCONTACT_ID);
}
} finally {
if (cursor != null)
cursor.close();
}
return rawContactId;
}
Ok let's try with this...
private static final Uri DATAGROUP_CONTENT_URI = ContactsContract.Data.CONTENT_URI.buildUpon().appendQueryParameter(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE).build();
public static void querytGroups(Context context) {
final ContentResolver resolver = context.getContentResolver();
long groupid=getGroupId(resolver, "Family");
final Cursor c = resolver.query(DATAGROUP_CONTENT_URI, DataQueryForContactsInGroup.PROJECTION, DataQueryForContactsInGroup.SELECTION, new String[] {ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE, String.valueOf(groupid)}, null);
try {
while (c.moveToNext()) {
final long rawContactId = c.getLong(DataQueryForContactsInGroup.RAW_CONTACT_ID);
//do something
}
}finally {
c.close();
}
}
private static long getGroupId(final ContentResolver resolver, String groupName) {
long groupid = -1;
Cursor cur = null;
try {
cur = resolver.query(Groups.CONTENT_URI, DataQueryForGroup.PROJECTION, DataQueryForGroup.SELECTION, new String[]{"%"+groupName+"%"}, null);
while (cur.moveToNext()) {
return groupid= cur.getLong(DataQueryForGroup.GROUP_ID);
}
}finally {
if (cur!=null) cur.close();
}
return groupid;
}
private interface DataQueryForGroup {
public final static String[] PROJECTION = new String[] {Groups._ID};
public static final String SELECTION = Groups.TITLE+" LIKE ?";
public final static int GROUP_ID = 0;
}
private interface DataQueryForContactsInGroup {
public final static String[] PROJECTION = new String[] { Data.RAW_CONTACT_ID };
public static final String SELECTION = "("+Data.MIMETYPE + "=?) and ("+ ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID+ "=?)";
public final static int RAW_CONTACT_ID = 0;
}
Please consider that if your google account is not English you need to look for the proper group's name

How to get contacts from native phonebook in android

I want to display all native contacts in a list and make user to add contacts from the list (Multiple contacts)to my application database.How to dothis can any one give me idea or share some code..
thanks in advance..
I used this code on Android 2.1. It pulls down anyone who has a phone number (as defined by the String SELECTION variable) and returns a List of type Person. Person is an object that held the name and phone number of the user. You will have to implement a Person object in order to use this code, but it works perfectly:
public List<Person> getContactList(){
ArrayList<Person> contactList = new ArrayList<Person>();
Uri contactUri = ContactsContract.Contacts.CONTENT_URI;
String[] PROJECTION = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
};
String SELECTION = ContactsContract.Contacts.HAS_PHONE_NUMBER + "='1'";
Cursor contacts = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, PROJECTION, SELECTION, null, null);
if (contacts.getCount() > 0)
{
while(contacts.moveToNext()) {
Person aContact = new Person();
int idFieldColumnIndex = 0;
int nameFieldColumnIndex = 0;
int numberFieldColumnIndex = 0;
String contactId = contacts.getString(contacts.getColumnIndex(ContactsContract.Contacts._ID));
nameFieldColumnIndex = contacts.getColumnIndex(PhoneLookup.DISPLAY_NAME);
if (nameFieldColumnIndex > -1)
{
aContact.setName(contacts.getString(nameFieldColumnIndex));
}
PROJECTION = new String[] {Phone.NUMBER};
final Cursor phone = managedQuery(Phone.CONTENT_URI, PROJECTION, Data.CONTACT_ID + "=?", new String[]{String.valueOf(contactId)}, null);
if(phone.moveToFirst()) {
while(!phone.isAfterLast())
{
numberFieldColumnIndex = phone.getColumnIndex(Phone.NUMBER);
if (numberFieldColumnIndex > -1)
{
aContact.setPhoneNum(phone.getString(numberFieldColumnIndex));
phone.moveToNext();
TelephonyManager mTelephonyMgr;
mTelephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (!mTelephonyMgr.getLine1Number().contains(aContact.getPhoneNum()))
{
contactList.add(aContact);
}
}
}
}
phone.close();
}
contacts.close();
}
return contactList;
}
EDIT: A rudimentary Person class:
public class Person {
String myName = "";
String myNumber = "";
public String getName() {
return myName;
}
public void setName(String name) {
myName = name;
}
public String getPhoneNum() {
return myNumber;
}
public void setPhoneNum(String number) {
myNumber = number;
}
}
This code works perfectly in android 4.2. And it works much faster, because you don't make additional query for each contact
private static final String CONTACT_ID = ContactsContract.Contacts._ID;
private static final String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
private static final String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
private static final String PHONE_NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
private static final String PHONE_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
public static ArrayList<Contact> getAll(Context context) {
ContentResolver cr = context.getContentResolver();
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{PHONE_NUMBER, PHONE_CONTACT_ID},
null,
null,
null
);
if(pCur != null){
if(pCur.getCount() > 0) {
HashMap<Integer, ArrayList<String>> phones = new HashMap<>();
while (pCur.moveToNext()) {
Integer contactId = pCur.getInt(pCur.getColumnIndex(PHONE_CONTACT_ID));
ArrayList<String> curPhones = new ArrayList<>();
if (phones.containsKey(contactId)) {
curPhones = phones.get(contactId);
}
curPhones.add(pCur.getString(pCur.getColumnIndex(PHONE_CONTACT_ID)));
phones.put(contactId, curPhones);
}
Cursor cur = cr.query(
ContactsContract.Contacts.CONTENT_URI,
new String[]{CONTACT_ID, DISPLAY_NAME, HAS_PHONE_NUMBER},
HAS_PHONE_NUMBER + " > 0",
null,
DISPLAY_NAME + " ASC");
if (cur != null) {
if (cur.getCount() > 0) {
ArrayList<Contact> contacts = new ArrayList<>();
while (cur.moveToNext()) {
int id = cur.getInt(cur.getColumnIndex(CONTACT_ID));
if(phones.containsKey(id)) {
Contact con = new Contact();
con.setMyId(id);
con.setName(cur.getString(cur.getColumnIndex(DISPLAY_NAME)));
con.setPhone(TextUtils.join(",", phones.get(id).toArray()));
contacts.add(con);
}
}
return contacts;
}
cur.close();
}
}
pCur.close();
}
return null;
}
Class Contact is similar to class Person from the answer.

Categories

Resources