获取手机通讯录的实战应用(含SIM卡中的联系人)

效果图:
 

正题:
本实例包含几下实际应用:
1. 获取手机通讯录(包括SIM卡中的联系人)
2. 几种Intent的传值应用
3. Adapter的自定义使用
4. AutoCompleteTextView应用
5. TextWatcher应用(带正则应用)
6. AsyncTask应用
7. 防止手机横屏时页面重新加载
8. 通讯录联系人按拼音重排序

(注:以下代码都是针对标题节选的关键代码,甚至有些不是同一文件中,详情请参考工程)
一.获取手机通讯录:

  1. //从本机中取号
  2. private void GetLocalContact(){
  3.   //读取手机中手机号
  4.   Cursor cursor = getContentResolver().query(People.CONTENT_URI, null,
  5.     null, null, null);
  6.   while (cursor.moveToNext()) {
  7.    ContactInfo cci = new ContactInfo();
  8.    //取得联系人名字
  9.    int nameFieldColumnIndex = cursor.getColumnIndex(People.NAME);
  10.    cci.contactName = cursor.getString(nameFieldColumnIndex);
  11.    //取得电话号码
  12.    int numberFieldColumnIndex = cursor.getColumnIndex(People.NUMBER);
  13.    cci.userNumber = cursor.getString(numberFieldColumnIndex);
  14.    cci.userNumber = GetNumber(cci.userNumber);
  15.    cci.isChecked = false;
  16.    if (IsUserNumber(cci.userNumber)) {
  17.     if (!IsContain(contactList, cci.userNumber)) {
  18.      if(IsAlreadyCheck(wNumStr, cci.userNumber)){
  19.       cci.isChecked = true;
  20.       numberStr += "," + cci.userNumber;
  21.      }
  22.      contactList.add(cci);
  23.       //Log.i("eoe", "*********"+cci.userNumber);
  24.     }
  25.    }
  26.   }
  27.   cursor.close();
  28. }

  29. //从SIM卡中取号
  30. private void GetSimContact(String add){
  31.   //读取SIM卡手机号,有两种可能:content://icc/adn与content://sim/adn
  32.   try {
  33.    Intent intent = new Intent();
  34.    intent.setData(Uri.parse(add));
  35.    Uri uri = intent.getData();
  36.    mCursor = getContentResolver().query(uri, null, null, null, null);
  37.    if (mCursor != null) {
  38.     while (mCursor.moveToNext()) {
  39.      ContactInfo sci = new ContactInfo();
  40.      // 取得联系人名字
  41.      int nameFieldColumnIndex = mCursor.getColumnIndex("name");
  42.      sci.contactName = mCursor.getString(nameFieldColumnIndex);
  43.      // 取得电话号码
  44.      int numberFieldColumnIndex = mCursor
  45.        .getColumnIndex("number");
  46.      sci.userNumber = mCursor.getString(numberFieldColumnIndex);
  47.      sci.userNumber = GetNumber(sci.userNumber);
  48.      sci.isChecked = false;
  49.      
  50.      if (IsUserNumber(sci.userNumber)) {
  51.       if (!IsContain(contactList, sci.userNumber)) {
  52.        if(IsAlreadyCheck(wNumStr, sci.userNumber)){
  53.         sci.isChecked = true;
  54.         numberStr += "," + sci.userNumber;
  55.        }
  56.        contactList.add(sci);
  57.         //Log.i("eoe", "*********"+sci.userNumber);
  58.       }
  59.      }
  60.     }
  61.     mCursor.close();
  62.    }
  63.   } catch (Exception e) {
  64.    Log.i("eoe", e.toString());
  65.   }
  66. }
复制代码


二. 几种Intent的传值应用
  1. //页面传值并获取回传值
  2. Intent intent = new Intent();
  3. intent.setClass(Eoe_Contact.this, ContactListView.class);
  4. Bundle bundle = new Bundle();
  5. String wNumberStr = eMsisdn.getText().toString();
  6. bundle.putString("wNumberStr", wNumberStr);
  7. intent.putExtras(bundle);
  8. startActivityForResult(intent, CONTACT_REQUEST_CODE);

  9. //获取前一页面所传值
  10.   Intent intent = this.getIntent();
  11.   Bundle  bundle = intent.getExtras();
  12.   String wNumberStr = bundle.getString("wNumberStr").replace(",", ",");

  13. //获取回传值
  14. //重写获取页面回传值
  15.     @Override
  16. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  17.      switch (requestCode) {
  18.      case CONTACT_REQUEST_CODE:
  19.    if (resultCode == RESULT_OK) {
  20.     String numberStr = null;
  21.     Bundle bundle = data.getExtras();
  22.     if (bundle != null) {
  23.      numberStr = bundle.getString("numberStr");
  24.     }
  25.     eMsisdn.setText(numberStr);
  26.    }
  27.    break;
  28.   }
  29.     }
复制代码


三. Adapter的自定义使用
继承BaseAdapter类,重写。这个内容比较多就不粘了,详情看ContactAdapter.JAVA页面
需要注意的一点是,getView方法,adapter是在页面变化的时候,重新获取当前页面的数据

四. AutoCompleteTextView应用 和 TextWatcher应用
大家都看过APIDEMOS的示例,看过AutoCompleteTextView的基本应用,但是实际当中那些是不够的,我们往往希望点击自动提示后对所获取的内容做自己的逻辑处理,因此TextWatcher可以派上用场了
  1. //编辑AUTOCOMPLETE数组
  2.     autoContact = new String[contactList.size()];
  3.     for(int c=0;c
  4.      autoContact[c]=contactList.get(c).contactName+"("+contactList.get(c).userNumber+")";
  5.     }
  6.     //绑定AUTOCOMPLETE
  7.     ArrayAdapter adapter = new ArrayAdapter(ContactListView.this,
  8.                   android.R.layout.simple_dropdown_item_1line, autoContact);
  9.     textView.setAdapter(adapter);
  10.     textView.addTextChangedListener(mTextWatcher);

  11. //监听AUTOTEXT内容变化,当出现符合选中联系人[联系人(手机号)]的情况下,将该勾中,并加入选中手机号中
  12. private TextWatcher mTextWatcher = new TextWatcher() {
  13.   public void beforeTextChanged(CharSequence s, int start, int
  14.                 before, int after) { }
  15.         public void onTextChanged(CharSequence s, int start,
  16.                 int before, int after) {
  17.                  String autoText = s.toString();
  18.          if(autoText.length()>=13){
  19.           Pattern pt=Pattern.compile("\\(([1][3,5,8]+\\d{9})\\)");
  20.           Matcher mc = pt.matcher(autoText);
  21.           if(mc.find()){
  22.            String sNumber = mc.group(1);
  23.            DealWithAutoComplete(contactList,sNumber);
  24.            //刷新列表
  25.            Toast.makeText(ContactListView.this, "已选中您搜索的结果!",1000).show();
  26.            ca.setItemList(contactList);
  27.            ca.notifyDataSetChanged();
  28.           }
  29.          }
  30.         }
  31.         public void afterTextChanged(Editable s) { }
  32. };
复制代码

五. AsyncTask应用
考虑到从机子上获取通讯有时间等待,因此使用了进程,提高体验效果(有关AsyncTask可以在EOE找专贴,我也是学来的,呵呵)
  1. //启动进程
  2.   new GetContactTask().execute("");

  3. //获取通讯录进程
  4. private class GetContactTask extends AsyncTask {
  5.   public String doInBackground(String... params) {

  6.    return "";
  7.   }
  8.   @Override
  9.   protected void onPreExecute() {
  10.    showDialog(DIALOG_KEY);
  11.   }
  12.   @Override
  13.   public void onPostExecute(String Re) {
  14.    
  15.           removeDialog(DIALOG_KEY);
  16.   }

  17.   //下面这段本例未使用,能配合doInBackground进行刷新效果
  18.   @Override
  19.   protected void onProgressUpdate(String... values) {
  20.    // TODO Auto-generated method stub
  21.   }
  22. }
  23. //
复制代码

六. 防止手机横屏时页面重新加载
AndroidManifest.xml中:
  1. android:theme="@android:style/Theme.NoTitleBar"
  2. android:noHistory="true"
  3. android:configChanges="orientation|keyboardHidden|navigation">
复制代码

七. 通讯录联系人按拼音重排序
  1. //按中文拼音顺序排序
  2.     Comparator comp = new Mycomparator(); 
  3.     Collections.sort(contactList,comp);

  4. //通讯社按中文拼音排序
  5. public class Mycomparator implements Comparator{ 
  6. public int compare(Object o1,Object o2) { 
  7. ContactInfo c1=(ContactInfo)o1; 
  8. ContactInfo c2=(ContactInfo)o2; 
  9. Comparator cmp = Collator.getInstance(java.util.Locale.CHINA);
  10. return cmp.compare(c1.contactName, c2.contactName); 


  11. }
复制代码


呃,应该都差不多这些了。。。不容易啊,也老长一贴啊~
个人认为已经贴的比较详细了,有关要点部分都粘出来了,并且源码中也作了相当的注释。
如果还有问题的话,我就想使用安脚无影腿、鸡风双眼插。。。

好吧。。。还是提供一个邮箱:
[email protected]


后记:
发现ANDROID 2.0以后提供了一个新的类,android.provider.ContactsContract,貌似可以直接取出SIM卡中的联系人。
以前代码都是使用ANDROID 1.5,毕竟需要考虑到一些低版本用户吧~

下次如果有时间的话,再写一个有关软件版本更新(XML)、文件下载(带进度条)、文件安装的实例

后续发现一些手机还需要从以下两处取:
content://icc/fdn
content://sim/fdn
MOTO XT800比较异常,通讯录在:
content://contacts/phones
双卡双待手机同时插两张卡无法取出...杯具!

附上大家最关注的东东--源码:
 Eoe_Contact.rar (67.8 KB, 下载次数: 1801)

你可能感兴趣的:(获取手机通讯录的实战应用(含SIM卡中的联系人))