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