Querying the Contacts Database for phone number and handling multiple numbers - android

I want to query the Contacts Database for phone number and if the selected contact has multiple numbers, I display the available numbers for the user to select one of them.
I have code in place that would pick up the default number of the selected contact.
Cursor cursor = null;
String phoneNumber = "";
try
{
Uri result = data.getData();
// get the contact id from the Uri
String id = result.getLastPathSegment();
// query for everything email
cursor = getContentResolver().query(Phone.CONTENT_URI,
null, Phone.CONTACT_ID + "=?", new String[] { id },
null);
int pNumberIdx = cursor.getColumnIndex(Phone.NUMBER);
// let's just get the first email
if (cursor.moveToFirst())
{
phoneNumber = cursor.getString(pNumberIdx);
}
}
catch (Exception e)
{
}
finally
{
if (cursor != null)
{
cursor.close();
}
EditText emailEntry = (EditText) findViewById(R.id.pNumber);
emailEntry.setText(phoneNumber);
if (phoneNumber.length() == 0)
{
Toast.makeText(this, "No number found for contact.",
Toast.LENGTH_LONG).show();
}
}

Related

Read contacts from phone is very slow

I am trying to get all contact from my phone, including get all numbers from contacts with multiple numbers.
So i've build query that while not over run all over contacts, and build Contact user, and have inside query with id selection to get all numbers for each user. but since my inside query is including selection it takes a long time. any other idea?
private Cursor initPhoneCursor() {
try {
// get the contacts URI
final Uri phoneUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
// get the name column's name depending on the Android Version
final String nameColumn = Contact.COLUMN_NAME_PHONE;
// declare columns object - init later depending on version
String selection = getQuerySelectionForCursor();
String[] columns = getColumnSelectionForCursor(nameColumn);
if (mApp != null) {
// return cursor from contentresolver
return mApp.getContentResolver().query(phoneUri, columns, selection, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
}
} catch (Exception e) {
// couldn't read phone cursor
CaughtExceptionHandler.reportException(e);
}
return null;
}
private void importContactsFromCursor(Cursor cursor, boolean isSimCard) {
mCurrentContactCursor = initPhoneCursor();
// check cursor is alive
if (cursor != null && !cursor.isClosed()) {
while (cursor.moveToNext() && shouldContinueImport()) {
// // as log as we have contacts, move through them
importContact(cursor, isSimCard);
mCurrentContact++;
}
// when done - close the cursor
cursor.close();
}
}
private void importContact(Cursor cursor, boolean simCard) {
// create Contact object
Contact row = new Contact(cursor, simCard);
// mContactsTimer.onContactCreated();
if (simCard) {
// if simCard, contact must have number
// validate number and create contact
row = validateAndCheckNumber(row, cursor);
}
else {
// if not sim card (phone cursor), a contact might have no numbers,
// single or multiple phone numberss
// let's check if this contact has any numbers
if (hasPhoneNumbers(cursor)) {
// get all of the contact's phone numbers
row = importAllNumbersForContact(row);
}
}
// check if this is valid
final boolean isValidForSaving = row != null && row.hasName() && row.hasNumbers();
if (isValidForSaving && !sStopRequested) {
mContactsToSave.add(row);
}
}
private Contact importAllNumbersForContact(Contact contact) {
// uri of contact phones
Uri contentUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
// contact_id = ?
String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?";
String[] selectionArgs = {String.valueOf(contact.getOriginalId())};
// do the query
Cursor phoneCursor = mApp.getContentResolver().query(contentUri, null, selection, selectionArgs, null);
if (phoneCursor != null) {
// save numbers if we got anything
contact = loopThroughContactNumbers(contact, phoneCursor);
// close cursor when done
phoneCursor.close();
}
return contact;
}
Go with the following solution:
Map<String,Contact> contactsMap = new TreeMap<>();
contacts = new ArrayList<>();
Cursor phones = getBaseContext().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" ASC");
assert phones != null;
while (phones.moveToNext())
{
Contact contact = new Contact();
contact.setDisplayName(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
contact.setPhoneNumber(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
contact.setDisplayPicture(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI)));
contactsMap.put(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)),contact);
}
contacts.addAll(contactsMap.values());
phones.close();
Modify it for all numbers of a contact. You are good to go with.

Can't get all contacts when use ContactsContract.CommonDataKinds.Phone

Below is the code I used to get all contacts from phone.
public static ArrayList<Recipient> getAllRecipient(Context context) {
ArrayList<Recipient> contacts = new ArrayList<>();
Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if (cursor != null) {
try {
final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
final int numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
final int typeIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
final int uriIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI);
String displayName, number, uri;
while (cursor.moveToNext()) {
int type = cursor.getInt(typeIndex);
if (type == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) {
displayName = cursor.getString(displayNameIndex);
number = cursor.getString(numberIndex);
number = number.replaceAll("[^0-9+]+", "");//remove all special character and space, just keep digit number and "+"
uri = cursor.getString(uriIndex);
Recipient recipient = new Recipient(displayName, number, uri);
contacts.add(recipient);
}
}
} catch (Exception e) {
LogUtil.debug("can't get recipient: " + e.getMessage());
} finally {
cursor.close();
}
}
cursor.close();
return contacts;
}
I got feedback from many users , they can not get full contacts in their phones, show almost contacts but missed some contacts.
Is there any problem with above code ? Thanks.
Use this code
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));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
phones.close();
Phone.CONTENT_URI includes all Phone entries of the device. If a contact does not have some phone you are not going to get any information about it.
If contacts is what you are after, you should query the ContactsContract.Contacts.CONTENT_URI.
Keep in mind that contacts and phone are two separate things for Android. Not all contacts have phone numbers and you would have to query the numbers separately.

Duplicate contacts are listed while reading device contacts

I am trying to read contacts from device. I am getting the list of device contacts , but the problem is most of them are duplicates. But in my default contacts app those duplicates are not there. Right now it is returning around 1150 contacts from device out of that around 602 are duplicates (when I checked the result using log), but my default contacts App is not showing this duplicates. This is my code
private void readPhoneContacts(Context context) {
try {
Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
HashMap<String, Contact> mContactListItems = new HashMap<>();
if (cursor != null) {
while (cursor.moveToNext()) {
String key = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String image_uri = "";
String phoneNumber = "";
String name = "";
String emailId = null;
int image_urlCursorIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI);
if (!cursor.isNull(image_urlCursorIndex)) {
image_uri = cursor.getString(image_urlCursorIndex);
}
int phoneNumberCursorIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
if (!cursor.isNull(phoneNumberCursorIndex)) {
phoneNumber = cursor.getString(phoneNumberCursorIndex);
}
int nameCursorIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
if (!cursor.isNull(nameCursorIndex)) {
name = cursor.getString(nameCursorIndex);
}
emailId = cursor.getString(ContactsContract.CommonDataKinds.Email.TYPE_HOME);
Contact contact = new Contact();
contact.setName(name);
contact.setEmailId(emailId);
contact.setMobileNumber(phoneNumber);
contact.setId(key);
key = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
if (image_uri != null && !image_uri.isEmpty()) {
contact.setHasLocalContactImage(true);
contact.setDeviceContactImageUri(Uri.parse(image_uri));
}
mContactListItems.put(String.valueOf(key), contact);
}
cursor.close();
}
} catch (SQLiteException e) {
} catch (SecurityException e) {
} catch (Exception e) {
}
}
What I want to get is Id , Name , Phone number , Email Id of all contacts from device. Also it should list all types of phone and email (home , office etc). Is there any way to avoid duplicates and get these data? Thanks in advance.

Get all phone number from a single contact and set in edittext

I want to get all phone numbers from a selected contact in edittext. My problem is edittext only displays the first phone number of that selected contact. Suppose a contact has two numbers like 12345 and 00001. My edittext only displays the first number 12345 but I'd like 12345,00001.
I'm trying with this:
Cursor cursor = null;
String phoneNumber = "";
int phoneIdx = 0;
Uri result = data.getData();
String id = result.getLastPathSegment();
cursor = getContentResolver().query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + "=?", new String[] { id }, null);
phoneIdx = cursor.getColumnIndex(Phone.DATA);
if (cursor.moveToFirst()) {
phoneNumber = cursor.getString(phoneIdx);
cursor.moveToNext();
}
else {
}
}
finally {
if (cursor != null) {
cursor.close();
}
final EditText phoneInput = (EditText) findViewById(R.id.contact_phone);
nameEntry.setText(phoneNumber);
}
Write
cursor.moveToFirst();
while (cursor.isAfterLast() != true) {
if (phoneNumber.equals("")) {
phoneNumber = cursor.getString(phoneIdx);
}
else {
phoneNumber = phoneNumber + "," + cursor.getString(phoneIdx);
}
cursor.moveToNext();
}
Instead of
if (cursor.moveToFirst()) {
phoneNumber = cursor.getString(phoneIdx);
cursor.moveToNext();
}

Using contact picker to get multiple data

I was able to successfully launch the contact picker and then set an editText in my activity to the phone number of the selected contact. What I'm trying to do now is to set two other editTexts to the first name and last name, respectively. I added the other editTexts and tried to retrieve the last and first name.
Here's what I have:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case CONTACT_PICKER_RESULT:
Cursor cursor = null;
String number = "";
String lastName = "";
String firstName = "";
try {
Uri result = data.getData();
Log.v(DEBUG_TAG, "Got a contact result: "
+ result.toString());
// get the contact id from the Uri
String id = result.getLastPathSegment();
// query for phone number
cursor = getContentResolver().query(Phone.CONTENT_URI,
null, Phone.CONTACT_ID + "=?", new String[] { id },
null);
int phoneIdx = cursor.getColumnIndex(Phone.DATA);
int lastNameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds
.StructuredName.FAMILY_NAME);
int firstNameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds
.StructuredName.GIVEN_NAME);
// get the phone number
if (cursor.moveToFirst()) {
number = cursor.getString(phoneIdx);
lastName = cursor.getString(lastNameIdx);
firstName = cursor.getString(firstNameIdx);
Log.v(DEBUG_TAG, "Got number " + number);
} else {
Log.w(DEBUG_TAG, "No results");
}
} catch (Exception e) {
Log.e(DEBUG_TAG, "Failed to get phone number data", e);
} finally {
if (cursor != null) {
cursor.close();
}
EditText phoneNumberEditText = (EditText) findViewById(R.id.number);
phoneNumberEditText.setText(number);
EditText lastNameEditText = (EditText)findViewById(R.id.last_name);
lastNameEditText.setText(lastName);
EditText firstNameEditText = (EditText)findViewById(R.id.first_name);
firstNameEditText.setText(firstName);
if (number.length() == 0) {
Toast.makeText(this, "No phone number found for this contact.",
Toast.LENGTH_LONG).show();
}
if(lastName.length()==0) {
Toast.makeText(this, "No last name found for this contact.",
Toast.LENGTH_LONG).show();
}
if(firstName.length()==0) {
Toast.makeText(this, "No first name found for this contact.",
Toast.LENGTH_LONG).show();
}
}
break;
}
} else {
Log.w(DEBUG_TAG, "Warning: activity result not ok");
}
}
I must be missing something basic. Any thoughts?
Try this:
String lastName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME))
If you call a managedQuery it will return the contacts full name and the id but no phone number.
Cursor cursor = managedQuery(intent.getData(), null, null, null, null);
cursor.moveToNext(); String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name=cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));

Categories

Resources