Android-获取手机通讯录的实战施用(含SIM卡中的联系人)
前言:
像获取SIM卡中的联系人问题,当时困扰了一两天,到处找资料,有的地方能找到只字片语,有的地方能提供一小段代码,但这些对一个初学者来说都是不够。。。我觉得初学者还是更喜欢拿来主义(我也一样 ),嘿嘿,一个运行的通的源码比什么都好~
其实后来这个功能实现后,其实感觉就是一层窗户纸,一捅破其实很简单,往往很多问题都是知者容易,未知者难如上擎天。。。
为后来人少走弯路,特献上处子原创实例讲解贴~
效果图:
正题:
本实例包含几下实际应用:
1. 获取手机通讯录(包括SIM卡中的联系人)
2. 几种Intent的传值应用
3. Adapter的自定义使用
4. AutoCompleteTextView应用
5. TextWatcher应用(带正则应用)
6. AsyncTask应用
7. 防止手机横屏时页面重新加载
8. 通讯录联系人按拼音重排序
(注:以下代码都是针对标题节选的关键代码,甚至有些不是同一文件中,详情请参考工程)
一.获取手机通讯录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
//从本机中取号 private void GetLocalContact(){ //读取手机中手机号 Cursor cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null); while (cursor.moveToNext()) { ContactInfo cci = new ContactInfo(); //取得联系人名字 int nameFieldColumnIndex = cursor.getColumnIndex(People.NAME); cci.contactName = cursor.getString(nameFieldColumnIndex); //取得电话号码 int numberFieldColumnIndex = cursor.getColumnIndex(People.NUMBER); cci.userNumber = cursor.getString(numberFieldColumnIndex); cci.userNumber = GetNumber(cci.userNumber); cci.isChecked = false; if (IsUserNumber(cci.userNumber)) { if (!IsContain(contactList, cci.userNumber)) { if(IsAlreadyCheck(wNumStr, cci.userNumber)){ cci.isChecked = true; numberStr += "," + cci.userNumber; } contactList.add(cci); //Log.i("umeng", "*********"+cci.userNumber); } } } cursor.close(); } //从SIM卡中取号 private void GetSimContact(String add){ //读取SIM卡手机号,有两种可能:content://icc/adn与content://sim/adn try { Intent intent = new Intent(); intent.setData(Uri.parse(add)); Uri uri = intent.getData(); mCursor = getContentResolver().query(uri, null, null, null, null); if (mCursor != null) { while (mCursor.moveToNext()) { ContactInfo sci = new ContactInfo(); // 取得联系人名字 int nameFieldColumnIndex = mCursor.getColumnIndex("name"); sci.contactName = mCursor.getString(nameFieldColumnIndex); // 取得电话号码 int numberFieldColumnIndex = mCursor .getColumnIndex("number"); sci.userNumber = mCursor.getString(numberFieldColumnIndex); sci.userNumber = GetNumber(sci.userNumber); sci.isChecked = false; if (IsUserNumber(sci.userNumber)) { if (!IsContain(contactList, sci.userNumber)) { if(IsAlreadyCheck(wNumStr, sci.userNumber)){ sci.isChecked = true; numberStr += "," + sci.userNumber; } contactList.add(sci); //Log.i("umeng", "*********"+sci.userNumber); } } } mCursor.close(); } } catch (Exception e) { Log.i("umeng", e.toString()); } } |
二. 几种Intent的传值应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
//页面传值并获取回传值 Intent intent = new Intent(); intent.setClass(Eoe_Contact.this, ContactListView.class); Bundle bundle = new Bundle(); String wNumberStr = eMsisdn.getText().toString(); bundle.putString("wNumberStr", wNumberStr); intent.putExtras(bundle); startActivityForResult(intent, CONTACT_REQUEST_CODE); //获取前一页面所传值 Intent intent = this.getIntent(); Bundle bundle = intent.getExtras(); String wNumberStr = bundle.getString("wNumberStr").replace(",", ","); //获取回传值 //重写获取页面回传值 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case CONTACT_REQUEST_CODE: if (resultCode == RESULT_OK) { String numberStr = null; Bundle bundle = data.getExtras(); if (bundle != null) { numberStr = bundle.getString("numberStr"); } eMsisdn.setText(numberStr); } break; } } |
三. Adapter的自定义使用
继承BaseAdapter类,重写。这个内容比较多就不粘了,详情看ContactAdapter.JAVA页面
需要注意的一点是,getView方法,adapter是在页面变化的时候,重新获取当前页面的数据
四. AutoCompleteTextView应用 和 TextWatcher应用
大家都看过APIDEMOS的示例,看过AutoCompleteTextView的基本应用,但是实际当中那些是不够的,我们往往希望点击自动提示后对所获取的内容做自己的逻辑处理,因此TextWatcher可以派上用场了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
//编辑AUTOCOMPLETE数组 autoContact = new String[contactList.size()]; for(int c=0;c<contactList.size();c++){ autoContact[c]=contactList.get(c).contactName+"("+contactList.get(c).userNumber+")"; } //绑定AUTOCOMPLETE ArrayAdapter<String> adapter = new ArrayAdapter<String>(ContactListView.this, android.R.layout.simple_dropdown_item_1line, autoContact); textView.setAdapter(adapter); textView.addTextChangedListener(mTextWatcher); //监听AUTOTEXT内容变化,当出现符合选中联系人[联系人(手机号)]的情况下,将该勾中,并加入选中手机号中 private TextWatcher mTextWatcher = new TextWatcher() { public void beforeTextChanged(CharSequence s, int start, int before, int after) { } public void onTextChanged(CharSequence s, int start, int before, int after) { String autoText = s.toString(); if(autoText.length()>=13){ Pattern pt=Pattern.compile("\\(([1][3,5,8]+\\d{9})\\)"); Matcher mc = pt.matcher(autoText); if(mc.find()){ String sNumber = mc.group(1); DealWithAutoComplete(contactList,sNumber); //刷新列表 Toast.makeText(ContactListView.this, "已选中您搜索的结果!",1000).show(); ca.setItemList(contactList); ca.notifyDataSetChanged(); } } } public void afterTextChanged(Editable s) { } }; |
五. AsyncTask应用
考虑到从机子上获取通讯有时间等待,因此使用了进程,提高体验效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//启动进程 new GetContactTask().execute(""); //获取通讯录进程 private class GetContactTask extends AsyncTask<String, String, String> { public String doInBackground(String... params) { return ""; } @Override protected void onPreExecute() { showDialog(DIALOG_KEY); } @Override public void onPostExecute(String Re) { removeDialog(DIALOG_KEY); } //下面这段本例未使用,能配合doInBackground进行刷新效果 @Override protected void onProgressUpdate(String... values) { // TODO Auto-generated method stub } } // |
六. 防止手机横屏时页面重新加载
AndroidManifest.xml中:
七. 通讯录联系人按拼音重排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//按中文拼音顺序排序 Comparator comp = new Mycomparator(); Collections.sort(contactList,comp); //通讯社按中文拼音排序 public class Mycomparator implements Comparator{ public int compare(Object o1,Object o2) { ContactInfo c1=(ContactInfo)o1; ContactInfo c2=(ContactInfo)o2; Comparator cmp = Collator.getInstance(java.util.Locale.CHINA); return cmp.compare(c1.contactName, c2.contactName); } } |
呃,应该都差不多这些了。。。
后记:
发现ANDROID 2.0以后提供了一个新的类,android.provider.ContactsContract,貌似可以直接取出SIM卡中的联系人。
以前代码都是使用ANDROID 1.5,毕竟需要考虑到一些低版本用户吧~