如何调用Android联系人列表?
我正在制作一个Android应用程序,并需要拨打电话的联系人列表。 我需要调用联系人列表function,select一个联系人,然后返回到我的应用程序与联系人的名字。 这是我在互联网上的代码,但它不工作。
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); } }
我不能100%确定你的示例代码应该做什么,但下面的代码段应该可以帮助你“调用联系人列表function,select一个联系人,然后用联系人的姓名返回到你的应用程序”。
这个过程有三个步骤。
1.权限
将联系人数据添加到您的应用程序清单的权限。
<uses-permission android:name="android.permission.READ_CONTACTS"/>
2.调用联系人选取器
在您的活动中,创build一个Intent,要求系统查找可以通过Contacts URI中的项目执行PICK操作的Activity。
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
调用startActivityForResult
,传入此Intent(以及请求代码整数,在本例中为PICK_CONTACT
)。 这将导致Android启动一个在People.CONTENT_URI
上注册以支持ACTION_PICK
的People.CONTENT_URI
,然后在做出select(或取消)时返回到此Activity。
startActivityForResult(intent, PICK_CONTACT);
3.听取结果
同样在Activity中,重写onActivityResult
方法来侦听从步骤2中启动的“select联系人”活动的返回。您应该检查返回的请求代码是否与您期望的值匹配,并且结果代码是RESULT_OK
。
您可以通过调用数据 Intent参数的getData()
来获取所选联系人的URI。 要获取所选联系人的名称,您需要使用该URI来创build一个新的查询并从返回的游标中提取名称。
@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联系人列表) 。
我这样做的Android 2.2的Froyo版本的这种方式:基本上使用eclipse来创build一个类如下:public class SomePickContactName extends Activity
然后插入这个代码。 请记住添加我的代码版本中引用的私有类variables和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
使用ContactsContract API来查找API Level 5解决scheme,可以使用以下方法稍微修改上面的代码:
Intent intent = new Intent(Intent.ACTION_PICK); intent.setType(ContactsContract.Contacts.CONTENT_TYPE); startActivityForResult(intent, PICK_CONTACT);
然后在onActivityResult中使用列名称:
ContactsContract.Contacts.DISPLAY_NAME
以下是获取联系人的代码片段:
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()); } }
}
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)); }
public void onActivityResult(int requestCode, int resultCode, Intent intent) { if (requestCode == PICK_CONTACT && intent != null) //here check whether intent is null R not { } }
因为没有select任何联系,它会给出例外。 所以更好地检查这种情况。
完整的代码如下
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
令我惊讶的是,您不需要用户权限CONTACT_READ来读取名称和一些基本信息(联系人是星号,最后的呼叫时间是什么)。 但是,您需要获得阅读电话号码等联系人详细信息的权限。
使用android联系人列表时要小心。
以上方法的阅读联系人列表可以在大多数Android设备上工作,除了HTC One和Sony Xperia。 浪费了我六个星期的时间,试图弄清楚什么是错的!
网上提供的大多数教程几乎是相似的 – 首先阅读“所有”联系人,然后用ArrayAdapter
显示在Listview
。 这不是内存有效的解决scheme。 首先在其他网站上寻找解决scheme,看看developer.android.com。 如果任何解决scheme在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); }
检索联系人列表: https : //developer.android.com/training/contacts-provider/retrieve-names.html
我正在使用此方法来读取联系人
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
您好我有一个代码保存在您的数据库中的联系人共享偏好这里是我的代码
public class Main22Activity 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); } }
-> 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
我使用@Colin MacKenzie – III提供的代码 。 非常感谢!
对于正在寻找替代“弃用”的managedQuery的用户:
1,假设使用v4支持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>
3,
// temporarily store the 'data.getData()' from onActivityResult private Uri tmp_url;
4,覆盖callback:
@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, 上面的代码 ,除了我把签名参数从Intent更改为Cursor:
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); } }
8,不要忘记这段代码
Intent intentContact = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); this.act.startActivityForResult(intentContact, PICK_CONTACT);
参考文献:
Android基础知识:正确加载数据
在活动中初始化加载器