I have this method to display the contact numbers in my inbox:
public ArrayList<String> fetchInboxNumbers() {
ArrayList<String> sms = new ArrayList<String>();
Uri uriSms = Uri.parse("content://sms/inbox");
Cursor cursor = getContentResolver().query(uriSms,
new String[] { "_id", "address", "date", "body" }, null, null, null);
cursor.moveToFirst();
while (cursor.moveToNext()) {
address = cursor.getString(1); // Displays phone number
Log.d("CONTACT", address);
sms.add(address); // + " " + body
}
Log.d("NAMES IN CALLLOG", sms.get(7));
return sms;
} // END FETCHINBOX
What I'm trying to do is change String address to its contact name.
From fetchContactNumbers() and 'fetchContactNames(), how can I changeaddress` to a contact name?
Its important to understand that fetchContactNumbers and fetchContactNames() are aligned, meaning fetchContactNumbers().get(5)'s contact name is fetchContactNames().get(5)`.
In the end, fetchInboxNumbers() populates a custom adapter.
This method returns a list of all contact names:
public ArrayList<String> fetchContactNames() {
ArrayList<String> names = new ArrayList<String>();
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, null);
while (phones.moveToNext()) {
String name = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
names.add(name);
}
phones.close();
return names;
}
And this method lists all phone numbers:
public ArrayList<String> fetchContactNumbers() {
ArrayList<String> numbers = new ArrayList<String>();
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, null);
while (phones.moveToNext()) {
String phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
numbers.add(phoneNumber);
}
phones.close();
return numbers;
}
You can use CONTENT_FILTER_URI to get the display name, instead of getting all names and numbers separately, something like below:
public ArrayList<String> fetchInboxNumbers() {
String displayName = "";
ArrayList<String> sms = new ArrayList<String>();
Uri uriSms = Uri.parse("content://sms/inbox");
Cursor cursor = getContentResolver().query(uriSms,
new String[] { "_id", "address", "date", "body" }, null, null, null);
cursor.moveToFirst();
while (cursor.moveToNext()) {
address = cursor.getString(1); // Displays phone number
displayName = getDisplayName(address);
sms.add(displayName); // + " " + body
}
return sms;
} // END FETCHINBOX
private String getDisplayName(String phoneNumber) {
String displayName = "";
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = context.getContentResolver().query(uri, new String[] { Phone._ID, Phone.DISPLAY_NAME}, null, null, null);
if (cursor.moveToFirst()) {
displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
}
return displayName;
}
Is it a spelling mistake? a variable mistake?
private String getDisplayName(String phoneNyumber) {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.
CONTENT_FILTER_URI, Uri.encode(phoneNumber));
.....
}
Your argument is having phoneNyumber and you are using phoneNumber.
Related
I want to implement search the contacts on basis of number provided.
I have used ContactsContract to read all the contacts. I have implemented search criteria on basis of name by proving a searchView and the matching name will be displayed but I want to do the same by number also
private List<ContactItem> getContacts(String s) {
String whereString = "display_name LIKE ?";
String[] whereParams = new String[]{ "%" + s + "%"};
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, whereString, whereParams, null);
List<ContactItem> contacts = new ArrayList<>();
assert cur != null;
while (cur.moveToNext()) {
String name = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contacts.add(new ContactItem(name,phoneNumber));
}
cur.close();
return contacts;
}
I want to use phone number instead of display_name here. How to do that
Try the following code, should filter based on both name and number:
private List<ContactItem> getContacts(String numberOrName) {
Uri searchUri = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, Uri.encode(numberOrName));
String[] projection = new String[] { Phone.DISPLAY_NAME, Phone.NUMBER };
Cursor cur = getContentResolver().query(searchUri, projection, null, null, null);
List<ContactItem> contacts = new ArrayList<>();
assert cur != null;
while (cur.moveToNext()) {
String name = cur.getString(0);
String phoneNumber = cur.getString(1);
contacts.add(new ContactItem(name, phoneNumber));
}
cur.close();
return contacts;
}
I'm getting 'name = null' in this code, while cursor has all my contacts in it, i tried many different ways but it all does the same thing.
String[] contact_names, mobile_numbers;
Cursor cursor = getActivity().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,null, null, null);
while (cursor.moveToFirst()) {
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contact_names[contact_names.length] = name;
Cursor phones = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?" + contactId, null, null);
while (phones.moveToNext()) {
String number = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
mobile_numbers[mobile_numbers.length] = number;
}
phones.close();
}
cursor.close();
You don't need to query multiple times, use the following to get it all in one query,
String[] PROJECTION_MAIN = new String[]{
ContactsContract.Contacts._ID,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.Contacts.DISPLAY_NAME
};
Cursor cursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
PROJECTION_MAIN, null, null, null);
while (cursor.moveToNext()) {
String contact_id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String phone = cleanNumber(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)), context);
}
I know to retrieve the names of contacts that's code below. But what should I change in this code to also have the numbers of phone associated with the contact list?
var uri = ContactsContract.Contacts.ContentUri;
string[] projection = { ContactsContract.Contacts.InterfaceConsts.Id,
ContactsContract.Contacts.InterfaceConsts.DisplayName };
var cursor = ManagedQuery(uri, projection, null, null, null);
var contactList = new List<string>();
if (cursor.MoveToFirst())
{
do
{
String phoneNumber = cursor.GetString(cursor.GetColumnIndex(ContactsContract.CommonDataKinds.Phone.Number));
contactList.Add(cursor.GetString(
cursor.GetColumnIndex(projection[1])));
} while (cursor.MoveToNext());
}
I came across your question while I recently wrote a similar code. The only thing you need in order to retrieve phone numbers, is to:
Make another query to Uri
ContactsContract.CommonDataKinds.Phone.ContentUri;
Set projection to include ContactsContract.CommonDataKinds.Phone.Number; and
Select based on id, i.e. selection parameter should include "_id = " +
contactId
Your query should look like this:
string[] projection = { ontactsContract.CommonDataKinds.Phone.Number };
string selection = "_id = " + contactId;
var cursor = ContentResolver.Query(ContactsContract.CommonDataKinds.Phone.ContentUri, projection, selection, null, null);
This query will bring you phone numbers for a contact id but in code below, due to performance issues, I just made one call for all phone numbers and then assign each contract their numbers. Hope it helps.
private List<Contact> GetContactList()
{
List<Contact> contacts = new List<Contact>();
string[] projection = {
ContactsContract.Contacts.InterfaceConsts.Id,
ContactsContract.Contacts.InterfaceConsts.DisplayName,
ContactsContract.Contacts.InterfaceConsts.PhotoUri
};
var uri = ContactsContract.Contacts.ContentUri;
ICursor cursor = ContentResolver.Query(uri, projection, null, null, null);
if (cursor.MoveToFirst())
{
do
{
string id = cursor.GetString(cursor.GetColumnIndex(projection[0]));
string name = cursor.GetString(cursor.GetColumnIndex(projection[1]));
string photoUri = cursor.GetString(cursor.GetColumnIndex(projection[2]));
contacts.Add(new Contact() { Id = long.Parse(id), DisplayName = name, PhotoUri = photoUri });
} while (cursor.MoveToNext());
GetContactPhoneNumber(contacts);
}
return contacts;
}
private async void GetContactPhoneNumber(List<Contact> list)
{
string[] projection =
{
ContactsContract.CommonDataKinds.Phone.Number,
ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId
};
var cursor = ContentResolver.Query(ContactsContract.CommonDataKinds.Phone.ContentUri, projection, null, null, null);
if (cursor.Count > 0)
{
await Task.Factory.StartNew(() =>
{
do
{
try
{
string id = cursor.GetString(cursor.GetColumnIndex(projection[1]));
string phoneNumber = cursor.GetString(cursor.GetColumnIndex(projection[0]));
Contact contact = list.Where(c => c.Id == long.Parse(id)).FirstOrDefault();
contact.PhoneNumber = phoneNumber;
}
catch
{
}
} while (cursor.MoveToNext());
cursor.Close();
});
}
}
I am using the below code to fetch the local phone contacts. It is working fine and also fetching the contacts very fast.
But the problem comes here, in my contact list there are few contacts that are having multiple Emails and multiple phone numbers.
In case of multiple phone or emails address it repeats the name of the same person multiple times.
And if i change
ContactsContract.CommonDataKinds.Email.CONTENT_URI
to ContactsContract.CommonDataKinds.Phone.CONTENT_URI then it will repeat name according to the number of phone number exists for a contact. Please help
private static final String[] PROJECTION = new String[]{
ContactsContract.CommonDataKinds.Email.CONTACT_ID,
ContactsContract.CommonDataKinds.Nickname.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Email.DATA,
ContactsContract.CommonDataKinds.Phone.NUMBER,
};
ContentResolver cr = mContext.getContentResolver();
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, PROJECTION, null, null, null);
if (cursor != null) {
try {
final int contactIdIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.CONTACT_ID);
final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
final int emailIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
final int phoneIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
long contactId;
String displayName, email, phone, photo;
while (cursor.moveToNext()) {
mNK_UserModel = new NK_Contact();
contactId = cursor.getLong(contactIdIndex);
displayName = cursor.getString(displayNameIndex);
//Adding display name
mNK_UserModel.setFirstName(displayName);
Util.DEBUG_LOG(1, "contact", "contact id :" + contactId);
al_PhoneContacts.add(mNK_UserModel);
}
} finally {
cursor.close();
}
}
If i had to guess i would say you are missing a "break" in your while-loop. Since the cursor tries to fetch the next available column entry. But have a look at my solution which worked for me in the past.
It uses a seperate cursor for each row which gives you more control over the data.
Map<String, String> contactDataMap = new HashMap<String, String>();
Uri contactData = data.getData();
Cursor cursor = getContentResolver().query(contactData, null, null, null, null);
cursor.moveToFirst();
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
String id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
contactDataMap.put(NAME, (name != null)?name:"");
if (Integer.parseInt(cursor.getString(
cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id},
null);
while (pCur.moveToNext()) {
String number = pCur.getString(pCur.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
contactDataMap.put(PHONE, (number != null)?number:"");
break;
}
pCur.close();
}
Cursor emailCur = getContentResolver().query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{id}, null);
while (emailCur.moveToNext()) {
String email = emailCur.getString(
emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
contactDataMap.put(MAIL, (email != null)?email:"");
break;
}
emailCur.close();
cursor.close();
I want to get all contact in local address book of Android device by Group Name. Such as "Family", "Friends", "Work" ... like Address book in android device.
Here is my code:
public void getAllContactsByGroup(ContentResolver cr) {
String a = "Friends";
Uri CONTENT_URI_GR = ContactsContract.Groups.CONTENT_URI;
String GR_ID = ContactsContract.Groups._ID;
String GR_NAME = ContactsContract.Groups.TITLE;
Cursor cursor = getContentResolver().query(CONTENT_URI_GR,
null, GR_NAME + "=?", new String[] { a }, null);
while (cursor.moveToNext())
{
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
Cursor phones = cr.query(CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
countContact = phones.getCount();
while (phones.moveToNext())
{
contact_id = phones.getString(phones.getColumnIndex(_ID));
String name = phones.getString(phones.getColumnIndex(DISPLAY_NAME));
name1.add(name);
_idd.add(contact_id);
}
phones.close();
}
cursor.close();
}
I tried to get all contact in group "Friends" of Address book, but it gets all contacts of all groups.
try
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor cur = getContacts();
ListView lv = getListView();
String[] fields = new String[] {ContactsContract.Data.DISPLAY_NAME};
SimpleCursorAdapter adapter =
new SimpleCursorAdapter(this,
R.layout.main,
cur,
fields,
new int[] {R.id.txtbox});
lv.setAdapter(adapter);
}
private Cursor getContacts() {
// Run query
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection =
new String[]{ ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME };
String selection = null;
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME +
" COLLATE LOCALIZED ASC";
return managedQuery(uri, projection, selection, selectionArgs, sortOrder);
}