Android动态权限(兼容6.0以下和魅族手机方案)

简介: 这里以照相机权限为例说明问题。实际开发过程中遇到了不少的坑。

Android动态权限(兼容6.0以下和魅族手机方案)

这里以照相机权限为例说明问题。实际开发过程中遇到了不少的坑。

1、一般情况下,6.0以上的手机:
①判断是否具有某项权限:
ContextCompat.checkSelfPermission()
下面这段代码展示了判断手机是否具有相机权限:

boolean hasCameraPermission = hasPermission(Manifest.permission.CAMERA);

@TargetApi(Build.VERSION_CODES.M)
public boolean hasPermission(String permission) {
    return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED;
}

2、在需要使用相机权限的页面中,我们需要判断应用是否具有相机权限,如果没有就进行申请。

以下代码可以检查应用是否具备调用照相机的权限,并根据需要请求该权限:

// Here, thisActivity is the current activity

if (ContextCompat.checkSelfPermission(thisActivity,Manifest.permission.CAMERA)
        != PackageManager.PERMISSION_GRANTED) {

    //①如果用户之前请求过此权限但用户拒绝了请求,并且用户没有勾选Don’t ask again选项,此方法会返回true;
    //②如果用户之前请求过此权限但用户拒绝了请求,并且用户勾选了Don’t ask again选项,此方法会返回false;
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.CAMERA)) {

        // 这里给用户一个提示对话框,让用户选择是否再次请求权限
    } else {
        
        // 逻辑走到这里说明用户已经拒绝了相机权限,并且都选了Don’t ask again选项,就算在这里直接请求相机权限,用户界面也不会弹出权限对话框,而是直接返回权限拒绝的结果。针对这种情况,我们可以考虑让用户进入设置页面,手动开启相机权限。
        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.CAMERA},
                MY_PERMISSIONS_REQUEST_CAMERA);
    }

}

上述代码用流程图表示,如下所示:
图1

3、请求权限的对话框:
当应用请求权限之后:
①如果用户之前没有做“拒绝并勾选’Don’t ask again’”的操作,那么系统会向用户展示一个对话框,如下所示:
Ps:第一次请求时是没有Don’t ask again选择框的。

图2

该对话框是个阻塞操作,不论用户点击了拒绝还是确认按钮,系统都会有对应的结果返回。
②如果用户之前做了“拒绝并勾选’Don’t ask again’”的操作,那么该对话框就不会展示,而是直接返回权限拒绝的结果。

4、请求权限的结果处理:
权限请求的回调方法是Activity#onRequestPermissionResult方法,如下所示。

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
        @NonNull int[] grantResults) {
    /* callback - no nothing */
}

这里我们需要重写该方法,获取权限请求的结果。
官方demo如下所示:

@Override

public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {

    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_CAMERA: {

            // 如果请求取消,grantResults会为空,所以这里需要做非空判断。
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        
                // 权限被授予了。恭喜!

            } else {

                // 权限被拒绝了。这里需要提示用户,并提供去设置页面开启的选项。

            }

            return;

        }

        //对其他权限进行处理,如果有的话。

    }

}

5、6.0以上手机(不包含魅族)完整版的解决方案:如下图所示:
图3

6、说完正常的之后,就说说不正常的,在实际开发中发现,6.0以下的某些手机(华为、OPPO等)和魅族手机(包括6.0以上)的表现有些与众不同,在需要使用相机权限之前,系统会额外弹出一个“禁止、允许”对话框,用户点击了允许按钮的话还好,如果点击了禁止按钮,那么上面对6.0手机的处理会对魅族高版本手机失效,很蛋疼。经过Google,发现了一篇帖子是可以适配这种情况的,具体链接在文章末尾的参考3中。
文章中介绍了一种可行的处理方法,使用抓取Camera.open()异常的方法来解决,比较暴力。

/**
 * 判断摄像头是否可用
 * 主要针对6.0 之前的版本,现在主要是依靠try...catch... 报错信息,感觉不太好,
 * 以后有更好的方法的话可适当替换
 *
 * https://blog.csdn.net/jm_beizi/article/details/51728495
 *
 * @return
 */
public static boolean isCameraCanUse() {
    boolean canUse = true;
    Camera mCamera = null;
    try {
        mCamera = Camera.open();
        // setParameters 是针对魅族MX5 做的。MX5 通过Camera.open() 拿到的Camera
        // 对象不为null
        Camera.Parameters mParameters = mCamera.getParameters();
        mCamera.setParameters(mParameters);
    } catch (Exception e) {
        canUse = false;
    }
    if (mCamera != null) {
        mCamera.release();
    }
    return canUse;
}

7、最终方案:
图4

参考:

1、https://developer.android.com/training/permissions/requesting?hl=zh-cn

2、https://github.com/android-cn/android-discuss/issues/174

3、https://blog.csdn.net/jm_beizi/article/details/51728495

相关文章
|
存储 Android开发
如何查看Flutter应用在Android设备上已被撤销的权限?
如何查看Flutter应用在Android设备上已被撤销的权限?
641 64
|
存储 Android开发 数据安全/隐私保护
如何在Android设备上撤销Flutter应用程序的所有权限?
如何在Android设备上撤销Flutter应用程序的所有权限?
831 64
|
9月前
|
Android开发 数据安全/隐私保护
安卓手机修改设备id, 安卓硬改一键新机,手机机型修改(伪装)
提供了完整的设备信息修改功能,包含设备模板配置、基础信息修改、网络信息修改、模拟器检测绕
|
9月前
|
存储 人工智能 文字识别
三款安卓手机word编辑器下载,Microsoft Word,wps office,Word手机版,手机word编辑查看阅读器,PDF转换器apk下载
WPS Office是一款功能强大的办公软件,支持文档编辑、表格处理和演示文稿制作,兼容多种格式并提供丰富的云服务。它具备低内存占用、快速运行的特点,支持跨设备同步与多人协作,内置海量模板及AI辅助功能,如智能写作和PPT自动生成。此外,还可扫描文件、编辑PDF并转换为其他格式,极大提升办公效率,适合手机用户便捷操作。
1028 1
|
存储 监控 API
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
1772 11
|
Android开发 数据安全/隐私保护 虚拟化
安卓手机远程连接登录Windows服务器教程
安卓手机远程连接登录Windows服务器教程
3704 5
|
安全 搜索推荐 Android开发
Android vs. iOS:解锁智能手机操作系统的奥秘####
【10月更文挑战第21天】 在当今这个数字化时代,智能手机已成为我们生活中不可或缺的伙伴。本文旨在深入浅出地探讨两大主流操作系统——Android与iOS的核心差异、优势及未来趋势,帮助读者更好地理解这两个平台背后的技术哲学和用户体验设计。通过对比分析,揭示它们如何塑造了我们的数字生活方式,并展望未来可能的发展路径。无论您是技术爱好者还是普通用户,这篇文章都将带您走进一个充满创新与可能性的移动世界。 ####
477 3
|
Web App开发 Android开发
利用firefox调试安卓手机端web
该教程详细介绍如何通过Firefox浏览器实现手机与电脑的远程调试。手机端需安装最新版Firefox,并按指定步骤设置完成;电脑端则需安装15版及以上Firefox。设置完成后,通过工具栏中的“远程调试”选项,输入手机IP地址即可连接。连接确认后,即可使用电脑端Firefox调试器调试手机上的Web信息。注意,调试前手机需提前打开目标网页。
1373 2
|
Android开发 iOS开发 UED
安卓与iOS的较量:谁才是智能手机市场的王者?
本文将深入探讨安卓和iOS两大智能手机操作系统之间的竞争关系,分析它们各自的优势和劣势。通过对比两者在市场份额、用户体验、应用生态等方面的表现,我们将揭示出谁才是真正的市场领导者。无论你是安卓粉丝还是iOS忠实用户,这篇文章都将为你提供一些有趣的观点和见解。
|
6月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1157 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡