Android get phone number from contact list

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


Android get phone number from contact list



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:


final ContentResolver cr = getContentResolver();

final Cursor c = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
myCursorAdapter = new SimpleCursorAdapter(this, R.layout.list_item, c, new String {ContactsContract.Contacts.DISPLAY_NAME}, 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(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)), Toast.LENGTH_SHORT).show();
}
});



In the onItemClick Method the


onItemClick


GetColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)



returns -1 and therefore I cannot get the phone number with this method.



I've also tried to print out all the columns of the cursor c and it returns 34 columns but the only column which seems to be related to the phone number is HasPhoneNumber.


c


HasPhoneNumber



So where's the problem and how can I fix it? Thanks!



The updated version, where the String array passed to construct myCursorAdapter is changed:


String


myCursorAdapter


final ContentResolver cr = getContentResolver();

final Cursor c = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
myCursorAdapter = new SimpleCursorAdapter(this, R.layout.list_item, c, new String {ContactsContract.CommonDataKinds.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(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)), Toast.LENGTH_SHORT).show();
}
});



I suppose the updated code will show the phone numbers in the ListView but I got an error says "column 'data1' does not exist".




4 Answers
4



The ContactsContract Android API stores data about contacts like phone number in the Data table, not the Contacts table.


ContactsContract


Data


Contacts



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();
}
});





It worked! Thanks!
– T. Yu
Dec 1 '16 at 4:33



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;
}

}



it returns -1 because you don't request the column ContactsContract.CommonDataKinds.Phone.NUMBER from DB:


ContactsContract.CommonDataKinds.Phone.NUMBER


new String {ContactsContract.Contacts.DISPLAY_NAME}



ContactsContract.Contacts.DISPLAY_NAME is the only field you request.


ContactsContract.Contacts.DISPLAY_NAME



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}


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


getView


onItemClick





I tried with only ContactsContract.CommonDataKinds.Phone.NUMBER in the String and get the error: column 'data1' does not exist. I think since I have already included all the fields in the query, the cursor should contain the field about phone number, and the adapter should not be the cause?
– T. Yu
Nov 29 '16 at 9:56





@T.Yu, I did not understand what you changed and what is a problem now
– Vladyslav Matviienko
Nov 29 '16 at 10:47





I changed new String {ContactsContract.Contacts.DISPLAY_NAME} to new String {ContactsContract.CommonDataKinds.Phone.NUMBER} and I suppose it will show the phone numbers in the ListView but I got an error says "column 'data1' does not exist".
– T. Yu
Nov 29 '16 at 11:46







@T.Yu, ok, ContactsContract.CommonDataKinds.Phone.NUMBER might be a wrong column name. Let me check it
– Vladyslav Matviienko
Nov 29 '16 at 11:48


ContactsContract.CommonDataKinds.Phone.NUMBER





It should be. Almost all the relative posts on the Internet I've visited so far use this column.
– T. Yu
Nov 29 '16 at 12:14



You can use below code for getting contact list in Recyclerview;


List<ContactVO> contactVOList = new ArrayList();
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
while (phones.moveToNext()) {
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

ContactVO contactModel = new ContactVO();
contactModel.setContactName(name);
contactModel.setContactNumber(phoneNumber);
contactVOList.add(contactModel);
Log.d("name>>", name + " " + phoneNumber);
}
phones.close();
AllContactsAdapter contactAdapter = new AllContactsAdapter(contactVOList, getApplicationContext());
rvContacts.setLayoutManager(new LinearLayoutManager(PhoneDirectoryActivity.this));
rvContacts.setAdapter(contactAdapter);



Below ContactVO class file;


ContactVO


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


AllContactsAdapter


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);
}
}
}
}






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Arduino Mega cannot recieve any sketches, stk500_recv() programmer is not responding

Visual Studio Code: How to configure includePath for better IntelliSense results

C++ virtual function: Base class function is called instead of derived