• Android如何动态申请应用权限?


    2019-10-23

    关键字: APK申请权限、通过代码获取权限、定位权限、相机权限


    这篇文章大部分的内容都搬自简书某位大神的博客: https://www.jianshu.com/p/e36f686588d6 。搬运的目的有二:一是方便自己后续查阅,二是添加一些自己的使用经验。感谢这位简书大神的奉献。

    APK 开发中的权限主要有三种:

    1、普通权限;

    2、危险权限;

    3、特殊权限;

    这三种不同类型的权限都是单独针对APK用的。这些权限的背后代表着一款 APK 的功能完整性。越靠后的权限 Android 系统对其的把控就越严格。

    1、普通权限

    普通权限就是那些可以直接在 AndroidManifest.xml 中配置一下即可获得的权限。系统对它们的管理非常宽松。

    常见的有使用网络、更改网络状态等。

    2、危险权限

    危险权限除了要在 AndroidManife.xml 中声明以外,还得额外通过代码或用户主动在系统权限管理设置中开启。下图是华为手机中某个应用的部分常用危险权限控制界面:

    危险权限的各类如下表所示

    权限组 权限详情
    CALENDAR

    READ_CALENDAR

    WRITE_CALENDAR

    CAMERA CAMERA
    CONTACTS

    READ_CONTACTS

    WRIGE_CONTACTS

    GET_ACCOUNTS

    LOCATION

    ACCESS_FINE_LOCATION

    ACCESS_CONARSE_LOCATION

    MICROPHONE RECORD_AUDIO
    PHONE

    READ_PHONE_STATE

    CALL_PHONE

    READ_CALL_LOG

    WRITE_CALL_LOG

    ADD_VOICEMAIL

    USE_SIP

    PROCESS_OUTGOING_CALLS

    SENSORS BODY_SENSORS
    SMS

    SEND_SMS

    RECEIVE_SMS

    READ_SMS

    RECEIVE_WAP_PUSH

    RECEIVE_MMS

    STORAGE

    READ_EXTERNAL_STORAGE

    WRITE_EXTERNAL_STORAGE

    关于危险权限的限制,不同的 ROM 有不同的做法,有的严格有的宽松。但在 APK 开发中,为了应用的兼容性,还是很有必要去检查这些权限的状态,并在有必要的情况下弹出申请弹窗。

    1、权限状态检查

    
    
    import androidx.core.content.ContextCompat;
    int perm = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);

    以上代码用于检查当前 APK 是否拥有使用摄像头的权限。它的返回值是一个整型。这个整型有两个值:PackageManager.PERMISSION_GRANTED 与 PackageManager.PERMISSION_DENIED ,分别代表着有权限与无权限。通常我们会根据当前权限的状态来决定是否去申请相关权限。

    2、申请危险权限

    ActivityCompat.requestPermissions(this, new String[]{
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.CAMERA
        }, 0);

    当执行了这段代码以后,会有两种情况:一种是所申请的权限在当前应用中确实没有。另一种是所申请的权限在当前应用中已拥有。

    对于第一种情况,执行以后会发现系统将会弹出如下图所示的弹窗供用户选择:

    对于第二种情况,执行以后系统不会有任何变化,一切就像没有发生过什么一样。

    当权限申请结果出来以后,系统会通过回调 Activity 中的以下方法来回传结果:

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestCode == 0) {
            try {
                for(int i = 0; i < permissions.length; i++) {
                    Logger.d(TAG, permissions[i] + ":" + grantResults[i]);
                }
    
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    
    }

    这段代码就遍历了所有申请的权限的结果,当然结果值仅会有值为数字 0 的 PackageManager.PERMISSION_GRANTED 以及值为数字 -1 的 PackageManager.PERMISSION_DENIED。

    3、特殊权限

    特殊权限主要包括:

    1、通知栏;

    2、自动启动;

    3、悬浮窗;

    4、无障碍辅助。

    略。

    4、注意事项

    在申请危险权限时有一些注意事项必须要提一下。

    由于权限申请结果是回调到 Activity 的 onRequestPermissionsResult 方法中的,所以我们通常都会直接在 Activity 里来做申请操作。

    当你执行了权限申请代码以后,即执行了 ActivityCompat.requestPermissions(this, new String[]{}, 0); 以后,无论上面图片所示的权限弹窗是否弹出,当前 Activity 的状态都会进入到 onPause() 态。并且在权限申请结果出来以后,Activity 会回到 onResume() 态,即这一申请过程会导致 onPause() 与 onResume() 被执行一次。

    如果你有在这两个方法中做一些逻辑操作的话,一定要注意处理一下这种额外的调用。

    笔者就是因为将权限申请操作放在 onResume() 中做的,导致了这个权限申请一直在无限调用。


    参考:https://www.jianshu.com/p/e36f686588d6  

  • 相关阅读:
    《吊打面试官》系列-缓存雪崩、击穿、穿透
    WebGL学习之纹理贴图
    小试小程序云开发
    关于socket.io的使用
    动画函数的绘制及自定义动画函数
    canvas实现俄罗斯方块
    Redis集群
    手工搭建基于ABP的框架
    手工搭建基于ABP的框架(3)
    手工搭建基于ABP的框架(2)
  • 原文地址:https://www.cnblogs.com/chorm590/p/10928246.html
Copyright © 2020-2023  润新知