详解Android6.0运行时权限管理
发布时间 - 2026-01-10 21:56:29 点击率:次自从Android6.0发布以来,在权限上做出了很大的变动,不再是之前的只要在manifest设置就可以任意获取权限,而是更加的注重用户的隐私和体验,不会再强迫用户因拒绝不该拥有的权限而导致的无法安装的事情,也不会再不征求用户授权的情况下,就可以任意的访问用户隐私,而且即使在授权之后也可以及时的更改权限。这就是6.0版本做出的更拥护和注重用户的一大体现。

一、认知
今天我们就来学习下Android6.0的权限管理。
Android6.0系统把权限分为两个级别:
一个是Normal Permissions,即普通权限,这类权限不会潜藏有侵害用户隐私和安全的问题,比如,访问网络的权限,访问WIFI的权限等;
另一类是Dangerous Permissions,即危险权限,这类权限会直接的威胁到用户的安全和隐私问题,比如说访问短信,相册等权限。
但是到底哪些是普通权限和危险权限呢,这里给出分类,大家在使用时以便参考。
1、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
使用以上权限是不会威胁到用户安全的,所以这类权限是可以直接的在manifest里面直接的使用,而且在安装后也会直接的生效了。
2、Dangerous Permissions (危险权限)
SMS(短信)
- SEND_SMS
- RECEIVE_SMS
- READ_SMS
- RECEIVE_WAP_PUSH
- RECEIVE_MMS
STORAGE(存储卡)
- READ_EXTERNAL_STORAGE
- WRITE_EXTERNAL_STORAGE
CONTACTS(联系人)
- READ_CONTACTS
- WRITE_CONTACTS
- GET_ACCOUNTS
PHONE(手机)
- READ_PHONE_STATE
- CALL_PHONE
- READ_CALL_LOG
- WRITE_CALL_LOG
- ADD_VOICEMAIL
- USE_SIP
- PROCESS_OUTGOING_CALLS
CALENDAR(日历)
- READ_CALENDAR
- WRITE_CALENDAR
CAMERA(相机)
- CAMERA
LOCATION(位置)
- ACCESS_FINE_LOCATION
- ACCESS_COARSE_LOCATION
SENSORS(传感器)
- BODY_SENSORS
MICROPHONE(麦克风)
- RECORD_AUDIO
危险权限和普通权限也有区别,普通权限是单条的权限,而危险权限是以组展示的,也就是说,当你接受一个危险权限时,不但但接受的是界面上展示的这一个权限,而是它所在这个组里面的其他所有访问权限也将会被自动获取权限,比如,一旦WRITE_CONTACTS被授权了,App也有READ_CONTACTS和GET_ACCOUNTS的权限了。
值得注意的是,这类权限也是需要在manifest中注册的。
ok,光说不练不是咱的风格,咱写东西都是基于自己遇到的问题,然后认真的学习后才记录下来的。一方面巩固自己的知识,另一方面也希望能帮助他人提供一点解决方案。
二、实战
实战部分分为几种情况,因为根据我们的目标SDK版本和Android真机版本的不同会有不同的情景,针对普通权限大家都熟悉,就不介绍了,下面一一介绍危险权限的使用情景:
在介绍使用情景之前,先看下我的开发和真机的Android版本。
我们这里以读取短信息为例讲解整个权限的使用:
1、没有访问权限的情况下:
首先我们先来设计下布局,如下:
看下代码,很简单,就直接读取短息:
然后,点击界面上的“读取收件箱中的短信”,相信大家都会知道发生什么情况,果然不出意外的程序直接崩溃了,打下日志:
日志中很清晰的告诉我们,这个异常是因为没有权限而造成的,那么我们就直接给它加上读取短信的权限来看看吧。
2、在manifest中添加了权限:
在manifest中加了对读取短信的权限,你应该很高兴的等待着总共有多少条短信出现在我们的界面上,但是,事实很让人崩溃:
再次出现了没有权限的异常,这是为什么呢?
这里我们先不解决这个问题,先来想象一种实际的情况,假如你现有的APP里面有很多使用到了危险权限,有时候你并完全清楚到底在哪里使用了,但是你的目标版本又是像我的版本一样指向了6.0,而有可能用户的手机是6.0以上的版本,那么这时候你的APP就有可能会出现这种,那么在你还没查清楚有哪些地方使用了危险权限是,该怎么解决呢?
那么你可以这么解决:
修改你build.gradle 中的 targetSdkVersion 目标版本号:
然后手机版本还是6.0以上,来看看结果:
可以了,哈哈,你很高兴,确实是可以了。
那么聪明的你或许意识到什么了,是的,以版本23,也就是android6.0位分割线,我们可以得出一个小结论:
当targetSdkVersion >= 23,且真机版本 >= 23时,即使在manifest中添加了相应的危险权限,在没有做相应的处理时(至于怎么处理后面会讲),还时会出现限权的异常,这时manifest中的危险权限并没有起作用,但是还必须声明。
当targetSdkVersion < 23,且真机版本 >= 23时,我们并没有做任何的相关处理,就得到了想要的访问权限,这说明在manifest中申请的危险权限起作用了。
我们在来看另外一种情况,就是,假如我的手机比较旧,还没更新6.0的系统,这种情况下又该是什么情况呢?
这次我们用个4.4.4版本的模拟机
目标targetSdkVersion 为21 来看看结果:
也是可以的,0条信息是因为我的模拟机上没短信,这个数字多少和我们没有关系。假如targetSdkVersion 为23呢,来看看结果:
很清晰的看出,我们又得到了正确的结果。
由此我们也得到了一个小结论:
当我们的真机系统版本 < 23时,不管我们的targetSdkVersion 值是否大于23,都不会影响我们在manifest里面申请的权限,也就是说这时候真机的系统版本在起着主导作用。
由上面的几条结论,我们应该很清晰的知道了访问权限在真机中的使用状况,但是我们的手机在升级,版本也会越来越高,因此我们现在的应用不可能一直只支持低版本的使用也不考虑兼顾高版本。所以现在APP权限升级是必然的趋势。
那么现在回来解决上面遗留的问题,当真机和目标版本都大于6.0时出现的权限异常我们该怎么解决呢?
主要分为三个步骤:
1:检查是否拥有权限
2:假如没有权限,则申请权限
3:处理权限回调
下面我们分别来看看这几个步骤。
1:检查是否拥有权限
检查是否已拥有了权限,可以使用ContextCompat.checkSelfPermission(Context context, String permission);
checkSelfPermission方法中有两个参数,分别是上下文,以及所申请的权限。
如果有权限,请让它直接去读取短信信息。如果没有权限则去申请。
2:申请权限
申请权限则是使用:
public static void requestPermissions(final Activity activity,final String[] permissions, final int requestCode) {}
requestPermissions方法中需要三个参数,当前的activity,所申请的权限,可以是多个,最后就是请求码,既然有请求码说明它会有一个回调,也就是我们下面要讲的处理回调。
3:处理权限回调
处理权限回调,需要在Activity中重写onRequestPermissionsResult方法:
然后在方法内判断用户是授权了该权限组还是拒绝授权,如果授权则就去获取短信信息,否则,在这里我只是显示了一个toast提示框。
这里再次说明下,权限组内只要有一个被授权,其他的权限也就有了权限,这也是为什么直接使用grantResults[0] == PackageManager.PERMISSION_GRANTED的原因。
ok,下面来具体的界面显示:
我们可以看到,当我们第一次点击读取短信时,它会先检查该应用是否有权限,如果没有,就去申请,这里在界面上对应的就是显示一个授权的对话框,第一次我们选择了拒绝授权,然后在回调里面就会对应先打印了我们的一个toast消失提醒我们拒绝了授权,但是当我们再次需要读取短信时,它还会去申请授权,这时我们允许授权,然后我们就看到了,在显示短信条数的TextView显示了短信的条数。(这里0条是因为的用的模拟器没有短信,这不是重点。)
值得提醒的事,当我们第一次选择拒绝授权时,当再次点击读取短信时,这时在授权对话框中会多一个“不再提醒”的提示,当我们在拒绝了授权,并选择不再提醒时,那么会出现什么情况呢?请看演示:
当多次拒绝并选择不提提醒,那么下次再去读取就不会在去申请授权,而是直接在回调中说明用户已拒绝授权。
那么这时候假如用户出于某种需要必须得给应用授权该怎么做呢,其实很简单,在回调中,提醒用户去“设置”里面手动给应用授权,或是发个广播打开设置界面等等都可,这里和我显示的提醒“权限已被拒绝”基本一样,只需在稍微优化即可,这里不在演示。
其实到这里已经差不多讲完,但是,有一个方法我们可以留一下,那就是shouldShowRequestPermissionRationale,这个方法默认返回false,但当用户在上一次已经拒绝过这个权限申请时,再次需要申请该权限时,就会返回ture,它的寓意是你已经拒绝了一次,结果又弹出个授权框,你需要给我一个解释,为什么要授权,也就是说对多次授权这个权限做出解释,以便用户知道为什么必须授权了才能够完成他操作。
下面,来看看它的使用:
我这里就简单的弹出个对话框,说明下为什么要用这个权限,然后再次去调用这个申请的权限的方法了,大家可以同回调的方法一起封装下,可以更好的应用。
看下界面操作:
讲到这里基本差不地讲完了,这里只是讲了单个申请权限,多个一起也是可以的,大家可以自己试试,基本是一样的操作,另外在说明一点,可能我们一个应用里,需要多出的使用到危险权限,这样就造成我们需要多次重写一样的代码,很不便利,所以网上也就出现了很多关于权限框架的开源代码,大家可以自行的使用。
ok,到这里就结束了,希望大家能学到点知识,同时也多自己的实操下,祝大家生活愉快。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
# Android6.0
# 权限
# Android6.0动态申请权限所遇到的问题小结
# 谈谈Android6.0运行时的权限处理
# Android6.0仿微信权限设置
# 一款不错的android6.0、7.0权限管理器推荐
# android6.0权限动态申请框架permissiondispatcher的方法
# Android 操作系统获取Root权限 原理详细解析
# Android获取ROOT权限的实例代码
# Android权限操作之uses-permission详解
# Android权限控制之自定义权限
# Android需要提升权限的操作方法
# 安卓Android6.0权限动态获取操作示例
# 回调
# 来看看
# 当我们
# 这类
# 是因为
# 没有权限
# 自己的
# 的是
# 访问权限
# 就会
# 对话框
# 也有
# 还没
# 也会
# 也就
# 多个
# 就不
# 我们可以
# 情况下
# 这时候
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
JavaScript如何实现继承_有哪些常用方法
Android GridView 滑动条设置一直显示状态(推荐)
Python面向对象测试方法_mock解析【教程】
如何生成腾讯云建站专用兑换码?
如何使用 jQuery 正确渲染 Instagram 风格的标签列表
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
长沙企业网站制作哪家好,长沙水业集团官方网站?
Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程
jQuery 常见小例汇总
香港服务器租用每月最低只需15元?
Laravel中间件如何使用_Laravel自定义中间件实现权限控制
如何快速搭建高效简练网站?
小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像
Thinkphp 中 distinct 的用法解析
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】
Laravel如何集成Inertia.js与Vue/React?(安装配置)
米侠浏览器网页背景异常怎么办 米侠显示修复
如何用AWS免费套餐快速搭建高效网站?
Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程
javascript中对象的定义、使用以及对象和原型链操作小结
制作公司内部网站有哪些,内网如何建网站?
5种Android数据存储方式汇总
焦点电影公司作品,电影焦点结局是什么?
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
高性价比服务器租赁——企业级配置与24小时运维服务
Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑
如何快速搭建高效WAP手机网站?
JavaScript如何实现错误处理_try...catch如何捕获异常?
Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
Python结构化数据采集_字段抽取解析【教程】
如何用低价快速搭建高质量网站?
油猴 教程,油猴搜脚本为什么会网页无法显示?
如何确保西部建站助手FTP传输的安全性?
IOS倒计时设置UIButton标题title的抖动问题
如何用西部建站助手快速创建专业网站?
C++用Dijkstra(迪杰斯特拉)算法求最短路径
,在苏州找工作,上哪个网站比较好?
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
JS实现鼠标移上去显示图片或微信二维码
Laravel如何使用Blade模板引擎?(完整语法和示例)
Laravel怎么实现微信登录_Laravel Socialite第三方登录集成
如何在VPS电脑上快速搭建网站?
🚀拖拽式CMS建站能否实现高效与个性化并存?
html5如何实现懒加载图片_ intersectionobserver api用法【教程】
简历在线制作网站免费版,如何创建个人简历?
如何有效防御Web建站篡改攻击?

