在Android应用中从联系人列表中选择一个数字和名称

33

我想从我的联系人列表中选择一个带有号码的联系人。 我阅读了很多解决方案和研究了几个星期,但所有文章都没有正常工作。 像以下这些代码:

Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);

// 并且在 activityresult 中:

if (resultCode == Activity.RESULT_OK) {
            Uri contactData = data.getData();
            Cursor c =  managedQuery(contactData, null, null, null, null);
            if (c.moveToFirst()) {
              String name = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
              tv1.setText(name);
            }
          }

以下代码可以获取所有联系人信息,但是无法得到联系人数量:

String[] contacts = new String[] {People.NAME, People.NUMBER};       
Uri contentUri = People.CONTENT_URI;        
Cursor cursor = managedQuery(contentUri, contacts, null, null, null);                 
String textContacts = "";                 
if (cursor.moveToFirst()) {         
    String myname = null;         
    String mynumber = null;         
    do {          
        textContacts = textContacts + cursor.getString(cursor.getColumnIndex(People.NAME)) + " : " + cursor.getString(cursor.getColumnIndex(People.NUMBER)) + "\n";         
    } while (cursor.moveToNext()); 
tv1.setText(textContacts);
}

能否有人帮帮我?我的安卓系统是2.3.3。


这个查询 Cursor c = managedQuery(contactData, null, null, null, null); 是否返回了所有内容?你有检查过吗? - Sergey Benner
你可以阅读这个帖子来查看示例:https://groups.google.com/group/android-developers/browse_thread/thread/133816827efc8eb9/8671f76b4111f215?pli=1 - Sergey Benner
尝试使用Android联系人提取器 - Nitesh Tiwari
17个回答

61

尝试使用以下代码,它会帮助你:

  // You need below permission to read contacts
  <uses-permission android:name="android.permission.READ_CONTACTS"/>

  // Declare
  static final int PICK_CONTACT=1;

  Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
  startActivityForResult(intent, PICK_CONTACT);

  //code 
  @Override
 public void onActivityResult(int reqCode, int resultCode, Intent data) {
 super.onActivityResult(reqCode, resultCode, data);

 switch (reqCode) {
 case (PICK_CONTACT) :
   if (resultCode == Activity.RESULT_OK) {

     Uri contactData = data.getData();
     Cursor c =  managedQuery(contactData, null, null, null, null);
     if (c.moveToFirst()) {


         String id =c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts._ID));

         String hasPhone =c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

           if (hasPhone.equalsIgnoreCase("1")) {
          Cursor phones = getContentResolver().query( 
                       ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, 
                       ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id, 
                       null, null);
             phones.moveToFirst();
              cNumber = phones.getString(phones.getColumnIndex("data1"));
             System.out.println("number is:"+cNumber);
           }
         String name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));


     }
   }
   break;
 }
 }

5
仅返回第一个联系人。有办法让我从联系人拥有的多个电话号码中选择一个电话号码吗? - Ubaid
1
managedQuery现在已经被弃用,有什么替代方案吗?请更新答案。 - Gopal Singh Sirvi
1
@GopalSinghSirvi,这里可能需要替换managedQuery(Uri, String[], String, String[], String)方法,可以尝试使用getContentResolver().query()方法进行替换,具体效果需要测试确认。 - user5395084
1
请使用ContactsContract.CommonDataKinds.Phone.NUMBER代替"data1",并使用ContactsContract.Contacts._ID代替"_id"。 - Anuj Jindal
由于某些原因,这在Android10上存在问题。 - Jendorski Labs
显示剩余3条评论

23

使用Intent.ACTION_PICK访问手机联系人。代码如下:

Uri uri = Uri.parse("content://contacts");
Intent intent = new Intent(Intent.ACTION_PICK, uri);
intent.setType(Phone.CONTENT_TYPE);
startActivityForResult(intent, REQUEST_CODE);

在哪里

private static final int REQUEST_CODE = 1;

并使用方法onActivityResult()访问已选联系人。代码如下:

@Override
    protected void onActivityResult(int requestCode, int resultCode,
            Intent intent) {
        if (requestCode == REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                Uri uri = intent.getData();
                String[] projection = { Phone.NUMBER, Phone.DISPLAY_NAME };

                Cursor cursor = getContentResolver().query(uri, projection,
                        null, null, null);
                cursor.moveToFirst();

                int numberColumnIndex = cursor.getColumnIndex(Phone.NUMBER);
                String number = cursor.getString(numberColumnIndex);

                int nameColumnIndex = cursor.getColumnIndex(Phone.DISPLAY_NAME);
                String name = cursor.getString(nameColumnIndex);

                Log.d(TAG, "ZZZ number : " + number +" , name : "+name);

            }
        }
    };

5
完成操作后别忘了调用 close() 方法关闭游标,最好使用 try-finally 块来处理。 - ubuntudroid
1
查询时抛出IllegalArgumentException。 - Alon Kogan

20
在您的应用程序清单中添加一个读取联系人数据的权限。
<uses-permission android:name="android.permission.READ_CONTACTS"/>

在您的Activity中使用Intent.Action_Pick,如下所示。
Intent contactPickerIntent = new Intent(Intent.ACTION_PICK,
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
        startActivityForResult(contactPickerIntent, RESULT_PICK_CONTACT);

然后重写onActivityResult()方法。
 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // check whether the result is ok
        if (resultCode == RESULT_OK) {
            // Check for the request code, we might be usign multiple startActivityForReslut
            switch (requestCode) {
            case RESULT_PICK_CONTACT:
               Cursor cursor = null;
        try {
            String phoneNo = null ;
            String name = null;           
            Uri uri = data.getData();            
            cursor = getContentResolver().query(uri, null, null, null, null);
            cursor.moveToFirst();           
            int  phoneIndex =cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
            phoneNo = cursor.getString(phoneIndex); 

            textView2.setText(phoneNo);
            cursor.close()
        } catch (Exception e) {
            e.printStackTrace();
        }
                break;
            }
        } else {
            Log.e("MainActivity", "Failed to pick contact");
        }
    }

这将起作用,看看吧。

这是一个简单直接的解决方案。我不知道为什么更多的人没有点赞它。 - Ishan
1
这正是我在寻找的。这是最好的答案。 - JAMSHAID
已在Android 8.1上进行了测试,即使没有“READ_CONTACTS”权限,它也可以完美运行。 - ARiF

4

如果希望在单击或焦点事件中从联系人列表中选择联系人,则可以复制此代码并粘贴到您的活动中。

  • FOCUS EVENT OF EDIT TEXT:

      phoneNo.setOnFocusChangeListener(new OnFocusChangeListener()
       {   public void onFocusChange(View v, boolean hasFocus) 
           {
              Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
              startActivityForResult(intent,PICK_CONTACT );//PICK_CONTACT is private static final int, so declare in activity class
        } });
    
  • A FUNCTION TO GET THE CONTACT NAME AND PHONE NO IS :

       public void onActivityResult(int reqCode, int resultCode, Intent data)
        {
          super.onActivityResult(reqCode, resultCode, data);
    
             switch(reqCode){
                case (PICK_CONTACT):
                  if (resultCode == Activity.RESULT_OK)
                  {
                      Uri contactData = data.getData();
                      Cursor c = managedQuery(contactData, null, null, null, null);
                   if (c.moveToFirst()) {
                   String id =   
                     c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
    
                   String hasPhone =
                   c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
    
                   if (hasPhone.equalsIgnoreCase("1")) {
                  Cursor phones = getContentResolver().query( 
                               ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, 
                               ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id, 
                               null, null);
                     phones.moveToFirst();
                     String phn_no = phones.getString(phones.getColumnIndex("data1"));
                     String name = c.getString(c.getColumnIndex(StructuredPostal.DISPLAY_NAME));
                    Toast.makeText(this, "contact info : "+ phn_no+"\n"+name, Toast.LENGTH_LONG).show();
    
                   }
                     }
                  }
             }
    }
    

3
如果联系人有多个电话号码,您也可以尝试此解决方案。
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
            startActivityForResult(intent , REQUEST_CODE_ADDRESS_BOOK

);

然后是活动结果:

@Override
    public void onActivityResult(int reqCode, int resultCode, Intent data) {
        super.onActivityResult(reqCode, resultCode, data);

        switch (reqCode) {
            case (REQUEST_CODE_ADDRESS_BOOK):
                if (resultCode == Activity.RESULT_OK) {
                    Uri contactData = data.getData();
                    Cursor c =  getContentResolver().query(contactData, null, null, null, null);

                    c.moveToFirst();
                    String phoneNumber =  c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    c.close();
                }
                break;
        }
    }

然后,号码将会存在phoneNumber变量中。


3

以下是针对需要使用Kotlin解决问题的人的答案,不要被“binding”一词所困惑,它只用于绑定视图。在单击“pickContact”时,我们只是打开通讯录应用程序。

首先在清单文件中添加权限。

<uses-permission android:name="android.permission.READ_CONTACTS"/>

val RESULT_PICK_CONTACT = 1

binding?.pickContact ->{
            val contactPickerIntent = Intent(
                Intent.ACTION_PICK,
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI
            )
            startActivityForResult(contactPickerIntent, RESULT_PICK_CONTACT)
        }

在点击pickContact时,我们会打开通讯录应用,并覆盖onActivityResult方法。

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    if (resultCode == Activity.RESULT_OK) {
        when (requestCode) {
            RESULT_PICK_CONTACT -> {
                var cursor: Cursor? = null
                try {
                    var phoneNo: String? = null
                    var name: String? = null
                    val uri: Uri? = data?.data
                    cursor = contentResolver.query(uri!!, null, null, null, null)
                    cursor?.moveToFirst()
                    val phoneIndex: Int =
                        cursor!!.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
                    val phoneContactName: String =
                        cursor!!.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))
                    phoneNo = cursor?.getString(phoneIndex)
                    et_name.setText(phoneContactName) //setting the contacts name
                    mobile_number.setText(phoneNo) //setting the contacts phone number

                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    } else {
        Log.e("ActivityName", "Something went wrong")
    }
}

如果您发现任何问题,请在下面评论,我会回答您的疑问。

请问您能否添加一段代码来获取电子邮件地址? - Aviharsh Shukla

3

这是我实现的内容:

private String[] getContactList(){
    ContentResolver cr = getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

    Log.i(LOG_TAG, "get Contact List: Fetching complete contact list");

    ArrayList<String> contact_names = new ArrayList<String>();

    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 (cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER.trim())).equalsIgnoreCase("1"))
            {
                if (name!=null){
                    //contact_names[i]=name;

                    Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",new String[]{id}, null);
                    while (pCur.moveToNext()) 
                    {
                        String PhoneNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        PhoneNumber = PhoneNumber.replaceAll("-", "");
                        if (PhoneNumber.trim().length() >= 10) {
                            PhoneNumber = PhoneNumber.substring(PhoneNumber.length() - 10);
                        }
                        contact_names.add(name + ":" + PhoneNumber);

                        //i++;
                        break;
                    }
                    pCur.close();
                    pCur.deactivate();
                    // i++;
                }
            }
        }
        cur.close();
        cur.deactivate();
    }

    String[] contactList = new String[contact_names.size()]; 

    for(int j = 0; j < contact_names.size(); j++){
        contactList[j] = contact_names.get(j);
    }

    return contactList;
}

你可以调用这个函数,也许使用AutoCompleteTextView来显示和选择联系人姓名和10位数字号码。这个函数返回一个字符串数组,你可以直接返回ArrayList并删除最后的for循环。


谢谢你,KKD。你的代码很好用。但是"Raju Barad"的代码也很好用。因为我只想选择一个联系人,所以他的代码对我来说更好。顺便说一句,非常感谢你。 - aTa
我同意。Raju Barad的代码似乎更好。不客气,aTa。 - drulabs

1
  • 列表项

这对我有用

获取手机号码和姓名

 startActivityForResult(new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI), TYPE_CONTACT);

如果是TYPE_CONTACT情况: 那么uriContact将会得到数据。

            String name=retrieveContactName();
            System.out.println("name = " + name);
            String number=retrieveContactNumber();
            System.out.println("number = " + number);
            break;

私有的字符串类型方法 retrieveContactNumber() {
    String contactNumber = null;

    // getting contacts ID
    Cursor cursorID = getContentResolver().query(uriContact,
            new String[]{ContactsContract.Contacts._ID},
            null, null, null);

    if (cursorID.moveToFirst()) {

        contactID = cursorID.getString(cursorID.getColumnIndex(ContactsContract.Contacts._ID));
    }

    cursorID.close();

    Log.d(TAG, "Contact ID: " + contactID);

    // Using the contact ID now we will get contact phone number
    Cursor cursorPhone = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER},

            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ? AND " +
                    ContactsContract.CommonDataKinds.Phone.TYPE + " = " +
                    ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE,

            new String[]{contactID},
            null);

    if (cursorPhone.moveToFirst()) {
        contactNumber = cursorPhone.getString(cursorPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
    }

    cursorPhone.close();

    Log.d(TAG, "Contact Phone Number: " + contactNumber);
    return contactNumber;
}

private String retrieveContactName() {

    String contactName = null;

    // querying contact data store
    Cursor cursor = getContentResolver().query(uriContact, null, null, null, null);

    if (cursor.moveToFirst()) {

        // DISPLAY_NAME = The display name for the contact.
        // HAS_PHONE_NUMBER =   An indicator of whether this contact has at least one phone number.

        contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
    }

    cursor.close();

    Log.d(TAG, "Contact Name: " + contactName);

    return contactName;
}

1

获取手机号和电子邮件地址

//获取电话号码

  name = getIntent().getExtras().getString("name");
  id = getIntent().getExtras().getString("contactid");

        Cursor cursorPhone = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER},

                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ? AND " +
                        ContactsContract.CommonDataKinds.Phone.TYPE + " = " +
                        ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE,

                new String[]{id.toString()},
                null);
        String contactNumber = null;

   if (cursorPhone.moveToFirst()) {
       contactNumber =  cursorPhone.getString(cursorPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
       System.out.println("contactnum"+contactNumber);
       }

  }
       cursorPhone.close();

//获取电子邮件地址

 Cursor emailCursor = getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
                 null,
                ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{id}, null);

        if (emailCursor.moveToFirst()) {
            String phone = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
            int type = emailCursor.getInt(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
            String s = (String) ContactsContract.CommonDataKinds.Email.getTypeLabel(AddContactActivity.this.getResources(), type, "");
            etEmail.setText(phone);
        }
        emailCursor.close();
}

1
这段代码适用于手机号联系人,不适用于电子邮件或其他。我发现这段代码最简单。如果有任何问题,请告诉我。
使用选择意图在手机数据类型上启动活动:
findViewById(R.id.choose_contact_button).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
            Intent pickContact = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
            startActivityForResult(pickContact, PICK_CONTACT_REQUEST);
      }
 });

现在设置 onAcitivityResult();
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent){
        switch (requestCode){
            case PICK_CONTACT_REQUEST:
                if (resultCode == RESULT_OK){
                    Uri contactUri = intent.getData();
                    Cursor nameCursor = getContentResolver().query(contactUri, null, null, null, null);
                    if (nameCursor.moveToFirst()){
                        String name = nameCursor.getString(nameCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                        String number = nameCursor.getString(nameCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        ((EditText)findViewById(R.id.person_name)).setText(name);
                        ((EditText)findViewById(R.id.enter_mobile)).setText(number);
                        nameCursor.close();
                    }
                }
                break;
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接