zoukankan      html  css  js  c++  java
  • 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  

  • 相关阅读:
    关于Maya Viewport 2.0 API 开发的介绍视频
    春节大假
    Some tips about the life cycle of Maya thread pool
    Can I compile and run Dx11Shader for Maya 2015 on my side?
    How to get current deformed vertex positions in MoBu?
    想加入全球首届的 欧特克云加速计划吗?
    三本毕业(非科班),四次阿里巴巴面试,终拿 offer(大厂面经)
    mac、window版编辑器 webstorm 2016... 永久破解方法。
    node 搭载本地代理,处理web本地开发跨域问题
    js 一维数组,转成嵌套数组
  • 原文地址:https://www.cnblogs.com/chorm590/p/10928246.html
Copyright © 2011-2022 走看看