Getting duplicates in Arraylist which should have contacts - java

Im trying to save the users contacts in an ArrayList <Contacts> but somehow I got duplicates in it. I found out that I should use
ContractsContact.Contacts.CONTENT_URI
and not
ContractsContact.DATA.CONTENT_URI
But its not helping me. I still got dublicates in my ArrayList. Here is my code :
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);
// 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) {
// 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));
if (phoneNumber.charAt(0) == '0' && phoneNumber.charAt(1) == '0')
{
String temp = "+";
for(int j=2;j<phoneNumber.length();++j)
temp += phoneNumber.charAt(j);
phoneNumber = temp;
}
if (!phoneNumber.contains("+"))
{
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber normalized_number = null;
TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
String current_iso_code = telephonyManager.getSimCountryIso();
current_iso_code = current_iso_code.toUpperCase();
try {
normalized_number = phoneUtil.parse(phoneNumber,current_iso_code);
}catch(Exception e){
e.printStackTrace();
}
String str_normalized_number = phoneUtil.format(normalized_number, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL);
str_normalized_number = str_normalized_number.replaceAll(" ","");
str_normalized_number = str_normalized_number.replaceAll("\\(","");
str_normalized_number = str_normalized_number.replaceAll("\\)","");
contacts.add(new Contact (name,str_normalized_number,current_iso_code,contact_id));
}
else {
phoneNumber = phoneNumber.replaceAll(" ","");
phoneNumber = phoneNumber.replaceAll("\\(","");
phoneNumber = phoneNumber.replaceAll("\\)","");
phoneNumber = phoneNumber.replaceAll("-","");
String iso_code = null;
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
Phonenumber.PhoneNumber numberProto = phoneUtil.parse(phoneNumber, "");
iso_code = phoneUtil.getRegionCodeForNumber(numberProto);
}catch(Exception e){}
contacts.add(new Contact (name,phoneNumber,iso_code,contact_id));
}
}
phoneCursor.close();
}
}
Is there a wrong part in my code which I'm not seeing ?

I think Hash set Concept in Java may help to solve this problem as it removes duplicate items.I hope it will address the problem
The following link may help in this regard.
Removing Duplicate Values from ArrayList

Related

CallLog.Calls.CACHED_NAME is always returning null for some saved contacts

I am trying to show the call log details in my app but CallLog.Calls.CACHED_NAME is always returning null for some contacts even if it is a saved contact with name. The built-in call log is showing the names for these contacts correctly.
This is my code:
protected customAdapRecent doInBackground(Void... params) {
ContentResolver resolver = context.getContentResolver();
final String[] PROJECTION = new String[] {
// CallLog.Calls.CACHED_LOOKUP_URI,
CallLog.Calls.NUMBER,
CallLog.Calls.CACHED_NAME,
CallLog.Calls.TYPE,
CallLog.Calls.DATE,
CallLog.Calls.DURATION
};
Cursor cursor = resolver.query(CallLog.Calls.CONTENT_URI, PROJECTION, null, null, CallLog.Calls.DATE + " DESC");
if(cursor.getCount() > 0)
{
int iNumber = cursor.getColumnIndex(CallLog.Calls.NUMBER);
int iName = cursor.getColumnIndex(CallLog.Calls.CACHED_NAME);
int iType = cursor.getColumnIndex(CallLog.Calls.TYPE);
int iDate = cursor.getColumnIndex(CallLog.Calls.DATE);
int iDuration = cursor.getColumnIndex(CallLog.Calls.DURATION);
DateFormat datePattern = DateFormat.getDateInstance(DateFormat.FULL);
String number;
String name;
String type;
String date;
String duration;
String contactId;
String callIs = "None";
String prevDate = "";
int callType;
while (cursor.moveToNext())
{
if(cursor.getString(iName) == null)
Log.e("DEBUG: ", "Position: " + cursor.getPosition());
number = cursor.getString(iNumber);
name = cursor.getString(iName);
type = cursor.getString(iType);
String tempdate = cursor.getString(iDate);
Long tempDate = Long.parseLong(tempdate);
date = datePattern.format(tempDate);
if(prevDate.equalsIgnoreCase(date))
{
prevDate = date;
date = "";
}
else
prevDate = date;
//date = new Date(Long.valueOf(strdate));
duration = cursor.getString(iDuration);
callType = Integer.parseInt(type);
switch (callType)
{
case CallLog.Calls.OUTGOING_TYPE:
callIs = "OUT";
recentRow newRowO = new recentRow(number, name, date, duration, callIs);
listItem_recentOut.add(newRowO);
break;
case CallLog.Calls.INCOMING_TYPE:
callIs = "IN";
recentRow newRowI = new recentRow(number, name, date, duration, callIs);
listItem_recentIn.add(newRowI);
break;
case CallLog.Calls.MISSED_TYPE:
callIs = "MISS";
recentRow newRowM = new recentRow(number, name, date, duration, callIs);
listItem_recentMiss.add(newRowM);
break;
}
recentRow newRow = new recentRow(number, name, date, duration, callIs);
//recentRow newRow = new recentRow(number, name, callIs);
listItem_recentAll.add(newRow);
}
cursor.close();
cAdapRecent = new customAdapRecent(context, listItem_recentAll);
}
return cAdapRecent;
}
The Debug statement given in the Log.e() is also printing.
Am I doing something wrong in the lookup? Pls. suggest a way as I am really blocked due to this!
Thanks in advance...
I also came across this strange behavior and figured out that sometimes you can't get name of the contact immediately even though you can get everything else from the CallLog.Calls. What I noticed is that after approximately one hour or so since that call you can fetch name along with all other CallLog.Calls data. Very strange. If you need immediate refresh after call you can get name for the number from ContactsContract like this:
fun getNameForNumber(context: Context, number: String): String? {
var res: String? = null
try {
val resolver = context.contentResolver
val uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number))
val c = resolver.query(uri, arrayOf(ContactsContract.PhoneLookup.DISPLAY_NAME), null, null, null)
if (c != null) {
if (c.moveToFirst()) {
res = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
}
c.close()
}
} catch (e: Exception) {
e.printStackTrace()
}
return res
}
Strangely, after you fetch one name from the ContactsContract fetching name in the way you did it, through CallLog.Calls.CACHED_NAME, misteriously works.
This is also answer for #PeterB and #shyam002

How get only mobile numbers in contact

I have the below code to get contact name and number. How to get only mobile numbers and name in contact? A name in contact may have a few numbers. How to get mobile numbers for a name?
ContentResolver cr = activity.getContentResolver();
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
while (phones.moveToNext()) {
name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
Try to use this code. Work for me.
private static final String[] PROJECTION =
{
Contacts._ID,
Contacts.LOOKUP_KEY,
Contacts.HAS_PHONE_NUMBER,
Build.VERSION.SDK_INT
>= Build.VERSION_CODES.HONEYCOMB ?
Contacts.DISPLAY_NAME_PRIMARY :
Contacts.DISPLAY_NAME
};
private static final String[] PROJECTION_PHONE =
{
Phone.NUMBER
};
private static final String SELECTION_PHONE = Phone.LOOKUP_KEY + " = ?";
HashMap<String, ArrayList<String>> contacts = new HashMap<>();
ContentResolver cr = context.getContentResolver();
Cursor cur = cr.query(Contacts.CONTENT_URI,
PROJECTION, null, null, null); //get contacts
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(
cur.getColumnIndex(Contacts._ID));
String name = cur.getString(
cur.getColumnIndex(Build.VERSION.SDK_INT
>= Build.VERSION_CODES.HONEYCOMB ?
Contacts.DISPLAY_NAME_PRIMARY :
Contacts.DISPLAY_NAME));
String lookUpKey = cur.getString(cur.getColumnIndex(Contacts.LOOKUP_KEY));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(Contacts.HAS_PHONE_NUMBER))) > 0) { //check if has numbers
Cursor pCur = cr.query(Phone.CONTENT_URI, PROJECTION_PHONE, SELECTION_PHONE,
new String[]{lookUpKey}, null); //get contacts phone numbers
ArrayList<String> phones = new ArrayList<>();
while (pCur.moveToNext()) {
String phone = pCur.getString(0);
phones.add(phone);
}
contacts.put(name, phones);
pCur.close();
}
}
}
cur.close();
You could query the ContactsContract.CommonDataKinds.Phone.TYPE column to determine the type of the number:
int type = phones.getInt(phones.
getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
if(type == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) {
phoneNumber = phones.getString(phones.
getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
// Query phone here. Covered next
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id,null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i("Number", phoneNumber);
}
phones.close();
}
}
}
You will have to ask for this permission:
uses-permission android:name="android.permission.READ_CONTACTS"

fetch all android contacts and details and put in single multidimensional array

Am new to android(Java) and i want to perform a simple task
how can i Fetch all the contacts phone numbers, email, and fullname on the device and their details and put
them in a single array as such
I am from a PHP BACKGROUND SO THE ARRAY WOULD LOOK LIKE THIS IN PHP :
ContactsArray[0] = array(
'fullname' => 'John doe',
'Phone' => '0909809890' ,
'email' => 'johndoe#email.com'
)
Thats what the array should look like from a PHP perspective,
Am new to android and would like a class to fetch all this data
put them in a single array
return the data.
PSEUDO CODE
function GetContacts(){
contacts = fetchAllContactsDetails
return contacts;
}
This could be a start. Please note that I haven't tested this out and there could be errors but you'll get the idea.
Read this for more info on multi dimensional array. Link
String phpArray;
int x=3;
int y=array.length();
String[][] myStringArray = new String [y][x];
for(int i=0; i<array.length; i++){
for(int j=0; j<3; j++){
phpArray = contactsArray[i];
myStringARray[i][j] = phpArray[j];
}
}
First you need add the permission to read the contacts in your manifest file:
<uses-permission android:name="android.permission.READ_CONTACTS" >
</uses-permission>
And you can check this code:
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);
}
}
}

Contact Details Returned Twice

I am trying fetch contact details such as Name, phone number, email and photo. attached to a contact in an arraylist.
But for a contact having both phone number and email address. I can see the same contact name twice at first with its email address & then with its phone number and is not shown as a single contact (which it should be).
Can anyone please help me out with this?
TIA :)
Ref.:
public ArrayList<User> getPhoneContact(String paramString, ArrayList<User> paramArrayList)
throws CustomException
{
//Cursor localCursor = null;
Cursor cursor = null;
ArrayList localArrayList = new ArrayList();
User user;
boolean flag;
String s1;
String s2;
String s6;
String s5;
String s3;
String s4;
int i;
int j;
int k;
int l;
int i1;
try
{
cursor = getNamesAndPictures(paramArrayList);
if(cursor != null && cursor.moveToFirst()){
user = null;
i = cursor.getColumnIndex("data1");
j = cursor.getColumnIndex("contact_id");
k = cursor.getColumnIndex("display_name");
l = cursor.getColumnIndex("data1");
i1 = cursor.getColumnIndex("mimetype");
s1 = null;
do{
s2 = cursor.getString(j);
if(s2 == null)
return localArrayList;
//if(s2.equals(s1))
//return localArrayList;
user = new User();
s1 = s2;
s3 = cursor.getString(k);
user.setName(s3);
user.setContactId(s2);
user.setContactType(paramString);
s4 = cursor.getString(i1);
if(s4 != null){
if(s4.equals("vnd.android.cursor.item/phone_v2")){
s6 = cursor.getString(i);
user.setPhone(s6);
}
else if(s4.equals("vnd.android.cursor.item/email_v2")){
s5 = cursor.getString(l);
user.setEmail(s5);
}
}
localArrayList.add(user);
}while(cursor.moveToNext());
}
}
catch (Exception localException)
{
//localException
}
finally
{
//closeCursor(localCursor);
closeCursor(cursor);
closeDatabase();
}
return localArrayList;
}
And:
private Cursor getNamesAndPictures(ArrayList<User> paramArrayList)
{
String str1 = prepareContactIdsString(paramArrayList);
ContentResolver localContentResolver = this.getAppContext().getContentResolver();
String[] arrayOfString = { "data1", "contact_id", "display_name", "_id", "data1", "mimetype" };
String str2 = "display_name != 'null' AND ( (mimetype = 'vnd.android.cursor.item/phone_v2' AND is_primary != -1 ) OR (mimetype = 'vnd.android.cursor.item/email_v2' AND is_primary != -1 ) ) AND contact_id NOT IN ( " + str1 + ")";
return localContentResolver.query(android.provider.ContactsContract.Data.CONTENT_URI, arrayOfString, str2, null, "display_name COLLATE LOCALIZED ASC");
}
this is because you query the Data table which holds data rows , each row foe some kind of information about the contact, for example one row for email and one row for phone number.
if you want to get only the contacts you should query ContactsContract.Contacts table but then you will have to query for each of them the email and phone.
http://developer.android.com/guide/topics/providers/contacts-provider.html

problem with reading contacts in android

i'm trying to read contacts with this code but it only gets Contacts but not contacts data.Please
tell me am i going on a wrong path or what is wrong with this.
Cursor contacts = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while(contacts.moveToNext()) {
int contactIdColumnIndex = contacts.getColumnIndex(ContactsContract.Contacts._ID);
long contactId = contacts.getLong(contactIdColumnIndex);
System.out.println(contactId);
Cursor c = getContentResolver().query(Data.CONTENT_URI,
new String[] {Data._ID, Phone.NUMBER, Phone.TYPE},
Data.CONTACT_ID + "=?" + " AND "
+ Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'",
new String[] {String.valueOf(contactId)}, null);
//retrieving data
while(c.moveToNext()){
long Id=c.getLong(0);
String number=c.getString(1);
String type=c.getString(2);
String name=c.getString(3);
System.out.println(Id);
System.out.println(number);
System.out.println(type);
System.out.println(name);
}
c.close();
}
contacts.close();
This runs well when i debug this and it only print ContactIds only
1
2
3
4
but no data...(apologize for long question)
try this code
String number = "";
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,null,null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER},
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
for(int i=0;i<pCur.getColumnCount();i++)
number = pCur.getString(i);
}
pCur.close();
pCur = null;
}
}
}
cur.close();
cur = null;
cr = null;

Categories

Resources