美文网首页
Android6.0运行时权限问题

Android6.0运行时权限问题

作者: chrnie | 来源:发表于2016-10-27 20:08 被阅读93次

    前言

    在 Android 6.0 之后的系统,除了要在 AndroidManifest.xml 文件中声明需要使用的权限,部分危险权限还需要在运行程序的过程中动态向用户申请。

    在 AndroidManifest.xml 中申请权限

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.app.myapp" >
        <uses-permission android:name="android.permission.RECEIVE_SMS" />
        ...
    </manifest>
    

    危险权限列表

    Permission Group Permissions
    CALENDAR READ_CALENDAR \ WRITE_CALENDAR
    CAMERA CAMERA
    CONTACTS READ_CONTACTS \ WRITE_CONTACTS \ GET_ACCOUNTS
    LOCATION ACCESS_FINE_LOCATION \ ACCESS_COARSE_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

    注意事项

    1. 危险权限有分组,在申请分组中的其中一个权限后,可以获得该分组中所有权限的使用权。
    2. 一次可以申请多个不同分组的权限,用户会进行多次授权,假若是同一分组的不同权限,因为如上原因,系统只对同一分组中的第一个权限进行一次用户授权询问。
    3. 假若用户已经同意该权限,再次申请会继续弹出对话框让用户选择,且假若用户拒绝会导致 Activity 摧毁再恢复,使得在 Fragment 中申请的权限没有系统回调。所以最好在申请前进行判断,以防万一。

    运行时权限获取

    使用 Activity

    Activity#requestPermissions() 方法要求 min API level >= 23 才能使用,因为这是 Android M 才推出的需求,所以可以使用 support-v4 包中的 ActivityCompat#requestPermissions() 方法替代以做到向下兼容。

    代码示例:

    public static final int REQEST_CODE = 0;
    public void example(){
        if(Build.VERSION.SDK_INT >= 23){
            int checkPermission = ContextCompat.checkSelfPermission(context, Manifest.permission.XXX);
            if(checkPermission != PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(context,new String[]{Manifest.permission.XXX},REQEST_CODE);
                return;
            }else{
                //do something
            }
        }else{
            // do something
        }
    }
    

    使用 Fragment

    如果使用的是 support-v4 包中的 Fragment,可以直接使用 requestPermissions() 申请权限,否则同上。在这里推荐使用 support 包中的 Fragment 而不使用 SDK 中的,因为 support 包中的 Fragment 会比 SDK 中的功能更多,而且可以自由更新不受系统版本影响。

    用户响应后的系统回调

    系统会回调 onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 方法。

    1. requestCode 为申请时传递的值
    2. permissions 为申请的权限
    3. grantResults 为对应权限的获取结果,permissions[i] 对应 grantResults[i]

    示例代码:

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){
        switch(requestCode){
            case REQEST_CODE:{
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    // Permission Granted
                }else{
                    // Permission Denied
                }
                break;
            }
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
    

    需要注意的是,onRequestPermissionsResult() 方法回在 Activity 恢复前调用,所以不可以在该方法中 commit FragmentTransaction,需要使用 commitAllowingStateLoss 替代。

    相关文章

      网友评论

          本文标题:Android6.0运行时权限问题

          本文链接:https://www.haomeiwen.com/subject/rlssuttx.html