一、Android6.0系统运行时权限

Android 6.0版本(Api 23)将权限分为普通权限和危险权限,危险权限需要在使用时让用户手动允许。

  • 对于普通权限,只需要在manifest.xml文件中声明,即可以代码中直接使用。
  • 对于危险,不仅仅需要在manifest.xml文件中声明,还需要在java代码调用requestPermissions来动态申请。注意如果不在manifest中声明,而是直接requestPermissions申请同样会抛出运行时异常。

危险权限一共9组24个权限,表格如下:

权限组名

权限名

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



二、Android8.0系统运行时权限行为变更

        Android 8.0 之前,如果应用在运行时请求权限并且被授予该权限,系统会错误地将属于同一权限组并且在清单中注册的其他权限也一起授予应用。
        对于针对 Android 8.0 的应用,此行为已被纠正。系统只会授予应用明确请求的权限。然而,一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准。

例如,假设某个应用在其清单中列出 READ_EXTERNAL_STORAGE 和WRITE_EXTERNAL_STORAGE。应用请求 READ_EXTERNAL_STORAGE,并且用户授予了该权限。如果该应用针对的是 API 级别 24 或更低级别,系统还会同时授予 WRITE_EXTERNAL_STORAGE,因为该权限也属于同一 STORAGE 权限组并且也在清单中注册过。如果该应用针对的是 Android 8.0,则系统此时仅会授予 READ_EXTERNAL_STORAGE;不过,如果该应用后来又请求 WRITE_EXTERNAL_STORAGE,则系统会立即授予该权限,而不会提示用户。

注意:

  • 在6.0-7.1的系统中,如果之前申请过READ_EXTERNAL_STORAGE并且通过申请,则后续的的java代码可以直接使用同一组内的其它权限,比如WRITE_EXTERNAL_STORAGE权限,而不需要再调用requestPermissions(WRITE_EXTERNAL_STORAGE);如果之前的申请没有通过,则后续使用同一组的其它权限时仍然需要申请
  • 在8.0及后续系统中,如果应用之前申请过READ_EXTERNAL_STORAGE并且通过申请,则后续的的java代码在使用同一组内的其它权限如WRITE_EXTERNAL_STORAGE之前,必须调用requestPermissions(WRITE_EXTERNAL_STORAGE),而此次调用系统将会立即回调onPermissionResult(),而不会弹出权限申请框。但如果不调用的话,将会崩溃。