Android中的权限管理(基于Permission ProtectionLevel)

2023-05-16

     1、什么是protectionlevel呢?

      我们经常在AndroidManifest中使用权限,如果我们想让应用程序可以发短信,那么应该这样写:

 <uses-permission android:name="android.permission.SEND_SMS" />

      那么这个权限的定义是在哪里定义的呢?如下:

      frameworks/base/core/res/AndroidManifest.xml

<permission android:name="android.permission.SEND_SMS"
        android:permissionGroup="android.permission-group.COST_MONEY"
        android:protectionLevel="dangerous"
        android:label="@string/permlab_sendSms"
        android:description="@string/permdesc_sendSms" />
     这个xml可以认为是系统apk使用的AndroidManifest.xml,该apk使用系统的私钥进行签名。

     name:权限的名字,uses-permisson使用的。

     permissionGroup:权限的分类,在提示用户安装时会把某些功能差不多的权限放到一类。

     protectionLevel:分为Normal、Dangerous、Signature、SignatureOrSystem,我们后面会着重讲这个。

     label:提示给用户的权限名。

     description:提示给用户的权限描述。


    2、protectionLevel

    (1)Normal

    权限被声明为Normal级别,任何应用都可以申请,在安装应用时,不会直接提示给用户,点击全部才会展示。

    (2)Dangerous

    权限被声明为Dangerous级别,任何应用都可以申请,在安装应用时,会直接提示给用户。

    (3)Signature

    权限被声明为Signature级别,只有和该apk(定义了这个权限的apk)用相同的私钥签名的应用才可以申请该权限。
    frameworks/base/core/res/AndroidManifest.xml声明的权限为Signature级别,那么只有Android官方使用相同私钥签名的应用才可以申请该权限。

    (4)SignatureOrSystem

    权限被声明为SignatureOrSystem级别,有两种应用可以申请该权限。

    1)和该apk(定义了这个权限的apk)用相同的私钥签名的应用

    2)在/system/app目录下的应用


    3、举个例子

    比如百度地图apk的AndroidManifest.xml里面声明了一个权限,

    (1)、权限定义为Dangerous,那么任何其他应用都可以使用。

    (2)、权限定义为Signature,那么只有使用同样私钥签名的apk,例如百度网盘,可以使用这个权限。

    (3)、权限定义为SignatureOrSystem,那么使用同样私钥签名的apk,例如百度网盘,可以使用这个权限。在/system/app下的应用也可以使用这个权限。


    4、我们自然想到一个问题,申请了某个权限与否,在代码中是怎么控制是否可以访问某个资源呢?

    (1)、Android系统独有的权限,在代码中是怎么控制是否可以访问某个资源呢?我们看一个实际的例子。

     Client端:

void startDockOrHome(){
	awakenDreams();
	......
}

private static void awakenDreams(){
	IDreamManager dreamManager = getDreamManager();
	if(dreamManager != null){
		try{
			dreamManager.awaken();//调用Server端的awaken
		} catch(RemoteException e){
			//fine, stay asleep then
		}
	}
      Server端:

@Override // Binder call
public void awaken() {
	checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);

    final long ident = Binder.clearCallingIdentity();
    try {
        requestAwakenInternal();
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
}

private void checkPermission(String permission) {
    if (mContext.checkCallingOrSelfPermission(permission)
               != PackageManager.PERMISSION_GRANTED) {
           throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
                  + ", must have permission " + permission);
    }
}
      Client端和Server端通过Binder进程间通信机制来通信。在Server端通过checkPermission来检查Client端是否申明了此权限。

  

      (2)、对于非Android特有的Service(底层平台已经提供,如File访问,TCPIP数据收发等),多个入口访问:Android API,Java API,NDK C API,shell都可以访问。这样权限控制就聚口在底层,所以在底层统一控制。这个底层统一控制其实就是传统的Linux文件读写执行权限(rwx)。

      例如在应用中申请了写SD卡的权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      我们需要把Android空间的Permission Mapping到OS的GID。

      我们看一个重要的类,frameworks\base\data\etc\Platform.xml

    <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
        <group gid="sdcard_rw" />
    </permission>

   

     对于申请了WRITE_EXTERNAL_STORAGE特权的应用,该应用的进程的gids就包含了sdcard_r,就可以对sd卡中的文件进行操作了。

     再看Android_filesystem_config.h的源码:

#define AID_SDCARD_RW 1015 /* external storage write access */

    也就是说这个权限映射到1015的gid,我们再来看一张图:

    我们查看com.android.phone这个进程,该应用申请了写外部内存卡的权限。首先使用ps查看该进程的进程号是1038,然后采用如下命令:


    我们看到这个进程的Groups里面有gid为1015,1015就是对应sdcard_r。

    5、除了我们在AndroidManifest.xml里面申请权限外,我们还可以在frameworks\base\data\etc\Platform.xml,assign权限,如下:

<assign-permission name="android.permission.WRITE_EXTERNAL_STORAGE" uid="shell" />
    <assign-permission name="android.permission.SEND_SMS" uid="shell" />
    <assign-permission name="android.permission.CALL_PHONE" uid="shell" />
    <assign-permission name="android.permission.READ_CONTACTS" uid="shell" />
    <assign-permission name="android.permission.WRITE_CONTACTS" uid="shell" />
    <assign-permission name="android.permission.READ_CALENDAR" uid="shell" />
    <assign-permission name="android.permission.WRITE_CALENDAR" uid="shell" />
    <assign-permission name="android.permission.READ_USER_DICTIONARY" uid="shell" />
    <assign-permission name="android.permission.WRITE_USER_DICTIONARY" uid="shell" />
    <assign-permission name="android.permission.ACCESS_FINE_LOCATION" uid="shell" />
    <assign-permission name="android.permission.ACCESS_COARSE_LOCATION" uid="shell" />
    <assign-permission name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" uid="shell" />
    <assign-permission name="android.permission.ACCESS_NETWORK_STATE" uid="shell" />
    <assign-permission name="android.permission.ACCESS_WIFI_STATE" uid="shell" />
    <assign-permission name="android.permission.BLUETOOTH" uid="shell" />
    <!-- System tool permissions granted to the shell. -->
    <assign-permission name="android.permission.GET_TASKS" uid="shell" />
    <assign-permission name="android.permission.CHANGE_CONFIGURATION" uid="shell" />
    <assign-permission name="android.permission.REORDER_TASKS" uid="shell" />
    <assign-permission name="android.permission.SET_ANIMATION_SCALE" uid="shell" />
    <assign-permission name="android.permission.SET_PREFERRED_APPLICATIONS" uid="shell" />
    <assign-permission name="android.permission.WRITE_SETTINGS" uid="shell" />
    <assign-permission name="android.permission.WRITE_SECURE_SETTINGS" uid="shell" />
    <assign-permission name="android.permission.BROADCAST_STICKY" uid="shell" />
    <!-- Development tool permissions granted to the shell. -->
    <assign-permission name="android.permission.SET_DEBUG_APP" uid="shell" />
    <assign-permission name="android.permission.SET_PROCESS_LIMIT" uid="shell" />
    <assign-permission name="android.permission.SET_ALWAYS_FINISH" uid="shell" />
    <assign-permission name="android.permission.DUMP" uid="shell" />
    <assign-permission name="android.permission.SIGNAL_PERSISTENT_PROCESSES" uid="shell" />
    <!-- Internal permissions granted to the shell. -->
    <assign-permission name="android.permission.FORCE_BACK" uid="shell" />
    <assign-permission name="android.permission.BATTERY_STATS" uid="shell" />
    <assign-permission name="android.permission.INTERNAL_SYSTEM_WINDOW" uid="shell" />
    <assign-permission name="android.permission.INJECT_EVENTS" uid="shell" />
    <assign-permission name="android.permission.SET_ACTIVITY_WATCHER" uid="shell" />
    <assign-permission name="android.permission.READ_INPUT_STATE" uid="shell" />
    <assign-permission name="android.permission.SET_ORIENTATION" uid="shell" />
    <assign-permission name="android.permission.INSTALL_PACKAGES" uid="shell" />
    <assign-permission name="android.permission.CLEAR_APP_USER_DATA" uid="shell" />
    <assign-permission name="android.permission.DELETE_CACHE_FILES" uid="shell" />
    <assign-permission name="android.permission.DELETE_PACKAGES" uid="shell" />
    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="shell" />
    <assign-permission name="android.permission.READ_FRAME_BUFFER" uid="shell" />
    <assign-permission name="android.permission.DEVICE_POWER" uid="shell" />
    <assign-permission name="android.permission.INSTALL_LOCATION_PROVIDER" uid="shell" />
    <assign-permission name="android.permission.BACKUP" uid="shell" />

    <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
    <assign-permission name="android.permission.ACCESS_DRM" uid="media" />
    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />

    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />
      shell进程的权限我们 在Android中的权限管理(基于uid gid gids setUid),已经看到过其申请的权限对应的gids。那时候没有讲shell进程是怎么样申请的这个权限,这里解决了我们的疑问。

      由于platform.xml只有root用户可以操作,避免了安全问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android中的权限管理(基于Permission ProtectionLevel) 的相关文章

  • 为什么 Android WebView 拒绝用户输入?

    我正在开发一个 Android 应用程序 它使用 WebView 来显示 Facebook 的登录页面 该页面加载精美 我可以选择用户名 密码文本框 但在其中输入内容将不起作用 也就是说 它们肯定有输入焦点 它们有橙色焦点突出显示框和闪烁的
  • RecognizerIntent 不起作用; “缺少额外的呼叫包”

    我在 Android 2 2 上使用 RecognizerIntent API 时遇到问题 当我使用以下代码调用 API 时 Intent intent new Intent RecognizerIntent ACTION RECOGNIZ
  • 标准呼叫屏幕上的活动窗口 - 启用按钮

    我想在通话屏幕活动上添加一个小窗口 弹出窗口 谷歌语音 and 世界通话地点和时间 http areacellphone com 2010 04 android worldcallplaceandtime apps know place a
  • ActionBar 下拉微调器项目默认为第一项

    我试图设置默认情况下需要在微调器中选择的项目的索引 但它始终默认为 0 第一项 actionBar setDisplayShowTitleEnabled false actionBar setNavigationMode ActionBar
  • 围绕二维坐标系中的特定点缩放

    Below is an image my coordinate system 我想做的是 我想开始围绕画布中的特定点进行缩放 缩放工作正常 但我的问题是我不知道如何计算缩放时移动画布的量 请注意 我我没有使用canvas scale 我只是
  • 视图绑定对应用程序大小的影响有多大?

    View Binding 按照文档的规定 为每个XML元素生成一个Binding类 以方便访问和检查 并减轻如下的时间负担 findViewById 虽然findViewById通过更昂贵的关联搜索进行操作 由于映射 绑定应该 直接 访问
  • 在 Android 上使用 MediaPlayer 流式传输经过身份验证的视频

    我正在尝试从具有基本身份验证的 SharePoint 服务器 URL 流式传输和播放视频 用户名密码 在我的 Android 设备中browser Media Player VideoView但我得到了 错误 sorry this vide
  • 使用AndroidKeyStore身份验证的无限循环

    当我使用需要用户身份验证才能使用密钥的 AndroidKeyStore 时 我的应用程序进入无限循环 setUserAuthenticationRequired true setUserAuthenticationValidityDurat
  • Android 通知 - 显示完整消息

    我的 Android 应用程序必须能够向一大群人发送简短的警报 执行此操作的明显位置是在通知中心 完整的通知毫无问题地显示在股票代码中 但在通知中心 用户只能看到前几个单词 然后是省略号 通知并不长 最多也就10 15个字 如何使文本自动换
  • Android 滚动视图无法以编程方式创建。

    我想在我的应用程序中使用滚动视图 我尝试将文本视图添加到滚动视图中 但除了滚动视图的背景颜色之外 我看不到任何渲染的内容 我是这样做的 public class MyView extends ViewGroup ScrollView myS
  • Camera2设置预览(View)并获取预览回调

    我想从 Camera2 获取预览以及用于处理帧的 byte 回调 mImageReader ImageReader newInstance largest getWidth largest getHeight ImageFormat RAW
  • 在 doInBackground AsyncTask Android 中传递更多值

    如何传递更多的值doInBackground My AsyncTask看起来像这样 private class DownloadFile extends AsyncTask
  • 输入连接-如何删除选定的文本?

    我为 Android 制作了一个自定义键盘 当我按下键盘的退格按钮时 我使用 getCurrentInputConnection deleteSurroundingText 1 0 从输入字段中删除一个字母 但是 当我选择一些文本然后按退格
  • Kotlin Room 数据库单例模式

    我正在尝试创建单人房间数据库 我找到了两种解决方案 但我不知道它们之间有什么区别 根据这个文件 companion object Volatile private var INSTANCE AppDatabase null fun getI
  • Android Realm.io:行/对象不再有效

    这是我的删除功能 它确实找到了workday1 object public static void delete Context context Workday workday Realm realm getRealm context re
  • Android系统每个应用程序的通知限制

    这可能偏离主题 但我找不到任何相关内容 Android应用程序可以显示的通知数量有限制吗 我在收到 100 条通知后遇到问题 没有文件明确说明这一点 注意 显示 100 条通知并不是一个好主意 但由于某些原因这是必需的 In API23 包
  • 单击输入字段会触发窗口调整大小

    我有一个带有徽标 菜单和搜索的标题 当我在桌面上时 我会按该顺序显示所有元素 但如果我的窗口宽度小于 980 像素 菜单会隐藏 有一个切换按钮 并且徽标会与nav并附在徽标之后 如果宽度更大 则徽标将再次分离并附加到 DOM 中的旧位置 w
  • 从代码动态更改多个文本视图的大小(没有“磁盘上”xml 主题)?

    我有 10 个文本视图在我的代码中 我想更改所有代码的字体大小 在我的布局中我使用了 style定义通用属性 但是我不知道一旦布局出现在屏幕上如何从代码中更改它们 我不想做的是更新 AND 对象 但只写在一处 我知道我可以使用应用主题但这假
  • 如何通过子 POJO 的属性过滤复合 ManyToMany POJO?

    我有两个像这样的房间实体 Entity public class Teacher implements Serializable PrimaryKey autoGenerate true public int id ColumnInfo n
  • mgwt - 以编程方式改变方向

    是否可以在 gwt mgwt 应用程序中更改强制执行特定的屏幕方向 可以说我希望用户始终以横向模式使用应用程序 这取决于 是作为phonegap应用程序 而不是在浏览器内部 如果您作为 Web 应用程序运行 则不需要t get any co

随机推荐