Android 6.0 通讯录及RecyclerView 复用错乱Bug

本文介绍了一个用于从Android设备读取联系人信息的工具类,并提供了一个简单的权限检查工具类。此外,还讨论了解决RecyclerView复用问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述

近期一直没有写过博客,,宝宝心里苦,天天加班到深夜,夜深人静的时候我就想,为什么我要入IT 坑
,然而第二天,还是要继续,,啦啦啦

进入正题


先不说6.0的权限问题

先来一个获取联系人的工具类

**
 * Created by Oblivion on 2017/2/27.
 * 获取联系人工具
 * ps : 工具类来着互联网
 */

public class ContactUtils {
    public static List<ContactsInfoBean> list = new ArrayList<>();

    public static List<ContactsInfoBean> load(Context context) {

        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));
                ContactsInfoBean contactsInfo = new ContactsInfoBean(contactName, contactNumber, contactSortKey, contactId);
                if (contactName != null)
                    list.add(contactsInfo);
            }
            cursor.close();//使用完后一定要将cursor关闭,不然会造成内存泄露等问题
        } catch (Exception e) {
            e.printStackTrace();
            return list;
        } finally {
            return list;
        }
    }

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

如何调用该工具类:

ContactUtils.load(this);

温馨提示:

  • 注意如果联系人信息过于庞大,,这回是一个耗时的操作,,你可能需要将这个东西放入到子线程中;

  • 调用完成之后,如何获取获取的信息?ContactUtils.list 就是这个集合啦,,里边包含的联系人姓名信息,电话,如果有需要,,你可自己定制


再来说一下权限问题 :

来一个我自己写的工具类,不过写的有瑕疵,有需要的可以拿过去修改,或者直接使用已经写好的第三方类库easypermissions;

/**
 * Created by Oblivion 2017/3/13.
 * 权限Utils
 */

public class PermissionUtils {
    public static boolean getPermission(Activity activity, @NonNull String[] permissions, int i) {
        if (Build.VERSION.SDK_INT > 22) {
            if (ContextCompat.checkSelfPermission(activity,
                    permissions[0])
                    != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                        permissions[0])) {
                    BaseFunc.showToast(activity, "请授予权限");
//                    // 帮跳转到该应用的设置界面,让用户手动授权
//                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
//                    Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
//                    intent.setData(uri);
//                    activity.startActivity(intent);
                }
                ActivityCompat.requestPermissions(activity,
                        permissions, i);
            } else {
                return true;
            }

        } else {
            return true;
        }
        return false;
    }
}

调用方式

if (PermissionUtils.getPermission(this, new String[]{Manifest.permission.READ_CONTACTS}, 1)) {
           //申请成功....你要调用的方法
        }

在你的Activity中重写方法


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //申请成功....你要调用的方法
            } else {
                BaseFunc.setToast(this, "未授予权限,无法查看通讯录");
            }
        }
    }


再来就是如何取消掉点击选择联系人的复用问题了,,RecyclerView 的复用Bug.

  • 在你的Adapter中定义一个Map<Integer, Integer> map = new HashMap<>();

  • 在Adapter的onBindHolder方法中bindDate 的时候传入刚才创建的Map :invHolder.bindDate(list, position, map, activity);

使用方式如下:

mBean = list.get(position);
        mBean.isCheck = false;
        //解决复用问题CheckBox
        mRbInv.setChecked(false);
        mRbInv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mRbInv.isChecked()) {
                    mRbInv.setChecked(true);
                    map.put(position, position);
                    mBean.isCheck = true;
                } else {
                    mRbInv.setChecked(false);
                    map.remove(position);
                    mBean.isCheck = false;
                }
            }
        });
        if (map.containsKey(position)) {
            mRbInv.setChecked(true);
        } else {
            mRbInv.setChecked(false);
        }

XML 文件如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:id="@+id/llQux"
            android:layout_width="match_parent"
            android:layout_height="20dp"
            android:background="#55999999"
            android:gravity="center_vertical">

            <TextView
                android:id="@+id/tvQux"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8.5dp"
                android:text="A"
                android:textColor="#999999"
                android:textSize="11sp"/>
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tvName"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8.5dp"
                android:layout_weight="1"
                android:text="宋江"
                android:textColor="#000"
                android:textSize="11sp"/>

            <CheckBox
                android:id="@+id/rbInv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="30.5dp"/>
        </LinearLayout>

        <View
            android:layout_width="match_parent"
            android:layout_height="1px"
            android:background="#cecece"/>
    </LinearLayout>
</LinearLayout>

额。。。 并不是继承好的,毕竟这玩意是项目中的,,不方便拿出,不过,,有问题请指教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值