|
前言:
以前一直搞了4、5年的.NET(C#),最近跟着一起搞一个ANDROID项目,所以从头开始学ANDROID、学java。
之前2、3个星期也是到处找资料、找教程,遇到实际问题就是一片海找,毕竟教程里面的实例都太过简单化,在实际应用中需要很多变化。
像获取SIM卡中的联系人问题,当时困扰了一两天,到处找资料,有的地方能找到只字片语,有的地方能提供一小段代码,但这些对一个初学者来说都是不够。。。我觉得初学者还是更喜欢拿来主义(我也一样 ),嘿嘿,一个运行的通的源码比什么都好~
其实后来这个功能实现后,其实感觉就是一层窗户纸,一捅破其实很简单,往往很多问题都是知者容易,未知者难如上擎天。。。
为后来人少走弯路,特献上处子原创实例讲解贴~
(估计台下手拿板砖作欲扔出状的人已经很多了,速度入题! )
效果图:
正题:
本实例包含几下实际应用:
1. 获取手机通讯录(包括SIM卡中的联系人)
2. 几种Intent的传值应用
3. Adapter的自定义使用
4. AutoCompleteTextView应用
5. TextWatcher应用(带正则应用)
6. AsyncTask应用
7. 防止手机横屏时页面重新加载
8. 通讯录联系人按拼音重排序
(注:以下代码都是针对标题节选的关键代码,甚至有些不是同一文件中,详情请参考工程)
一.获取手机通讯录:
//从本机中取号
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("eoe", "*********"+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("eoe", "*********"+sci.userNumber);
}
}
}
mCursor.close();
}
} catch (Exception e) {
Log.i("eoe", e.toString());
}
}
复制代码二. 几种Intent的传值应用 //页面传值并获取回传值
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可以派上用场了 //编辑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应用
考虑到从机子上获取通讯有时间等待,因此使用了进程,提高体验效果(有关AsyncTask可以在EOE找专贴,我也是学来的,呵呵) //启动进程
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中: <activity android:name=".ContactListView"
android:theme="@android:style/Theme.NoTitleBar"
android:noHistory="true"
android:configChanges="orientation|keyboardHidden|navigation">
</activity>
复制代码七. 通讯录联系人按拼音重排序 //按中文拼音顺序排序
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);
}
}
复制代码呃,应该都差不多这些了。。。不容易啊,也老长一贴啊~
个人认为已经贴的比较详细了,有关要点部分都粘出来了,并且源码中也作了相当的注释。
如果还有问题的话,我就想使用安脚无影腿、鸡风双眼插。。。
好吧。。。还是提供一个邮箱:
yingmuxiaodao@yahoo.com.cn
后记:
发现ANDROID 2.0以后提供了一个新的类,android.provider.ContactsContract,貌似可以直接取出SIM卡中的联系人。
以前代码都是使用ANDROID 1.5,毕竟需要考虑到一些低版本用户吧~
下次如果有时间的话,再写一个有关软件版本更新(XML)、文件下载(带进度条)、文件安装的实例
后续发现一些手机还需要从以下两处取:
content://icc/fdn
content://sim/fdn
MOTO XT800比较异常,通讯录在:
content://contacts/phones
双卡双待手机同时插两张卡无法取出...杯具! |
|