重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
天冷了,老夫要把伙食搞上去,这不最近在软件园二楼吃,伙食15块,杠杠的。
创新互联公司是一家专注于成都做网站、网站建设与策划设计,桥西网站建设哪家好?创新互联公司做网站,专注于网站建设十余年,网设计领域的专业建站公司;建站业务涵盖:桥西等地区。桥西做网站价格咨询:18982081108
美包包,不说了,进入正题。今天老夫要讲的是读取联系人,其实我做这个的初衷是想做一个短信拦截,电话拦截的功能。
我们先看一下界面,还是不错的,挺绚丽的。
OK,我们一看就知道,这又是一个ListView。目前的功能是当你在复选框打钩,点击后面的拨号就会将电话打出去。如果不打钩,电话则不会拨出去。OK,我们先看看页面布局
我们再看看ListView要加载的模版
依然是TableLayout布局,我们设置它的收缩列为第二列,伸展列也是第二列。这样如果第二列不够显示则会收缩。OK,我们看一下后台代码
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.punchinalarm); owner = this; btnSelAll = (Button) this.findViewById(R.id.btnSelAll); btnSelInverse = (Button) this.findViewById(R.id.btnInverseSel); btnSet = (Button) this.findViewById(R.id.btnSet); contactUserListView = (ListView) this .findViewById(R.id.contactListView); dataList = new ArrayList
在OnCreate方法中,我们初始化数据。
private void InitData() { String phoneUserName = null; String phoneNumber = null; Long contactId = null; Long photoId = null; MapdataMap = null; ContentResolver resolver = this.getApplicationContext() .getContentResolver(); /* * 获取Sim卡联系人 Uri uri = Uri.parse("content://icc/adn"); */ Cursor phoneCursor = resolver.query(Phone.CONTENT_URI, PHONE_PROJECTION, null, null, null); if (phoneCursor != null) { while (phoneCursor.moveToNext()) { dataMap = new HashMap (); phoneUserName = phoneCursor.getString(0); phoneNumber = phoneCursor.getString(1); photoId = phoneCursor.getLong(2); contactId = phoneCursor.getLong(3); if (phoneNumber == null || phoneNumber.trim().length() < 11) { continue; } Bitmap contactPhoto = null; if (photoId > 0) { Uri uri = ContentUris.withAppendedId( ContactsContract.Contacts.CONTENT_URI, contactId); InputStream input = ContactsContract.Contacts .openContactPhotoInputStream(resolver, uri); contactPhoto = BitmapFactory.decodeStream(input); } else { contactPhoto = BitmapFactory.decodeResource(getResources(), R.drawable.usersmall); } dataMap.put("UserName", phoneUserName); dataMap.put("UserPhoneNumber", phoneNumber); dataMap.put("UserPhoto", contactPhoto); dataList.add(dataMap); } if (dataList != null && dataList.size() > 0) { customAdapter simpleAdapter = new customAdapter(this, dataList, R.layout.contactdetailtemplate, new String[] { "UserPhoto", "UserName", "UserPhoneNumber" }, new int[] { R.id.chkContactUser, R.id.imgContactPhoto, R.id.txtContactName, R.id.txtContactTelNumber, R.id.btnDail }); this.contactUserListView.setAdapter(simpleAdapter); } } }
我们知道外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用的 ContentResolver实例。因为通讯录和短消息都可以通过接口访问,所以我们就可以通过getContentResolver访问SIM卡和手机中的联系人信息。
我们主要到下面的这句
Cursor phoneCursor = resolver.query(Phone.CONTENT_URI, PHONE_PROJECTION, null, null, null);
通过接口查询,我们会得到一个Cursor。通过查看Cursor的定义,我们发现它是个抽象类
public abstract interface android.database.Cursor
我们发现它提供了一些方法,如下
由此可见,它是一个既可以前进又可以后退的无向游标,类似于SqlServer中的游标。这样的话我们不论是读取联系人信息,还是读取短消息,都可以随时定位游标。
在上面我们看到Query的几个参数,Phone.Content_URI,获取联系人的时候需要去这个URI去取数据。其实这里的Phone.Content_URI的值是content://com.android.contacts/contacts。它的定义如下
public static final android.net.Uri CONTENT_URI;
ok,我们拿到联系人之后,我们进行循环,游标下移,拿出所有的有电话号码的联系人的数据。因为我们传入的PHONE_PROJECTION的顺序是姓名,电话号码,照片ID,以及一个ContactID。所以我们看到取数据的顺序如下
phoneUserName = phoneCursor.getString(0); phoneNumber = phoneCursor.getString(1); photoId = phoneCursor.getLong(2); contactId = phoneCursor.getLong(3);
拿到PhotoID之后,我们判断是否大于0,如果大于0,我们会获取用户图像。
获取用户图像的时候,先通过下面的代码将URI和参数连接起来
ContentUris.withAppendedId( ContactsContract.Contacts.CONTENT_URI, contactId)
其实这个类似于Get方式的API,比如ContactUser/100,意思是获取编号为100的人的信息。
OK,URI构造好之后,我们获取图像
InputStream input = ContactsContract.Contacts .openContactPhotoInputStream(resolver, uri); contactPhoto = BitmapFactory.decodeStream(input);
最后加入List
class customAdapter extends BaseAdapter { private List
这里,其实很简单,我们就是拿到控件,然后根据Position,拿到List中的某行数据,然后赋值。
最后我们看看按钮的Click事件,我们传入了Position和每行的CheckBox。
class ViewButtonListener implements OnClickListener { private int position; Object phoneNumber; CheckBox chkContactUser; ViewButtonListener(int position,CheckBox chkContactUser) { this.position = position; this.phoneNumber = dataList.get(position).get("UserPhoneNumber"); this.chkContactUser= chkContactUser; } @Override public void onClick(View view) { int vid = view.getId(); if (vid == R.id.btnDail&&chkContactUser.isChecked()) { Intent dialIntent = new Intent(Intent.ACTION_CALL, Uri .parse("tel:" + phoneNumber)); startActivity(dialIntent); } } }
在OnClick中,我们判断如果是拨号按钮并且列头的CheckBox是勾选的,则会拨号,否则不会拨号。OK,最后我们希望在按回退键的时候,弹出是否退出的提示
ok,代码如下
public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)) { dialog(); return true; } return true; } protected void dialog() { AlertDialog.Builder builder = new Builder(punchinalarm.this); builder.setMessage("确定要退出吗?"); builder.setTitle("提示"); builder.setPositiveButton("确认", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); android.os.Process.killProcess(android.os.Process.myPid()); } }); builder.setNegativeButton("取消", new android.content.DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.create().show(); }
最后,哥们的博客是货真价实,小米3测试机。