关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 安卓开发 »Android访问和加载本地联系人的代码实现

    Android访问和加载本地联系人的代码实现

    2015-03-07 00:00:00 出处:creasylai19
    分享

    在Android开发中,我们经常会遇到访问和加载本地联系人的情况,毕竟手机中联系人是最重要的数据之一,很多手机应用都会需要手机联系人的信息,比如姓名、手机号码等。本文通过一个简单的例子以及Android代码,来实现一个本地联系人加载读取的功能。

    首先先建布局文件,界面很简单,就是一个搜索框和下面的联系人列表:

    < xml version="1.0"encoding="utf-8" >
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#FFD3D7DF"
    android:orientation="vertical"
     android:padding="0dip">
    <RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="3dip"
    android:layout_marginRight="3dip"
     android:layout_marginTop="3dip">
    
    <EditText
    android:id="@+id/search_view"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:hint="@string/hint_search_contacts"
    android:paddingLeft="32dip"
    android:singleLine="true"
     android:textSize="16sp"/>
    
    <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@id/search_view"
    android:layout_centerVertical="true"
    android:layout_marginLeft="3dip"
     android:src="@drawable/contacts"/>
    </RelativeLayout>
    
    <ListView
    android:id="@+id/contact_list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="0dip"
    android:layout_marginLeft="0dip"
    android:layout_marginRight="0dip"
    android:layout_marginTop="0dip"
    android:layout_weight="1.0"
    android:cacheColorHint="#00000000"
    android:divider="#00000000"
    android:dividerHeight="0.1px"
    android:fadingEdge="none"
    android:footerDividersEnabled="false"
    android:listSelector="@null"
    android:paddingBottom="0dip"
    android:paddingLeft="0dip"
    android:paddingRight="0dip"
     android:paddingTop="0dip"/>
    
    </LinearLayout>
    < xml version="1.0" encoding="utf-8" > 
    <LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="horizontal" 
    android:layout_height="wrap_content" 
    android:layout_width="fill_parent" 
    android:paddingTop="2dip" 
    android:paddingBottom="2dip" 
    android:background="@color/list_item_background"> 
    <ImageView 
    android:id="@+id/photo" 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:layout_marginLeft="5dip" 
    android:layout_gravity="center_vertical" 
    android:layout_weight="1" 
    android:src="@drawable/default_avatar" 
    /> 
    <LinearLayout 
    android:orientation="vertical" 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:layout_gravity="center_vertical" 
    android:layout_marginLeft="5dip" 
    android:layout_weight="100"> 
    <TextView android:id="@+id/text1" 
    android:typeface="serif" 
    android:singleLine="true" 
    style="@style/list_font_main_text" /> 
    
    <LinearLayout 
    android:orientation="horizontal" 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:layout_marginTop="3dip"> 
    <TextView android:id="@+id/text2" 
    android:typeface="serif" 
    android:singleLine="true" 
    style="@style/list_font_detail_text" /> 
    
    <TextView android:id="@+id/text3" 
    android:ellipsize="marquee" 
    android:layout_marginLeft="3dip" 
    android:marqueeRepeatLimit="marquee_forever" 
    android:scrollHorizontally="true" 
    style="@style/list_font_detail_text" /> 
    </LinearLayout> 
    </LinearLayout> 
    </LinearLayout>

    然后是点击事件:(点击后要把选择的联系人号码返回到输入框里)

    // 获取联系人按钮对象并绑定onClick单击事件 
    phoneButton = (Button) findViewById(R.id.find_phone); 
    phoneButton.setOnClickListener(new OnClickListener() { 
    public void onClick(View v) { 
    // 从联系人选择号码,再通过onActivityResult()方法处理回调结果 
    Intent intent = new Intent(context, ContactsActivity.class); 
    startActivityForResult(intent, REQUEST_CODE); 
    } 
    }); 
    /** 
    * 选择联系人的回调处理函数 
    */ 
    @Override 
    public void onActivityResult(int reqCode, int resultCode, Intent data) { 
    super.onActivityResult(reqCode, resultCode, data); 
    if (resultCode == RESULT_OK) { 
    switch (reqCode) { 
    case REQUEST_CODE: 
    String phone = data.getStringExtra("phone"); 
    phoneEditText.setText(phone); 
    break; 
    } 
    } 
    }

    下面就是联系人界面的activity了:

    /** 
    * 显示用户手机上的联系人 
    * 
    * @author Mr.Z 
    * @time 2012-3-21 
    * 
    */ 
    public class ContactsActivity extends Activity { 
    private Context ctx = ContactsActivity.this; 
    private TextView topTitleTextView; 
    private ListView listView = null; 
    List<HashMap<String, String>> contactsList = null; 
    private EditText contactsSearchView; 
    private ProgressDialog progressDialog = null; 
    // 数据加载完成的消息 
    private final int MESSAGE_SUCC_LOAD = 0; 
    // 数据查询完成的消息 
    private final int MESSAGE_SUCC_QUERY = 1; 
    private Handler handler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 
    super.handleMessage(msg); 
    switch (msg.what) { 
    case MESSAGE_SUCC_LOAD: 
    listView.setAdapter(new ContactsAdapter(ctx)); 
    progressDialog.dismiss(); 
    break; 
    case MESSAGE_SUCC_QUERY: 
    listView.setAdapter(new ContactsAdapter(ctx)); 
    break; 
    } 
    } 
    }; 
    protected void onCreate(Bundle savedInstanceState) { 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    super.onCreate(savedInstanceState); 
    this.setContentView(R.layout.contacts); 
    // 使用listView显示联系人 
    listView = (ListView) findViewById(R.id.contact_list); 
    loadAndSaveContacts(); 
    // 绑定listView item的单击事件 
    listView.setOnItemClickListener(new OnItemClickListener() { 
    @SuppressWarnings("unchecked") 
    public void onItemClick(AdapterView< > adapterView, View view, int position, long _id) { 
    HashMap<String, String> map = (HashMap<String, String>) adapterView.getItemAtPosition(position); 
    String phone = map.get("phone"); 
    // 对手机号码进行预处理(去掉号码前的+86、首尾空格、“-”号等) 
    phone = phone.replaceAll("^(\+86)", ""); 
    phone = phone.replaceAll("^(86)", ""); 
    phone = phone.replaceAll("-", ""); 
    phone = phone.trim(); 
    // 假如当前号码并不是手机号码 
    if (!SaleUtil.isValidPhoneNumber(phone)) 
    SaleUtil.createDialog(ctx, R.string.dialog_title_tip, getString(R.string.alert_contacts_error_phone)); 
    else { 
    Intent intent = new Intent(); 
    intent.putExtra("phone", phone); 
    setResult(RESULT_OK, intent); 
    // 关闭当前窗口 
    finish(); 
    } 
    } 
    }); 
    contactsSearchView = (EditText) findViewById(R.id.search_view); 
    contactsSearchView.addTextChangedListener(new TextWatcher() { 
    public void afterTextChanged(Editable s) { 
    } 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
    } 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
    queryContacts(s.toString()); 
    } 
    }); 
    } 
    /** 
    * 加载并存储联系人数据 
    */ 
    private void loadAndSaveContacts() { 
    progressDialog = ProgressDialog.show(ctx, null, "正在加载联系人数据..."); 
    new Thread() { 
    @Override 
    public void run() { 
    // 获取联系人数据 
    contactsList = findContacts(); 
    // 临时存储联系人数据 
    DBHelper.saveContacts(ctx, contactsList); 
    // 发送消息通知更新UI 
    handler.sendEmptyMessage(MESSAGE_SUCC_LOAD); 
    } 
    }.start(); 
    } 
    /** 
    * 根据条件从本地临时库中获取联系人 
    * 
    * @param keyWord 查询关键字 
    */ 
    private void queryContacts(final String keyWord) { 
    new Thread() { 
    @Override 
    public void run() { 
    // 获取联系人数据 
    contactsList = DBHelper.findContactsByCond(ctx, keyWord); 
    // 发送消息通知更新UI 
    handler.sendEmptyMessage(MESSAGE_SUCC_QUERY); 
    } 
    }.start(); 
    } 
    /** 
    * 获取手机联系人信息 
    * 
    * @return List<HashMap<String, String>> 
    */ 
    public List<HashMap<String, String>> findContacts() { 
    List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>(); 
    // 查询联系人 
    Cursor contactsCursor = ctx.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, PhoneLookup.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); 
    // 姓名的索引 
    int nameIndex = 0; 
    // 联系人姓名 
    String name = null; 
    // 联系人头像ID 
    String photoId = null; 
    // 联系人的ID索引值 
    String contactsId = null; 
    // 查询联系人的电话号码 
    Cursor phoneCursor = null; 
    while (contactsCursor.moveToNext()) { 
    nameIndex = contactsCursor.getColumnIndex(PhoneLookup.DISPLAY_NAME); 
    name = contactsCursor.getString(nameIndex); 
    photoId = contactsCursor.getString(contactsCursor.getColumnIndex(PhoneLookup.PHOTO_ID)); 
    contactsId = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts._ID)); 
    phoneCursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactsId, null, null); 
    // 遍历联系人号码(一个人对应于多个电话号码) 
    while (phoneCursor.moveToNext()) { 
    HashMap<String, String> phoneMap = new HashMap<String, String>(); 
    // 添加联系人姓名 
    phoneMap.put("name", name); 
    // 添加联系人头像 
    phoneMap.put("photo", photoId); 
    // 添加电话号码 
    phoneMap.put("phone", phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); 
    // 添加号码类型(住宅电话、手机号码、单位电话等) 
    phoneMap.put("type", getString(ContactsContract.CommonDataKinds.Phone.getTypeLabelResource(phoneCursor.getInt(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)))));
    list.add(phoneMap); 
    } 
    phoneCursor.close(); 
    } 
    contactsCursor.close(); 
    return list; 
    } 
    /** 
    * 获取联系人头像 
    * 
    * @param context 上下文环境 
    * @param photoId 头像ID 
    * @return Bitmap 
    */ 
    public static Bitmap getPhoto(Context context, String photoId) { 
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.default_avatar); 
    if (photoId != null && "".equals(photoId)) { 
    String[] projection = new String[] { ContactsContract.Data.DATA15 }; 
    String selection = "ContactsContract.Data._ID = " + photoId; 
    Cursor cur = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI, projection, selection, null, null); 
    if (cur != null) { 
    cur.moveToFirst(); 
    byte[] contactIcon = null; 
    contactIcon = cur.getBlob(cur.getColumnIndex(ContactsContract.Data.DATA15)); 
    if (contactIcon != null) { 
    bitmap = BitmapFactory.decodeByteArray(contactIcon, 0, contactIcon.length); 
    } 
    } 
    } 
    return bitmap; 
    } 
    /** 
    * 自定义联系人Adapter 
    */ 
    class ContactsAdapter extends BaseAdapter { 
    private LayoutInflater inflater = null; 
    public ContactsAdapter(Context ctx) { 
    inflater = LayoutInflater.from(ctx); 
    } 
    public int getCount() { 
    return contactsList.size(); 
    } 
    public Object getItem(int position) { 
    return contactsList.get(position); 
    } 
    public long getItemId(int position) { 
    return position; 
    } 
    public View getView(int position, View convertView, ViewGroup parent) { 
    ViewHolder holder = null; 
    if (convertView == null) { 
    holder = new ViewHolder(); 
    convertView = inflater.inflate(R.layout.contacts_listview_item, null); 
    holder.text1 = (TextView) convertView.findViewById(R.id.text1); 
    holder.text2 = (TextView) convertView.findViewById(R.id.text2); 
    holder.text3 = (TextView) convertView.findViewById(R.id.text3); 
    convertView.setTag(holder); 
    } else { 
    holder = (ViewHolder) convertView.getTag(); 
    } 
    holder.text1.setText(contactsList.get(position).get("name")); 
    holder.text2.setText(contactsList.get(position).get("type")); 
    holder.text3.setText(contactsList.get(position).get("phone")); 
    return convertView; 
    } 
    public final class ViewHolder { 
    private TextView text1; 
    private TextView text2; 
    private TextView text3; 
    } 
    } 
    }

    查询方法语句:

    /** 
    * 根据条件查询联系人数据 
    * 
    * @param context 上下文环境 
    * @param keyWord 查询关键字 
    * @return List<HashMap<String, String>> 
    */ 
    public static List<HashMap<String, String>> findContactsByCond(Context context, String keyWord) { 
    List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>(); 
    SQLiteDatabase db = DBHelper.getSQLiteDb(context); 
    String sql = "select * from contacts where name like '" + keyWord + "%' or name_alias like '" + keyWord + "%' order by _id"; 
    // 查询数据 
    Cursor cursor = db.rawQuery(sql, null); 
    while (cursor.moveToNext()) { 
    HashMap<String, String> map = new HashMap<String, String>(); 
    map.put("name", cursor.getString(cursor.getColumnIndex("name"))); 
    map.put("phone", cursor.getString(cursor.getColumnIndex("phone"))); 
    map.put("type", cursor.getString(cursor.getColumnIndex("type"))); 
    map.put("photo", cursor.getString(cursor.getColumnIndex("photo"))); 
    list.add(map); 
    } 
    cursor.close(); 
    db.close(); 
    return list; 
    } 
    /** 
    * 存储联系人信息 
    * 
    * @param context 上下文环境 
    * @param contactsList 联系人列表 
    */ 
    public static void saveContacts(Context context, List<HashMap<String, String>> contactsList) { 
    SQLiteDatabase db = DBHelper.getSQLiteDb(context); 
    // 开启事务控制 
    db.beginTransaction(); 
    try { 
    // 先将联系人数据清空 
    db.execSQL("drop table if exists contacts"); 
    db.execSQL("create table contacts(_id integer not null primary key autoincrement, name varchar(50), name_alias varchar(10), phone varchar(30), type varchar(50), photo varchar(50))"); 
    String sql = null; 
    for (HashMap<String, String> contactsMap : contactsList) { 
    sql = String.format("insert into contacts(name,name_alias,phone,type,photo) values('%s','%s','%s','%s','%s')", contactsMap.get("name"), SaleUtil.getPinYinFirstAlphabet(contactsMap.get("name")), contactsMap.get("phone"), contactsMap.get("type"), contactsMap.get("photo")); 
    db.execSQL(sql); 
    } 
    // 设置事务标志为成功 
    db.setTransactionSuccessful(); 
    } finally { 
    // 结束事务 
    db.endTransaction(); 
    db.close(); 
    } 
    }

    工具类:

    /** 
    * 判断客户手机号码是否符合规则 
    * 
    * @param userPhone 客户手机号码 
    * @return true | false 
    */ 
    public static boolean isValidPhoneNumber(String userPhone) { 
    if (null == userPhone || "".equals(userPhone)) 
    return false; 
    Pattern p = Pattern.compile("^0 1[0-9]{10}"); 
    Matcher m = p.matcher(userPhone); 
    return m.matches(); 
    } 
    /** 
    * 获取中文的拼音首字母 
    * 
    * @param chinese 中文 
    * @return 拼音首字母 
    */ 
    public static String getPinYinFirstAlphabet(String chinese) { 
    String convert = ""; 
    for (int j = 0; j < chinese.length(); j++) { 
    char word = chinese.charAt(j); 
    String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word); 
    if (pinyinArray != null) { 
    convert += pinyinArray[0].charAt(0); 
    } else { 
    convert += word; 
    } 
    } 
    return convert; 
    }

    最后加上权限就行了;

     <!-- 访问联系人的权限 -->
     <uses-permission android:name="android.permission.READ_CONTACTS"/>
    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    SQL汉字转换为拼音的函数

    windows 7系统无法运行Photoshop CS3的解决方法

    巧用MySQL加密函数对Web网站敏感数据进行保护

    MySQL基础知识简介

    Windows7和WinXP下如何实现不输密码自动登录系统的设置方法介绍

    windows 7系统ip地址冲突怎么办?windows 7系统IP地址冲突问题的

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。