I am trying to save all contacts telephone numbers in an ArrayList but I cant find a way how. Is there a way to get them instead of picking them one by one with ContactsCont
This code will work much faster than code in the answer, because you don't make additional query for each contact.
private static final String CONTACT_ID = ContactsContract.Contacts._ID;
private static final String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
private static final String PHONE_NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
private static final String PHONE_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
public static ArrayList<String> getAll(Context context) {
ContentResolver cr = context.getContentResolver();
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{PHONE_NUMBER, PHONE_CONTACT_ID},
null,
null,
null
);
if(pCur != null){
if(pCur.getCount() > 0) {
HashMap<Integer, ArrayList<String>> phones = new HashMap<>();
while (pCur.moveToNext()) {
Integer contactId = pCur.getInt(pCur.getColumnIndex(PHONE_CONTACT_ID));
ArrayList<String> curPhones = new ArrayList<>();
if (phones.containsKey(contactId)) {
curPhones = phones.get(contactId);
}
curPhones.add(pCur.getString(pCur.getColumnIndex(PHONE_NUMBER)));
phones.put(contactId, curPhones);
}
Cursor cur = cr.query(
ContactsContract.Contacts.CONTENT_URI,
new String[]{CONTACT_ID, HAS_PHONE_NUMBER},
HAS_PHONE_NUMBER + " > 0",
null,null);
if (cur != null) {
if (cur.getCount() > 0) {
ArrayList<String> contacts = new ArrayList<>();
while (cur.moveToNext()) {
int id = cur.getInt(cur.getColumnIndex(CONTACT_ID));
if(phones.containsKey(id)) {
contacts.addAll(phones.get(id));
}
}
return contacts;
}
cur.close();
}
}
pCur.close();
}
return null;
}
This method is optimized as well as fetch only distinct contacts
@RequiresApi(api = Build.VERSION_CODES.N)
private List<ModelContacts> getContacts() {
ArrayList<ModelContacts> list = new ArrayList<>();
Cursor cursor = this.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
cursor.moveToFirst();
while (cursor.moveToNext()) {
list.add(new ModelContacts(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
, cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))));
}
cursor.close();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
List<ModelContacts> distinctList = list.stream().filter(distinctByKey(c -> c.getName()))
.collect(Collectors.toList());
return distinctList;
}
else {
return list;
}
}
@RequiresApi(api = Build.VERSION_CODES.N)
public static <T> Predicate<T> distinctByKey (final Function<? super T, Object> keyExtractor)
{
Map<Object, Boolean> map = new ConcurrentHashMap<>();
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
in kotlin try this to get all contacts
fun getContacts(ctx: Context): List<ContactModel>? {
val list: MutableList<ContactModel> = ArrayList()
val contentResolver = ctx.contentResolver
val cursor: Cursor? =
contentResolver.query(
ContactsContract.Contacts.CONTENT_URI, null,
null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"
)
if (cursor!!.count > 0) {
while (cursor.moveToNext()) {
val id =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID))
if (cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
val cursorInfo: Cursor? = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
arrayOf(id),
null
)
val inputStream: InputStream? =
ContactsContract.Contacts.openContactPhotoInputStream(
ctx.contentResolver,
ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI,
id.toLong()
)
)
val person: Uri =
ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI,
id.toLong()
)
val pURI: Uri = Uri.withAppendedPath(
person,
ContactsContract.Contacts.Photo.CONTENT_DIRECTORY
)
var photo: Bitmap? = null
if (inputStream != null) {
photo = BitmapFactory.decodeStream(inputStream)
}
while (cursorInfo!!.moveToNext()) {
val info = ContactModel()
info.setId(id)
info.setName(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)))
info.setMobileNumber(
cursorInfo.getString(
cursorInfo.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER
)
)
)
photo?.let { info.setPhoto(it) }
info.setPhotoURI(pURI)
list.add(info)
}
cursorInfo.close()
}
}
cursor.close()
}
return list
}
Need to create one data class for this
class ContactModel {
@SerializedName("id")
private var id: String = ""
@SerializedName("name")
private var name: String? = ""
@SerializedName("mobileNumber")
private var mobileNumber: String? = ""
@SerializedName("photo")
private var photo: Bitmap? = null
@SerializedName("photoURI")
private var photoURI: Uri? = null
fun getId(): String {
return id
}
fun setId(id: String) {
this.id = id
}
fun getName(): String? {
return name
}
fun setName(name: String) {
this.name = name
}
fun getMobileNumber(): String? {
return mobileNumber
}
fun setMobileNumber(mobileNumber: String) {
this.mobileNumber = mobileNumber
}
fun getPhoto(): Bitmap? {
return photo
}
fun setPhoto(photo: Bitmap) {
this.photo = photo
}
fun getPhotoURI(): Uri? {
return photoURI
}
fun setPhotoURI(photoURI: Uri) {
this.photoURI = photoURI
}
override fun toString(): String {
return "ContactModel(id='$id', name=$name, mobileNumber=$mobileNumber, photo=$photo, photoURI=$photoURI)"
}
}
Try this also get all contacts.
Cursor cursor = context.getContentResolver().query(Phone.CONTENT_URI, null , null , null,
"upper("+Phone.DISPLAY_NAME + ") ASC");
Try this:
Cursor managedCursor = getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[] {Phone._ID, Phone.DISPLAY_NAME, Phone.NUMBER}, null, null, Phone.DISPLAY_NAME + " ASC");
And by traversing through the cursor, you can store all this data in any data structure of your choice.
ContentResolver cr = mContext.getContentResolver(); //Activity/Application android.content.Context
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if(cursor.moveToFirst())
{
ArrayList<String> alContacts = new ArrayList<String>();
do
{
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
if(Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",new String[]{ id }, null);
while (pCur.moveToNext())
{
String contactNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
alContacts.add(contactNumber);
break;
}
pCur.close();
}
} while (cursor.moveToNext()) ;
}