运行时权限介绍
Android 6.0在我们原有的AndroidManifest.xml声明权限的基础上,
又新增了运行时权限动态检测,以下权限都需要在运行时判断:
身体传感器 日历 摄像头 通讯录 地理位置 麦克风 电话 短信 存储空间
运行时权限处理
Android6.0系统默认为targetSdkVersion小于23的应用默认授予了所申请的所有权限,
所以如果你以前的APP设置的targetSdkVersion低于23,在运行时也不会崩溃,
但这也只是一个临时的救急策略,用户还是可以在设置中取消授予的权限。
-
声明目标SDK版本
我们需要在build.gradle中声明targetSdkVersion为23
1 android { 2 compileSdkVersion 23 3 buildToolsVersion "23.0.1" 4 5 defaultConfig { 6 applicationId "com.yourcomany.app 7 minSdkVersion 18 8 targetSdkVersion 23 9 versionCode 1 10 versionName "1.0" 11 } 12 buildTypes { release { 13 minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } 14 } 15 }
检查并申请权限
我们需要在用到权限的地方,每次都检查是否APP已经拥有权限,
比如我们有一个下载功能,需要写SD卡的权限,
我们在写入之前检查是否有WRITE_EXTERNAL_STORAGE权限,没有则申请权限
1 if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) 2 != PackageManager.PERMISSION_GRANTED) { 3 //申请WRITE_EXTERNAL_STORAGE权限 4 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 5 WRITE_EXTERNAL_STORAGE_REQUEST_CODE); 6 }
-
请求权限后,系统会弹出请求权限的Dialog
用户选择允许或需要后,会回调onRequestPermissionsResult方法, 该方法类似于onActivityResult
1 @Override 2 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 3 super.onRequestPermissionsResult(requestCode, permissions, grantResults); 4 doNext(requestCode,grantResults); 5 }
我们接着需要根据requestCode和grantResults(授权结果)做相应的后续处理
1 private void doNext(int requestCode, int[] grantResults) { 2 if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST_CODE) { 3 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 4 // Permission Granted 5 } else { 6 // Permission Denied 7 } 8 } 9 }
Fragment中运行时权限的特殊处理
-
在Fragment中申请权限,不要使用ActivityCompat.requestPermissions, 直接使用Fragment的requestPermissions方法,否则会回调到Activity的 onRequestPermissionsResult
-
如果在Fragment中嵌套Fragment,在子Fragment中使用requestPermissions方 法,onRequestPermissionsResult不会回调回来,建议使用 getParentFragment().requestPermissions方法,
这个方法会回调到父Fragment中的onRequestPermissionsResult,加入以下代码可以把回调透传到子Fragment
1 @Override 2 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 3 super.onRequestPermissionsResult(requestCode, permissions, grantResults); 4 List<Fragment> fragments = getChildFragmentManager().getFragments(); 5 if (fragments != null) { 6 for (Fragment fragment : fragments) { 7 if (fragment != null) { 8 fragment.onRequestPermissionsResult(requestCode,permissions,grantResults); 9 } 10 } 11 } 12 }
相关开源项目
PermissionsDispatcher
使用标注的方式,动态生成类处理运行时权限,目前还不支持嵌套Fragment。
RxPermissions
基于RxJava的运行时权限检测框架
Grant
简化运行时权限的处理,比较灵活
android-RuntimePermissions
Google官方的例子
附录
以下权限只需要在AndroidManifest.xml中声明即可使用
1 android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 2 android.permission.ACCESS_NETWORK_STATE 3 android.permission.ACCESS_NOTIFICATION_POLICY 4 android.permission.ACCESS_WIFI_STATE 5 android.permission.ACCESS_WIMAX_STATE 6 android.permission.BLUETOOTH 7 android.permission.BLUETOOTH_ADMIN 8 android.permission.BROADCAST_STICKY 9 android.permission.CHANGE_NETWORK_STATE 10 android.permission.CHANGE_WIFI_MULTICAST_STATE 11 android.permission.CHANGE_WIFI_STATE 12 android.permission.CHANGE_WIMAX_STATE 13 android.permission.DISABLE_KEYGUARD 14 android.permission.EXPAND_STATUS_BAR 15 android.permission.FLASHLIGHT 16 android.permission.GET_ACCOUNTS 17 android.permission.GET_PACKAGE_SIZE 18 android.permission.INTERNET 19 android.permission.KILL_BACKGROUND_PROCESSES 20 android.permission.MODIFY_AUDIO_SETTINGS 21 android.permission.NFC 22 android.permission.READ_SYNC_SETTINGS 23 android.permission.READ_SYNC_STATS 24 android.permission.RECEIVE_BOOT_COMPLETED 25 android.permission.REORDER_TASKS 26 android.permission.REQUEST_INSTALL_PACKAGES 27 android.permission.SET_TIME_ZONE 28 android.permission.SET_WALLPAPER 29 android.permission.SET_WALLPAPER_HINTS 30 android.permission.SUBSCRIBED_FEEDS_READ 31 android.permission.TRANSMIT_IR 32 android.permission.USE_FINGERPRINT 33 android.permission.VIBRATE 34 android.permission.WAKE_LOCK 35 android.permission.WRITE_SYNC_SETTINGS 36 com.android.alarm.permission.SET_ALARM 37 com.android.launcher.permission.INSTALL_SHORTCUT 38 com.android.launcher.permission.UNINSTALL_SHORTCUT
来自:http://www.jianshu.com/p/b4a8b3d4f587