跳转应用设置页面方便用户修改已拒绝的权限,是经常遇到的需求,但是MIUI 8 系统上测试发现有坑,写一篇文章记录一下。

通常的跳转应用设置页面方法

Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);Uri uri = Uri.fromParts("package", activity.getPackageName(), null);intent.setData(uri);activity.startActivityForResult(intent, CODE_REQUEST);

就是通过系统封装的隐式意图直接打开设置页面的详情而已,intent 中提供了包名告诉系统需要调取哪个应用的信息。别忘了通过 startActivityForResult 方式打开,毕竟从设置页面返回之后你还要重走一遍权限检查和后续方法是吧。

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    super.onActivityResult(requestCode, resultCode, data);    if (requestCode == CODE_REQUEST) {        //TODO something;    }}

Settings 这个类中封装了很多有用的系统属性,看一下 Settings.ACTION_APPLICATION_DETAILS_SETTINGS 这一条的注释:

/**     * Activity Action: Show screen of details about a particular application.     * 

* In some cases, a matching Activity may not exist, so ensure you * safeguard against this. *

* Input: The Intent's data URI specifies the application package name * to be shown, with the "package" scheme. That is "package:com.my.app". *

* Output: Nothing. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_APPLICATION_DETAILS_SETTINGS = "android.settings.APPLICATION_DETAILS_SETTINGS";


MIUI 8 系统上遇到的问题

场景是这样的,我需要请求的是打开照相机权限,模拟检测到用户禁用该权限后提示去系统设置页面打开权限的情况。

在系统权限设置页授予权限后回调可以检测到权限已获取,但是小米 MIX 的测试机打开照相机后是黑屏,并提示我权限被禁用,需要在安全中心开启。

原来小米系统在安全中心另外做了一套权限管理页面,并且直接无视了 Android 本身的权限设置页面的操作结果。明目张胆的架空啊。但是用户是不管的,所以我们在 MIUI 系统上就只能提示用户去安全中心的权限管理页面进行修改了。

MIUI 上一些特殊适配的问题可以看这篇帖子: http://www.miui.com/thread-2442999-1-1.html

上代码:

public static void settingPermissionActivity(Activity activity) {    //判断是否为小米系统    if (TextUtils.equals(BrandUtils.getSystemInfo().getOs(), BrandUtils.SYS_MIUI)) {        Intent miuiIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");        miuiIntent.putExtra("extra_pkgname", activity.getPackageName());        //检测是否有能接受该Intent的Activity存在        List resolveInfos = activity.getPackageManager().queryIntentActivities(miuiIntent, PackageManager.MATCH_DEFAULT_ONLY);        if (resolveInfos.size() > 0) {            activity.startActivityForResult(miuiIntent, CODE_REQUEST_CAMERA_PERMISSIONS);            return;        }    }    //如果不是小米系统 则打开Android系统的应用设置页    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);    Uri uri = Uri.fromParts("package", activity.getPackageName(), null);    intent.setData(uri);    activity.startActivityForResult(intent, CODE_REQUEST_CAMERA_PERMISSIONS);}

判断系统的代码如下:

/** * Created by Yomii on 2017/4/12. */public class BrandUtils {    public static final String SYS_EMUI = "sys_emui";    public static final String SYS_MIUI = "sys_miui";    public static final String SYS_FLYME = "sys_flyme";    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";    private static final String KEY_EMUI_API_LEVEL = "ro.build.hw_emui_api_level";    private static final String KEY_EMUI_VERSION = "ro.build.version.emui";    private static final String KEY_EMUI_CONFIG_HW_SYS_VERSION = "ro.confg.hw_systemversion";    private static SystemInfo systemInfoInstance;    public static SystemInfo getSystemInfo() {        if (systemInfoInstance == null) {            synchronized (BrandUtils.class) {                if (systemInfoInstance == null) {                    systemInfoInstance = new SystemInfo();                    getSystem(systemInfoInstance);                }            }        }        return systemInfoInstance;    }    private static void getSystem(SystemInfo info) {        try {            Properties prop = new Properties();            prop.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));            if (prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null                    || prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null                    || prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null) {                info.os = SYS_MIUI;//小米                info.versionCode = Integer.valueOf(prop.getProperty(KEY_MIUI_VERSION_CODE, "0"));                info.versionName = prop.getProperty(KEY_MIUI_VERSION_NAME, "V0");            } else if (prop.getProperty(KEY_EMUI_API_LEVEL, null) != null                    || prop.getProperty(KEY_EMUI_VERSION, null) != null                    || prop.getProperty(KEY_EMUI_CONFIG_HW_SYS_VERSION, null) != null) {                info.os = SYS_EMUI;//华为                info.versionCode = Integer.valueOf(prop.getProperty(KEY_EMUI_API_LEVEL, "0"));                info.versionName = prop.getProperty(KEY_EMUI_VERSION, "unknown");            } else if (getMeizuFlymeOSFlag().toLowerCase().contains("flyme")) {                info.os = SYS_FLYME;//魅族                info.versionCode = 0;                info.versionName = "unknown";            }        } catch (IOException e) {            e.printStackTrace();        }    }    private static String getMeizuFlymeOSFlag() {        return getSystemProperty("ro.build.display.id", "");    }    private static String getSystemProperty(String key, String defaultValue) {        try {            Class<?> clz = Class.forName("android.os.SystemProperties");            Method get = clz.getMethod("get", String.class, String.class);            return (String) get.invoke(clz, key, defaultValue);        } catch (Exception e) {        }        return defaultValue;    }    public static class SystemInfo {        private String os = "android";        private String versionName = Build.VERSION.RELEASE;        private int versionCode = Build.VERSION.SDK_INT;        public String getOs() {            return os;        }        public String getVersionName() {            return versionName;        }        public int getVersionCode() {            return versionCode;        }        @Override        public String toString() {            return "SystemInfo{" +                    "os='" + os + '\'' +                    ", versionName='" + versionName + '\'' +                    ", versionCode=" + versionCode +                    '}';        }    }}

更多相关文章

  1. Android自定义action与permission
  2. android屏幕页面实现滚动,页面跳转
  3. Android中,单位dp、sp、px互相转换工具类
  4. android Notification 的使用!!!
  5. Xamarin.Forms读取并展示Android和iOS通讯录 - TerminalMACS客户
  6. Android(安卓)Tint使用
  7. Android——常用的系统服务
  8. Android(安卓)系统剪贴板的使用 - 复制、获取和清空
  9. java.net.SocketException: socket failed: EPERM (Operation no

随机推荐

  1. android图片透明度跟缩放大小动画事件
  2. [置顶] 基于ichartjs图形库在android上使
  3. Android Google Map实例 - 创建一个Googl
  4. android 可自定义大小和位置的Dialog
  5. Android菜鸟日记 23获取数据方式- sql,Sd
  6. 【摘录】Android画图之抗锯齿
  7. Android include 标签注意点
  8. Android 快速开发框架androidannotations
  9. Android(安卓)干货技术,欢迎收藏
  10. android dalvik heap 浅析