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
代码请参考:点击打开链接