简体   繁体   中英

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

    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 .

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:

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".

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

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

}

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM