效果图:

 


正题:

本实例包含几下实际应用:

1. 获取手机通讯录(包括SIM卡中的联系人)

2. 几种Intent的传值应用

3. Adapter的自定义使用

4. AutoCompleteTextView应用

5. TextWatcher应用(带正则应用)

6. AsyncTask应用

7. 防止手机横屏时页面重新加载

8. 通讯录联系人按拼音重排序


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

一.获取手机通讯录:


1. 2.  //从本机中取号
3.  private void GetLocalContact(){
4.    //读取手机中手机号
5.    Cursor cursor = getContentResolver().query(People.CONTENT_URI, null,
6.      null, null, null);
7.    while (cursor.moveToNext()) {
8.     ContactInfo cci = new ContactInfo();
9.     //取得联系人名字
10.     int nameFieldColumnIndex = cursor.getColumnIndex(People.NAME);
11.     cci.contactName = cursor.getString(nameFieldColumnIndex);
12.     //取得电话号码
13.     int numberFieldColumnIndex = cursor.getColumnIndex(People.NUMBER);
14.     cci.userNumber = cursor.getString(numberFieldColumnIndex);
15.     cci.userNumber = GetNumber(cci.userNumber);
16.     cci.isChecked = false;
17.     if (IsUserNumber(cci.userNumber)) {
18.      if (!IsContain(contactList, cci.userNumber)) {
19.       if(IsAlreadyCheck(wNumStr, cci.userNumber)){
20.        cci.isChecked = true;
21.        numberStr += "," + cci.userNumber;
22.       }
23.       contactList.add(cci);
24.        //Log.i("eoe", "*********"+cci.userNumber);
25.      }
26.     }
27.    }
28.    cursor.close();
29.  }
30. 31.  //从SIM卡中取号
32.  private void GetSimContact(String add){
33.    //读取SIM卡手机号,有两种可能:content://icc/adn与content://sim/adn
34.    try {
35.     Intent intent = new Intent();
36.     intent.setData(Uri.parse(add));
37.     Uri uri = intent.getData();
38.     mCursor = getContentResolver().query(uri, null, null, null, null);
39.     if (mCursor != null) {
40.      while (mCursor.moveToNext()) {
41.       ContactInfo sci = new ContactInfo();
42.       // 取得联系人名字
43.       int nameFieldColumnIndex = mCursor.getColumnIndex("name");
44.       sci.contactName = mCursor.getString(nameFieldColumnIndex);
45.       // 取得电话号码
46.       int numberFieldColumnIndex = mCursor
47.         .getColumnIndex("number");
48.       sci.userNumber = mCursor.getString(numberFieldColumnIndex);
49.       sci.userNumber = GetNumber(sci.userNumber);
50.       sci.isChecked = false;
51.       
52.       if (IsUserNumber(sci.userNumber)) {
53.        if (!IsContain(contactList, sci.userNumber)) {
54.         if(IsAlreadyCheck(wNumStr, sci.userNumber)){
55.          sci.isChecked = true;
56.          numberStr += "," + sci.userNumber;
57.         }
58.         contactList.add(sci);
59.          //Log.i("eoe", "*********"+sci.userNumber);
60.        }
61.       }
62.      }
63.      mCursor.close();
64.     }
65.    } catch (Exception e) {
66.     Log.i("eoe", e.toString());
67.    }
68.  }


复制代码




二. 几种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.  //获取前一页面所传值
11.    Intent intent = this.getIntent();
12.    Bundle  bundle = intent.getExtras();
13.    String wNumberStr = bundle.getString("wNumberStr").replace(",", ",");
14. 15.  //获取回传值
16.  //重写获取页面回传值
17.      @Override
18.  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
19.       switch (requestCode) {
20.       case CONTACT_REQUEST_CODE:
21.     if (resultCode == RESULT_OK) {
22.      String numberStr = null;
23.      Bundle bundle = data.getExtras();
24.      if (bundle != null) {
25.       numberStr = bundle.getString("numberStr");
26.      }
27.      eMsisdn.setText(numberStr);
28.     }
29.     break;
30.    }
31.      }


复制代码




三. 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<contactList.size();c++){
4.       autoContact[c]=contactList.get(c).contactName+"("+contactList.get(c).userNumber+")";
5.      }
6.      //绑定AUTOCOMPLETE
7.      ArrayAdapter<String> adapter = new ArrayAdapter<String>(ContactListView.this,
8.                    android.R.layout.simple_dropdown_item_1line, autoContact);
9.      textView.setAdapter(adapter);
10.      textView.addTextChangedListener(mTextWatcher);
11. 12.  //监听AUTOTEXT内容变化,当出现符合选中联系人[联系人(手机号)]的情况下,将该勾中,并加入选中手机号中
13.  private TextWatcher mTextWatcher = new TextWatcher() {
14.    public void beforeTextChanged(CharSequence s, int start, int
15.                  before, int after) { }
16.          public void onTextChanged(CharSequence s, int start,
17.                  int before, int after) {
18.                   String autoText = s.toString();
19.           if(autoText.length()>=13){
20.            Pattern pt=Pattern.compile("\\(([1][3,5,8]+\\d{9})\\)");
21.            Matcher mc = pt.matcher(autoText);
22.            if(mc.find()){
23.             String sNumber = mc.group(1);
24.             DealWithAutoComplete(contactList,sNumber);
25.             //刷新列表
26.             Toast.makeText(ContactListView.this, "已选中您搜索的结果!",1000).show();
27.             ca.setItemList(contactList);
28.             ca.notifyDataSetChanged();
29.            }
30.           }
31.          }
32.          public void afterTextChanged(Editable s) { }
33.  };



复制代码



五. AsyncTask应用

考虑到从机子上获取通讯有时间等待,因此使用了进程,提高体验效果(有关AsyncTask可以在EOE找专贴,我也是学来的,呵呵)


1.  //启动进程
2.    new GetContactTask().execute("");
3. 4.  //获取通讯录进程
5.  private class GetContactTask extends AsyncTask<String, String, String> {
6.    public String doInBackground(String... params) {
7. 8.     return "";
9.    }
10.    @Override
11.    protected void onPreExecute() {
12.     showDialog(DIALOG_KEY);
13.    }
14.    @Override
15.    public void onPostExecute(String Re) {
16.     
17.            removeDialog(DIALOG_KEY);
18.    }
19. 20.    //下面这段本例未使用,能配合doInBackground进行刷新效果
21.    @Override
22.    protected void onProgressUpdate(String... values) {
23.     // TODO Auto-generated method stub
24.    }
25.  }
26.  //


复制代码



六. 防止手机横屏时页面重新加载

AndroidManifest.xml中:

1.  <activity android:name=".ContactListView"
2.  android:theme="@android:style/Theme.NoTitleBar"
3.  android:noHistory="true"
4.  android:configChanges="orientation|keyboardHidden|navigation">
5.  </activity>


复制代码



七. 通讯录联系人按拼音重排序


1.  //按中文拼音顺序排序
2.      Comparator comp = new Mycomparator(); 
3.      Collections.sort(contactList,comp);
4. 5.  //通讯社按中文拼音排序
6.  public class Mycomparator implements Comparator{ 
7.  public int compare(Object o1,Object o2) { 
8.  ContactInfo c1=(ContactInfo)o1; 
9.  ContactInfo c2=(ContactInfo)o2; 
10.  Comparator cmp = Collator.getInstance(java.util.Locale.CHINA);
11.  return cmp.compare(c1.contactName, c2.contactName); 
12.  } 
13. 14.  }

复制代码




呃,应该都差不多这些了。。。不容易啊,也老长一贴啊~

个人认为已经贴的比较详细了,有关要点部分都粘出来了,并且源码中也作了相当的注释。

如果还有问题的话,我就想使用安脚无影腿、鸡风双眼插。。。



后记:

发现ANDROID 2.0以后提供了一个新的类,android.provider.ContactsContract,貌似可以直接取出SIM卡中的联系人。

以前代码都是使用ANDROID 1.5,毕竟需要考虑到一些低版本用户吧~


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


后续发现一些手机还需要从以下两处取:

content://icc/fdn

content://sim/fdn

MOTO XT800比较异常,通讯录在:

content://contacts/phones

双卡双待手机同时插两张卡无法取出...杯具!