赞
踩
android的权限系统一直是首要的安全概念,因为这些权限只在安装的时候被询问一次。一旦安装了,app可以在用户毫不知晓的情况下访问权限内的所有东西。
这是极其危险的事情
所以,在Android M 权限请求设计改版了,有点类似iOS的权限请求
在android6.0棉花糖,app将不会在安装的时候授予权限。取而代之的是,app不得不在运行时一个一个询问用户授予权限。
注意权限询问对话框不会自己弹出来。开发者不得不自己调用。如果开发者要调用的一些函数需要某权限而用户又拒绝授权的话,函数将抛出异常甚至导致程序崩溃.
为了与旧版本兼容,比如你的 build.gradle 中的 targetSdkVersion 设置为 23 之前,比如22.
也能在Android6.0 的手机上面跑,并且权限请求机制使用6.0之前的 安装时请求 的模式.
吐槽一下: Excuse Me? 这到底是兼容还是漏洞... targetSdkVersion 设置为23以前,不让跑6.0不是更合理?
可能处于市场应用的API版本考虑,不兼容估计大部分应用都不能跑6.0
所以,如果你觉得运行时弹出权限框让用户勾选很不友好,那么就取巧使用targetSdkVersion <23 吧,但这绝对不是长久之计...(丑陋...)
1.初次请求,弹出对话框叫你勾选
2,第二次请求之后,弹出对话框,出现不再提醒字样
当用户点击了不再提醒,你再次请求权限的时候,就不会弹出对话框,所以这时,你需要根据需求另做处理
下面会如何处理
分为两类 Normal permissions 和 Dangerous permissions
只需要在xml中申请就可以了,与6.0之前没什么区别
包括的权限有
其实不需要记,记住哪些是危险权限就是了
危险权限,需要在运行时请求.
注意: 危险权限是按组来分的,所以,当你申请了多个同组的危险权限时,运行时只需要申请一个就行
例如:
你申请了关于电话的那么多权限,在动态申请的时候,它只会弹出
这一个权限框
所以,这是一个权限组的概念,运行时选择你申请的同组权限的一个就行
目前所有的危险权限组集合
对应的java code
1.在xml中注册
2. 运行时请求权限
以下是权限检查的帮助类
注意: 其中的requestPermissions 方法,它会弹出权限提示框( 没有点击不再提醒的话 ),然后调用public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 方法,该方法在Activity或者Fragment中回调
3.在onRequestPermissionsResult回调中处理
在 public void onRequestPermissionsResult() 方法中,你可以捕获到用于是点击了 不再提醒 还是 拒绝 ,然后做出不同的操作..
下面提供一种我认为还不错的策略
在需要某权限的Activity的 onStrart() 中去请求权限
在 onRequestPermissionsResult 回调中,如果用户点击了拒绝,则继续请求权限
如果用户点击了不再提醒,则弹出自定义对话框,引导用户手动去开启权限,如果用户不授权,则退出当前页面
注意:适用于没有权限就无法使用该功能的情况
Activity代码
在Fragment中申请权限,不要使用ActivityCompat.requestPermissions, 直接使用Fragment的requestPermissions方法,否则会回调到Activity的onRequestPermissionsResult
如果在Fragment中嵌套Fragment,在子Fragment中使用requestPermissions方法,onRequestPermissionsResult不会回调回来,建议使用getParentFragment().requestPermissions方法,
这个方法会回调到父Fragment中的onRequestPermissionsResult,加入以下代码可以把回调透传到子Fragment
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); List<Fragment> fragments = getChildFragmentManager().getFragments(); if (fragments != null) { for (Fragment fragment : fragments) { if (fragment != null) { fragment.onRequestPermissionsResult(requestCode,permissions,grantResults); } } } } |
PermissionsDispatcher
使用标注的方式,动态生成类处理运行时权限,目前还不支持嵌套Fragment。
RxPermissions
基于RxJava的运行时权限检测框架
Grant
简化运行时权限的处理,比较灵活
android-RuntimePermissions
Google官方的例子
以下权限只需要在AndroidManifest.xml中声明即可使用
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS android.permission.ACCESS_NETWORK_STATE android.permission.ACCESS_NOTIFICATION_POLICY android.permission.ACCESS_WIFI_STATE android.permission.ACCESS_WIMAX_STATE android.permission.BLUETOOTH android.permission.BLUETOOTH_ADMIN android.permission.BROADCAST_STICKY android.permission.CHANGE_NETWORK_STATE android.permission.CHANGE_WIFI_MULTICAST_STATE android.permission.CHANGE_WIFI_STATE android.permission.CHANGE_WIMAX_STATE android.permission.DISABLE_KEYGUARD android.permission.EXPAND_STATUS_BAR android.permission.FLASHLIGHT android.permission.GET_ACCOUNTS android.permission.GET_PACKAGE_SIZE android.permission.INTERNET android.permission.KILL_BACKGROUND_PROCESSES android.permission.MODIFY_AUDIO_SETTINGS android.permission.NFC android.permission.READ_SYNC_SETTINGS android.permission.READ_SYNC_STATS android.permission.RECEIVE_BOOT_COMPLETED android.permission.REORDER_TASKS android.permission.REQUEST_INSTALL_PACKAGES android.permission.SET_TIME_ZONE android.permission.SET_WALLPAPER android.permission.SET_WALLPAPER_HINTS android.permission.SUBSCRIBED_FEEDS_READ android.permission.TRANSMIT_IR android.permission.USE_FINGERPRINT android.permission.VIBRATE android.permission.WAKE_LOCK android.permission.WRITE_SYNC_SETTINGS com.android.alarm.permission.SET_ALARM com.android.launcher.permission.INSTALL_SHORTCUT com.android.launcher.permission.UNINSTALL_SHORTCUT |
转载自:http://www.cnblogs.com/onespieces/p/5435852.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。