使用 ContentProvider 从联系人获取电话号码 - Android

Posted

技术标签:

【中文标题】使用 ContentProvider 从联系人获取电话号码 - Android【英文标题】:Getting phone number from contacts using ContentProvider - Android 【发布时间】:2016-01-08 05:06:58 【问题描述】:

我正在制作一个小应用程序,我可以在其中使用内容提供商获取手机的联系人,并将它们显示在列表视图中,如图所示。

我想选择列表视图的一行并自动拨打电话给该特定联系人。我尝试了一些东西,但它们不起作用。有任何想法吗?这是我的代码。

public class MainActivity extends ListActivity implements AdapterView.OnItemClickListener
ArrayAdapter<String> adapter;
@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);

    ContentResolver cr = getContentResolver();
    Cursor c = cr.query(ContactsContract.Contacts.CONTENT_URI,
            new String[] ContactsContract.Contacts.DISPLAY_NAME,
            null, null, null);

    List<String> contacts = new ArrayList<String>();
    if (c.moveToFirst()) 
        do 
            contacts.add(c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
         while (c.moveToNext());
    
    adapter = new ArrayAdapter<String>(this, R.layout.activity_main, contacts);
    setListAdapter(adapter);





@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) 

      //The answer should be inside here.

  

【问题讨论】:

不要创建 POJO 类,不要在循环中迭代 Cursor,不要使用 ArrayAdapter,该怎么办?使用SimpleCursorAdapter,仅此而已 @pskink 好电话。出于某种原因,我总是忘记 CursorAdapters。从来没有用过很多, @MikeM。至少您知道将它们与基于 Cursor 的数据模型一起使用比使用 POJO/loop/ArrayAdapter 要好得多,这里 95% 的人不这样做,更糟糕的是,他们如此顽固地使用不良做法...... 【参考方案1】:

首先,确保您已将权限添加到您的 androidManifest.xml 文件中:

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

更新: 在 Android 6 及更高版本中,仅在清单中声明权限是不够的,您必须明确要求用户授予读取联系人的权限,否则会出现异常。详情请见this answer。

然后你可以像这样循环浏览你的手机联系人:

Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null); 
while (cursor.moveToNext())  
    String contactId = cursor.getString(cursor.getColumnIndex( 
    String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

    if (Boolean.parseBoolean(hasPhone))  
        // You know it has a number so now query it like this
        Cursor phones = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null); 
        while (phones.moveToNext())  
            String phoneNumber = phones.getString(phones.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER));                 
         
        phones.close(); 
    

    Cursor emails = getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + contactId, null, null); 

    while (emails.moveToNext())  
        // This would allow you get several email addresses 
        String emailAddress = emails.getString( 
        emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)); 
     

    emails.close();

【讨论】:

感谢@Theo 的回复。【参考方案2】:

尝试:

private void doMagicContacts() 
    Cursor cursor = getContentResolver()
            .query(ContactsContract.Contacts.CONTENT_URI,
                    null,
                    null,
                    null,
                    null);

    if (cursor == null) 
        return;
    

    cursor.moveToFirst();

    do 
        String name = cursor.getString(
                cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
        String id = cursor.getString(
                cursor.getColumnIndex(ContactsContract.Contacts.NAME_RAW_CONTACT_ID));

        Cursor phones = getContentResolver()
                .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID+" = " + id,
                        null,
                        null);
        if (phones != null) 
            while (phones.moveToNext()) 
                String phoneNumber = phones.getString(
                        phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                Log.d(TAG, "doMagicContacts: " + name + " " + phoneNumber);
            
            phones.close();
        

     while (cursor.moveToNext());

    cursor.close();

【讨论】:

以上是关于使用 ContentProvider 从联系人获取电话号码 - Android的主要内容,如果未能解决你的问题,请参考以下文章

Android 开发 ContentProvider 获取歌曲列表和联系人的样例

ContentProvider(联系人) - 没有这样的列:metadata_dirty

用ContentProvider获取通讯录联系人

安卓 ContentProvider

如何使用ContentResolver

Android 四大组件学习之ContentProvider四