Android通讯录管理(获取联系人 通话记录 短信消息)(一)
<!-- 读联系人权限 --> <uses-permission android:name="android.permission.READ_CONTACTS" /> <!-- 写联系人权限 --> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> <!-- 拨号权限 --> <uses-permission android:name="android.permission.CALL_PHONE" /> <!-- 读短信权限 --> <uses-permission android:name="android.permission.READ_SMS" />
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/contact_list_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000000" > <com.suntek.contact.view.SlidingLinearLayout android:id="@+id/slidingview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" > <ListView android:id="@+id/contact_list" android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="#000000" android:divider="#00000000" android:fadingEdge="none" android:scrollbars="none" android:scrollingCache="false" android:visibility="visible" /> </com.suntek.contact.view.SlidingLinearLayout> <com.suntek.contact.view.QuickAlphabeticBar android:id="@+id/fast_scroller" android:layout_width="22dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:layout_gravity="top|right|center" android:layout_marginTop="0dip" android:background="@null" android:scaleType="centerInside" android:src="@drawable/dic_background" > </com.suntek.contact.view.QuickAlphabeticBar> <TextView android:id="@+id/fast_position" android:layout_width="70dip" android:layout_height="70dip" android:layout_centerInParent="true" android:layout_gravity="center_horizontal|top" android:layout_margin="34dip" android:background="@drawable/sort_icon_bg_click" android:gravity="center" android:padding="2dip" android:textColor="#404040" android:textSize="48dip" android:visibility="invisible" /></RelativeLayout>
/Contact_Demo/res/layout/contact_list_item.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" > <!-- 首字母 --> <TextView android:id="@+id/alpha" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#333333" android:paddingLeft="10dip" android:textColor="#FFFFFF" android:visibility="gone" /> <!-- 联系人信息 --> <QuickContactBadge android:id="@+id/qcb" android:layout_width="75dip" android:layout_height="75dip" android:layout_alignParentLeft="true" android:layout_below="@+id/alpha" android:layout_marginBottom="3dip" android:layout_marginTop="3dip" android:src="@drawable/touxiang" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="5.0dip" android:layout_toRightOf="@+id/qcb" android:singleLine="true" android:textAppearance="?android:textAppearanceLarge" android:textColor="#FFFFFF" /> <TextView android:id="@+id/number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginLeft="5.0dip" android:layout_toRightOf="@+id/qcb" android:singleLine="true" android:textAppearance="?android:textAppearanceSmall" android:textColor="#FFFFFF" /></RelativeLayout>
package com.suntek.contact.model;public class ContactBean { private int contactId; //id private String desplayName;//姓名 private String phoneNum; // 电话号码 private String sortKey; // 排序用的 private Long photoId; // 图片id private String lookUpKey; private int selected = 0; private String formattedNumber; private String pinyin; // 姓名拼音 public int getContactId() { return contactId; } public void setContactId(int contactId) { this.contactId = contactId; } public String getDesplayName() { return desplayName; } public void setDesplayName(String desplayName) { this.desplayName = desplayName; } public String getPhoneNum() { return phoneNum; } public void setPhoneNum(String phoneNum) { this.phoneNum = phoneNum; } public String getSortKey() { return sortKey; } public void setSortKey(String sortKey) { this.sortKey = sortKey; } public Long getPhotoId() { return photoId; } public void setPhotoId(Long photoId) { this.photoId = photoId; } public String getLookUpKey() { return lookUpKey; } public void setLookUpKey(String lookUpKey) { this.lookUpKey = lookUpKey; } public int getSelected() { return selected; } public void setSelected(int selected) { this.selected = selected; } public String getFormattedNumber() { return formattedNumber; } public void setFormattedNumber(String formattedNumber) { this.formattedNumber = formattedNumber; } public String getPinyin() { return pinyin; } public void setPinyin(String pinyin) { this.pinyin = pinyin; }}
package com.suntek.contact.adapter;import java.io.InputStream;import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Set;import java.util.regex.Pattern;import android.content.ContentUris;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.provider.ContactsContract;import android.provider.ContactsContract.Contacts;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.QuickContactBadge;import android.widget.TextView;import com.suntek.contact.R;import com.suntek.contact.model.ContactBean;import com.suntek.contact.view.QuickAlphabeticBar;public class ContactListAdapter extends BaseAdapter { private LayoutInflater inflater; private List<ContactBean> list; private HashMap<String, Integer> alphaIndexer; // 字母索引 private String[] sections; // 存储每个章节 private Context ctx; // 上下文 public ContactListAdapter(Context context, List<ContactBean> list, QuickAlphabeticBar alpha) { this.ctx = context; this.inflater = LayoutInflater.from(context); this.list = list; this.alphaIndexer = new HashMap<String, Integer>(); this.sections = new String[list.size()]; for (int i = 0; i < list.size(); i++) { // 得到字母 String name = getAlpha(list.get(i).getSortKey()); if (!alphaIndexer.containsKey(name)) { alphaIndexer.put(name, i); } } Set<String> sectionLetters = alphaIndexer.keySet(); ArrayList<String> sectionList = new ArrayList<String>(sectionLetters); Collections.sort(sectionList); // 根据首字母进行排序 sections = new String[sectionList.size()]; sectionList.toArray(sections); alpha.setAlphaIndexer(alphaIndexer); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } public void remove(int position) { list.remove(position); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = inflater.inflate(R.layout.contact_list_item, null); holder = new ViewHolder(); holder.quickContactBadge = (QuickContactBadge) convertView .findViewById(R.id.qcb); holder.alpha = (TextView) convertView.findViewById(R.id.alpha); holder.name = (TextView) convertView.findViewById(R.id.name); holder.number = (TextView) convertView.findViewById(R.id.number); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } ContactBean contact = list.get(position); String name = contact.getDesplayName(); String number = contact.getPhoneNum(); holder.name.setText(name); holder.number.setText(number); holder.quickContactBadge.assignContactUri(Contacts.getLookupUri( contact.getContactId(), contact.getLookUpKey())); if (0 == contact.getPhotoId()) { holder.quickContactBadge.setImageResource(R.drawable.touxiang); } else { Uri uri = ContentUris.withAppendedId( ContactsContract.Contacts.CONTENT_URI, contact.getContactId()); InputStream input = ContactsContract.Contacts .openContactPhotoInputStream(ctx.getContentResolver(), uri); Bitmap contactPhoto = BitmapFactory.decodeStream(input); holder.quickContactBadge.setImageBitmap(contactPhoto); } // 当前字母 String currentStr = getAlpha(contact.getSortKey()); // 前面的字母 String previewStr = (position - 1) >= 0 ? getAlpha(list.get( position - 1).getSortKey()) : " "; if (!previewStr.equals(currentStr)) { holder.alpha.setVisibility(View.VISIBLE); holder.alpha.setText(currentStr); } else { holder.alpha.setVisibility(View.GONE); } return convertView; } private static class ViewHolder { QuickContactBadge quickContactBadge; TextView alpha; TextView name; TextView number; } /** * 获取首字母 * * @param str * @return */ private String getAlpha(String str) { if (str == null) { return "#"; } if (str.trim().length() == 0) { return "#"; } char c = str.trim().substring(0, 1).charAt(0); // 正则表达式匹配 Pattern pattern = Pattern.compile("^[A-Za-z]+$"); if (pattern.matcher(c + "").matches()) { return (c + "").toUpperCase(); // 将小写字母转换为大写 } else { return "#"; } }}
package com.suntek.contact;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.app.Activity;import android.content.AsyncQueryHandler;import android.content.ContentResolver;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.provider.ContactsContract;import android.view.View;import android.widget.ListView;import com.suntek.contact.adapter.ContactListAdapter;import com.suntek.contact.model.ContactBean;import com.suntek.contact.view.QuickAlphabeticBar;/** * 联系人列表 * * @author Administrator * */public class ContactListActivity extends Activity { private ContactListAdapter adapter; private ListView contactList; private List<ContactBean> list; private AsyncQueryHandler asyncQueryHandler; // 异步查询数据库类对象 private QuickAlphabeticBar alphabeticBar; // 快速索引条 private Map<Integer, ContactBean> contactIdMap = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.contact_list_view); contactList = (ListView) findViewById(R.id.contact_list); alphabeticBar = (QuickAlphabeticBar) findViewById(R.id.fast_scroller); // 实例化 asyncQueryHandler = new MyAsyncQueryHandler(getContentResolver()); init(); } /** * 初始化数据库查询参数 */ private void init() { Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; // 联系人Uri; // 查询的字段 String[] projection = { ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.DATA1, "sort_key", ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.PHOTO_ID, ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY }; // 按照sort_key升序查詢 asyncQueryHandler.startQuery(0, null, uri, projection, null, null, "sort_key COLLATE LOCALIZED asc"); } /** * * @author Administrator * */ private class MyAsyncQueryHandler extends AsyncQueryHandler { public MyAsyncQueryHandler(ContentResolver cr) { super(cr); } @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { if (cursor != null && cursor.getCount() > 0) { contactIdMap = new HashMap<Integer, ContactBean>(); list = new ArrayList<ContactBean>(); cursor.moveToFirst(); // 游标移动到第一项 for (int i = 0; i < cursor.getCount(); i++) { cursor.moveToPosition(i); String name = cursor.getString(1); String number = cursor.getString(2); String sortKey = cursor.getString(3); int contactId = cursor.getInt(4); Long photoId = cursor.getLong(5); String lookUpKey = cursor.getString(6); if (contactIdMap.containsKey(contactId)) { // 无操作 } else { // 创建联系人对象 ContactBean contact = new ContactBean(); contact.setDesplayName(name); contact.setPhoneNum(number); contact.setSortKey(sortKey); contact.setPhotoId(photoId); contact.setLookUpKey(lookUpKey); list.add(contact); contactIdMap.put(contactId, contact); } } if (list.size() > 0) { setAdapter(list); } } super.onQueryComplete(token, cookie, cursor); } } private void setAdapter(List<ContactBean> list) { adapter = new ContactListAdapter(this, list, alphabeticBar); contactList.setAdapter(adapter); alphabeticBar.init(ContactListActivity.this); alphabeticBar.setListView(contactList); alphabeticBar.setHight(alphabeticBar.getHeight()); alphabeticBar.setVisibility(View.VISIBLE); }}
package com.suntek.contact.view;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.LinearLayout;public class SlidingLinearLayout extends LinearLayout { public SlidingLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev); }}
package com.suntek.contact.view;import java.util.HashMap;import android.app.Activity;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Typeface;import android.os.Handler;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.ImageButton;import android.widget.ListView;import android.widget.TextView;import com.suntek.contact.R;/** * 字母索引条 * * @author Administrator * */public class QuickAlphabeticBar extends ImageButton { private TextView mDialogText; // 中间显示字母的文本框 private Handler mHandler; // 处理UI的句柄 private ListView mList; // 列表 private float mHight; // 高度 // 字母列表索引 private String[] letters = new String[] { "#", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; // 字母索引哈希表 private HashMap<String, Integer> alphaIndexer; Paint paint = new Paint(); boolean showBkg = false; int choose = -1; public QuickAlphabeticBar(Context context) { super(context); } public QuickAlphabeticBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public QuickAlphabeticBar(Context context, AttributeSet attrs) { super(context, attrs); } // 初始化 public void init(Activity ctx) { mDialogText = (TextView) ctx.findViewById(R.id.fast_position); mDialogText.setVisibility(View.INVISIBLE); mHandler = new Handler(); } // 设置需要索引的列表 public void setListView(ListView mList) { this.mList = mList; } // 设置字母索引哈希表 public void setAlphaIndexer(HashMap<String, Integer> alphaIndexer) { this.alphaIndexer = alphaIndexer; } // 设置字母索引条的高度 public void setHight(float mHight) { this.mHight = mHight; } @Override public boolean onTouchEvent(MotionEvent event) { int act = event.getAction(); float y = event.getY(); final int oldChoose = choose; // 计算手指位置,找到对应的段,让mList移动段开头的位置上 int selectIndex = (int) (y / (mHight / letters.length)); if (selectIndex > -1 && selectIndex < letters.length) { // 防止越界 String key = letters[selectIndex]; if (alphaIndexer.containsKey(key)) { int pos = alphaIndexer.get(key); if (mList.getHeaderViewsCount() > 0) { // 防止ListView有标题栏,本例中没有 this.mList.setSelectionFromTop( pos + mList.getHeaderViewsCount(), 0); } else { this.mList.setSelectionFromTop(pos, 0); } mDialogText.setText(letters[selectIndex]); } } switch (act) { case MotionEvent.ACTION_DOWN: showBkg = true; if (oldChoose != selectIndex) { if (selectIndex > 0 && selectIndex < letters.length) { choose = selectIndex; invalidate(); } } if (mHandler != null) { mHandler.post(new Runnable() { @Override public void run() { if (mDialogText != null && mDialogText.getVisibility() == View.INVISIBLE) { mDialogText.setVisibility(VISIBLE); } } }); } break; case MotionEvent.ACTION_MOVE: if (oldChoose != selectIndex) { if (selectIndex > 0 && selectIndex < letters.length) { choose = selectIndex; invalidate(); } } break; case MotionEvent.ACTION_UP: showBkg = false; choose = -1; if (mHandler != null) { mHandler.post(new Runnable() { @Override public void run() { if (mDialogText != null && mDialogText.getVisibility() == View.VISIBLE) { mDialogText.setVisibility(INVISIBLE); } } }); } break; default: break; } return super.onTouchEvent(event); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int height = getHeight(); int width = getWidth(); int sigleHeight = height / letters.length; // 单个字母占的高度 for (int i = 0; i < letters.length; i++) { paint.setColor(Color.WHITE); paint.setTextSize(20); paint.setTypeface(Typeface.DEFAULT_BOLD); paint.setAntiAlias(true); if (i == choose) { paint.setColor(Color.parseColor("#00BFFF")); // 滑动时按下字母颜色 paint.setFakeBoldText(true); } // 绘画的位置 float xPos = width / 2 - paint.measureText(letters[i]) / 2; float yPos = sigleHeight * i + sigleHeight; canvas.drawText(letters[i], xPos, yPos, paint); paint.reset(); } }}
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow
Android通讯录管理(获取联系人 通话记录 短信消息)(一)相关推荐
- android通讯录管理(获取联系人,通话记录,短信消息),Android通讯录管理(获取联系人、通话记录、短信消息)(二)...
Android通讯录管理(获取联系人.通话记录.短信消息)(二) 前言:上一篇博客介绍的是获取联系人的实现,本篇博客将介绍通话记录的实现. 界面布局: /Contact_Demo/res/layout ...
- Android通讯录管理 获取联系人 通话记录 短信消息 一
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Andr ...
- Android通讯录管理(获取联系人 通话记录 短信消息)(三)
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Andr ...
- Android手机拨打电话、手动发送短信与自动拨打电话、自动发送短信(代码很简单哦)
Android实现手动拨打电话,即点击后跳转到手机默认电话号码输入页面,可以将相应号码传送过去: <span style="font-size:18px;"> Inte ...
- Android实现拨打电话和发送短信,Android手机拨打电话、手动发送短信与自动拨打电话、自动发送短信(代码很简单哦)...
Android实现手动拨打电话,即点击后跳转到手机默认电话号码输入页面,可以将相应号码传送过去: Intent intent = new Intent(Intent.ACTION_DIAL, Uri. ...
- Android实战技巧之三十九:短信收发
7月4日从广州出差回来就定下写作计划,但迟迟没有动笔.耽搁的原因还是老样子,工作上又有新任务,全部精力都投入过去了,每天精疲力竭的回来也打不起精神做其他事了.这就是精力管理不当所致,就像我把很多要做的 ...
- Android通讯录管理(获取联系人、通话记录、短信消息)(二)
Android通讯录管理(获取联系人.通话记录.短信消息)(二) 前言:上一篇博客介绍的是获取联系人的实现,本篇博客将介绍通话记录的实现. 同样的,你可以到这里下载源码:http://download ...
- Android通讯录管理(获取联系人、通话记录、短信消息)(三)
Android通讯录管理(获取联系人.通话记录.短信消息)(三) 这是通讯录管理的最后一篇,前面两篇已经把获取联系人和通话记录解决了,短息消息就相对来说要稍微复杂那么一点.我们先来看看效果图: 源码下 ...
- Android通讯录管理(获取联系人、通话记录、短信消息)
前言:前阵子主要是记录了如何对联系人的一些操作,比如搜索,全选.反选和删除等在实际开发中可能需要实现的功能,本篇博客是小巫从一个别人开源的一个项目抽取出来的部分内容,把它给简化出来,可以让需要的朋友清 ...
最新文章
- MyEclipse的Java Web项目配置环境搭建-如何安装tomact
- Linux软件管理器(如何使用软件管理器来管理软件)
- idea 将普通Java项目打包成可直接执行的jar
- MyBatis-学习笔记12【12.Mybatis注解开发】
- 【嵌入式Linux】嵌入式Linux应用开发基础知识之输入系统应用编程
- 聊天机器人mysql数据_自己动手开发智能聊天机器人完全指南(附完整源码)
- 杰出企业家的20个好习惯
- Flutter 判断横竖屏(含尺寸、方向改变时触发)
- 几种蓝屏分析及解决汇总
- 聊斋志异读后感 [20180818]
- 算法设计与分析中用到的渐近记号:Θ、O、Ω、o和ω
- python输出欢迎某某某_python中怎么写注释
- 如何快速拆分PDF文件(照片快速转换成pdf)
- 在 iPhone 上体验安卓系统,无需越狱,免费
- java ico图标_javaweb中如何给自己的网站更改ico图标
- C语言中:的其中一种作用
- verilog乘法器以及booth编码改进
- 参加论文写作课后心得体会
- 【前端安全】密码安全
- Python控制安卓模拟器
热门文章
- 华为手机按下这个键,瞬间投屏到电视大屏幕,效果惊艳堪比电影院
- 一文读懂mysql主从复制机制
- 2345 看图王广告弹窗 删除
- 李行健教授畅谈成语规范
- php 伪静态 rewriterule,PHP实现伪静态 RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] 是什么意思?...
- 埃隆·马斯克推荐的《你相信这台电脑吗?》上映,不火爆但AI威胁的论战又起(附视频地址)...
- Zynq7000简介
- WPF Border设置虚线边框
- Mpp 的一种 java 读写解决方案
- 程序员职业规划:30岁后如何实现质的突破!