本文主要介绍Android权限控制机制的原理。Android的权限控制主要分为两种类型。
这种类型主要指访问网络等类似的权限。Android直接使用了Linux的用户权限机制。
当应用程序在安装的时候,系统会给应用程序分配一个用户名,同时,会检查AndroidManifest.xml中的权限声明。对于在系统的platform.xml文件中存在的权限(platform.xml存储了group gid和权限字符串的对应关系),系统会把这个用户添加到相应的group中。
例如,如果在AndroidManifest.xml声明了android.permission.INTERNET权限,那么这个用户将会被加到inet组中。
查看platform.xml的方法
如果安装了Android SDK的话,可以执行下面的命令: adb shell cat etc/permissions/platform.xml 如果有Android源代码的话,可以直接查看下面这个路径: frameworks/base/data/etc/platform.xml |
验证方法:
1.新建一个Android工程,然后在AndroidMenifest.xml中添加两个权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
2.在源代码中添加下面的一段运行linux的id命令的代码
01 |
try { |
02 |
java.lang.Process process=Runtime.getRuntime().exec( "id" ); |
03 |
InputStream input = process.getInputStream(); |
04 |
byte [] bytes = new byte [ 1024 ]; |
05 |
int len; |
06 |
while ((len = (input.read(bytes))) > 0 ) { |
07 |
System.out.println( new String(bytes, 0 , len)); |
08 |
} |
09 |
input.close(); |
10 |
} catch (IOException e) { |
11 |
e.printStackTrace(); |
12 |
} |
3.运行程序。在DDMS中可以看到输出结果
04-12 07:36:42.805: INFO/System.out(1395): uid=10034(app_34) gid=10034(app_34) groups=3002(net_bt),3003(inet) |
id命令的功能是输出当前用户的uid,主要的group id和所在的group。
这里可以看到应用程序的uid是10034,被添加到net_bt和inet组中。
4.查看platform.xml中相应的配置
<permission name="android.permission.BLUETOOTH" >
<group gid="net_bt" />
</permission>
<permission name="android.permission.INTERNET" >
<group gid="inet" />
</permission>
可以看到net_bt和inet组对应的权限就是在AndroidManifest.xml中声明的权限。
这种类型主要指读取短信等类似没有涉及到硬件的权限(也有部分硬件使用了这个方式,如发送短信)。这种访问是通过Android的Service机制来实现的。
以发送短信为例,当一个应用程序需要发送短信时,由于应用程序的进程并没有发送短信的权限,因此需要向系统的短信客户端(另一个有权限的进程)发起请求(进程通信),然后系统的短信客户端会检查相应的权限,如果发现请求的进程并没有相应的权限,那么就拒绝提供短信内容,如果有相应的权限,那么客户端就会替应用程序进行发送短信的操作。
例如,下面是Android源代码中对发送短信的权限检查代码
01 |
public void sendData(String destAddr, String scAddr, int destPort, |
02 |
byte [] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { |
03 |
mPhone.getContext().enforceCallingPermission( |
04 |
"android.permission.SEND_SMS" , |
05 |
"Sending SMS message" ); |
06 |
if (Log.isLoggable( "SMS" , Log.VERBOSE)) { |
07 |
log( "sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" + |
08 |
destPort + " data='" + HexDump.toHexString(data) + "' sentIntent=" + |
09 |
sentIntent + " deliveryIntent=" + deliveryIntent); |
10 |
} |
11 |
mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent); |
12 |
} |
这种机制简单地说,就是应用程序利用了一个有权限的进程来完成相应的功能,权限的检查由提供相应功能的进程自己负责。ContentProvider机制事实上是基于Service机制的,在此就不介绍了。
PS,Android的进程通信机制是Binder,有时间再介绍一下。
原文地址:点击打开链接