最近公司的app有一个需求,需要对应用程序是否授权进行判断,如果没有授权就引导用户去设置页面打开授权本以为很简单,结果app上线后出现很多问题。为了让各位程序猿哥们少走弯路把解决方案奉献给大家。废话不多说:
由于各个手机厂商对自己的room做了严格的封装,导致我们使用Android系统自带读取是否权限的api无法获取到,因此无法判断某个权限是否已经授权,比如现在市场上最火的OPPO手机,每次读取联系人权限是否被打开的时候总是返回true,因此我们无法去判断。这一章我们主要以检测app是否对读取联系人授权为例,其他权限判断也一样。
首先我们来分析下,读取权限的方案有四种:分别是通过packageManager,Activity,ActivityCompat,PermissionCheck这四个类去读取,比如判断联系人权限是否打开:
boolean permission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.READ_CONTACTS", "包名"));
其他的方法网上有很多,在此不多说。
前面说了,由于各种原因,这个permission是一个不准确的值,我们拿到它很多情况下无法用来判断权限是否打开,尝试了很久之后于是总结一套很有效的方案:就是直接去读取联系人,我们可以开启一个异步任务去读取联系人,这里我用的是AsyncTask:
protected ArrayList<Contact> doInBackground(Context... voids) { ContentResolver resolver = context.getContentResolver(); // 获取Sims卡联系人 Uri uri = Uri.parse("content://com.android.contacts/contacts"); //访问raw_contacts表 //获得_id属性 Cursor cursor = null; try { cursor = resolver.query(uri, new String[]{ContactsContract.Data._ID}, null, null, "sort_key asc"); } catch (Exception e) { e.printStackTrace(); } if (cursor == null) { return null; // error } ArrayList<Contact> result = new ArrayList<>(); while (cursor.moveToNext()) { Contact contact = new Contact(); StringBuilder buf = new StringBuilder(); //获得id并且在data中寻找数据 int id = cursor.getInt(0); // buf.append("id="+id); uri = Uri.parse("content://com.android.contacts/contacts/" + id + "/data"); //data1存储各个记录的总数据,mimetype存放记录的类型,如电话、ema