Hey all i have a programmer thats having some trouble with getting my phone image to display in an app. the following code is what he is using to get the contact picture:
private long getContactIdFromNumber(String number) {
Cursor c = null;
try {
String[] projection = new String[] { Contacts.Phones.PERSON_ID };
Uri contactUri = Uri.withAppendedPath(
Contacts.Phones.CONTENT_FILTER_URL, Uri.encode(number));
c = getContentResolver().query(contactUri, projection, null, null,
null);
if (c.moveToFirst()) {
long contactId = c.getLong(c
.getColumnIndex(Contacts.Phones.PERSON_ID));
return contactId;
}
} finally {
c.close();
}
return -1;
}
private boolean initPhoto() {
boolean result = true;
try {
contactPhoto = People.loadContactPhoto(getApplicationContext(),
ContentUris.withAppendedId(People.CONTENT_URI,
getContactIdFromNumber(phoneNumber)),
R.drawable.header, null);
} catch (Exception e) {
result = false;
}
return result;
}
if (initPhoto()) {
contact1.setImageBitmap(contactPhoto);
contact2.setImageBitmap(contactPhoto);
contact3.setImageBitmap(contactPhoto);
}
I made a contact with my phone number and image but it never loads up in the app. What should he be looking for in the code i posted above in order to make sure it is grabbing the correct phone number?
Do you have to use Contacts instead of ContactsContract? Contacts was deprecated in API level 5.
If you're trying to load a photo for a phone number, use ContactsContract.PhoneLookup. There's an example in the reference doc for android.provider.ContactsContract.PhoneLookup. Querying on that table will return LOOKUP_KEY for the Contact. Use that to query
ContactsContract.Contacts.Photo.
Turned out the number was formatted incorrectly. It was looking for xxxxxxxxxx and the number was this way (xxx)xxx-xxxx in the phone so it never matched up.
Related
So I made this question but nobody answered: How to identify a contact by pressing it in Android Studio?
Maybe because it was hard to understand, so I'll explain in a short manner.
How can I remove a specific contact by pressing it?
I saw this similar question, but I don't know what to insert in the deleteContact(Context ctx, String phone, String name) parameters.
Anyways, here's the code used there:
public static boolean deleteContact(Context ctx, String phone, String name) {
Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone));
Cursor cur = ctx.getContentResolver().query(contactUri, null, null, null, null);
try {
if (cur.moveToFirst()) {
do {
if (cur.getString(cur.getColumnIndex(PhoneLookup.DISPLAY_NAME)).equalsIgnoreCase(name)) {
String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
ctx.getContentResolver().delete(uri, null, null);
return true;
}
} while (cur.moveToNext());
}
} catch (Exception e) {
System.out.println(e.getStackTrace());
}
return false;
}
I don't know if this is the best code to use in my case, but here's the button connected to the "Remove Contacts" button code in the MainActivity.java:
Button rem_btn = findViewById(R.id.rem_btn);
rem_btn.setOnClickListener(v -> deleteContacts());
As you can see, deleteContacts() needs parameters, I just don't know what context is needed (apparently none in the MainActivity, but then half the code disappears; I didn't even know my phone had a String attached to it; I also don't know if the name stands for the contact's name or the phone's name).
If you want more details, the link is at the top.
Really hope someone can help me.
Hey i use that code same in my application is work totally fine in all devices the parameters are
deleteContact(MainActivity.this, name eg-jhony, number eg-123578996)
But make sure to also add this in your mainactivity for working the parameters
public static boolean deleteContact(Context ctx, String name, String phone) {
Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone));
Cursor cur = ctx.getContentResolver().query(contactUri, null, null, null, null);
try {
if (cur.moveToFirst()) {
do {
if (cur.getString(cur.getColumnIndex(PhoneLookup.DISPLAY_NAME)).equalsIgnoreCase(name)) {
String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
ctx.getContentResolver().delete(uri, null, null);
return true;
}
} while (cur.moveToNext());
}
} catch (Exception e) {
System.out.println(e.getStackTrace());
}
return false;
}
So I've written a query to extract the WhatsApp contacts of a phone. My initial query goes like this:
Cursor c = con.getContentResolver().query(
ContactsContract.RawContacts.CONTENT_URI,
new String[]{ContactsContract.RawContacts.CONTACT_ID, ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY},
ContactsContract.RawContacts.ACCOUNT_TYPE + "= ?",
new String[]{"com.whatsapp"},
null
);
ArrayList<String> myWhatsappContacts = new ArrayList<String>();
int contactNameColumn = c.getColumnIndex(ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY);
while (c.moveToNext()) {
// You can also read RawContacts.CONTACT_ID to read the
// ContactsContract.Contacts table or any of the other related ones.
myWhatsappContacts.add(c.getString(contactNameColumn));
}
The purpose of this is to find out how many WhatsApp contacts the phone has at any one time. When I do:
Log.i("WhatsApp contacts found:", Integer.toString(myWhatsappContacts.size());
It should print out how many WhatsApp contacts there were into LogCat. And this works - up to a point.
Let's say for example that the number of WhatsApp contacts I have now is 101. The next phase of this little project is to delete away ALL contacts if there are more than 100 of them. In which case, we go:
if (myWhatsappContacts.size() > 100) {
//Delete all contacts code here
}
I've tested the delete contacts code, it works. I check the contacts directory of the phone via the contacts app, and it says 0. But now when I do the query again (refer to code above), it still shows 101! What's going on?
If it helps, my DeleteContacts method is as follows:
private void deleteContact(Context ctx, String phone, String name) {
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone));
Cursor cur = ctx.getContentResolver().query(contactUri, null, null, null, null);
try {
if (cur.moveToFirst()) {
do {
if (cur.getString(cur.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME)).equalsIgnoreCase(name)) {
String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
ctx.getContentResolver().delete(uri, null, null);
return;
}
} while (cur.moveToNext());
}
} catch (Exception e) {
System.out.println(e.getStackTrace());
} finally {
cur.close();
}
return;
}
What am I doing wrong? Is my DeleteContacts code faulty? Or is the query itself faulty?
I implemented a code to retrieve all contacts but it is not showing all contacts where few of them are missed.
Here is my code:
String[] projection = new String[]{
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER,
};
Cursor cursor = null;
try {
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, null, null, null);
} catch (SecurityException e) {
}
if (cursor != null) {
try {
HashSet<String> normalizedNumbersAlreadyFound = new HashSet<>();
int indexOfNormalizedNumber = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER);
int indexOfDisplayName = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int indexOfDisplayNumber = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
while (cursor.moveToNext()) {
String normalizedNumber = cursor.getString(indexOfNormalizedNumber);
if (normalizedNumbersAlreadyFound.add(normalizedNumber)) {
String displayName = cursor.getString(indexOfDisplayName);
String displayNumber = cursor.getString(indexOfDisplayNumber);
listOfContacts.add(new PhoneContactsModel(displayName, displayNumber, false));
} else {
}
}
Log.d("tag", "size of listOfContacts =1====" + listOfContacts.size());
} finally {
cursor.close();
}
}
don't know what is happening. Please help me.
There are many issues in the code:
You're querying over the CommonDataKinds.Phone.CONTENT_URI table, so naturally, you won't get contacts that have no phone numbers (e.g. contacts with name and email)
You're skipping contacts that contains phones you've already encountered in normalizedNumbersAlreadyFound, so if you have two contacts with a shared phone (like a home phone number) you might skip one of them.
CommonDataKinds.Phone.NORMALIZED_NUMBER may be null, in which case you'll skip many contacts that do not have their NORMALIZED_NUMBER field set
If you need to also include contacts that have no phones, I would recommend a completely different code. If you only need to get contacts with phones, I would recommend not relying on NORMALIZED_NUMBER, and instead add CommonDataKinds.Phone.CONTACT_ID to your projection, and have that as your unique key per contact.
I'm developing a SMS application and come to the following issue. Currently I can read SMS conversation by using provider Telephony.Sms.Conversations by using CursorLoader. From cursor returned by this CursorLoader, I can display conversations's address which are phone numbers.
My question is how to retrieve SMS conversation contact name efficiently to display along with SMS conversation, not the phone number. Is there anyway to load list of contacts from list of phone numbers returned by the CursorLoader before?. Of course I've tried to load one by one contact name by using phone number but that terribly reduce the application performance.
Thank you in advance.
I've been searching for a solution myself and eventually came out with a good compromise in my opinion.
As soon as my query is finished, I store in an HashMap<String, String> contact_map my values as
int SENDER_ADDRESS = cursor.getColumnIndex(Telephony.TextBasedSmsColumns.ADDRESS);
while (cursor.moveToNext()) {
contact_map.put(
cursor.getString(SENDER_ADDRESS),
getContactName(getApplicationContext(), cursor.getString(SENDER_ADDRESS))
);
}
Method getContactName:
public static String getContactName(Context context, String phoneNumber) {
ContentResolver cr = context.getContentResolver();
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = cr.query(uri, new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
if (cursor == null) {
return null;
}
String contactName = null;
if(cursor.moveToFirst()) {
contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
}
if(cursor != null && !cursor.isClosed()) {
cursor.close();
}
if (contactName != null) {
return contactName;
} else {
return phoneNumber;
}
}
EDIT:
I then get the contact name with
String name = contact_map.get(cursor.getString(SENDER_ADDRESS));
Hope it helps!
In my android app when an incoming call i want to show my custom ui and i am able to do this.
No i want to check incoming number is from contacts or not.
Below is my code for doing so but it returns null for an incoming number which is stored in my contacts list.
public String findNameByNumber(String num){
Uri uri = Uri.withAppendedPath(Phones.CONTENT_FILTER_URL, Uri.encode(num));
String name = null;
Cursor cursor = mContext.getContentResolver().query(uri,
new String[] { Phones.DISPLAY_NAME }, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
name = cursor.getString(cursor.getColumnIndex(Phones.DISPLAY_NAME));
cursor.close();
callyName.setText(name+" Calling..");
}
return name;
}
and i have incoming call from a number say+917878787878 but in my contacts this contact is stored as name XYZ with number 78 78 787878,which is formated because between number there are space.and also try by excluding +91 but still it returns null.
So how can i find number which is stored in any format.Which may be stored with country code or not.
Thanks In advance.
Try this code instead (using PhoneLookup.CONTENT_FILTER_URI instead of Phones):
String res = null;
try {
ContentResolver resolver = ctx.getContentResolver();
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor c = resolver.query(uri, new String[]{PhoneLookup.DISPLAY_NAME}, null, null, null);
if (c != null) { // cursor not null means number is found contactsTable
if (c.moveToFirst()) { // so now find the contact Name
res = c.getString(c.getColumnIndex(CommonDataKinds.Phone.DISPLAY_NAME));
}
c.close();
}
} catch (Exception ex) {
/* Ignore */
}
return res;
As docs says ContactsContract.PhoneLookup: A table that represents the result of looking up a phone number, for example for caller ID. To perform a lookup you must append the number you want to find to CONTENT_FILTER_URI. This query is highly optimized.