小米6.0动态权限特殊处理

来源:互联网 发布:知乎 弗莱彻 编辑:程序博客网 时间:2024/06/05 22:57

Android原生系统,对动态权限进行了划分,但在项目中,使用小米测试时遇到下列问题,明明在系统设置里打开了权限允许,为何还是获取不到想要的权限信息。

其实,小米对权限管理控制在谷歌之前就考虑好了,所以有自己的权限管理(安全中心),所以在授权是必须要安全中心、详情中的权限管理2个入口的权限都是开启状态才能正常使用该权限。
在第一授权时,如果用户允许权限,2处的权限开关都是开启的,可以正常使用;如果拒绝该权限,那2处的权限开关都是关闭的,即使开启详情、权限管理中的权限,也还不能使用,必须手动开启安全中心中对应的权限。

所以在使用过程中需要增加一个逻辑,通过正常的方式检测获取到权限后,需要判断小米手机在安全中心权限是否已授权.

也就是说在系统设置里与安全中心同时打开允许状态,才可以获取到权限信息。

下面是代码,仅供参考。

首先是判断是否是小米系统:

import java.io  .IOException; /* * 小米系统检测工具类 */public class MIUIUtils {private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name  ";private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage"; public static boolean isMIUI() {try {final BuildProperties prop = BuildProperties.newInstance();return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null;} catch (final IOException e) {return false;}}}

上面的一个类用到一个BuildProperties工具类:

import java.io  .File;import java.io  .FileInputStream;import java.io  .IOException;import java.util.Collection;import java.util.Enumeration;import java.util.Properties;import java.util.Set;import java.util.Map.Entry; import android.os.Environment; public class BuildProperties {private final Properties properties; private BuildProperties() throws IOException {properties = new Properties();properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));} public boolean containsKey(final Object key) {return properties.containsKey(key);} public boolean containsValue(final Object value) {return properties.containsValue(value);} public Set<Entry<Object, Object>> entrySet() {return properties.entrySet();} public String getProperty(final String name) {return properties.getProperty(name);} public String getProperty(final String name, final String defaultValue) {return properties.getProperty(name, defaultValue);} public boolean isEmpty() {return properties.isEmpty();} public Enumeration<Object> keys() {return properties.keys();} public Set<Object> keySet() {return properties.keySet();} public int size() {return properties.size();} public Collection<Object> values() {return properties.values();} public static BuildProperties newInstance() throws IOException {return new BuildProperties();}}
接下来是判断权限允许与禁止的关键代码,需要对系统进行适配:
//对于小米系统,测试时需要安全中心与系统设置权限都打开才能获取到记录,有一个拒绝则获取不到@TargetApi(Build.VERSION_CODES.KITKAT)public boolean checkPermissionGranted(boolean isMIUI, String permission) { if (getSdkVersion() >= 23) {if (isMIUI) {AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);int checkOp = appOpsManager.checkOp(permission,Binder.getCallingUid(), context.getPackageName());if (checkOp == AppOpsManager.MODE_IGNORED) {return false;}} else {if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {return false;}}}return true;}

对于上面的函数,permission的值,如果是普通的系统可以写如下:Manifest.permission.READ_CALL_LOG ,如果是小米系统则可以写成:AppOpsManager.OPSTR_READ_CALL_LOG;

需要注意一点,编译时,需要在Android23及以上版本进行编译,也就是6.0.否则代码不会通过。

代码仅供参考,如需转载请注明出处:http://www.data100.top/2017/08/15/小米系统6-0动态权限特殊处理

上面代码仅判断了权限的允许与禁止,如需对后续进一步处理,请参考文章:

http://blog.csdn.net/u013233097/article/details/70174230

代码请参考:点击打开链接 

原创粉丝点击