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

相关文章
|
6月前
|
网络协议 Android开发 数据安全/隐私保护
Android手机上使用Socks5全局代理-教程+软件
Android手机上使用Socks5全局代理-教程+软件
5006 2
|
1月前
|
Web App开发 定位技术 iOS开发
Playwright 是一个强大的工具,用于在各种浏览器上测试应用,并模拟真实设备如手机和平板。通过配置 `playwright.devices`,可以轻松模拟不同设备的用户代理、屏幕尺寸、视口等特性。此外,Playwright 还支持模拟地理位置、区域设置、时区、权限(如通知)和配色方案,使测试更加全面和真实。例如,可以在配置文件中设置全局的区域设置和时区,然后在特定测试中进行覆盖。同时,还可以动态更改地理位置和媒体类型,以适应不同的测试需求。
Playwright 是一个强大的工具,用于在各种浏览器上测试应用,并模拟真实设备如手机和平板。通过配置 `playwright.devices`,可以轻松模拟不同设备的用户代理、屏幕尺寸、视口等特性。此外,Playwright 还支持模拟地理位置、区域设置、时区、权限(如通知)和配色方案,使测试更加全面和真实。例如,可以在配置文件中设置全局的区域设置和时区,然后在特定测试中进行覆盖。同时,还可以动态更改地理位置和媒体类型,以适应不同的测试需求。
54 1
|
3月前
|
开发框架 Dart 前端开发
Android 跨平台方案对比之Flutter 和 React Native
本文对比了 Flutter 和 React Native 这两个跨平台移动应用开发框架。Flutter 使用 Dart 语言,提供接近原生的性能和丰富的组件库;React Native 则基于 JavaScript,具备庞大的社区支持和灵活性。两者各有优势,选择时需考虑团队技能和项目需求。
411 8
|
3月前
|
vr&ar 图形学 UED
电子沙盘VR模型大屏平板手机微信使用方案
数字孪生电子沙盘和VR模型被广泛应用在房地产等行业,为不同设备定制不同版本的模型是常见做法。然而,通过实时云渲染技术,可以将PC端的VR模型转化为网页版,使用户能够在平板或手机上流畅浏览详细信息,无需开发多个版本。这不仅提升了用户体验,还简化了模型提供商的工作流程,降低了成本。尤其在新楼盘发布时,可通过公众号或广告链接快速吸引潜在客户。成本主要取决于并发用户数及显卡性能要求,但该技术显著提高了跨设备访问的便利性。
53 1
|
3月前
|
Web App开发 网络协议 Android开发
Android平台一对一音视频通话方案大比拼:WebRTC VS RTMP VS RTSP,谁才是王者?
【9月更文挑战第4天】本文详细对比了在Android平台上实现一对一音视频通话时常用的WebRTC、RTMP及RTSP三种技术方案。从技术原理、性能表现与开发难度等方面进行了深入分析,并提供了示例代码。WebRTC适合追求低延迟和高质量的场景,但开发成本较高;RTMP和RTSP则在简化开发流程的同时仍能保持较好的传输效果,适用于不同需求的应用场景。
186 1
|
4月前
|
存储 安全 API
Android经典实战之存储方案对比:SharedPreferences vs MMKV vs DataStore
本文介绍了 Android 开发中常用的键值对存储方案,包括 SharedPreferences、MMKV 和 DataStore,并对比了它们在性能、并发处理、易用性和稳定性上的特点。通过实际代码示例,帮助开发者根据项目需求选择最适合的存储方案,提升应用性能和用户体验。
130 1
|
4月前
|
Android开发 C++ 开发者
Android经典实战之跨平台开发方案:Kotlin Multiplatform vs Flutter
本文对比了Kotlin Multiplatform与Flutter两大跨平台开发框架,从技术特性、性能、开发效率、UI体验、可扩展性及适用场景等维度进行了详尽分析,帮助开发者根据项目需求和技术背景选择最优方案。
169 2
|
4月前
|
Web App开发 网络协议 Android开发
### 惊天对决!Android平台一对一音视频通话方案大比拼:WebRTC VS RTMP VS RTSP,谁才是王者?
【8月更文挑战第14天】随着移动互联网的发展,实时音视频通信已成为移动应用的关键部分。本文对比分析了Android平台上WebRTC、RTMP与RTSP三种主流技术方案。WebRTC提供端到端加密与直接数据传输,适于高质量低延迟通信;RTMP适用于直播场景,但需服务器中转;RTSP支持实时流播放,但在复杂网络下稳定性不及WebRTC。三种方案各有优劣,WebRTC功能强大但集成复杂,RTMP和RTSP实现较简单但需额外编码支持。本文还提供了示例代码以帮助开发者更好地理解和应用这些技术。
157 0
|
6月前
|
缓存 NoSQL Java
案例 采用Springboot默认的缓存方案Simple在三层架构中完成一个手机验证码生成校验的程序
案例 采用Springboot默认的缓存方案Simple在三层架构中完成一个手机验证码生成校验的程序
116 5
|
7月前
|
运维 安全 Android开发
手机与电脑投屏互联方案
手机与电脑投屏互联方案
195 7