I'm making a Dialer and I want to search the contacts by name.
But since the Dialer accepts only numbers, how should I search for JOHN by entering the number 5-6-4-6? Are there any existing methods to do so in android?
If this number 5-6-4-6 exists in your contacst than you can use Content uri and hpone uri to lookup for this number and you can compare it with the fetched results...
You can fetch all the contacts and you get the name by comparing this number an d with the fetched numbers from the andorid conatcts api.
public void fetchContacts() {
String phoneNumber = null;
String email = null;
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
Uri EmailCONTENT_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
String EmailCONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;
String DATA = ContactsContract.CommonDataKinds.Email.DATA;
StringBuffer output = new StringBuffer();
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null,null, null, null);
// Loop for every contact in the phone
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String contact_id = cursor.getString(cursor.getColumnIndex( _ID ));
String name = cursor.getString(cursor.getColumnIndex( DISPLAY_NAME ));
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex( HAS_PHONE_NUMBER )));
if (hasPhoneNumber > 0) {
output.append("\n First Name:" + name);
// Query and loop for every phone number of the contact
Cursor phoneCursor = contentResolver.query(PhoneCONTENT_URI, null, Phone_CONTACT_ID + " = ?", new String[] { contact_id }, null);
while (phoneCursor.moveToNext()) {
phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
output.append("\n Phone number:" + phoneNumber);
}
phoneCursor.close();
// Query and loop for every email of the contact
Cursor emailCursor = contentResolver.query(EmailCONTENT_URI, null, EmailCONTACT_ID+ " = ?", new String[] { contact_id }, null);
while (emailCursor.moveToNext()) {
email = emailCursor.getString(emailCursor.getColumnIndex(DATA));
output.append("\nEmail:" + email);
}
emailCursor.close();
}
output.append("\n");
}
outputText.setText(output);
}
}
}
this link may help you..
there are various ways to do this.
Assign each letter a numeric code as per numeric keypad with letters.
e.g.
assign 2 to a b & c
assign 3 to d e & f and so on.
Then modify your search accordingly.
Related
I am trying to fetch contacts from phone by MIME-TYPE, so i can select contacts that has the type:
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
Here is the method i use:
public static ArrayList<Contact> fetchContactsFromPhone(#NonNull Context context) {
ArrayList<Contact> contacts = new ArrayList<>();
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String contact_id = cursor.getString(cursor.getColumnIndex(_ID));
String name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
long hasPhoneNumber = Long.parseLong(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER)));
if (hasPhoneNumber > 0) {
Cursor phoneCursor = contentResolver.query(
PhoneCONTENT_URI,
null,
Phone_CONTACT_ID + " = " + contact_id + " AND " + ContactsContract.Data.MIMETYPE + " = " + "'"+ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE+"'"
, null, null);
if (phoneCursor != null) {
while (phoneCursor.moveToNext()) {
Contact contact = new Contact();
String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
phoneNumber = phoneNumber.replaceAll("[()\\-\\s]", "").trim();
contact.setName(name);
contact.setPhoneNum(phoneNumber);
contacts.add(contact);
}
phoneCursor.close();
}
}
}
cursor.close();
}
//return data
return contacts;
}
The problem is this query, return ZERO contacts.
Any Idea why?
You're querying the table CommonDataKinds.Phone.CONTENT_URI which contains only Data rows with MIMETYPE = CommonDataKinds.Phone.CONTENT_ITEM_TYPE.
But you're asking for rows with MIMETYPE CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE so you're getting an empty cursor.
It's an easy fix to your existing code, but even when fixed, you're code is very slow, it'll run a query per contact on the device, this can easily be hundreds or even thousands of queries. If you just need to get the name+number of all contacts, try the following code (one query to get all):
ArrayList<Contact> contacts = new ArrayList<>();
// Make sure you import Phone from ContactsContract.CommonDataKinds.Phone
String[] projection = { Phone.CONTACT_ID, Phone.DISPLAY_NAME, Phone.NUMBER };
Cursor cur = cr.query(Phone.CONTENT_URI, projection, null, null, null);
while (cur != null && cur.moveToNext()) {
long id = cur.getLong(0);
String name = cur.getString(1);
String number = cur.getString(2);
Log.d(TAG, "got " + id + ", " + name + ", " + number);
Contact contact = new Contact();
contact.setName(name);
contact.setPhoneNum(number);
contacts.add(contact);
}
if (cur != null) {
cur.close();
}
Note that similar to your code, this code might create multiple Contact objects for each contact, in case a contact has more then one phone.
If you want only one Contact object per contact, you need to modify your Contact object to contain a list of phones, and change the ArrayList<Contact> to HashMap<Long, Contact> so you can add a phone to an existing object instead of creating a new one.
Here is the code used to get the contact information :
String id = data.getData().getLastPathSegment();
Cursor cursor = getActivity().getContentResolver()
.query(ContactsContract.Data.CONTENT_URI,
new String[] {ContactsContract.Data.DISPLAY_NAME},
ContactsContract.Data.CONTACT_ID + "=?",
new String[]{id},
null);
// short circuit if we didn't pick a contact
if (cursor.getCount() == 0) {
return;
}
String contact = "";
String contactName = "";
//code to get contact name
if (cursor.moveToFirst() && cursor.getString(0) != null) {
contact = contact + cursor.getString(0) + ",";
contactName = cursor.getString(0);
}
else {
contact = contact + ","; //changed
}
cursor.close();
// code to get phone number
cursor = getActivity().getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
newString[{ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.TYPE},
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?",
new String[]{id},null);
if (cursor.moveToFirst() && cursor.getString(0) != null) {
contact = contact + cursor.getString(0) + ",";
contact = contact + cursor.getString(0) + ",";
}
else {
contact = contact + ",,"; //changed
}
cursor.close();
//Code to get email
cursor = getActivity().getContentResolver()
.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
new String[]{ContactsContract.CommonDataKinds.Email.ADDRESS},
ContactsContract.CommonDataKinds.Email.CONTACT_ID + "=?",
new String[]{id},null);
if (cursor.moveToFirst() && cursor.getString(0) != null) {
contact = contact + cursor.getString(0);
}
cursor.close();
contact = contact.replace("+", "");
Log.i("TAG", "CONTACT INFO = " + contact);
What I am trying to do:
Here, I query the contact name, phone number and email from Contacts through content provider and concatenate all three into a single string, with commas separating them within the string .
The problem :
I get the contact name and email, without any issues.
However, when I select some contacts from contact, the phone number returned is empty.
The Contacts that return empty phone numbers are phone numbers from a different country, from my current location.
I am right now in Canada and when I select Canadian Contacts, I get the phone number correctly.
However, when I select phone numbers from India, the number is not returned, instead, I get empty result.
The same happens when I select a Contact with numbers like "12345" or "5555555555"etc.
My Question
Could it be that Android is trying to validate the authenticity of the number and returning an empty number, if it finds the phone number Invalid? *(probably not! Must be my mistake!)*
How can I solve this issue? Can't I get the value of the phone number just like how it is saved in the Contacts by the user?
I apologize for any unambiguity in the code or my question. I am a novice programmer and thanks a lot for all your inputs!
One thing i observed from that code is, you are reading contacts with out using
ContactsContract.Contacts.CONTENT_URI
I Modified your code and created a new method to print all contacts.
public static void fetchContacts(Context context) {
String phoneNumber = null;
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
StringBuffer output = new StringBuffer();
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null,null, null, null);
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String contact_id = cursor.getString(cursor.getColumnIndex( _ID ));
String name = cursor.getString(cursor.getColumnIndex( DISPLAY_NAME ));
long hasPhoneNumber = Long.parseLong(cursor.getString(cursor.getColumnIndex( HAS_PHONE_NUMBER )));
if (hasPhoneNumber > 0) {
output.append("\n Name:" + name);
Cursor phoneCursor = contentResolver.query(PhoneCONTENT_URI, null, Phone_CONTACT_ID + " = ?", new String[] { contact_id }, null);
while (phoneCursor.moveToNext()) {
phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
output.append("\n Number:" + phoneNumber);
System.out.println("Number:::::"+phoneNumber);
System.out.println("Contact:::::"+output.toString());
}
phoneCursor.close();
}
}
}else{
// Toast.makeText(context, "No contacts Found", Toast.LENGTH_LONG).show();
}
}
I want to retrieve all contact names and numbers from a mobile phone in Android. Then, I want to display that data in a ListView. How can I achieve this?
try this...
public void getContacts(ContentResolver cr) {
Cursor phones = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, null);
while (phones.moveToNext()) {
String name = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
phones.close();// close cursor
}
call method
getContacts(this.getContentResolver());
from this code you will get name n numbers save in your contact list, add them in arraylist or array, n then you may show them in listview
try {
String phoneNumber = null;
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null, null,
null, null);
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String contact_id = cursor.getString(cursor
.getColumnIndex(_ID));
int hasPhoneNumber = Integer
.parseInt(cursor.getString(cursor
.getColumnIndex(HAS_PHONE_NUMBER)));
if (hasPhoneNumber > 0) {
Cursor phoneCursor = contentResolver.query(
PhoneCONTENT_URI, null, Phone_CONTACT_ID
+ " = ?", new String[] { contact_id },
null);
while (phoneCursor.moveToNext()) {
phoneNumber = phoneCursor.getString(phoneCursor
.getColumnIndex(NUMBER));
String contname = phoneCursor.getString(phoneCursor
.getColumnIndex(DISPLAY_NAME));
if (!contname.equals(null)) {
Toast.makeText(getApplicationContext(),
contname, Toast.LENGTH_SHORT).show();
}
}
}
phoneCursor.close();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
I'm create an application to get all contacts from phone book of Android device. I synch my contacts list from Gmail to android device and I see all contacts in phone book. But when running application, cannot get any contacts from phone book.
Here is my code
MainActivity.java
public class MainActivity extends Activity {
private TextView outputText;
TextView txtViewContactsInfor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
outputText =(TextView)findViewById(R.id.textView2);
txtViewContactsInfor = (TextView) findViewById(R.id.txtViewContactsInfor);
Import_contacts_from_address_book();
}
private void Import_contacts_from_address_book() {
// TODO Auto-generated method stub
String phoneNumber = null;
String email = null;
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Uri PHONECONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String PHONECONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
Uri EMAILCONTENT_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
String EMAILCONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;
String EMAIL = ContactsContract.CommonDataKinds.Email.DATA;
StringBuffer output = new StringBuffer();
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null, null);
System.out.println("---------------------->"+cursor.getCount());
if(cursor.getCount() >0){
int aa = cursor.getCount();
while(cursor.moveToNext()){
String contact_id = cursor.getString(cursor.getColumnIndex(_ID));
String name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER)));
if(hasPhoneNumber > 0 ){
output.append("\nFirst Name: "+name);
// Query and loop for every phone number of the contact
Cursor phoneCursor = contentResolver.query(PHONECONTENT_URI, null, PHONECONTACT_ID + "=?", new String[]{contact_id}, null);
while(phoneCursor.moveToNext()){
phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
output.append("\n Phone number: "+phoneNumber);
}
phoneCursor.close();
// Query and loop for every email of the contact
Cursor emailCurosr = contentResolver.query(EMAILCONTENT_URI, null, EMAILCONTACT_ID+"=?",new String[]{contact_id},null);
while(emailCurosr.moveToNext()){
email = emailCurosr.getString(emailCurosr.getColumnIndex(EMAIL));
output.append("\nEmail: "+email);
}
emailCurosr.close();
}
output.append("\n");
}
cursor.close();
}
outputText.setText(output.toString());
}
I debug in cursor.getCount and see "544 contact" was found. But
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER))); always zero.
I dont know why.
You might have a lot contacts without number, because contacts are stored in multiple columns.
I simplified and modified your code to count rows with and with out numbers and let it run on my phone:
private void readContacts() {
Cursor c = getContentResolver()
.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
int foundWithNumber = 0;
int foundWithOutNumber = 0;
if (c.moveToFirst()) {
int idHasNumber = c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
do {
boolean hasNumber = c.getInt(idHasNumber) > 0;
if (hasNumber) {
++foundWithNumber;
} else {
++foundWithOutNumber;
}
} while (c.moveToNext());
}
Log.d(TAG, "foundWithNumber: " + foundWithNumber);
Log.d(TAG, "foundWithOutNumber: " + foundWithOutNumber);
c.close();
}
The ouput on my phone is:
MainActivity D foundWithNumber: 184
D foundWithOutNumber: 303
So, I guess, you just looked at the wrong rows. ;)
You nead add Read contact permission in Android manifest
android.permission.READ_CONTACTS
I'm trying to read contact numbers from users contact list. Here is my code
Cursor cursor = getContacts();
if(cursor.getCount()>0){
while (cursor.moveToNext()) {
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
int numberField = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
textViewDisplay.append("Name: ");
textViewDisplay.append(displayName+"Number :"+numberField);
textViewDisplay.append("\n");
}
}
You are taking cursor.getColumnIndex(COLUMN) into int. So the method as it says returns the index of COLUMN sent to it as parameter. You need Phone Number which will never be contained by an int as its size is always be greater than 4 bytes, and also it contains some special characters like +
So you need to take your Number to some String variable
Use String numberField = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
as suggested by Anuj.
use this
String numberField = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
instead of
int numberField = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
It returns "1" means that contact has phone number. try this,
String hasPhone = c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
String cNumber="";
if (hasPhone.equalsIgnoreCase("1"))
{
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id,null, null);
phones.moveToFirst();
cNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
phones.close();
}
try this one :
public void readContacts() {
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
// Get contact id (id)
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
// Get contact name (displayName)
String displayName = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
// Get Phone Number....
Uri URI_PHONE = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String SELECTION_PHONE = ContactsContract.CommonDataKinds.Phone.CONTACT_ID+ " = ?";
String[] SELECTION_ARRAY_PHONE = new String[] { id };
Cursor currPhone = cr.query(URI_PHONE, null,SELECTION_PHONE, SELECTION_ARRAY_PHONE, null);
int indexPhoneNo = currPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int indexPhoneType = currPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
if (currPhone.getCount() > 0) {
while (currPhone.moveToNext()) {
String phoneNoStr = currPhone.getString(indexPhoneNo);
String phoneTypeStr = currPhone.getString(indexPhoneType);
}
}
currPhone.close();
}
}
}
cur.close();
}