① android 权限统计
<uses-permission
android:name="${applicationId}.permission.JPUSH_MESSAGE"
android:protectionLevel="signature" /> 激光推送
<uses-permission android:name="android.permission.INTERNET" /> 网络
<uses-permission android:name="android.permission.CALL_PHONE" /> 打电话
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />存储
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />存储
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />这是在sd卡内创建和删除文件权限,添加该权限和
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />允许程序访问Wi-Fi网络状态信息
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />获取网络信息状态,如当前的网络连接是否有效
<uses-permission android:name="android.permission.READ_PHONE_STATE" />访问电话状态氏带羡
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />允许一个程序访问CellID或WiFi热点来获取粗略的位置
<uses-permission android:name="歼拍android.permission.RESTART_PACKAGES" />允许程序重新启动其他程序
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />改变WiFi状态
<uses-permission android:name="android.permission.GET_TASKS" />允许一个程序获取信息有关当前或最近运行的任务,一个缩略行凳的任务状态,是否活动等等
<uses-permission android:name="android.permission.RECORD_AUDIO" />允许程序录制音频
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />允许程序修改全局音频设置
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 允许程序开机自动运行
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />屏幕常亮
<uses-permission android:name="android.permission.WRITE_SETTINGS" />读写系统设置
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 允许一个程序打开窗口使用 TYPE_SYSTEM_ALERT,显示在其他所有程序的顶层
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />获取精确位置
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />访问定位额外命令
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />改变网络状态
<uses-permission android:name="android.permission.READ_LOGS" />读取系统日志
<uses-permission android:name="android.permission.SET_DEBUG_APP" />设置调试程序
<uses-permission android:name="android.permission.GET_ACCOUNTS" />访问账户Gmail列表
<uses-permission android:name="android.permission.USE_CREDENTIALS" />使用证书
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />管理账户
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />允许一个应用程序来管理文档的访问,通常是一个文档选择器部分
<uses-permission android:name="android.permission.REAL_GET_TASKS" />允许一个程序获取信息有关当前或最近运行的任务,一个缩略的任务状态,是否活动等等
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />允许程序禁用键盘锁
<uses-permission android:name="android.permission.CAMERA" />请求访问使用照相设备
<uses-permission android:name="android.permission.FLASHLIGHT" />使用闪光灯
照相设备并自动对焦拍照
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
② 安卓权限控制指南
早期的 Android 系统没有现在这么多权限控制设定,管理功能也较不完善(其实是因为当时软件申请的权限也没有现在这么过分)。
在 Android 4.0 中,谷歌对权限系统进行了改进,于是再经过各大手机厂商的优化,每个国内定制系统就有了如今的权限管理功能。
权限管理,各大品牌其实差不多。
就我用过的几个品牌来讲,华为的权限管理最好,小米其次,OPPO 最差。
当然,这里的“差”是相对的,相对于原生 Android 系统来说,这些厂商的权限管理做的都很好。
(其实是因为 Google Play 的审核比较严格,上架的软件几乎都很克制)
所以,如果你要买新手机,在预算充足的情况下,选华为吧。不只是因为技术很牛,可定制性上也很好。
目前,安卓系统的权限主要分为以下几类:
这里,重点解释一下某些权限的用途。
获取 IMEI 码:很多应用都会申请这一权限, 读取手机的唯一识别码 (估计是用于用户的身份验证和判断多开)
存储:这里指的是 内置存储的读写权限 ,不包含系统 Android/data 文件夹下的应用私有文件夹,如果这些应用需要在根目录下存储数据,则必须拥有该权限。
读取位置信息: 只有在已经开启位置信息开关时,应用才能读取该信息 。这项权限不包含加速度计等传感器。
读取已安装应用列表: 允许应用读取已经安装的软件 ,一些应用中让用户选择其它应用的功能就是这样实现的。
身体传感器:允许应用使用诸如 计步器 等传感器。这可以实现计步功能。
运动数据:也可以实现计步功能,但这项权限是 依赖系统自带的计步算法 实现的,这也是有些计步软件的数据和其它软件数据不同的原因。
创建快捷方式:你在手机主屏上看到的 APP 图标就属于快捷方式,但这是系统在应用安装完成后自动创建的。这项权限允许应用 主动创建快捷方式 (比如微信小程序的图标和的“写文章”按钮)。
悬浮窗:微信视频聊天时切换到其它应用或主屏,这就是悬浮窗。但输入法不属于悬浮窗。
忽略电池优化:在 Android 6.0 以上系统中,有一种成为 Doze 模式的省电策略。在这种模式下,应用的联网将被禁止,直到下一个窗口或接收到 Google 高优先级推送(需要开发者和网络环境支持)。该权限允许应用在这种模式下连接网络。
是否授予软件相应的权限,取决于该软件的功能和你的需要。
例如,在导航软件中,获取位置信息是一项核心权限,但在效率软件中并不是。
对于所有软件,都建议启用“获取 IMEI 码”权限 ,否则会给开发者带来不便,也会影响用户体验(国内的一些软件甚至会在启动时进行检查,如该权限未开启则不能使用软件)。
建议对所有软件关闭“拨打电话”和除“存储”以外的所有操作类权限(考虑到可能会有恶意软件利用这些权限进行扣费)。
建议关闭除“获取位置信息”和“读取已安装应用列表”以外的所有读取类权限( 注意:关闭“读取短信”权限会导致部分应用无法自动填充短信验证码,但考虑到国内 ROM 对此都有一定优化,故不建议开启该权限 )
对于位置信息权限,我建议以下软件保持开启:
其它软件要求位置信息权限的,一律拒绝(有些软件失去此权限可能不能正常运行,视情况而定)
至于“读取已安装应用列表”权限,凡是不需要获取其它软件名称的,都可以拒绝此权限。
摄像头和录音权限比较好判断,凡是软件需要这些功能的,都应该允许,否则拒绝即可。
身体传感器和运动数据权限除计步软件外均选择拒绝。
创建快捷方式权限,目前我打开的软件只有一个:com.tencent.mm 包名,slogan 是“生活方式”,启动界面是月亮的那个国民级应用。
悬浮窗权限,一部分辅助类软件需要打开,比如手机管家和绿色守护,以及前面提到的那个国民级应用的视频悬浮窗。
至于开机自启动等关于后台省电的权限,请看下期......
③ Android的权限都有哪些
(一)linux文件系统上的权限
-rwxr-x--x system system 4156 2010-04-30 16:13 test.apk
代表的是相应的用户/用户组及其他人对此文件的访问权限,与此文件运行起来具有的权限完全不相关。
比如上面的例子只能说明system用户拥有对此文件的读写执行权限;system组的用户对此文件拥有读、执行权限;其他人对此文件只具有执行权限。
而test.apk运行起来后可以干哪些事情,跟这个就不相关了。
千万不要看apk文件系统上属于system/system用户及用户组,或者root/root用户及用户组,就认为apk具有system或root权限
(二)Android的权限规则
(1)Android中的apk必须签名
这种签名不是基于权威证书的,不会决定某个应用允不允许安装,而是一种自签名证书。
重要的是,android系统有的权限是基于签名的。比如:system等级的权限有专门对应的签名,签名不对,权限也就获取不到。
默认生成的APK文件是debug签名的。
获取system权限时用到的签名,见:如何使Android应用程序获取系统权限
(2)基于UserID的进程级别的安全机制
大家都知道,进程有独立的地址空间,进程与进程间默认是不能互相访问的,是一种很可靠的保护机制。
Android通过为每一个安装在设备上的包(apk)分配唯一的linux userID来实现,名称为"app_"加一个数字,比如app_43
不同的UserID,运行在不同的进程,所以apk之间默认便不能相互访问。
Android提供了如下的一种机制,可以使两个apk打破前面讲的这种壁垒。
在AndroidManifest.xml中利用sharedUserId属性给不同的package分配相同的userID,通过这样做,两个package可以被当做同一个程序,
系统会分配给两个程序相同的UserID。当然,基于安全考虑,两个package需要有相同的签名,否则没有验证也就没有意义了。
(这里补充一点:并不是说分配了同样的UserID,两程序就运行在同一进程, 下面为PS指令摘取的,
显然,system、app_2分别对应的两个进程的PID都不同,不知Android到底是怎样实现它的机制的)
User PID PPID
system 953 883 187340 55052 ffffffff afe0cbcc S system_server
app_2 1072 883 100264 19564 ffffffff afe0dcc4 S com.android.inputmethod.
system 1083 883 111808 23192 ffffffff afe0dcc4 S android.process.omsservi
app_2 1088 883 156464 45720 ffffffff afe0dcc4 S android.process.acore
(3)默认apk生成的数据对外是不可见的
实现方法是:Android会为程序存储的数据分配该程序的UserID。
借助于Linux严格的文件系统访问权限,便实现了apk之间不能相互访问似有数据的机制。
例:我的应用创建的一个文件,默认权限如下,可以看到只有UserID为app_21的程序才能读写该文件。
-rw------- app_21 app_21 87650 2000-01-01 09:48 test.txt
如何对外开放?
<1> 使用MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE 标记。
When creating a new file with getSharedPreferences(String, int), openFileOutput(String, int), or openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory), you can use the MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE flags to allow any other package to read/write the file. When setting these flags, the file is still owned by your application, but its global read and/or write permissions have been set appropriately so any other application can see it.
(4)AndroidManifest.xml中的显式权限声明
Android默认应用是没有任何权限去操作其他应用或系统相关特性的,应用在进行某些操作时都需要显式地去申请相应的权限。
一般以下动作时都需要申请相应的权限:
A particular permission may be enforced at a number of places ring your program's operation:
At the time of a call into the system, to prevent an application from executing certain functions.
When starting an activity, to prevent applications from launching activities of other applications.
Both sending and receiving broadcasts, to control who can receive your broadcast or who can send a broadcast to you.
When accessing and operating on a content provider.
Binding or starting a service.
在应用安装的时候,package installer会检测该应用请求的权限,根据该应用的签名或者提示用户来分配相应的权限。
在程序运行期间是不检测权限的。如果安装时权限获取失败,那执行就会出错,不会提示用户权限不够。
大多数情况下,权限不足导致的失败会引发一个 SecurityException, 会在系统log(system log)中有相关记录。
(5)权限继承/UserID继承
当我们遇到apk权限不足时,我们有时会考虑写一个linux程序,然后由apk调用它去完成某个它没有权限完成的事情,很遗憾,这种方法是行不通的。
前面讲过,android权限是经营在进程层面的,也就是说一个apk应用启动的子进程的权限不可能超越其父进程的权限(即apk的权限),
即使单独运行某个应用有权限做某事,但如果它是由一个apk调用的,那权限就会被限制。
实际上,android是通过给子进程分配父进程的UserID实现这一机制的。
(三)常见权限不足问题分析
首先要知道,普通apk程序是运行在非root、非system层级的,也就是说看要访问的文件的权限时,看的是最后三位。
另外,通过system/app安装的apk的权限一般比直接安装或adb install安装的apk的权限要高一些。
言归正传,运行一个android应用程序过程中遇到权限不足,一般分为两种情况:
(1)Log中可明显看到权限不足的提示。
此种情况一般是AndroidManifest.xml中缺少相应的权限设置,好好查找一番权限列表,应该就可解决,是最易处理的情况。
有时权限都加上了,但还是报权限不足,是什么情况呢?
Android系统有一些API及权限是需要apk具有一定的等级才能运行的。
比如 SystemClock.setCurrentTimeMillis()修改系统时间,WRITE_SECURE_SETTINGS权限好像都是需要有system级的权限才行。
也就是说UserID是system.
(2)Log里没有报权限不足,而是一些其他Exception的提示,这也有可能是权限不足造成的。
比如:我们常会想读/写一个配置文件或其他一些不是自己创建的文件,常会报java.io.FileNotFoundException错误。
系统认为比较重要的文件一般权限设置的也会比较严格,特别是一些很重要的(配置)文件或目录。
如
-r--r----- bluetooth bluetooth 935 2010-07-09 20:21 dbus.conf
drwxrwx--x system system 2010-07-07 02:05 data
dbus.conf好像是蓝牙的配置文件,从权限上来看,根本就不可能改动,非bluetooth用户连读的权利都没有。
/data目录下存的是所有程序的私有数据,默认情况下android是不允许普通apk访问/data目录下内容的,通过data目录的权限设置可知,其他用户没有读的权限。
所以adb普通权限下在data目录下敲ls命令,会得到opendir failed, Permission denied的错误,通过代码file.listfiles()也无法获得data目录下的内容。
④ Android权限机制
我们知道 Android 应用程序是沙箱隔离的,每个应用都有一个只有自己具有读写权限的专用数据目录。但是如果应用要访问别人的组件或者一些设备上全局可访问的资源,这时候权限机制就能系统化地规范并强制各类应用程序的行为准则。
Android 安全性概览
在 Android 中,一个权限,本质上是一个字符串,一个可以表示执行特定操作的能力的字符串。比如说:访问 SD 卡的能力,访问通讯录的能力,启动或访问一个第三方应用中的组件的能力。 权限被授予了之后,首先会在内存和本地中有记录,这在调用系统binder服务和其他应用组件时做鉴权依据,比如调用系统binder服务时会通过Binder.getCallingUid()拿到调用者的Uid,而Uid一般都是与应用包名一一对应的,再拿这个Uid到PMS里去查这个应用对应的权限。 其次会按被授予的权限将应用分到某个组。 可以参考 https://www.jianshu.com/p/a17c8bed79d9
自定义权限的应用场景在于限制其它应用对本应用四大组件的访问。具体用法可以参考 https://www.cnblogs.com/aimqqroad-13/p/8927179.html
pm list permissions -f 命令可以详细查看 Android 所有预定义的权限。
更详细的权限信息参考 https://developer.android.com/reference/android/Manifest.permission?hl=zh-cn#WRITE_EXTERNAL_STORAGE
可以看到一个权限的信息包括:定义的包名、标签、描述、 权限组 和 保护级别 。
权限根据设备的功能或特性分为多个组。如果应用已在相同权限组中被授予另一危险权限,系统将立即授予该权限,如READ_CONTACTS和WRITE_CONTACTS。
SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS 由于其特殊性,其申请方式与其它权限都不同。
其授予流程如下:
(关于 AppOpsManager 是什么可以参考: https://segmentfault.com/a/1190000009214983 )
这里简要分析下ActivityCompat#requestPermissions的流程:
更详细的权限授予流程源码分析可以参考: https://segmentfault.com/a/1190000009214983
普通权限: 清单文件中声明即可。
危险权限: 方式一: pm grant application_package android.permission.CHANGE_CONFIGURATION 方式二:appops set application_package permission_num 0/1
appops可以授予的权限参考 android.app.AppOpsManager 中的声明
系统签名权限: 方式一:将app迁移到system/priv-app目录中。 方式二:看不懂,参考 https://blog.csdn.net/abcd_3344_abcd/article/details/50698759
android 4.4 访问sd卡需要申请权限。 您的应用在 Android 4.4 上运行时无法读取外部存储空间上的共享文件,除非您的应用具有 READ_EXTERNAL_STORAGE 权限。也就是说,没有此权限,您无法再访问 () 返回的目录中的文件。但是,如果您仅需要访问 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 政策禁止在您的应用外部公开 file://URI。如果一项包含文件 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
隐私权限变更。
更详细的版本变更请参考 https://developer.android.com/preview/privacy?hl=zh-cn
⑤ Android有哪些"权限"
Android是在Linux内核上建立一个硬件抽象层(Android HAL),通过Dalvik以及各种库来执行android应用的。在手机启动时,首先需要由Bootloader(HTC手机上称作Hboot)引导Linux及手机上各个硬件设备的驱动程序,之后才启动Android系统。所以其实我们会涉及到四种不同涵义的权限:
Android权限(Permission)
这指Android中的一系列"Android.Permission.*"对象,是本文的中心内容。
Google在Android框架内把各种对象(包括设备上的各类数据,传感器,拨打电话,发送信息,控制别的应用程序等)的访问权限进行了详细的划分,列出了约一百条"Android.Permission"。应用程序在运行前必须向Android系统声明它将会用到的权限,否则Android将会拒绝该应用程序访问通过该"Permission"许可的内容。
比方说,搜狗输入法提供了一个智能通讯录的功能,用户可以在输入联系人拼音的前几个字符,或首字母,输入法就能自动呈现相关联系人的名字。为了实现这个功能,输入法必须声明它需要读取手机中联系人的能力,也就是在相关代码中加上声明"android.permission.READ_CONTACTS"对象。
图5 搜狗输入法的智能联系人功能
原生Android只提供了对"一刀切"式的管理,要么同意使用,否则就根本就不安装应用程序。当用户遇到希望使用程序的同时,又想禁止部分Permission的场合,他就无路可走。
于是,不少开发者就捣鼓出了"第三条道路";可惜的是,没有一种方法能同时做到既不需要将手机固件Root,又完全不涉及对原始应用程序进行反向工程的方法。
RootRoot指获得Android所在的Linux系统的Root(根)权限,有了根权限,你才能对Linux做出任意的修改。iOS中的越狱(Jailbreak) 相当于获得iOS系统的Root权限(iOS是一种类Unix系统,和Linux都使用Root的概念)。在已Root的设备中,通常都是使用一个叫"Superuser"(简称SU)的应用程序来向许可的程序授以Root权限。
Bootloader的解锁(Unlock)
利用数字签名,Bootloader可以限定只有正确签名的系统可以被引导。在修改固件以获得Root以前,解锁Bootloader通常是必须的。安装第三方修改、编译的固件也需要解锁Bootloader。
基带(Radio)解锁
在Android系统中,基带是上层软件与手机中无线设备(手机网络,Wi-Fi,蓝牙等)的驱动程序之间的中介。国外的网络运营商很喜欢锁定基带,从而保证用户只能使用运营商自己指定的sim卡。在我国,锁定基带是非法的,手机制造商、网络运营商也不可以通过锁定基带的方法对待违约客户。iOS的"解锁"就是解锁iOS中的基带软件。
鱼和熊掌不可兼得,Android的世界有很多自由,坏人也能自由地做坏事。它的生态系统很强调自主:用户可以自主地减小风险,仅使用官方市场的应用程序,也可以自主地解除安全限制,从而获得更多自由。因此,在遇到坏事的时候,用户也不得不自主一下:
1, 抵制不道德,乃至非法行为
几乎所有的Android安全软件都能对来电、信息进行控制,以减少骚扰。
另一方面,很多应用都会要求它们实际功能以外的权限,表现在非(主动)告知地搜集设备序列号,位置信息,诱使用户默认地上传联系人列表等方面。
更坏一点的应用程序,则会踏入犯罪的范畴,比如能偷偷发出扣费信息,或是作为黑客的偷窥工具。
2, 减少恶意软件的损害
恶意软件即便潜伏成功,也难以获得权限,从而减少损失。
3, 用户有权自主地在抑制应用程序的部分权限时,继续使用该应用程序,而只承担由于自行设置不当而带来的后果。
用户拥有设备的所有权,因此有权自主控制设备上的内容、传感器等对象的访问;同时有权(不)运行,(不)编译设备上的应用程序。
大多数应用程序在运行时,并未达成主动告知的义务,是失误;然而即使主动告知,用户还是可以不理会。
通过Android官方市场,"打包安装器"安装应用程序时,所显示的"权限"仅是在安装包内AndroidManifest.xml声明的值,而非应用程序实际上会调用的内容。该值仅用来表明Android系统能向应用授予的最大可能的权限。即便一个"Hello World"式的应用程序,也可以在AndroidManifest.xml中声明所有可能的Android Permission。
这就是说,在AndroidManifest.xml中声明的值与应用程序实际调用的权限有关联,但不等同,且这种提示是由Android系统负责实施的强制行为。
正确的理解是:"应用程序(被迫地)让Android系统告知用户,它在AndroidManifest.xml中所声明的事项。"
这意味着应用程序在使用重要权限前,依然需要自行、主动地通知用户相关事宜。