实现对手机联系人列表进行读写操作,并用RecyclerView收缩展开方式展现

实现对手机联系人列表进行读写操作,并用RecyclerView收缩展开方式展现

在之前做的类微信界面上加了显示手机联系人,姓名,电话,邮箱三项信息的功能,同时可以添加联系人同步到手机联系人记录中,添加完下拉刷新显示。

完整的项目代码

在Android中,如果想把A应用的数据库增加一个共享方式,就为A应用写一个ContentProvider方法,标识B应用要访问的数据。然后通过ContentResolver的增删改查方法实现对数据的共享操作。而读写手机联系人的ContentResolver方法直接调用即可。

获取数据存到自定义数据类型里的方法

 public void showlist(){
         dataBeanList = new ArrayList<>();
        Cursor cursor = getActivity().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
                null,null,null,null);
        while(cursor.moveToNext()){
            String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
            String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            dataBean = new DataBean();
            dataBean.setID(contactId);

            dataBean.setType(0);
            dataBean.setChildBean(dataBean);
            dataBean.setParentLeftTxt("Name:"+name);


            Cursor phones = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+contactId,null,null);
            while(phones.moveToNext()){
                String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                dataBean.setChildLeftTxt("MobilePhone:"+phoneNumber);
            }
            phones.close();

            Cursor emails = getActivity().getContentResolver().query(
                    ContactsContract.CommonDataKinds.Email.CONTENT_URI,
                    null, ContactsContract.CommonDataKinds.Email
                            .CONTACT_ID + " = " + contactId, null, null);
            while (emails.moveToNext())
            {
                // 获取查询结果中E-mail地址列中数据
                String emailAddress = emails.getString(emails
                        .getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
                dataBean.setChildRightTxt("Email:"+emailAddress);
            }
            emails.close();

            dataBeanList.add(dataBean);
        }
        cursor.close();
    }

相比较之前写的RecyclerView收缩展开静态数据的方式,这次展现的数据是动态的。所以新建了个数据类,用于对手机联系人姓名,号码,邮箱的获取/赋值。由于数据是展开,收缩的形式,便为一级列表和二级列表各写了相应的ViewHolder,两者继承相同的父类。

添加数据功能的思路,在点击添加按钮后出现一个弹框,用EditText接收输入的信息。

final View view1 = getLayoutInflater().inflate(R.layout.addcontact, null);
                new AlertDialog.Builder(MainActivity.this).setTitle("添加手机联系人信息").setView(view1).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int which) {
                        et_name = (EditText)view1.findViewById(R.id.et_name);
                        et_phone = (EditText)view1.findViewById(R.id.et_phone);
                        et_email=(EditText)view1.findViewById(R.id.et_email);
                         String name = et_name.getText().toString();
                        final  String phone = et_phone.getText().toString();
                        final  String email = et_email.getText().toString();
                        // 创建一个空的ContentValues
                        ContentValues values = new ContentValues();
                        // 向RawContacts.CONTENT_URI执行一个空值插入
                        // 目的是获取系统返回的rawContactId
                        Uri rawContactUri = getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values);
                        long rawContactId = ContentUris.parseId(rawContactUri);
                        values.clear();

                        values.put(Data.RAW_CONTACT_ID, rawContactId);
                        // 设置内容类型
                        values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
                        // 设置联系人名字
                        values.put(StructuredName.GIVEN_NAME, name);
                        // 向联系人URI添加联系人名字
                        getContentResolver().insert(ContactsContract
                                .Data.CONTENT_URI, values);
                        values.clear();

                        values.put(Data.RAW_CONTACT_ID, rawContactId);
                        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
                        // 设置联系人的电话号码
                        values.put(Phone.NUMBER, phone);
                        // 设置电话类型
                        values.put(Phone.TYPE, Phone.TYPE_MOBILE);
                        // 向联系人电话号码URI添加电话号码
                        getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
                        values.clear();

                        values.put(Data.RAW_CONTACT_ID, rawContactId);
                        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
                        // 设置联系人的E-mail地址
                        values.put(Email.DATA, email);
                        // 设置该电子邮件的类型
                        values.put(Email.TYPE, Email.TYPE_WORK);
                        // 向联系人E-mail URI添加E-mail数据
                        getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
                    }
                }).show();
                

最初没有写刷新功能,添加完后得重新进入应用才能显示,于是参照刷新布局控件
SwipeRefreshLayout的使用方法,加了个下拉刷新的功能。

布局文件

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/srl"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rcv_expandcollapse"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="8dp"
        android:overScrollMode="never"
        android:scrollbars="none"/>

    </android.support.v4.widget.SwipeRefreshLayout>

刷新部分的实现

 private SwipeRefreshLayout msrl;
 msrl = view.findViewById(R.id.srl);
 msrl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        showlist();
                       setData();
                       msrl.setRefreshing(false);
                    }
                },1200);

            }
        });

实现效果如下
在这里插入图片描述

这次遇到了大大小小很多错误,其中最令人深刻的是下面这个空指针异常的错误。
在这里插入图片描述
错误部分的代码如下

 case R.id.id_add_contact:
                final View view1 = getLayoutInflater().inflate(R.layout.addcontact, null);
                new AlertDialog.Builder(MainActivity.this).setTitle("添加手机联系人信息").setView(view1).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int which) {
                        et_name = (EditText)view1.findViewById(R.id.et_name);
                        et_phone = (EditText)view1.findViewById(R.id.et_phone);
                        et_email=(EditText)view1.findViewById(R.id.et_email);

最后找到了原因是我实例化EditText时,没有加view1,导致我在处理这个错误上花了很多时间。最后查找了关于findViewById的解释,才明白,findViewById默认上下文是在Activity的主布局中,在子布局,如弹窗Dialog中,要用view.findViewById方法才行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值