Android 运行时权限

在Android6.0(API-23)以上且 targetSdkVersion 是23时申请危险权限需要动态申请。

如果设备运行的是 Android 5.1(API 级别 22)或更低版本,并且应用的 targetSdkVersion 是 22 或更低版本则不需要申请权限。在目前强制要求项目中,最 省事 解决方案是targetSdkVersion=22

危险权限包括

权限组 权限
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_LOGWRITE_CALL_LOG ADD_VOICEMAIL USE_SIPPROCESS_OUTGOING_CALLS
SENSORS BODY_SENSORS
SMS SEND_SMS RECEIVE_SMS READ_SMSRECEIVE_WAP_PUSH RECEIVE_MMS
STORAGE READ_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE

普通权限

  • 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
  • MODIFY_AUDIO_SETTINGS
  • NFC
  • READ_SYNC_SETTINGS
  • READ_SYNC_STATS
  • RECEIVE_BOOT_COMPLETED
  • REORDER_TASKS
  • REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
  • REQUEST_INSTALL_PACKAGES
  • SET_ALARM
  • SET_TIME_ZONE
  • SET_WALLPAPER
  • SET_WALLPAPER_HINTS
  • TRANSMIT_IR
  • UNINSTALL_SHORTCUT
  • USE_FINGERPRINT
  • VIBRATE
  • WAKE_LOCK
  • WRITE_SYNC_SETTINGS
  • 注意:以上权限在部分国产ROM中仍有可能被禁用。

运行时权限的几个基本方法

API 作用
checkSelfPermission() 判断权限是否具有某项权限
requestPermissions() 申请权限
onRequestPermissionsResult() 申请权限回调方法
shouldShowRequestPermissionRationale() 是否要提示用户申请该权限的缘由,该方法只有当用户第一次拒绝之后再请求时会返回true 如果用户勾选不再询问之后会返回false

运行时权限实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) !=
PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest
.permission.READ_PHONE_STATE)) {
// 用户首次拒绝权限第二次请求的时候会执行这段代码,可以在这段代码里弹出对话框解释申请权限的原因并且引导用户再次申请权限
Toast.makeText(this, “show reason”, Toast.LENGTH_SHORT).show();
} else {
// 第一次直接申请权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission
.READ_PHONE_STATE}, REQ_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQ_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 权限获取成功
Toast.makeText(this, “权限获取成功”, Toast.LENGTH_SHORT).show();
} else {
// 权限获取失败
Toast.makeText(this, “权限获取失败”, Toast.LENGTH_SHORT).show();
}
}
}

图例