1.现状
在Android6.0之前,app申请权限是在安装时候申请,必须接受了对应应用的权限列表才能安装应用,同时接受了无法去系统设置里修改权限,即安装时权限;
然而到了6.0之后,权限系统发生了新的变化,是在app运行时才会动态的申请对应权限,同时也可以在系统设置里去修改,即运行时权限
2. 6.0之后新的权限等级及8.0新特性
在6.0之后,权限主要分为Normal permissions、Dangerous permissions、Signature permissions和Special permissions,我们经常接触的也就是Normal 和Dangerous 两个,这里也主要介绍这两个
2.1 Normal permissions
普通权限一般不涉及用户隐私。比如:访问网络,这类权限在app安装时就会被赋予,系统不提示用户赋予了这些权限,用户也无法撤销这些权限。普通权限列表如下:
ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
GET_PACKAGE_SIZE
INSTALL_SHORTCUT
INTERNET
KILL_BACKGROUND_PROCESSES
MANAGE_OWN_CALLS
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_COMPANION_RUN_IN_BACKGROUND
REQUEST_COMPANION_USE_DATA_IN_BACKGROUND
REQUEST_DELETE_PACKAGES
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
SET_ALARM
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
2.2 Dangerous permissions
Dangerous:危险权限涉及到用户隐私。比如:读取用户通讯录,这类权限在app运行时需要用户赋予,并且可以在设置里开启或者关闭此类权限。
在6.0新增权限组的概念,即相同类型的权限分类为一组,比如权限组CALENDAR包含READ_CALENDAR和WRITE_CALENDAR,如果用户赋予了app一个权限组的某一个权限,系统就会默认赋予app这一权限组的所有权限。在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,则系统会立即授予该权限,而不会提示用户。
危险权限列表取下:
Dangerous Permissions List
3.相关实现
3.1在AndroidManifest 进行权限声明
3.2检查是否有权限
通过ContextCompat.checkSelfPermission(@NonNull Context context, @NonNull String permission) 用来检测应用是否已经具有权限,当返回为PackageManager.PERMISSION_GRANTED时即表示已经赋予了权限,可以进行后续操作
3.3请求权限
通过ActivityCompat.requestPermissions(final @NonNull Activity activity,final @NonNull String[] permissions, final @IntRange(from= 0) int requestCode) 进行请求单个或多个权限
3.4请求结果回调
重写onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 来获得用户对请求作出响应后的回调,当grantResults[0] == PackageManager.PERMISSION_GRANTED 即表示用户同意授权
部分代码如下:
参考文档: