189 8069 5689

android权限系统,安卓系统软件权限设置

Android权限机制

我们知道 Android 应用程序是沙箱隔离的,每个应用都有一个只有自己具有读写权限的专用数据目录。但是如果应用要访问别人的组件或者一些设备上全局可访问的资源,这时候权限机制就能系统化地规范并强制各类应用程序的行为准则。

坚守“ 做人真诚 · 做事靠谱 · 口碑至上 · 高效敬业 ”的价值观,专业网站建设服务10余年为成都成都凿毛机小微创业公司专业提供成都企业网站定制营销网站建设商城网站建设手机网站建设小程序网站建设网站改版,从内容策划、视觉设计、底层架构、网页布局、功能开发迭代于一体的高端网站建设服务。

Android 安全性概览

在 Android 中,一个权限,本质上是一个字符串,一个可以表示执行特定操作的能力的字符串。比如说:访问 SD 卡的能力,访问通讯录的能力,启动或访问一个第三方应用中的组件的能力。 权限被授予了之后,首先会在内存和本地中有记录,这在调用系统binder服务和其他应用组件时做鉴权依据,比如调用系统binder服务时会通过Binder.getCallingUid()拿到调用者的Uid,而Uid一般都是与应用包名一一对应的,再拿这个Uid到PMS里去查这个应用对应的权限。 其次会按被授予的权限将应用分到某个组。 可以参考

自定义权限的应用场景在于限制其它应用对本应用四大组件的访问。具体用法可以参考

pm list permissions -f 命令可以详细查看 Android 所有预定义的权限。

更详细的权限信息参考

可以看到一个权限的信息包括:定义的包名、标签、描述、 权限组 和 保护级别 。

权限根据设备的功能或特性分为多个组。如果应用已在相同权限组中被授予另一危险权限,系统将立即授予该权限,如READ_CONTACTS和WRITE_CONTACTS。

SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS 由于其特殊性,其申请方式与其它权限都不同。

其授予流程如下:

(关于 AppOpsManager 是什么可以参考: )

这里简要分析下ActivityCompat#requestPermissions的流程:

更详细的权限授予流程源码分析可以参考:

普通权限: 清单文件中声明即可。

危险权限: 方式一: pm grant application_package android.permission.CHANGE_CONFIGURATION 方式二:appops set application_package permission_num 0/1

appops可以授予的权限参考 android.app.AppOpsManager 中的声明

系统签名权限: 方式一:将app迁移到system/priv-app目录中。 方式二:看不懂,参考

android 4.4 访问sd卡需要申请权限。 您的应用在 Android 4.4 上运行时无法读取外部存储空间上的共享文件,除非您的应用具有 READ_EXTERNAL_STORAGE 权限。也就是说,没有此权限,您无法再访问 getExternalStoragePublicDirectory() 返回的目录中的文件。但是,如果您仅需要访问 getExternalFilesDir() 提供的您的应用特有目录,那么,您不需要 READ_EXTERNAL_STORAGE `权限。

android 6.0 运行时权限。 此版本引入了一种新的权限模式,如今,用户可直接在运行时管理应用权限。这种模式让用户能够更好地了解和控制权限,同时为应用开发者精简了安装和自动更新过程。用户可为所安装的各个应用分别授予或撤销权限。 对于以 Android 6.0(API 级别 23)或更高版本为目标平台的应用,请务必在运行时检查和请求权限。要确定您的应用是否已被授予权限,请调用新增的 checkSelfPermission() 方法。要请求权限,请调用新增的 requestPermissions() 方法。即使您的应用并不以 Android 6.0(API 级别 23)为目标平台,您也应该在新权限模式下测试您的应用。 如需了解有关在您的应用中支持新权限模式的详情,请参阅 使用系统权限 。如需了解有关如何评估新模式对应用的影响的提示,请参阅 权限最佳做法 。

android 7.+ 应用间共享文件要使用FileProvider。 对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。 要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider `类。如需了解有关权限和共享文件的详细信息,请参阅 共享文件 。

android 8.+

同一权限组的权限在被授予了之后也需要显式的再申请一次。

在 Android 8.0 之前,如果应用在运行时请求权限并且被授予该权限,系统会错误地将属于同一权限组并且在清单中注册的其他权限也一起授予应用。 对于针对 Android 8.0 的应用,此行为已被纠正。系统只会授予应用明确请求的权限。然而,一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准。 例如,假设某个应用在其清单中列出 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 。应用请求 READ_EXTERNAL_STORAGE ,并且用户授予了该权限。如果该应用针对的是 API 级别 24 或更低级别,系统还会同时授予 WRITE_EXTERNAL_STORAGE ,因为该权限也属于同一 STORAGE 权限组并且也在清单中注册过。如果该应用针对的是 Android 8.0,则系统此时仅会授予 READ_EXTERNAL_STORAGE ;不过,如果该应用后来又请求 WRITE_EXTERNAL_STORAGE ,则系统会立即授予该权限,而不会提示用户。

android 9

隐私权限变更。

为了增强用户隐私,Android 9 引入了若干行为变更,如限制后台应用访问设备传感器、限制通过 Wi-Fi 扫描检索到的信息,以及与通话、手机状态和 Wi-Fi 扫描相关的新权限规则和权限组。

android 10

隐私权变更。

外部存储访问权限范围限定为应用文件和媒体,在后台运行时访问设备位置信息需要权限,针对从后台启动 Activity 的限制等。

android 11

隐私权限变更。

更详细的版本变更请参考

安卓系统手机如何设置软件权限

若是使用vivo手机,可以进入设置--应用与权限/更多设置--权限管理--权限中设置应用的权限。

聊聊Android6.0 以上系统权限

一个新建的Android应用默认是没有权限的,这意味着它不能执行任何可能对用户体验有不利影响的操作或者访问设备数据。为了使用受保护的功能,你必须包含一个或者多个标签在你的app manifest中。

1、Android 6.0中权限分为两种,普通权限和危险权限(即运行时权限,下面统称运行时权限)。

1.1普通权限

如果你的应用manifest中只申明了普通权限(也就是说,这些权限对于用户隐私和设备操作不会造成太多危险),系统会自动授予这些权限。

1.2运行时权限

如果你的应用manifest中声明了运行时权限(也就是说,这些权限可能会影响用户隐私和设备的普通操作),系统会明确的让用户决定是否授予这些权限。系统请求用户授予这些权限的方式是由当前应用运行的系统版本来决定的。

1.2.1 Android6.0及以上的系统

如果你的设备运行的是Android6.0(API level 23)及以上的系统,并且你的应用的targetSdkVersion也是23或者更高,那么应用向用户请求这些权限是实时的。这意味着用户可以随时取消 这些运行时权限的授权。所以应用在每次需要用到这些运行时权限的时候都需要去检查是否还有这些权限的授权。

1.2.2 Android 5.1及以下的系统

如果你的设备运行在Android5.1(API level 22)及以下的系统中,或者你的app的targetSdkVersion是22或者更低。系统会请求用户在apk安装的时候授予这些权限。

如果你的应用更新的时候添加了一个权限,系统会在用户更新应用的时候请求用户授予这个权限 , 一旦用户安装了这个应用,唯一可以取消授权的方式就是卸载掉这个应用。 注意这句话的意思,想一下如果app的targetSdkVersion是22或者以下,但是运行在Android6.0及以上的设备中会有什么问题?后面会分析这个问题 。

常常来说一个授权失败会抛出SecurityException,然而这并不是在 所有情况下都会发生。比如,发送一个广播去检查授权(SendBroadcast(Intent)),数据会被发送给所有接收者,但是当这个方法的请求返 回的时候,你不会收到任何一个因为授权失败抛出的异常,其实在大多数情况下,授权失败只会打印系统日志。

1.3自动权限调整

简单的说,如果你的app targetSdkVersion是3,而你当前运行的系统版本是4,那么在android version 4 中新添加的权限会自动添加到你的app中。

比如 WRITE_EXTERNAL_STORAGE权限是在api 4的时候添加的,而你的应用的targetSdkVersion是3,那么这个权限会自动添加到你的应用中。而且在官方商店上这个权限也会列出来(尽管可能你并不需要这个权限)。

所以建议经常更新你的targetSdkVersion到最新版本。

下面来回答上面的那个问题,如果app的targetSdkVersion是22或者以下,但是运行在android 6.0或以上版本的手机中,会发生什么?

安装过程中,会一起请求用户授予所有 权限,如果用户拒绝,将不能安装这个app,只有用户全部同意这些授权,才能安装这个应用,但是问题来了,安装好了这个应用之后,android6.0以 上的系统中,用户是可以去设置中取消授权的,而且是随时都可以取消,所以很多运行时权限可能也得不到,目前官方的做法是,如果用户取消该项授权,那么依赖 该项授权的方法的返回值为null,所以你的app可能会报空指针异常。以后是否会针对22以下的app做改变还不得而知,毕竟crash是很难让人接受 的,但是crash是由用户造成的,用户应该也可以理解。

2、普通权限和运行时权限

系统权限会被传递给两种不同的保护级别,我们所知道这两种最重要的保护级别就是普通权限和运行时权限。

2.1 普通权限

普通权限的覆盖区域是在你的app需要访问沙盒以外的数据和资源的时候,但是对用户隐私和其他app的操作只有很少的影响,比如开启手电筒的权限。这个时候,系统会自动授权这些普通权限。

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

2.2 运行时权限

运行时权限的覆盖区域是你的app想要的数据和资源涉及用户的隐私信息,或者是可能潜在的影响用户的存储数据或者其他app的操作。比如,请求获取用户联系人信息的权限。如果一个app申明了运行时权限,用户必须明确的授权这些权限给app。

2.3 权限组

所有的运行时权限都属于对应的权限组,如果你的app运行在android6.0及以上系统,下面的规则都适用:

2.3.1 如果一个app在manifest中请求了一个运行时权限,而且app还没有得到这个运行时权限所在的权限组中的任何一个运行时权限授权,那么系统会弹出一个对话框,描述app想要访问的运行时权限的权限组,这个对话框不会描述这个权限组中某一个特定的权限。比如,你的app想要请求READ_CONTACT权限,对话框只会描述app想要请求设备的联系人,如果用户授权通过,系统会授予app所请求的该项权限。

2.3.2 如果一个app在manifest中请求一个运行时权限,并且这个app已经在相同的权限组中有了另一个运行时权限的授权,那么系统不会弹出对话框,而是会立即授予app该项运行时权限的授权。比如,一个app之前请求过一个READ_CONTACT的权限并且被授权通过,之后又请求一个WRITE_CONTACT(在同一个权限组)权限,那么系统会自动授予该权限。

其实所有权限(普通权限、运行时权限、用户自定义权限)都属于特定的权限组,但是只有运行时权限的权限组才会影响用户体验。

2.3.3运行时权限组和权限组列表

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是不能进行定制的)。不过需要注意的是,不要对权限组过多的依赖,尽可能对每个危险权限都进行正常流程的申请,因为在后期的版本中这个权限组可能会产生变化。

3、相关API

3.1 在AndroidManifest文件中添加需要的权限。

这个步骤和我们之前的开发并没有什么变化,试图去申请一个没有声明的权限可能会导致程序崩溃。

3.2 检查权限

if (ContextCompat.checkSelfPermission(thisActivity,

Manifest.permission.READ_CONTACTS)

!= PackageManager.PERMISSION_GRANTED) {

}else{

//

}

这里涉及到一个API,ContextCompat.checkSelfPermission,主要用于检测某个权限是否已经被授予,方法返回值为PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。当返回DENIED就需要进行申请授权了

3.3 申请授权

ActivityCompat.requestPermissions(thisActivity,

new String[]{Manifest.permission.READ_CONTACTS},

MY_PERMISSIONS_REQUEST_READ_CONTACTS);

该方法是异步的,第一个参数是Context;第二个参数是需要申请的权限的字符串数组;第三个参数为requestCode,主要用于回调的时候检测。可以从方法名requestPermissions以及第二个参数看出,是支持一次性申请多个权限的,系统会通过对话框 逐一 询问用户是否授权。

3.4 处理权限申请回调

@Override

publicvoidonRequestPermissionsResult(intrequestCode,

String permissions[],int[] grantResults) {

switch(requestCode) {

case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {

// If request is cancelled, the result arrays are empty.

if(grantResults.length 0 grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// permission was granted, yay! Do the contacts-related task you need to do.

}else{

// permission denied, boo! Disable the functionality that depends on this permission.

}

return;

}

}

}

ok,对于权限的申请结果,首先验证requestCode定位到你的申请,然后验证grantResults对应于申请的结果,这里的数组对应于申请时的第二个权限字符串数组。如果你同时申请两个权限,那么grantResults的length就为2,分别记录你两个权限的申请结果。如果申请成功,就可以做你的事情了!

那么将上述几个步骤结合到一起就是:

// Here, thisActivity is the current activity

if (ContextCompat.checkSelfPermission(thisActivity,

Manifest.permission.READ_CONTACTS)

!= PackageManager.PERMISSION_GRANTED) {

// Should we show an explanation?

if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,

Manifest.permission.READ_CONTACTS)) {

// Show an expanation to the user *asynchronously* -- don't block

// this thread waiting for the user's response! After the user

// sees the explanation, try again to request the permission.

} else {

// No explanation needed, we can request the permission.

ActivityCompat.requestPermissions(thisActivity,

new String[]{Manifest.permission.READ_CONTACTS},

MY_PERMISSIONS_REQUEST_READ_CONTACTS);

// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an

// app-defined int constant. The callback method gets the

// result of the request.

}

}

谢幕,至此有关于android6.0 以上权限相关的内容已经详细讲完了!

安卓权限控制指南

早期的 Android 系统没有现在这么多权限控制设定,管理功能也较不完善(其实是因为当时软件申请的权限也没有现在这么过分)。

在 Android 4.0 中,谷歌对权限系统进行了改进,于是再经过各大手机厂商的优化,每个国内定制系统就有了如今的权限管理功能。

权限管理,各大品牌其实差不多。

就我用过的几个品牌来讲,华为的权限管理最好,小米其次,OPPO 最差。

当然,这里的“差”是相对的,相对于原生 Android 系统来说,这些厂商的权限管理做的都很好。

(其实是因为 Google Play 的审核比较严格,上架的软件几乎都很克制)

所以,如果你要买新手机,在预算充足的情况下,选华为吧。不只是因为技术很牛,可定制性上也很好。

目前,安卓系统的权限主要分为以下几类:

这里,重点解释一下某些权限的用途。

获取 IMEI 码:很多应用都会申请这一权限, 读取手机的唯一识别码 (估计是用于用户的身份验证和判断多开)

存储:这里指的是 内置存储的读写权限 ,不包含系统 Android/data 文件夹下的应用私有文件夹,如果这些应用需要在根目录下存储数据,则必须拥有该权限。

读取位置信息: 只有在已经开启位置信息开关时,应用才能读取该信息 。这项权限不包含加速度计等传感器。

读取已安装应用列表: 允许应用读取已经安装的软件 ,一些应用中让用户选择其它应用的功能就是这样实现的。

身体传感器:允许应用使用诸如 计步器 等传感器。这可以实现计步功能。

运动数据:也可以实现计步功能,但这项权限是 依赖系统自带的计步算法 实现的,这也是有些计步软件的数据和其它软件数据不同的原因。

创建快捷方式:你在手机主屏上看到的 APP 图标就属于快捷方式,但这是系统在应用安装完成后自动创建的。这项权限允许应用 主动创建快捷方式 (比如微信小程序的图标和的“写文章”按钮)。

悬浮窗:微信视频聊天时切换到其它应用或主屏,这就是悬浮窗。但输入法不属于悬浮窗。

忽略电池优化:在 Android 6.0 以上系统中,有一种成为 Doze 模式的省电策略。在这种模式下,应用的联网将被禁止,直到下一个窗口或接收到 Google 高优先级推送(需要开发者和网络环境支持)。该权限允许应用在这种模式下连接网络。

是否授予软件相应的权限,取决于该软件的功能和你的需要。

例如,在导航软件中,获取位置信息是一项核心权限,但在效率软件中并不是。

对于所有软件,都建议启用“获取 IMEI 码”权限 ,否则会给开发者带来不便,也会影响用户体验(国内的一些软件甚至会在启动时进行检查,如该权限未开启则不能使用软件)。

建议对所有软件关闭“拨打电话”和除“存储”以外的所有操作类权限(考虑到可能会有恶意软件利用这些权限进行扣费)。

建议关闭除“获取位置信息”和“读取已安装应用列表”以外的所有读取类权限( 注意:关闭“读取短信”权限会导致部分应用无法自动填充短信验证码,但考虑到国内 ROM 对此都有一定优化,故不建议开启该权限 )

对于位置信息权限,我建议以下软件保持开启:

其它软件要求位置信息权限的,一律拒绝(有些软件失去此权限可能不能正常运行,视情况而定)

至于“读取已安装应用列表”权限,凡是不需要获取其它软件名称的,都可以拒绝此权限。

摄像头和录音权限比较好判断,凡是软件需要这些功能的,都应该允许,否则拒绝即可。

身体传感器和运动数据权限除计步软件外均选择拒绝。

创建快捷方式权限,目前我打开的软件只有一个:com.tencent.mm 包名,slogan 是“生活方式”,启动界面是月亮的那个国民级应用。

悬浮窗权限,一部分辅助类软件需要打开,比如手机管家和绿色守护,以及前面提到的那个国民级应用的视频悬浮窗。

至于开机自启动等关于后台省电的权限,请看下期......


标题名称:android权限系统,安卓系统软件权限设置
本文链接:http://jkwzsj.com/article/dsdhcgo.html

其他资讯