Android6.0的通讯录获取


在Android Studio上实现基于Android6.0的通讯录获取功能


1、新建一个Android项目,API选择23: Android6.0(Marshmallow)

2、在MainActivity的layout中添加一个button用于获取通信录功能

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取联系人信息"
        android:id="@+id/btnGetContacts"
        android:layout_below="@+id/textView"
        android:layout_alignParentStart="true"/>

MainActivity的layout

3、为了后续开发的方便和规整,新建一个包Contacts用于存放获取通讯录所需的类。并在包中新建一个Activity:GetContacts。
由于Android6.0对APP运行权限做了较大改变,获取通讯录信息不仅需要静态授权还需要动态申请权限,详情见
Android6.0系统权限那些事
http://www.open-open.com/lib/view/open1450578678148.html

Android 6.0 运行时权限处理完全解析
http://www.w2bc.com/article/101798?from=extend

所以在这里需要给APP添加动态申请权限代码,暂时先将其实现,下一篇博客再考虑封装。新建一个String类型的方法getContacts(Context context),第一步检查是否授权,如果没有授权就申请权限

 if (ContextCompat.checkSelfPermission(context,android.Manifest.permission.READ_CONTACTS)
                                                !=PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions((Activity) context,
                    new String[]{android.Manifest.permission.READ_CONTACTS},
                    1);
        }

这里涉及到的API:

  1. ContextCompat.checkSelfPermission,主要用于检测某个权限是否已经被授予,方法返回值为PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。当返回DENIED就需要进行申请授权了。
  2. ActivityCompat.requestPermissions,该方法是异步的,第一个参数是Context;第二个参数是需要申请的权限的字符串数组;第三个参数为requestCode,主要用于回调的时候检测。可以从方法名requestPermissions以及第二个参数看出,是支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权。

注:这里暂时没有考虑权限申请回调onRequestPermissionsResult()方法,只是为了跑通该程序,在下一篇博客再具体分析关于权限的事儿。

4、授权成功后,开始执行获取通讯录功能:

在写具体代码前,先新建一个类:ContactsInfo用于通讯录的数据封装。定义需要获取到的通讯录信息字符串,并写好构造函数。

public class ContactsInfo {
    private String name;
    private String number;
    private String sortKey;
    private int id;


    public ContactsInfo(String name,String number,String sortKey,int id){
        setName(name);
        setNumber(number);
        setSortKey(sortKey);
        setId(id);

    }

定义一个ContactsInfo类型的List用于保存数据:public static List<ContactsInfo> list = new ArrayList<ContactsInfo>();

然后再开始写具体功能:

else {
            try {
                Uri contactUri =ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
                Cursor cursor = context.getContentResolver().query(contactUri,
                                                                  new String[]{"display_name", "sort_key", "contact_id","data1"},
                                                                  null, null, "sort_key");
                String contactName;
                String contactNumber;
                String contactSortKey;
                int contactId;
                while (cursor.moveToNext()) {
                    contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    contactNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    contactId = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
                    contactSortKey =getSortkey(cursor.getString(1));
                    ContactsInfo contactsInfo = new ContactsInfo(contactName,contactNumber,contactSortKey,contactId);
                    if (contactName!=null)
                         list.add(contactsInfo);
                }
                cursor.close();//使用完后一定要将cursor关闭,不然会造成内存泄露等问题

            }catch (Exception e){
                e.printStackTrace();
            }finally {
                context = null;
            }

这里使用了sort_key对获取到的通讯录信息进行了排序,实现一个方法:

private static String getSortkey(String sortKeyString){
        String key =sortKeyString.substring(0,1).toUpperCase();
        if (key.matches("[A-Z]")){
            return key;
        }else
            return "#";   //获取sort key的首个字符,如果是英文字母就直接返回,否则返回#。
    }

5、实现了基本功能后,我们需要将获取到的数据展示在界面上。
在GetContacts的layout中添加一张ListView

<ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/ContactsLv"
        android:layout_weight="1"/>

之后需要自定义一个adapter用于对ListView的数据传递。新建一个类:ContactsAdapter 扩展自BaseAdapter,新建一个contacts布局来展示该adapter的界面,并重构其四个方法:

public class ContactsAdapter extends BaseAdapter{
    private List<ContactsInfo> list;
    private Context context;

    public ContactsAdapter(List<ContactsInfo> list,Context context){
        this.list = list;
        this.context = context;
    }

    @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;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;
        if(convertView == null){
            convertView =LayoutInflater.from(context).inflate(R.layout.contacts,null);
            holder = new ViewHolder();
            holder.nametv = (TextView) convertView.findViewById(R.id.contactName);
            holder.numbertv = (TextView) convertView.findViewById(R.id.contactNumber);
            holder.nametv.setText(list.get(position).getName());
            holder.numbertv.setText(list.get(position).getNumber());
            convertView.setTag(holder);
        }else {
            holder = (ViewHolder) convertView.getTag();
            holder.nametv.setText(list.get(position).getName());
            holder.numbertv.setText(list.get(position).getNumber());
        }

        return convertView;
    }

    private static class ViewHolder{
        TextView nametv;
        TextView numbertv;
    }

}
/**
 * ViewHolder就是一个持有者的类,他里面一般没有方法,只有属性,作用就是一个临时的储存器,
 * getView方法中每次返回的View存起来,可以下次再用。
 * 这样做的好处就是不必每次都到布局文件中去拿到你的View,提高了效率。
 */

这里使用了ViewHolder来对listvier进行优化

6、在GetContacts活动中将ListView与ContactsAdapter进行绑定:

  private ListView ContactsLv;
  private ContactsAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_get_contacts);

        GetContacts.getContacts(this);
        ContactsLv = (ListView) findViewById(R.id.ContactsLv);
        adapter = new ContactsAdapter(list, this);
        ContactsLv.setAdapter(adapter);

    }

另外,需要对list清除缓存,不然每一次运行都会重复加载数据:

    @Override
    public void onBackPressed() {   //清除缓存
        list.clear();
        super.onBackPressed();
    }

7、OK,大功告成~~在MainActvity中增加对Button的监听即可。
权限申请
运行界面:

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值