在上一篇中,我们已经获取了单个联系人发送短信,但是在大多数应用中,我们可以看到他们跳转的是自定义的联系人列表,然后进行多选,然后进行群发。比如,在微会应用里面短信邀请功能。

要做这项功能,我们首先就要获取本地手机通讯录里面的联系人信息,我们还是通过ContentResolver对象来获取。实现方法如下:
我们先定义一些ContentResolver获取信息要使用的局部变量:

/** 获取库Phone表字段 **/
    private static final String[] PHONES_PROJECTION = new String[] {
            Phone.DISPLAY_NAME, Phone.NUMBER, Photo.PHOTO_ID,
            Phone.CONTACT_ID };

    /** 联系人显示名称 **/
    private static final int PHONES_DISPLAY_NAME_INDEX = 0;

    /** 电话号码 **/
    private static final int PHONES_NUMBER_INDEX = 1;

    /** 头像ID **/
    private static final int PHONES_PHOTO_ID_INDEX = 2;

    /** 联系人的ID **/
    private static final int PHONES_CONTACT_ID_INDEX = 3;

然后获取信息:

/********* 获取手机通讯录信息 **********/
    private void getPhoneContacts() {

        ContentResolver resolver = this.getContentResolver();

        // 获取手机联系人
        Cursor phoneCursor = resolver.query(Phone.CONTENT_URI,
                PHONES_PROJECTION, null, null, null);

        if (phoneCursor != null) {
            while (phoneCursor.moveToNext()) {

                // 得到手机号码
                String phoneNumber = phoneCursor
                        .getString(PHONES_NUMBER_INDEX);
                // 当手机号码为空的或者为空字段 跳过当前循环
                if (TextUtils.isEmpty(phoneNumber))
                    continue;

                // 得到联系人名称
                String contactName = phoneCursor
                        .getString(PHONES_DISPLAY_NAME_INDEX);

                // 得到联系人ID
                Long contactid = phoneCursor
                        .getLong(PHONES_CONTACT_ID_INDEX);

                // 得到联系人头像ID
                Long photoid = phoneCursor.getLong(PHONES_PHOTO_ID_INDEX);

                // 得到联系人头像Bitamp
                Bitmap contactPhoto = null;

                // photoid 大于0 表示联系人有头像 如果没有给此人设置头像则给他一个默认的
                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.contact_photo);
                }

                SortModel sortModel = new SortModel();
                sortModel.setFriend_image(contactPhoto);
                sortModel.setFriend_username(contactName);
                sortModel.setFriend_id(phoneNumber);
                sortModel.setSelected(false);
                // 汉字转换成拼音
                String pinyin = characterParser.getSelling(contactName);
                String sortString = pinyin.substring(0, 1).toUpperCase();

                // 正则表达式,判断首字母是否是英文字母
                if (sortString.matches("[A-Z]")) {
                    sortModel.setSortLetters(sortString.toUpperCase());
                } else {
                    sortModel.setSortLetters("#");
                }
                // 添加数据
                listData.add(sortModel);// listData中每个sortModel分别包含的数据有以上几项
            }
            // 根据a-z进行排序源数据
            Collections.sort(listData, pinyinComparator);
            phoneCursor.close();
        }

    }

在上面的代码可以看到我们使用了a-z进行排序源数据的代码,这里参考了这位博主的文章 点击跳转直接拿来主义;效果图如下所示:

android共享联系人信息 app 安卓手机共享联系人_应用

排序基本功能就是将文字转换为字母,这样就可以从a-z进行排序了。这里就不进行详解了。
得到了ArrayList数据后,我们就可以通过RecyclerView或者ListView进行显示了,Adapter如下,直接看注释:

public class SortAdapter extends BaseAdapter implements SectionIndexer{
    private List<SortModel> list = null;
    private Context mContext;


    public SortAdapter(Context mContext, List<SortModel> list) {
        this.mContext = mContext;
        this.list = list;
    }

    /**
     * 当ListView数据发生变化时,调用此方法来更新ListView
     * @param list
     */
    public void updateListView(List<SortModel> list){
        this.list = list;
        notifyDataSetChanged();
    }

    public int getCount() {
        return this.list.size();
    }

    public Object getItem(int position) {
        return list.get(position);
    }

    public long getItemId(int position) {
        return position;
    }
    @Override
    public boolean areAllItemsEnabled() {
        return false;
    }
    public View getView(final int position, View view, ViewGroup arg2) {
        ViewHolder viewHolder = null;
        final SortModel mContent = list.get(position);
        if (view == null) {
            viewHolder = new ViewHolder();
            view = LayoutInflater.from(mContext).inflate(R.layout.item, null);
            viewHolder.tvLetter = (TextView) view.findViewById(R.id.catalog);
            viewHolder.image = (ImageView) view.findViewById(R.id.friend_image);
            viewHolder.username = (TextView) view.findViewById(R.id.friend_username);
            viewHolder.id = (TextView) view.findViewById(R.id.friend_id);
            viewHolder.check = (TextView) view.findViewById(R.id.selected);
            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }
        viewHolder.image.setImageBitmap(list.get(position).getFriend_image());
        viewHolder.username.setText(list.get(position).getFriend_username());
        viewHolder.id.setText(list.get(position).getFriend_id());
        viewHolder.check.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                list.get(position).setSelected(
                         !list.get(position).isSelected());
                v.setSelected(list.get(position).isSelected());
            }
        });
        viewHolder.check.setSelected(list.get(position).isSelected());
        //根据position获取分类的首字母的Char ascii值
        int section = getSectionForPosition(position);

        //如果当前位置等于该分类首字母的Char的位置 ,则认为是第一次出现
        Log.d("zgx","section====="+getPositionForSection(section));
        //如果当前位置等于该分类首字母的Char的位置 ,则认为是第一次出现
        if(position == getPositionForSection(section)){
            viewHolder.tvLetter.setVisibility(View.VISIBLE);
            viewHolder.tvLetter.setText(mContent.getSortLetters());
        }else{
            viewHolder.tvLetter.setVisibility(View.GONE);
        }
        return view;

    }



    final static class ViewHolder {
        TextView tvLetter;
        ImageView image;
        TextView username;
        TextView id;
         TextView check;
    }


    /**
     * 根据ListView的当前位置获取分类的首字母的Char ascii值
     */
    public int getSectionForPosition(int position) {
        return list.get(position).getSortLetters().charAt(0);
    }

    /**
     * 根据分类的首字母的Char ascii值获取其第一次出现该首字母的位置
     */
    public int getPositionForSection(int section) {
        for (int i = 0; i < getCount(); i++) {
            String sortStr = list.get(i).getSortLetters();
            char firstChar = sortStr.toUpperCase().charAt(0);
            if (firstChar == section) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 提取英文的首字母,非英文字母用#代替。
     * 
     * @param str
     * @return
     */
    private String getAlpha(String str) {
        String  sortStr = str.trim().substring(0, 1).toUpperCase();
        // 正则表达式,判断首字母是否是英文字母
        if (sortStr.matches("[A-Z]")) {
            return sortStr;
        } else {
            return "#";
        }
    }

    @Override
    public Object[] getSections() {
        return null;
    }

基本的布局文件详细见下面源码,
实现了选择联系人后,我们就要进行群发短信了,基本的监听事件如下:

// 发送按钮事件响应
    OnClickListener listener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            // 发送点击事件处理
            /************ 设置提示框 ************/
            String options = "选择的项是:";
            ArrayList<SortModel> listDatachecked = new ArrayList<SortModel>();// 被选中项包含的内容
            for (int j = 0; j < listData.size(); j++) {// 选中listItemAdapter.getCount()项
                if (listData.get(j).isSelected() == true) {// 如果j被选中
                    SortModel sortModel = (SortModel) listData.get(j);// 将选中的信息放到map中
                    String username = sortModel.getFriend_username();
                    String id = sortModel.getFriend_id();
                    listDatachecked.add(sortModel);
                    options += "\n" + id + "." + username;
                }
            }
            // 调用系统界面发送短信
            if (listDatachecked.size() > 0) {
                String number = getStringToList(listDatachecked);
                sendSmsWithBody(MainActivity.this, number, "这个是邀请内容!!!");
            }
        }
    };

发送短信功能代码如下:

/**
     * 调用系统界面,给指定的号码发送短信,并附带短信内容
     *
     * @param context
     * @param number
     * @param body
     */
    public void sendSmsWithBody(Context context, String number, String body) {
        Log.d("zgx", "number===========" + number);
        Intent sendIntent = new Intent(Intent.ACTION_SENDTO);
        sendIntent.setData(Uri.parse("smsto:" + number));
        sendIntent.putExtra("sms_body", body);
        context.startActivity(sendIntent);
    }

    private String getStringToList(List<SortModel> list) {
        StringBuilder sb = new StringBuilder();
        for (SortModel sortModel : list) {
            sb.append(sortModel.getFriend_id());
            sb.append(";");
        }
        if (sb.toString().endsWith(";")) {
            sb.deleteCharAt(sb.toString().length() - 1);
        }
        return sb.toString();
    }

以上只是部分代码,详细请看源码 点击下载源码