Develop系列-API Guides-简介-系统权限
系统权限
安全架构
app在独立进程沙盒中运行,互不影响。app静态定义所需要的权限,系统安装时提醒用户是否给app授权。
应用签名
所有应用必须用证书签名,证书由开发者管理,它们是开发者的唯一标识。
用户ID和文件访问
1、同样的shareUserId和签名,才能在同一个进程中共用一个用户ID
2、在创建新文件时,可以通过MODE_WORLD_READABLE
或 MODE_WORLD_WRITEABLE
标签来设置其他应用能否读写此文件
使用权限
默认的,app没有任何权限,需要在AndroidManifest中的
标签来定义所需的权限。<uses-permission>
比如app需要监听短信消息时:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.app.myapp" > <uses-permission android:name="android.permission.RECEIVE_SMS" /> ... </manifest>
应用在安装的时候,package installer能够根据应用的签名和用户的选择来授权。
通常来说,授权失败将抛出SecurityException异常,但并不是每次授权失败都会抛此异常。
然而,正常安装过程中,所有的app需要的权限都必须确认后,才能安装,所以基本不存在运行时授权失败的问题。
Android系统提供的所有权限可以在Manifest.permission
查询,任何应用都可以自定义权限。
特定的权限可以用于各种场景:
- 系统调用的时候,通过权限来避免应用执行特定功能
- 启动activity时,通过权限来阻止被其他应用所启动
- 收发广播时,通过权限来控制广播收发的对象
- 访问和操作content provider
- 绑定或者启动服务
Caution:?
自定义权限
如果app想控制其他app能否有权限启动自身,可用通过如下方式来定义:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.me.app.myapp" > <permission android:name="com.me.app.myapp.permission.DEADLY_ACTIVITY"
<!--app用到此权限,安装时弹出的提示标题--> android:label="@string/permlab_deadlyActivity"
<!--提示内容--> android:description="@string/permdesc_deadlyActivity"
<!--可选项--> android:permissionGroup="android.permission-group.COST_MONEY"
<!--必选项--> android:protectionLevel="dangerous" /> ... </manifest>
adb shell pm list permissions(TODO:adb shell pm命令解析)
对于组件的访问权限,可以在AndroidManifest.xml中定义特定组件的android:permission
属性来控制
Activity:
谁能启动它,权限在Context.startActivity()
和 Activity.startActivityForResult()
检查,失败会抛SecurityException
Service:
谁能启动或绑定它,权限在Context.startService()
, Context.stopService()
和 Context.bindService()
检查,失败抛SecurityException
BroadcastReceiver:
谁能给它发广播,在Context.sendBroadcast()
检查,失败不会抛异常,同时
也能检查。在ontext.registerReceiver()
Context.sendBroadcast()
时,可以带权限字符串的参数来确认权限。广播发送和接收都可以设置权限,如果同时设置,那么必须同时匹配才能生效。
ContentProvider:
谁能访问它的数据(CP还有另外一个非常重要的权限机制:URI permissions ),CP分读(android:readPermission)和写(android:writePermission)两种权限,必须注意的是,如果读和写权限同时存在,那么仅仅拥有写权限的应用无法读取数据。读权限在ContentResolver.query()
检查,写权限在ContentResolver.insert()
,ContentResolver.update()
, ContentResolver.delete()
检查,失败会抛SecurityException
还有其他检查权限的方式,比如Context.checkCallingPermission(),
Context.checkPermission(String, int, int),
PackageManager.checkPermission(String, String)
URI权限
content providers中还有一些场景需要特殊的授权模型,比如mail的附件,是需要权限才能打开的,因为这是敏感的用户数据,然后如果把mail附件的URI传递给图片查看器,图片查看器没有理由有权限能打开这张图片。
解决办法就是调用者主动设置Intent.FLAG_GRANT_READ_URI_PERMISSION
或Intent.FLAG_GRANT_WRITE_URI_PERMISSION
.给接收intent的activity授权访问URI的权限。