如何在安卓应用中列出所有移动通讯录联系人

huangapple go评论89阅读模式
英文:

How Can I list all mobile contacts on an App Android

问题

我开始学习使用Android Studio进行移动应用开发。我想创建一个简单的应用程序(用于测试),在其中的一个ListView中显示所有手机联系人。

我已经有了主活动(MainActivity)及其XML文件,在其中我已经添加了一个ListView元素,我想在那里显示所有联系人。

以下是主活动类的代码:

package com.example.contactlist;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

以下是主活动XML的代码:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- 其他布局元素 -->

    <ListView
        android:id="@+id/listado_contactos"
        android:layout_width="346dp"
        android:layout_height="644dp"
        android:layout_marginStart="24dp"
        android:layout_marginLeft="24dp"
        android:layout_marginTop="21dp"
        android:layout_marginEnd="23dp"
        android:layout_marginRight="23dp"
        android:layout_marginBottom="29dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/subtitulo_container"
        tools:listitem="@android:layout/simple_list_item_multiple_choice" />
</androidx.constraintlayout.widget.ConstraintLayout>

以下是AndroidManifest文件的代码:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.contactlist">
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

您想要知道的是如何从手机获取所有联系人数据并在ListView中显示它们。

英文:

I started to learn Mobile App Development with Android Studios. I want to create a simple app(for testing) where I display all cellphone contacts in a ListView.

I have the main activity and its xml file where I have added a ListView element, I want to display all contacts there.

This is the code of the main activity class:

package com.example.contactlist;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
   }
}

this is the code of the main activity XML:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout 
xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
xmlns:tools=&quot;http://schemas.android.com/tools&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;match_parent&quot;
tools:context=&quot;.MainActivity&quot;&gt;

&lt;androidx.appcompat.widget.Toolbar
    android:id=&quot;@+id/toolbar&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;66dp&quot;
    android:background=&quot;@color/colorPrimaryDark&quot;
    android:minHeight=&quot;?attr/actionBarSize&quot;
    android:theme=&quot;?attr/actionBarTheme&quot;
    app:layout_constraintEnd_toEndOf=&quot;parent&quot;
    app:layout_constraintStart_toStartOf=&quot;parent&quot;
    app:layout_constraintTop_toTopOf=&quot;parent&quot;
    app:title=&quot;Contact Lists&quot; /&gt;

&lt;TextView
    android:id=&quot;@+id/subtitulo_container&quot;
    android:layout_width=&quot;wrap_content&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:text=&quot;Contact Lists&quot;
    android:textColor=&quot;@android:color/black&quot;
    app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
    app:layout_constraintHorizontal_bias=&quot;0.087&quot;
    app:layout_constraintLeft_toLeftOf=&quot;parent&quot;
    app:layout_constraintRight_toRightOf=&quot;parent&quot;
    app:layout_constraintTop_toTopOf=&quot;parent&quot;
    app:layout_constraintVertical_bias=&quot;0.119&quot; /&gt;

&lt;ListView
    android:id=&quot;@+id/listado_contactos&quot;
    android:layout_width=&quot;346dp&quot;
    android:layout_height=&quot;644dp&quot;
    android:layout_marginStart=&quot;24dp&quot;
    android:layout_marginLeft=&quot;24dp&quot;
    android:layout_marginTop=&quot;21dp&quot;
    android:layout_marginEnd=&quot;23dp&quot;
    android:layout_marginRight=&quot;23dp&quot;
    android:layout_marginBottom=&quot;29dp&quot;
    app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
    app:layout_constraintEnd_toEndOf=&quot;parent&quot;
    app:layout_constraintStart_toStartOf=&quot;parent&quot;
    app:layout_constraintTop_toBottomOf=&quot;@+id/subtitulo_container&quot;
    tools:listitem=&quot;@android:layout/simple_list_item_multiple_choice&quot; /&gt;

 &lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

and this is the code of the AndroidManifest file:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
package=&quot;com.example.contactlist&quot;&gt;
&lt;uses-permission android:name=&quot;android.permission.READ_CONTACTS&quot;/&gt;
&lt;application
    android:allowBackup=&quot;true&quot;
    android:icon=&quot;@mipmap/ic_launcher&quot;
    android:label=&quot;@string/app_name&quot;
    android:roundIcon=&quot;@mipmap/ic_launcher_round&quot;
    android:supportsRtl=&quot;true&quot;
    android:theme=&quot;@style/AppTheme&quot;&gt;
    &lt;activity android:name=&quot;.MainActivity&quot;&gt;
        &lt;intent-filter&gt;
            &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;

            &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
        &lt;/intent-filter&gt;
    &lt;/activity&gt;
&lt;/application&gt;

&lt;/manifest&gt;

What I want to know is how can I get all contacts data from the cellphone and display them in my ListView?

答案1

得分: 3

这里是一个可以获取联系人的函数:

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

    if ((cur != null ? cur.getCount() : 0) > 0) {
        while (cur != null && cur.moveToNext()) {
            String id = cur.getString(
                    cur.getColumnIndex(ContactsContract.Contacts._ID));
            String name = cur.getString(cur.getColumnIndex(
                    ContactsContract.Contacts.DISPLAY_NAME));

            if (cur.getInt(cur.getColumnIndex(
                    ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
                Cursor pCur = cr.query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                        new String[]{id}, null);
                while (pCur.moveToNext()) {
                    String phoneNo = pCur.getString(pCur.getColumnIndex(
                            ContactsContract.CommonDataKinds.Phone.NUMBER));
                    Log.i(TAG, "Name: " + name);
                    Log.i(TAG, "Phone Number: " + phoneNo);
                }
                pCur.close();
            }
        }
    }
    if(cur != null){
        cur.close();
    }
}

参考:android-get-all-contacts

英文:

Here is a function from which you can get contacts

private void getContactList() {
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
if ((cur != null ? cur.getCount() : 0) &gt; 0) {
while (cur != null &amp;&amp; cur.moveToNext()) {
String id = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME));
if (cur.getInt(cur.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER)) &gt; 0) {
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + &quot; = ?&quot;,
new String[]{id}, null);
while (pCur.moveToNext()) {
String phoneNo = pCur.getString(pCur.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i(TAG, &quot;Name: &quot; + name);
Log.i(TAG, &quot;Phone Number: &quot; + phoneNo);
}
pCur.close();
}
}
}
if(cur!=null){
cur.close();
}
}

Reference android-get-all-contacts

答案2

得分: 1

你必须将列表推送或设置到您的适配器。

public List<String> getNumber(ContentResolver cr)
{
    List<String> phonebook = new ArrayList<>();
    Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
    // 使用游标访问联系人
    while (phones.moveToNext())
    {
        String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        phonebook.add(phoneNumber);
    }
    return phonebook;
}
英文:

you must push or set list to your adapter

public List&lt;String&gt; getNumber(ContentResolver cr)
{
List&lt;String&gt; phonebook = new ArrayList&lt;&gt;();
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
// use the cursor to access the contacts
while (phones.moveToNext())
{
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
phonebook.add(phoneNumber);
}
return phonebook;
}

答案3

得分: 1

我已经开发了一个实用程序类来检索设备联系人。它可以在GitHub上找到:

ContactUtils.kt

由于处理检索联系人时可能发生的所有情况都需要一些时间,我建议您获取此文件并将其添加到您的项目中。它是用kotlin编写的,但如果您使用java,也可以像以下方式一样获取联系人列表:

List<ContactData> contacts = ContactUtilsKt.retrieveAllContacts(context);

// 或者检索所有与特定搜索模式匹配的联系人:
List<ContactData> contacts = ContactUtilsKt.retrieveAllContacts(context, "John");
英文:

I've developed a utility class to retrieve device contacts. It's available on GitHub:

ContactUtils.kt

Since handling all situations that might happen in retrieving contacts is a bit time consuming, I suggest you get this file and add it to your project. It's written in kotlin, but if you are using java, also it's possible to get the list of contacts like the following:

List&lt;ContactData&gt; contacts = ContactUtilsKt.retrieveAllContacts(context);
// or to retrieve all contacts matching specific search pattern:
List&lt;ContactData&gt; contacts = ContactUtilsKt.retrieveAllContacts(context, &quot;John&quot;);

答案4

得分: 0

我尝试了被接受的答案但每次我使用时我的特定 contactId 的列表都会得到 0

val result: MutableList<ContactData> = mutableListOf()
contentResolver.query(
    ContactsContract.Contacts.CONTENT_URI,
    CONTACT_PROJECTION,
    if (searchPattern.isNotBlank()) "${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} LIKE '%?%'" else null,
    if (searchPattern.isNotBlank()) arrayOf(searchPattern) else null,
    if (limit > 0 && offset > -1) "${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} ASC LIMIT $limit OFFSET $offset"
    else ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " ASC"
)?.use {
    if (it.moveToFirst()) {
        do {
            val contactId = it.getLong(it.getColumnIndex(CONTACT_PROJECTION[0]))
            val name = it.getString(it.getColumnIndex(CONTACT_PROJECTION[2])) ?: "";
            val hasPhoneNumber = it.getString(it.getColumnIndex(CONTACT_PROJECTION[3])).toInt()
            val phoneNumber: List<String> = if (hasPhoneNumber > 0) {
                retrievePhoneNumber(contactId)
            } else mutableListOf()

            val avatar = if (retrieveAvatar) retrieveAvatar(contactId) else null
            result.add(ContactData(contactId, name, phoneNumber, avatar))
        } while (it.moveToNext())
    }
}
return result

对于这段代码的第一部分因为它内部调用了 **retrivePhoneNumber(contactId)**

val result: MutableList<String> = mutableListOf()
contentResolver.query(
    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
    null,
    "${ContactsContract.CommonDataKinds.Phone.CONTACT_ID} =?",
    arrayOf(contactId.toString()),
    null
)?.use {
    if (it.moveToFirst()) {
        do {
            result.add(it.getString(it.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)))
        } while (it.moveToNext())
    }
}
return result

在这个代码块中**it.moveToFirst()** 总是为 false所以返回的列表总是空的

下面是可以返回所有号码列表的工作代码排除那些号码中带有空格的号码比如 **+91123 344 55**

val contactsNumberMap = HashMap<String, HashSet<String>>()
val result: MutableList<String> = mutableListOf()
withContext(Dispatchers.IO) {
    context.contentResolver.query(
        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
        null,
        null,
        null,
        null
    )?.use { c ->
        val contactIdIndex =
            c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID)
        val numberIndex = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
        while (c.moveToNext()) {
            val contactId = c.getString(contactIdIndex)
            val number: String = c.getString(numberIndex)
            if (number.contains(' ').not()) {
                if (contactsNumberMap.containsKey(contactId)) {
                    contactsNumberMap[contactId]?.add(number)
                } else {
                    contactsNumberMap[contactId] = hashSetOf(number)
                }
            }
        }
        contactsNumberMap.map { m ->
            m.apply {
                value.forEach {
                    result.add(it)
                }
            }
        }
    }
    return@withContext result
}
return result
英文:

I tried with the aceepted answer, but everytime i used to get my list of particluar contactId as 0

val result: MutableList&lt;ContactData&gt; = mutableListOf()
contentResolver.query(
ContactsContract.Contacts.CONTENT_URI,
CONTACT_PROJECTION,
if (searchPattern.isNotBlank()) &quot;${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} LIKE &#39;%?%&#39;&quot; else null,
if (searchPattern.isNotBlank()) arrayOf(searchPattern) else null,
if (limit &gt; 0 &amp;&amp; offset &gt; -1) &quot;${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} ASC LIMIT $limit OFFSET $offset&quot;
else ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + &quot; ASC&quot;
)?.use {
if (it.moveToFirst()) {
do {
val contactId = it.getLong(it.getColumnIndex(CONTACT_PROJECTION[0]))
val name = it.getString(it.getColumnIndex(CONTACT_PROJECTION[2])) ?: &quot;&quot;
val hasPhoneNumber = it.getString(it.getColumnIndex(CONTACT_PROJECTION[3])).toInt()
val phoneNumber: List&lt;String&gt; = if (hasPhoneNumber &gt; 0) {
retrievePhoneNumber(contactId)
} else mutableListOf()
val avatar = if (retrieveAvatar) retrieveAvatar(contactId) else null
result.add(ContactData(contactId, name, phoneNumber, avatar))
} while (it.moveToNext())
}
}
return result

for this first part of code as it internally calls retrivePhoneNumber(contactId)

val result: MutableList&lt;String&gt; = mutableListOf()
contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
&quot;${ContactsContract.CommonDataKinds.Phone.CONTACT_ID} =?&quot;,
arrayOf(contactId.toString()),
null
)?.use {
if (it.moveToFirst()) {
do {
result.add(it.getString(it.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)))
} while (it.moveToNext())
}
}
return result

here in this block of code it.moveToFirst() always false, so returned list is always zero

Here is the working code which will return all list number as list excluding those number who is the same number but space in it like +91123 344 55

val contactsNumberMap = HashMap&lt;String, HashSet&lt;String&gt;&gt;()
val result: MutableList&lt;String&gt; = mutableListOf()
withContext(Dispatchers.IO) {
context.contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
null,
null,
null
)?.use { c -&gt;
val contactIdIndex =
c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID)
val numberIndex = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
while (c.moveToNext()) {
val contactId = c.getString(contactIdIndex)
val number: String = c.getString(numberIndex)
if (number.contains(&#39; &#39;).not()) {
if (contactsNumberMap.containsKey(contactId)) {
contactsNumberMap[contactId]?.add(number)
} else {
contactsNumberMap[contactId] = hashSetOf(number)
}
}
}
contactsNumberMap.map { m -&gt;
m.apply {
value.forEach {
result.add(it)
}
}
}
}
return@withContext result
}
return result

huangapple
  • 本文由 发表于 2020年8月17日 10:48:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/63443919.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定