Android 6.0运行时权限
2017-09-28 15:21
246 查看
一、运行时权限的变化及特点
在6.0以下的系统,安装的时候有一个权限列表,一般情况下点了安装就都给应用授权了相应的权限。在6.0以上,我们安装APP也是直接安装了,不用管权限,一些比较隐私的权限,安装的时候是自己设置成询问的,比如定位啊,录音,摄像头之类的,在我们应用运行的途中,需要某一个隐私权限,就要弹窗询问,让用户授权,这就是运行时权限。新的权限机制更好的保护了用户的隐私,Google将权限分为两类,一类是Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等;另一类是Dangerous Permission,一般是涉及到用户隐私的,需要用户进行授权,比如读取sdcard、访问通讯录等。
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_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:
group:android.permission-group.CONTACTS permission:android.permission.WRITE_CONTACTS permission:android.permission.GET_ACCOUNTS permission:android.permission.READ_CONTACTS group:android.permission-group.PHONE permission:android.permission.READ_CALL_LOG permission:android.permission.READ_PHONE_STATE permission:android.permission.CALL_PHONE permission:android.permission.WRITE_CALL_LOG permission:android.permission.USE_SIP permission:android.permission.PROCESS_OUTGOING_CALLS permission:com.android.voicemail.permission.ADD_VOICEMAIL group:android.permission-group.CALENDAR permission:android.permission.READ_CALENDAR permission:android.permission.WRITE_CALENDAR group:android.permission-group.CAMERA permission:android.permission.CAMERA group:android.permission-group.SENSORS permission:android.permission.BODY_SENSORS group:android.permission-group.LOCATION permission:android.permission.ACCESS_FINE_LOCATION permission:android.permission.ACCESS_COARSE_LOCATION group:android.permission-group.STORAGE permission:android.permission.READ_EXTERNAL_STORAGE permission:android.permission.WRITE_EXTERNAL_STORAGE group:android.permission-group.MICROPHONE permission:android.permission.RECORD_AUDIO group:android.permission-group.SMS permission:android.permission.READ_SMS permission:android.permission.RECEIVE_WAP_PUSH permission:android.permission.RECEIVE_MMS permission:android.permission.RECEIVE_SMS permission:android.permission.SEND_SMS permission:android.permission.READ_CELL_BROADCASTS
可以通过adb shell pm list permissions -d -g进行查看。
看到上面的dangerous permissions,会发现一个问题,好像危险权限都是一组一组的,恩,没错,的确是这样的,
那么有个问题:分组对我们的权限机制有什么影响吗?
的确是有影响的,如果app运行在Android 6.x的机器上,对于授权机制是这样的。如果你申请某个危险的权限,假设你的app早已被用户授权了同一组的某个危险权限,那么系统会立即授权,而不需要用户去点击授权。比如你的app对READ_CONTACTS已经授权了,当你的app申请WRITE_CONTACTS时,系统会直接授权通过。此外,对于申请时弹出的dialog上面的文本说明也是对整个权限组的说明,而不是单个权限(ps:这个dialog是不能进行定制的)。
不过需要注意的是,不要对权限组过多的依赖,尽可能对每个危险权限都进行正常流程的申请,因为在后期的版本中这个权限组可能会产生变化。
二、相关API
注意:还是需要在AndroidManifest文件中添加应用需要的权限。1.检查权限
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { }else{ // }
这里涉及到一个API,ContextCompat.checkSelfPermission,主要用于检测某个权限是否已经被授予,方法返回值为PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。当返回DENIED就需要进行申请授权了。
2.申请权限
ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
该方法是异步的,第一个参数是Context;第二个参数是需要申请的权限的字符串数组;第三个参数为requestCode,主要用于回调的时候检测。可以从方法名requestPermissions以及第二个参数看出,是支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权。
3.处理权限申请回调
@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { // 如果询问授权被取消,这个results数组就为空.grantResults存放的是授权结果 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // GRANTED就是被授权了 } else { // 否则权限被拒绝 } return; } } }
ok,对于权限的申请结果,首先验证requestCode定位到你的申请,然后验证grantResults对应于申请的结果,这里的数组对应于申请时的第二个权限字符串数组。如果你同时申请两个权限,那么grantResults的length就为2,分别记录你两个权限的申请结果。如果申请成功,就可以做你的事情了~
4.当第一次被拒绝后,需要调用的API
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, Manifest.permission.READ_CONTACTS)) //如果第一次授权用户拒绝了,再次需要授权的时候就进到这里,进行解释,这里第一次不会进入 //这里一般用个dialog进行解释,为什么要用这个权限,然后可以帮助用户跳转到系统设置界面 //开启权限 }
这个API主要用于给用户一个申请权限的解释,该方法只有在用户在上一次已经拒绝过你的这个权限申请。也就是说,用户已经拒绝一次了,你又要弹个授权框,你需要给用户一个解释,为什么要授权,则使用该方法。
三、结合起来
// 检查权限 if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { //判断用户拒绝过没有,拒绝过,就进到这里面 if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, Manifest.permission.READ_CONTACTS)) { //如果第一次授权用户拒绝了,再次需要授权的时候就进到这里,进行解释,这里第一次不会进入 //这里一般用个dialog进行解释,为什么要用这个权限,然后可以帮助用户跳转到系统设置界面 //开启权限 } else { //没拒绝过,也就是说权限还在询问状态 //那么我们询问用户授权 ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS); } } ... ... ... /** * Activity父类的方法,询问是否授权的回调 */ @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { //授权了 } else { //拒绝了 } return; } super.onRequestPermissionsResult(requestCode, permissions, grantResults); }
参考:
http://blog.csdn.net/lmj623565791/article/details/50709663
相关文章推荐
- Android 6.0运行时权限解决办法
- Android 6.0 运行时权限处理完全解析
- Android 6.0 运行时权限处理完全解析
- Android 6.0运行时权限理解
- Android 6.0 运行时权限管理最佳实践
- Android 6.0 运行时权限封装框架
- Android 6.0+ 运行时权限
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理完全解析
- Android 6.0 运行时权限
- Android 6.0 运行时权限处理完全解析
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理完全解析
- Android 6.0后所必须的运行时权限申请的常用权限集合及使用方法
- Android 6.0版本以后运行时权限提醒
- Android 6.0 运行时请求权限
- Android 6.0 运行时权限处理
- Android 6.0运行时权限
- Android 6.0 运行时权限处理
- Android 6.0运行时权限