博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 6.0 权限管理
阅读量:4453 次
发布时间:2019-06-07

本文共 9642 字,大约阅读时间需要 32 分钟。

Android 6.0 权限管理

运行时权限(Runtime permission)

android的权限系统一直是首要的安全概念,因为这些权限只在安装的时候被询问一次。一旦安装了,app可以在用户毫不知晓的情况下访问权限内的所有东西。

这是极其危险的事情
所以,在Android M 权限请求设计改版了,有点类似iOS的权限请求

权限请求对比
1461651981945.jpg

在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. android { 

  2. compileSdkVersion 23 

  3. buildToolsVersion "23.0.2" 

  4.  

  5. defaultConfig { 

  6. minSdkVersion 8 

  7. targetSdkVersion 22 

  8. versionCode 1 

  9. versionName "1.0" 


  10. buildTypes { 

  11. release { 

  12. minifyEnabled false 

  13. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 




enter description here
1461662965441.jpg

6.0权限弹框的两种模式

1.初次请求,弹出对话框叫你勾选

enter description here
1461654947945.jpg

2,第二次请求之后,弹出对话框,出现不再提醒字样

enter description here
1461655014689.jpg

当用户点击了不再提醒,你再次请求权限的时候,就不会弹出对话框,所以这时,你需要根据需求另做处理

下面会如何处理

6.0之后的权限分类

分为两类 Normal permissionsDangerous permissions

Normal permissions(普通权限)

只需要在xml中申请就可以了,与6.0之前没什么区别

包括的权限有

  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 

其实不需要记,记住哪些是危险权限就是了

Dangerous permissions(危险权限)

危险权限,需要在运行时请求.

注意: 危险权限是按组来分的,所以,当你申请了多个同组的危险权限时,运行时只需要申请一个就行
例如:

  1. <!-- 电话 --> 

  2. <uses-permission android:name="android.permission.READ_CALL_LOG" /> 

  3. <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 

  4. <uses-permission android:name="android.permission.CALL_PHONE" /> 

  5. <uses-permission android:name="android.permission.WRITE_CALL_LOG" /> 

  6. <uses-permission android:name="android.permission.USE_SIP" /> 

  7. <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> 

  8. <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" /> 

你申请了关于电话的那么多权限,在动态申请的时候,它只会弹出

enter description here
1461654947945.jpg

这一个权限框

所以,这是一个权限组的概念,运行时选择你申请的同组权限的一个就行

目前所有的危险权限组集合

  1. <!-- Dangerous Permissions. --> 

  2. <!-- 联系人 --> 

  3. <uses-permission android:name="android.permission.WRITE_CONTACTS" /> 

  4. <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 

  5. <uses-permission android:name="android.permission.READ_CONTACTS" /> 

  6.  

  7. <!-- 录音 --> 

  8. <uses-permission android:name="android.permission.RECORD_AUDIO" /> 

  9.  

  10. <!-- 电话 --> 

  11. <uses-permission android:name="android.permission.READ_CALL_LOG" /> 

  12. <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 

  13. <uses-permission android:name="android.permission.CALL_PHONE" /> 

  14. <uses-permission android:name="android.permission.WRITE_CALL_LOG" /> 

  15. <uses-permission android:name="android.permission.USE_SIP" /> 

  16. <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> 

  17. <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" /> 

  18.  

  19. <!-- 日历 --> 

  20. <uses-permission android:name="android.permission.READ_CALENDAR" /> 

  21. <uses-permission android:name="android.permission.WRITE_CALENDAR" /> 

  22.  

  23. <!-- 相机 --> 

  24. <uses-permission android:name="android.permission.CAMERA" /> 

  25.  

  26. <!-- 传感器 --> 

  27. <uses-permission android:name="android.permission.BODY_SENSORS" /> 

  28.  

  29. <!-- 定位 --> 

  30. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

  31. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 

  32.  

  33. <!-- 存储 --> 

  34. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

  35. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

  36.  

  37. <!-- 短信 --> 

  38. <uses-permission android:name="android.permission.READ_SMS" /> 

  39. <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" /> 

  40. <uses-permission android:name="android.permission.RECEIVE_MMS" /> 

  41. <uses-permission android:name="android.permission.RECEIVE_SMS" /> 

  42. <uses-permission android:name="android.permission.SEND_SMS" /> 

对应的java code

  1. // 联系人 

  2. Manifest.permission.WRITE_CONTACTS, 

  3. Manifest.permission.GET_ACCOUNTS, 

  4. Manifest.permission.READ_CONTACTS, 

  5.  

  6. // 电话 

  7. Manifest.permission.READ_CALL_LOG, 

  8. Manifest.permission.READ_PHONE_STATE, 

  9. Manifest.permission.CALL_PHONE, 

  10. Manifest.permission.WRITE_CALL_LOG, 

  11. Manifest.permission.USE_SIP, 

  12. Manifest.permission.PROCESS_OUTGOING_CALLS, 

  13. Manifest.permission.ADD_VOICEMAIL, 

  14.  

  15. // 日历 

  16. Manifest.permission.READ_CALENDAR, 

  17. Manifest.permission.WRITE_CALENDAR, 

  18.  

  19. // 相机 

  20. Manifest.permission.CAMERA, 

  21.  

  22. // 传感器 

  23. Manifest.permission.BODY_SENSORS, 

  24.  

  25. // 定位 

  26. Manifest.permission.ACCESS_FINE_LOCATION, 

  27. Manifest.permission.ACCESS_COARSE_LOCATION, 

  28.  

  29. // 存储 

  30. Manifest.permission.READ_EXTERNAL_STORAGE, 

  31. Manifest.permission.WRITE_EXTERNAL_STORAGE, 

  32.  

  33. // 录音 

  34. Manifest.permission.RECORD_AUDIO, 

  35.  

  36. // 短信 

  37. Manifest.permission.READ_SMS, 

  38. Manifest.permission.RECEIVE_WAP_PUSH, 

  39. Manifest.permission.RECEIVE_MMS, 

  40. Manifest.permission.RECEIVE_SMS, 

  41. Manifest.permission.SEND_SMS, 

运行时权限请求的基本步骤

1.在xml中注册

2. 运行时请求权限

以下是权限检查的帮助类

  1. /** 

  2. * 检查权限是否已请求到 (6.0) 

  3. */ 

  4. public void checkPermissions(String... permissions)

  5. // 版本兼容 

  6. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M 

  7. // 判断缺失哪些必要权限 

  8. && lacksPermissions(permissions)) { 

  9. // 如果缺失,则申请 

  10. requestPermissions(permissions); 



  11.  

  12. /** 

  13. * 判断是否缺失权限集合中的权限 

  14. */ 

  15. private boolean lacksPermissions(String... permissions)

  16. for (String permission : permissions) { 

  17. if (lacksPermission(permission)) { 

  18. return true



  19. return false


  20.  

  21. /** 

  22. * 判断是否缺少某个权限 

  23. */ 

  24. private boolean lacksPermission(String permission)

  25. return ContextCompat.checkSelfPermission(context, permission) == 

  26. PackageManager.PERMISSION_DENIED; 


  27.  

  28. /** 

  29. * 请求权限 

  30. */ 

  31. private void requestPermissions(String... permissions)

  32. ActivityCompat.requestPermissions(context, permissions, PERMISSION_REQUEST_CODE); 


  33.  

  34. /** 

  35. * 启动应用的设置,进入手动配置权限页面 

  36. */ 

  37. private void startAppSettings()

  38. Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 

  39. Uri uri = Uri.fromParts("package", context.getPackageName(), null); 

  40. intent.setData(uri); 

  41. context.startActivity(intent); 


注意: 其中的 requestPermissions 方法,它会弹出权限提示框( 没有点击不再提醒的话 ),然后调用 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 方法,该方法在Activity或者Fragment中回调

3.在onRequestPermissionsResult回调中处理

public void onRequestPermissionsResult() 方法中,你可以捕获到用于是点击了 不再提醒 还是 拒绝 ,然后做出不同的操作..

  1. @Override 

  2. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)

  3. // 版本兼容 

  4. if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M || 

  5. requestCode != PermissionsChecker.PERMISSION_REQUEST_CODE) 

  6. return

  7.  

  8. for (int i = 0, len = permissions.length; i < len; i++) { 

  9. String permission = permissions[i]; 

  10. // 缺失的权限 

  11. if (grantResults[i] == PackageManager.PERMISSION_DENIED) { 

  12. boolean showRationale = shouldShowRequestPermissionRationale(permission); 

  13. if (!showRationale) { 

  14. // 用户点击不再提醒 

  15. // TODO 

  16. break

  17. } else {  

  18. // 用户点击了取消... 

  19. // possibly check more permissions...  





权限请求策略

下面提供一种我认为还不错的策略

在需要某权限的Activity的 onStrart() 中去请求权限
onRequestPermissionsResult 回调中,如果用户点击了拒绝,则继续请求权限
如果用户点击了不再提醒,则弹出自定义对话框,引导用户手动去开启权限,如果用户不授权,则退出当前页面
注意:适用于没有权限就无法使用该功能的情况

enter description here
1461661615410.jpg

Activity代码

  1. public class BaseActivity extends AppCompatActivity

  2. private static final String TAG = "BaseActivity"

  3. private PermissionsChecker checker; 

  4.  

  5. @Override 

  6. protected void onCreate(@Nullable Bundle savedInstanceState)

  7. super.onCreate(savedInstanceState); 

  8. checker = new PermissionsChecker(this); 


  9.  

  10. public PermissionsChecker getChecker()

  11. return checker; 


  12.  

  13. /** 

  14. * 在该声明周期,检查权限申请情况 

  15. */ 

  16. @Override 

  17. protected void onStart()

  18. super.onStart(); 

  19. checker.checkPermissions(PermissionsChecker.PERMISSIONS); 


  20.  

  21. /** 

  22. * 请求权限检查完后回调的结果 

  23. * 

  24. * @param requestCode . 

  25. * @param permissions 所请求的权限 

  26. * @param grantResults . 

  27. */ 

  28. @TargetApi(Build.VERSION_CODES.M) 

  29. @Override 

  30. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)

  31. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || 

  32. requestCode != PermissionsChecker.PERMISSION_REQUEST_CODE) 

  33. return

  34.  

  35.  

  36. for (int i = 0, len = permissions.length; i < len; i++) { 

  37. String permission = permissions[i]; 

  38. if (grantResults[i] == PackageManager.PERMISSION_DENIED) { 

  39. boolean showRationale = shouldShowRequestPermissionRationale(permission); 

  40. if (!showRationale) { 

  41. // 用户点击不再提醒,弹出权限框,引导其手动开启权限 

  42. checker.showMissingPermissionDialog(); 

  43. break

  44. } else

  45. // 用户点击取消,继续提示 

  46. checker.checkPermissions(PermissionsChecker.PERMISSIONS); 

  47. break






  48.  

转载于:https://www.cnblogs.com/onespieces/p/5435852.html

你可能感兴趣的文章
二分图匹配
查看>>
NoSQL现状
查看>>
在ASP.NET页面中实现数据饼图
查看>>
在WPF中自定义控件(3) CustomControl (下)
查看>>
C# 验证识别基类
查看>>
用bat 删除当前文件夹下的某类文件
查看>>
先序遍历和后序遍历构建二叉树
查看>>
linux xorddos样本分析1
查看>>
【数论】-素数问题整理
查看>>
提高你的Java代码质量吧:正确使用String、StringBuffer、StringBuilder
查看>>
[happyctf]部分writeup
查看>>
HDU 1195 Open the Lock(BFS)
查看>>
Struts2的crud
查看>>
java上传文件
查看>>
大学生对技术网站需求的调查问卷结果分析
查看>>
Pascal程序练习-与7无关的数
查看>>
Linux:cut命令...未完待续
查看>>
react实现svg实线、虚线、方形进度条
查看>>
Web
查看>>
那些容易忽略的事(1) -变量与运算符+
查看>>