I have these codes which basically use a ListView to display the names in the contact list and I want to get their phone number when click each single name:
it returns -1 because you don't request the column ContactsContract.CommonDataKinds.Phone.NUMBER
from DB:
new String[] {ContactsContract.Contacts.DISPLAY_NAME}
ContactsContract.Contacts.DISPLAY_NAME
is the only field you request.
To be able to get the phone number, you firstly need to include it into list of columns you want to get from DB:
new String[] {ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}
Now you have to override adapter's getView
so it sets the name into the textView of the list row. After that your onItemClick
will work as expected
First of all add this line in AndroidManifest.xml to take permission from user.
<uses-permission android:name="android.permission.READ_CONTACTS"/>
implement the button of contact
phoneContactsButtton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// The below two line is needed to open the contact list of mobile
Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(contactPickerIntent,1);
}
});
you have to override the onActivityResult() which will be written to the outside of onCreate() mehtod similar to this
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case 1 :
if (resultCode == Activity.RESULT_OK) {
Uri contactData = data.getData();
Cursor cur = getContentResolver().query(contactData, null, null, null, null);
if (cur.getCount() > 0) {// thats mean some resutl has been found
if(cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Log.e("Names", name);
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
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.e("Number", phoneNumber);
}
phones.close();
}
}
}
cur.close();
}
break;
}
}
You can use below code for getting contact list in Recyclerview;
List<ContactVO> contactVOList = new ArrayList();
String[] projection = new String[]{ContactsContract.Contacts._ID, ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.PHOTO_URI};
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, null, null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
List<ContactVO> userList = new ArrayList<>();
String lastPhoneName = " ";
if (phones.getCount() > 0) {
while (phones.moveToNext()) {
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String contactId = phones.getString(phones.getColumnIndex(ContactsContract.Contacts._ID));
String photoUri = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
if (!name.equalsIgnoreCase(lastPhoneName)) {
lastPhoneName = name;
ContactVO user = new ContactVO();
user.setContactName(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
user.setContactNumber(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
userList.add(user);
Log.d("getContactsList", name + "---" + phoneNumber + " -- " + contactId + " -- " + photoUri);
}
}
}
phones.close();
AllContactsAdapter contactAdapter = new AllContactsAdapter(userList, getApplicationContext());
rvContacts.setLayoutManager(new LinearLayoutManager(PhoneDirectoryActivity.this));
rvContacts.setAdapter(contactAdapter);
Below ContactVO
class file;
public class ContactVO
{
private String ContactImage;
private String ContactName;
private String ContactNumber;
public String getContactImage() {
return ContactImage;
}
public void setContactImage(String contactImage) {
this.ContactImage = ContactImage;
}
public String getContactName() {
return ContactName;
}
public void setContactName(String contactName) {
ContactName = contactName;
}
public String getContactNumber() {
return ContactNumber;
}
public void setContactNumber(String contactNumber) {
ContactNumber = contactNumber;
}
}
and below is AllContactsAdapter
file
public class AllContactsAdapter extends RecyclerView.Adapter<AllContactsAdapter.ContactViewHolder> {
private List<ContactVO> contactVOList;
private Context mContext;
private SparseBooleanArray itemStateArray = new SparseBooleanArray();
public AllContactsAdapter(List<ContactVO> contactVOList, Context mContext) {
this.contactVOList = contactVOList;
this.mContext = mContext;
}
@Override
public ContactViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.single_contact_view, null);
ContactViewHolder contactViewHolder = new ContactViewHolder(view);
return contactViewHolder;
}
@Override
public void onBindViewHolder(ContactViewHolder holder, int position) {
ContactVO contactVO = contactVOList.get(position);
holder.tvContactName.setText(contactVO.getContactName());
holder.tvPhoneNumber.setText(contactVO.getContactNumber());
holder.bind(position);
holder.cbContact.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int adapterPosition = position;
if (!itemStateArray.get(adapterPosition, false)) {
holder.cbContact.setChecked(true);
contactsList.add(holder.tvPhoneNumber.getText().toString());
itemStateArray.put(adapterPosition, true);
} else {
holder.cbContact.setChecked(false);
itemStateArray.put(adapterPosition, false);
contactsList.remove(holder.tvPhoneNumber.getText().toString());
}
}
});
}
@Override
public int getItemCount() {
return contactVOList.size();
}
public class ContactViewHolder extends RecyclerView.ViewHolder {
ImageView ivContactImage;
TextView tvContactName;
TextView tvPhoneNumber;
CheckBox cbContact;
public ContactViewHolder(View itemView) {
super(itemView);
ivContactImage = itemView.findViewById(R.id.ivContactImage);
tvContactName = itemView.findViewById(R.id.tvContactName);
tvPhoneNumber = itemView.findViewById(R.id.tvPhoneNumber);
cbContact = itemView.findViewById(R.id.cbContact);
}
void bind(int arg1) {
// use the sparse boolean array to check
if (!itemStateArray.get(arg1, false)) {
cbContact.setChecked(false);
} else {
cbContact.setChecked(true);
}
}
}
}
The ContactsContract
Android API stores data about contacts like phone number in the Data
table, not the Contacts
table.
Read this carefully: https://developer.android.com/reference/android/provider/ContactsContract.html.
Update - here's a fixed version of your code (untested):
final ContentResolver cr = getContentResolver();
String[] projection = new String[] {Contacts.DISPLAY_NAME, Phone.NUMBER};
final Cursor c = cr.query(Data.CONTENT_URI, projection, null, null, null);
myCursorAdapter = new SimpleCursorAdapter(this, R.layout.list_item, c, new String[] {Phone.NUMBER}, new int[]{R.id.TVRow}, 0);
myPhoneList.setAdapter(myCursorAdapter);
myPhoneList.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
c.moveToPosition(position);
Toast.makeText(getApplicationContext(), c.getString(1), Toast.LENGTH_SHORT).show();
}
});