英文:
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:
<?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">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="66dp"
android:background="@color/colorPrimaryDark"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:title="Contact Lists" />
<TextView
android:id="@+id/subtitulo_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Contact Lists"
android:textColor="@android:color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.087"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.119" />
<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>
and this is the code of the AndroidManifest file:
<?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>
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();
}
}
英文:
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) > 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();
}
}
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<String> getNumber(ContentResolver cr)
{
List<String> phonebook = new ArrayList<>();
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<ContactData> contacts = ContactUtilsKt.retrieveAllContacts(context);
// or to retrieve all contacts matching specific search pattern:
List<ContactData> contacts = ContactUtilsKt.retrieveAllContacts(context, "John");
答案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<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
for this first part of code as it internally calls 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
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<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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论