如何调用 Android 联系人列表?

我正在开发一个 Android 应用程序,需要打电话给手机的联系人列表。我需要调用联系人列表函数,选择一个联系人,然后返回到我的应用程序与联系人的名称。这是我在网上找到的代码,但是不能用。

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;


public class Contacts extends ListActivity {


private ListAdapter mAdapter;
public TextView pbContact;
public static String PBCONTACT;
public static final int ACTIVITY_EDIT=1;
private static final int ACTIVITY_CREATE=0;


// Called when the activity is first created.
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Cursor C = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
startManagingCursor(C);


String[] columns = new String[] {People.NAME};
int[] names = new int[] {R.id.row_entry};


mAdapter = new SimpleCursorAdapter(this, R.layout.mycontacts, C, columns, names);
setListAdapter(mAdapter);
} // end onCreate()
// Called when contact is pressed
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);


Cursor C = (Cursor) mAdapter.getItem(position);
PBCONTACT = C.getString(C.getColumnIndex(People.NAME));


// RHS 05/06
//pbContact = (TextView) findViewById(R.id.myContact);
//pbContact.setText(new StringBuilder().append("b"));


Intent i = new Intent(this, NoteEdit.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
}
203442 次浏览

我不是100% 确定你的示例代码应该做什么,但是下面的代码片段可以帮助你“调用联系人列表函数,选择一个联系人,然后用联系人的名字返回到[你的]应用程序”。

这个过程有三个步骤。

1. 许可

向应用程序清单中添加读取联系人数据的权限。

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

2. 呼叫联系人选择器

在 Activity 中,创建一个意图,该意图要求系统查找一个 Activity,该 Activity 可以从 Contacts URI 中的项目执行 PICK 操作。

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

调用 startActivityForResult,传入此意图(以及本例中的请求代码整数 PICK_CONTACT)。这将导致 Android 启动一个在 People.CONTENT_URI上注册为支持 ACTION_PICK的活动,然后在选择完成(或取消)后返回到该活动。

startActivityForResult(intent, PICK_CONTACT);

聆听结果

同样在您的 Activity 中,覆盖 onActivityResult方法来侦听您在步骤2中启动的“ select a contact”Activity 的返回值。您应该检查返回的请求代码是否与预期的值相匹配,并且结果代码是 RESULT_OK

您可以通过在 资料 Inent 参数上调用 getData()来获得所选联系人的 URI。要获取所选联系人的名称,需要使用该 URI 创建新查询并从返回的游标中提取名称。

@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 =  getContentResolver().query(contactData, null, null, null, null);
if (c.moveToFirst()) {
String name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
// TODO Whatever you want to do with the selected contact name.
}
}
break;
}
}

完整源代码: Tutorials-android.blogspot.com (如何调用 android 联系人列表)

查找使用 ContactsContractAPI 的 API Level 5解决方案,您可以使用下面的代码稍微修改上面的代码:

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

然后在 onActivityResult 中使用列名:

  ContactsContract.Contacts.DISPLAY_NAME

对于 Android 2.2 Froyo 的发布,我是这样做的: 基本上使用 eclipse 创建一个类: Public 类 SomPickContactName 扩展活动

然后插入这段代码。请记住添加在我的代码版本中引用的私有类变量和 CONSTANTS:

protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent intentContact = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intentContact, PICK_CONTACT);
}//onCreate


public void onActivityResult(int requestCode, int resultCode, Intent intent)
{


if (requestCode == PICK_CONTACT)
{
getContactInfo(intent);
// Your class variables now have the data, so do something with it.
}
}//onActivityResult


protected void getContactInfo(Intent intent)
{


Cursor cursor =  managedQuery(intent.getData(), null, null, null, null);
while (cursor.moveToNext())
{
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));


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


if ( hasPhone.equalsIgnoreCase("1"))
hasPhone = "true";
else
hasPhone = "false" ;


if (Boolean.parseBoolean(hasPhone))
{
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,null, null);
while (phones.moveToNext())
{
phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
phones.close();
}


// Find Email Addresses
Cursor emails = getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,null,ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + contactId,null, null);
while (emails.moveToNext())
{
emailAddress = emails.getString(emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
}
emails.close();


Cursor address = getContentResolver().query(
ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + " = " + contactId,
null, null);
while (address.moveToNext())
{
// These are all private class variables, don't forget to create them.
poBox      = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POBOX));
street     = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));
city       = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
state      = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
postalCode = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE));
country    = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY));
type       = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.TYPE));
}  //address.moveToNext()
}  //while (cursor.moveToNext())
cursor.close();
}//getContactInfo

下面给出了完整的代码

    package com.testingContect;


import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.Contacts.People;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;


public class testingContect extends Activity implements OnClickListener{
/** Called when the activity is first created. */


EditText ed;
Button bt;
int PICK_CONTACT;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bt=(Button)findViewById(R.id.button1);
ed =(EditText)findViewById(R.id.editText1);
ed.setOnClickListener(this);
bt.setOnClickListener(this);




}


@Override
public void onClick(View v) {


switch(v.getId())
{
case R.id.button1:


break;
case R.id.editText1:
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
startActivityForResult(intent, PICK_CONTACT);




break;


}


}
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{


if (requestCode == PICK_CONTACT)
{
Cursor cursor =  managedQuery(intent.getData(), null, null, null, null);
cursor.moveToNext();
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String  name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));


Toast.makeText(this, "Contect LIST  =  "+name, Toast.LENGTH_LONG).show();
}
}//onActivityResult
}//class ends
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
if (requestCode == PICK_CONTACT && intent != null) //here check whether intent is null R not
{
}
}

因为没有选择任何联系人,它会给一个例外。所以最好检查这个条件。

下面是获取联系人的代码片段:

package com.contact;


import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;


public class GetContactDemoActivity extends Activity implements OnClickListener {


private Button btn = null;
private TextView txt = null;


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);


btn = (Button) findViewById(R.id.button1);
txt = (TextView) findViewById(R.id.textView1);


btn.setOnClickListener(this);
}


@Override
public void onClick(View arg0) {
if (arg0 == btn) {
try {
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, 1);
} catch (Exception e) {
e.printStackTrace();
Log.e("Error in intent : ", e.toString());
}
}
}


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


try {
if (resultCode == Activity.RESULT_OK) {
Uri contactData = data.getData();
Cursor cur = managedQuery(contactData, null, null, null, null);
ContentResolver contect_resolver = getContentResolver();


if (cur.moveToFirst()) {
String id = cur.getString(cur.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
String name = "";
String no = "";


Cursor phoneCur = contect_resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { id }, null);


if (phoneCur.moveToFirst()) {
name = phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
no = phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}


Log.e("Phone no & name :***: ", name + " : " + no);
txt.append(name + " : " + no + "\n");


id = null;
name = null;
no = null;
phoneCur = null;
}
contect_resolver = null;
cur = null;
//                      populateContacts();
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
Log.e("IllegalArgumentException :: ", e.toString());
} catch (Exception e) {
e.printStackTrace();
Log.e("Error :: ", e.toString());
}
}

}

令我惊讶的是,您不需要用户权限 CONTACT _ READ 来读取姓名和一些基本信息(联系人是否为星号,最后一次通话时间是什么)。 但是,您需要获得许可才能阅读联系人的详细信息,比如电话号码。

        Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
String Name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)
String Number=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));


}

使用 android 联系人列表时要小心。

阅读上述方法中的联系人列表可以在除 HTC One 和索尼 Xperia 之外的大多数 Android 设备上使用。浪费了我六周的时间试图找出问题所在!

大多数在线教程几乎是相似的-首先阅读“所有”联系人,然后显示在 ListviewArrayAdapter。这不是内存高效的解决方案。与其先在其他网站上寻找解决方案,不如先看看 developer.android.com。如果 developer.android.com 上没有任何解决方案,你应该去其他地方寻找。

解决方案是使用 CursorAdapter而不是 ArrayAdapter来检索联系人列表。使用 ArrayAdapter可以在大多数设备上工作,但效率不高。在滚动 ListView时,CursorAdapter在运行时只检索联系人列表的一部分。

public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
...
// Gets the ListView from the View list of the parent activity
mContactsList =
(ListView) getActivity().findViewById(R.layout.contact_list_view);
// Gets a CursorAdapter
mCursorAdapter = new SimpleCursorAdapter(
getActivity(),
R.layout.contact_list_item,
null,
FROM_COLUMNS, TO_IDS,
0);
// Sets the adapter for the ListView
mContactsList.setAdapter(mCursorAdapter);
}

检索联系人列表: 检索联系人列表

-> Add a permission to read contacts data to your application manifest.


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


-> Use Intent.Action_Pick in your Activity like below


Intent contactPickerIntent = new Intent(Intent.ACTION_PICK,
ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(contactPickerIntent, RESULT_PICK_CONTACT);


-> Then Override the 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);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
} else {
Log.e("MainActivity", "Failed to pick contact");
}
}


This will work check it out

我有一个代码,保存在您的数据库中的联系人共享首选项 这是我的密码

public class MainActivity extends AppCompatActivity {
EditText nameInput,phoneInput;
TextView LargeText;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main22);
nameInput = (EditText) findViewById(R.id.nameInput);
phoneInput = (EditText) findViewById(R.id.phoneInput);


LargeText = (TextView) findViewById(R.id.textView2);
}


public void saveInfo (View view){
SharedPreferences sharedPref = getSharedPreferences("nameInfo" , Context.MODE_PRIVATE);
SharedPreferences.Editor editor= sharedPref.edit();
editor.putString("name", nameInput.getText().toString());
editor.putString("phone", phoneInput.getText().toString());
editor.apply();
Toast.makeText(this, "Saved", Toast.LENGTH_LONG).show();
}


public void displayData(View view){
SharedPreferences sharedPref = getSharedPreferences("nameInfo" , Context.MODE_PRIVATE);
String name = sharedPref.getString("name", "");
String ph = sharedPref.getString ("phone","");
LargeText.setText(name + " " + ph);
}
}

我使用的是@Colin MacKenzie-III 提供的 密码。非常感谢!

对于那些正在寻找“不推荐的”manedQuery 替代品的人来说:

首先,假设使用 v4 support lib:

import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;

第二名:

your_(activity)_class implements LoaderManager.LoaderCallbacks<Cursor>

第三,

// temporarily store the 'data.getData()' from onActivityResult
private Uri tmp_url;

第四,覆盖回调:

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// create the loader here!
CursorLoader cursorLoader = new CursorLoader(this, tmp_url, null, null, null, null);
return cursorLoader;
}


@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
getContactInfo(cursor); // here it is!
}


@Override
public void onLoaderReset(Loader<Cursor> loader) {
}

第五名:

public void initLoader(Uri data){
// will be used in onCreateLoader callback
this.tmp_url = data;
// 'this' is an Activity instance, implementing those callbacks
this.getSupportLoaderManager().initLoader(0, null, this);
}

第6,以上代码,除了我把签名参数从意图改为光标:

protected void getContactInfo(Cursor cursor)
{


// Cursor cursor =  managedQuery(intent.getData(), null, null, null, null);
while (cursor.moveToNext())
{
// same above ...
}

7,调用 initLoader:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (PICK_CONTACT == requestCode) {
this.initLoader(data.getData(), this);
}
}

第八,别忘了这段代码

    Intent intentContact = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
this.act.startActivityForResult(intentContact, PICK_CONTACT);

参考文献:

Android 基础: 正确加载数据

在活动中初始化加载程序

我正在使用此方法读取“联系人”

public static List<ContactItem> readPhoneContacts(Context context) {
List<ContactItem> contactItems = new ArrayList<ContactItem>();
try {
Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, "upper("+ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") ASC");


/*context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID+ " = ?",
new String[] { id },
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" ASC");*/


Integer contactsCount = cursor.getCount(); // get how many contacts you have in your contacts list
if (contactsCount > 0) {
while (cursor.moveToNext()) {


String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
ContactItem contactItem = new ContactItem();
contactItem.setContactName(contactName);
//the below cursor will give you details for multiple contacts
Cursor pCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id}, null);
// continue till this cursor reaches to all phone numbers which are associated with a contact in the contact list
while (pCursor.moveToNext()) {
int phoneType = pCursor.getInt(pCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
//String isStarred      = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.STARRED));
String phoneNo = pCursor.getString(pCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//you will get all phone numbers according to it's type as below switch case.
//Logs.e will print the phone number along with the name in DDMS. you can use these details where ever you want.
switch (phoneType) {
case Phone.TYPE_MOBILE:
contactItem.setContactNumberMobile(phoneNo);
Log.e(contactName + ": TYPE_MOBILE", " " + phoneNo);
break;
case ContactsContract.CommonDataKinds.Phone.TYPE_HOME:
contactItem.setContactNumberMobile(phoneNo);
Log.e(contactName + ": TYPE_HOME", " " + phoneNo);
break;
case ContactsContract.CommonDataKinds.Phone.TYPE_WORK:
contactItem.setContactNumberMobile(phoneNo);
Log.e(contactName + ": TYPE_WORK", " " + phoneNo);
break;
case ContactsContract.CommonDataKinds.Phone.TYPE_WORK_MOBILE:
contactItem.setContactNumberMobile(phoneNo);
Log.e(contactName + ": TYPE_WORK_MOBILE", " " + phoneNo);
break;
case Phone.TYPE_OTHER:
contactItem.setContactNumberMobile(phoneNo);
Log.e(contactName + ": TYPE_OTHER", " " + phoneNo);
break;
default:
break;
}
}
contactItem.setSelectedAddress(getContactPostalAddress(pCursor));
pCursor.close();
contactItems.add(contactItem);
}


}
cursor.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}




return contactItems;
}//loadContacts