【问题标题】:Android get phone number from contact listAndroid从联系人列表中获取电话号码
【发布时间】:2017-04-13 05:03:42
【问题描述】:

我有这些代码,它们基本上使用 ListView 来显示联系人列表中的姓名,我想在单击每个姓名时获取他们的电话号码:

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

onItemClick方法中

    GetColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)

返回 -1,因此我无法使用此方法获取电话号码。

我还尝试打印出光标 c 的所有列,它返回 34 列,但似乎与电话号码相关的唯一列是 HasPhoneNumber

那么问题出在哪里,我该如何解决?谢谢!


更新版本,其中 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();
        }
    });

我想更新后的代码将在 ListView 中显示电话号码,但我收到一条错误消息“列 'data1' 不存在”。

【问题讨论】:

    标签: android android-contacts


    【解决方案1】:

    首先在 AndroidManifest.xml 中添加这一行以获得用户的许可。

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

    实现联系按钮

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

    你必须重写 onActivityResult() 它将被写入 onCreate() 方法的外部 类似这个

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

    【讨论】:

      【解决方案2】:

      您可以使用以下代码在 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);
      

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

      以下是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);
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        ContactsContract Android API 将联系人数据(例如电话号码)存储在Data 表中,而不是Contacts 表中。

        仔细阅读:https://developer.android.com/reference/android/provider/ContactsContract.html

        更新 - 这是您的代码的固定版本(未经测试):

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

        【讨论】:

          【解决方案4】:

          它返回 -1 因为您没有从 DB 请求列 ContactsContract.CommonDataKinds.Phone.NUMBER

          new String[] {ContactsContract.Contacts.DISPLAY_NAME}
          

          ContactsContract.Contacts.DISPLAY_NAME 是您请求的唯一字段。

          为了能够获取电话号码,您首先需要将其包含在要从 DB 获取的列列表中:

          新字符串[] {ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}

          现在您必须覆盖适配器的getView,以便将名称设置到列表行的 textView 中。之后,您的 onItemClick 将按预期工作

          【讨论】:

          • 我只尝试了 String[] 中的 ContactsContract.CommonDataKinds.Phone.NUMBER 并得到错误:列 'data1' 不存在。我想既然我已经在查询中包含了所有字段,那么光标应该包含关于电话号码的字段,适配器应该不是原因?
          • @T.Yu,我不明白你改变了什么,现在有什么问题
          • 我将 new String[] {ContactsContract.Contacts.DISPLAY_NAME} 更改为 new String[] {ContactsContract.CommonDataKinds.Phone.NUMBER} 我想它会在 ListView 中显示电话号码,但我得到了错误提示“列 'data1' 不存在”。
          • @T.Yu,好的,ContactsContract.CommonDataKinds.Phone.NUMBER 可能是错误的列名。让我检查一下
          • 应该是。到目前为止,我访问过的几乎所有互联网上的相关帖子都使用了这个专栏。
          【解决方案5】:

          此答案只是上述答案的一个小更新。它可能对某人有所帮助。

          StarActivityForResult 已弃用。所以我们可以在 Kotlin 中使用下面的模型。

          在清单中:

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

          请同时实现运行时权限。我的代码中还没有完成。

          用于处理结果的以下行:

              private val openContacts = registerForActivityResult(ActivityResultContracts.PickContact()) {
          
              val contactData: Uri = it
              val phone: Cursor? = contentResolver.query(contactData!!, null, null, null, null)
              if (phone!!.moveToFirst()) {
                  val contactName: String = phone.getString(phone.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))
          
                  // To get number - runtime permission is mandatory.
                  val id: String = phone.getString(phone.getColumnIndex(ContactsContract.Contacts._ID))
                  if (phone.getString(phone.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)).toInt() > 0) {
                      val phones = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id, null, null)
                      while (phones!!.moveToNext()) {
                          val phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
                          Log.d("## Number", phoneNumber)
                      }
                      phones!!.close()
                  }
          
                  Log.d("## Contact Name", contactName)
              }
          
          }
          

          打开联系人:

          button.setOnClickListener {
                  openContacts.launch(null)
              }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-05-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-04-01
            • 1970-01-01
            • 2014-05-26
            相关资源
            最近更新 更多