Android6.0以后新增了权限管理,对于Android来说是很大的改进,毕竟谁也不愿意赤裸裸的将自己的个人信息暴露给所有的APP。当然对于我们开发者来说不一定是一件好事,如果我们项目的 targetSdkVersion设置为23或23以上,那么我们就要对这些权限做一些处理。
首先我们要知道6.0以后权限分为两类,一类是不涉及用户隐私的不需要处理,直接注册就可以了;一类是涉及用户隐私的,不仅要在清单文件中注册,还要在使用的时候向用户申请权限。
Normal Permissions 不需要申请的权限
- 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
Dangerous 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
手动授权需要的类:
ContextCompat.checkSelfPermission()
ActivityCompat.requestPermissions()
ActivityCompat.shouldShowRequestPermissionRationale()
当targetSdkVersion设置了23以上时,需要用到用户隐私权限时候Android Studio会报错,提示我们需要手动授权。
使用系统原生方法获取权限
- 检查权限
//检查是否有权限
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) !=
PackageManager.PERMISSION_GRANTED) {
//没有权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE},
101);
} else {
//有权限
callPhone();
}
PackageManager有连个常量判断我们的应用是否获得了该权限:
PackageManager.PERMISSION_DENIED:该权限是被拒绝的。
PackageManager.PERMISSION_GRANTED:该权限是被授权的。
- 注册权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE},
101);
- 权限回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 101:
if (grantResults.length >= 0 && grantResults[0] == PackageManager.PERMISSION_DENIED)
XLog.i("权限请求通过");
callPhone();
break;
}
}
如果用户拒绝权限申请且勾选了不在提示功能,那么系统的权限申请窗口就不会再显示,这样给用户的体验会很不好。那么我们需要自定义一个对话框,告诉用户为什么我们需要这个权限并引导用户开启该权限。我们需要用到另一个方法:
if (!ActivityCompat.shouldShowRequestPermissionRationale((Activity) context,
permission)) {
showMessageOKCancel(context, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Uri packageURI = Uri.parse("package:" + context.getPackageName());
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
packageURI);
context.startActivity(intent);
}
});
}
在调用checkSelfPermission方法后,使用shouldShowRequestPermissionRationale方法检查是否需要展示我们自己的对话框。
看了一些三方封装的库,使用起来都不是很简单,代码改动较大,并且需要引入第三方的内容。所以个人认为如果需要使用,可以根据大神们的逻辑自己简单的封装一下。