Android系统 理解/sys/目录权限和UID和GID?
一般自定义系统和应用权限用于客制化的一些接口比较常见 , 比如我在系统中增加了一套接口 , 正常情况下 所有都能调用到系统接口 , 这是很不标准的。为了跟精细的控制权限 需要自定义权限 可以在系统中去检查权限是否申请, 如果申请了才能允许调用。那需要怎么自定义权限呢? 我们来学习下…
自定义权限允许开发者在系统或应用级别定义特定的权限,从而更精确地控制应用间的交互和数据保护。自定义权限的目的: 提供更细粒度的控制。
Android权限模型
Android权限模型概述
Android权限模型控制应用对系统资源和用户数据的访问。其核心特点如下:
- 基于声明的:应用在
AndroidManifest.xml
中声明所需权限,用户在安装或运行时授予或拒绝。
<uses-permission android:name="android.permission.CAMERA" />
- 基于分组的:预定义权限被分为组(如位置、存储、电话)。用户可以管理每个应用的权限组。
- 基于级别的:
- 正常:无需用户授权。
- 危险:运行时需要用户授权。
- 签名:仅相同签名的应用可用。
- 特殊:仅系统应用或特定身份应用可用。
- 基于角色的:角色是功能或数据的抽象身份(如电话应用、浏览器)。每个角色包含了一组相关的权限,用户可以在设置中为每个角色选择一个默认的应用。当用户选择了一个角色的默认应用后,该应用会自动获得该角色所需的所有权限,而其他应用则需要用户手动授予。
Android权限的分类
Android权限分类
Android权限主要分为两类:
- 系统权限 (System Permission):
- 由Android系统预定义。
- 与系统资源或功能相关,如网络、联系人、相机。
- 适用于任何应用,但需遵循系统的授权方式和保护级别。
<uses-permission android:name="android.permission.CAMERA" />
- 应用权限 (Application Permission):
- 由开发者定义。
- 与应用内部数据或逻辑相关。
- 仅在定义它们的应用或具有相同签名的应用中使用。
<permission android:name="com.example.MY_PERMISSION" android:protectionLevel="signature"/>
自定义系统权限
如何在Android系统中自定义权限
自定义系统权限是一种特殊的系统权限,它们由系统开发者或厂商自己定义和声明,然后在系统应用中使用。自定义系统权限可以让系统开发者或厂商实现一些特定的功能或需求,例如控制某些硬件设备、访问某些系统服务、管理某些系统接口等。
要在Android系统中自定义权限,需要:
- 在系统的清单文件(frameworks/base/core/res/AndroidManifest.xml)中声明自定义权限,使用标签,并为其指定一个唯一的名称、保护级别和描述。
- 在使用的自定义权限的系统应用的清单文件中,使用标签,引用自定义权限的名称。
- 在提供自定义权限的系统服务或组件中,使用checkPermission()方法,检查调用者是否具有自定义权限。
例如,假设想在Android系统中自定义一个名为com.example.permission.CUSTOM_SYSTEM_PERMISSION的权限,它可以让应用访问一个名为CustomSystemService的系统服务,该服务提供了一个名为doSomething()的方法。那么可以这样做:
- 在系统的清单文件中,声明的自定义权限:
<permission android:name="com.example.permission.CUSTOM_SYSTEM_PERMISSION" android:protectionLevel="signature" android:label="@string/custom_system_permission_label" android:description="@string/custom_system_permission_description" />
这里我们为自定义权限设置了签名级别的保护级别,表示只有具有相同签名证书的应用才能使用该权限。我们也为自定义权限提供了一个标签和一个描述,用来在设置中显示给用户。
- 在使用自定义权限的系统应用的清单文件中,引用自定义权限:
<uses-permission android:name="com.example.permission.CUSTOM_SYSTEM_PERMISSION" />
这里我们告诉系统,我们的应用需要使用该自定义权限。
- 在提供自定义权限的系统服务或组件中,检查调用者是否具有自定义权限:
public class CustomSystemService extends Service { private static final String CUSTOM_SYSTEM_PERMISSION = "com.example.permission.CUSTOM_SYSTEM_PERMISSION"; @Override public IBinder onBind(Intent intent) { return new CustomServiceBinder(); } private class CustomServiceBinder extends ICustomService.Stub { @Override public void doSomething() { // Check if the caller has the custom permission int uid = Binder.getCallingUid(); int pid = Binder.getCallingPid(); if (checkPermission(CUSTOM_SYSTEM_PERMISSION, pid, uid) != PackageManager.PERMISSION_GRANTED) { // Throw a security exception if not throw new SecurityException("Caller does not have the custom permission"); } // Do something if yes Log.d("CustomSystemService", "Doing something..."); } } }
这里我们使用checkPermission()方法,根据调用者的进程ID和用户ID,检查它是否具有我们的自定义权限。如果没有,我们抛出一个异常;如果有,我们执行我们想要做的事情。
如何在系统应用中使用自定义的系统权限
如果一个系统应用的开发者,可能想要使用一些自定义的系统权限,来实现一些特殊的功能或需求。要在系统应用中使用自定义的系统权限,需要:
- 在系统应用的清单文件中,使用标签,引用想要使用的自定义权限的名称。
- 在系统应用中,调用提供该自定义权限的系统服务或组件,使用Context.getSystemService()方法,获取该服务或组件的实例,并调用其方法。
例如,假设在系统应用中使用上一节中定义的com.example.permission.CUSTOM_SYSTEM_PERMISSION权限,来访问CustomSystemService服务,并调用其doSomething()方法。那么可以这样做:
- 在系统应用的清单文件中,引用该自定义权限:
<uses-permission android:name="com.example.permission.CUSTOM_SYSTEM_PERMISSION" />
这里我们告诉系统,我们的应用需要使用该自定义权限。
- 在系统应用中,调用提供该自定义权限的系统服务,并调用其方法:
public class CustomSystemApp extends Activity { private ICustomService mCustomService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_custom_system_app); // Get the custom service instance mCustomService = ICustomService.Stub.asInterface(getSystemService("custom_service")); // Call the custom service method try { mCustomService.doSomething(); } catch (RemoteException e) { e.printStackTrace(); } } }
这里我们使用getSystemService()方法,根据服务的名称(这里是"custom_service"),获取服务的实例,并转换为接口类型。然后我们调用服务的方法,如果发生远程异常,我们捕获并处理它。
自定义应用权限
如何在Android应用中自定义权限
自定义应用权限是一种常见的应用权限,它们由应用开发者自己定义和声明,然后在自己的应用或具有相同签名的应用中使用。自定义应用权限可以让应用开发者实现一些特定的功能或需求,例如控制某些服务或组件的访问、保护某些数据或逻辑等。
要在Android应用中自定义权限,需要:
- 在应用的清单文件中声明自定义权限,使用标签,并为其指定一个唯一的名称、保护级别和描述。
- 在提供自定义权限的服务或组件中,使用android:permission属性,引用自定义权限的名称。
- 在使用自定义权限的应用的清单文件中,使用标签,引用自定义权限的名称。
假设想在应用中自定义一个名为com.example.permission.CUSTOM_APP_PERMISSION的权限,它可以让应用访问一个名为CustomAppService的服务,该服务提供了一个名为doSomething()的方法。那么可以这样做:
- 在应用的清单文件中,声明的自定义权限:
<permission android:name="com.example.permission.CUSTOM_APP_PERMISSION" android:protectionLevel="normal" android:label="@string/custom_app_permission_label" android:description="@string/custom_app_permission_description" />
这里我们为自定义权限设置了正常级别的保护级别,表示该权限不需要用户授权,只需要在清单文件中声明即可。我们也为自定义权限提供了一个标签和一个描述,用来在设置中显示给用户。
- 在提供自定义权限的服务中,引用自定义权限:
<service android:name=".CustomAppService" android:permission="com.example.permission.CUSTOM_APP_PERMISSION"> <intent-filter> <action android:name="com.example.action.CUSTOM_APP_ACTION" /> </intent-filter> </service>
这里我们使用android:permission属性,告诉系统,只有具有该自定义权限的应用才能访问该服务。
- 在使用自定义权限的应用的清单文件中,引用自定义权限:
<uses-permission android:name="com.example.permission.CUSTOM_APP_PERMISSION" />
这里我们告诉系统,我们的应用需要使用该自定义权限。
如何在应用中使用自定义的应用权限
如果一个应用的开发者,可能想要使用一些自定义的应用权限,来实现一些特殊的功能或需求。要在应用中使用自定义的应用权限,需要:
- 在应用的清单文件中,使用标签,引用想要使用的自定义权限的名称。
- 在应用中,调用提供该自定义权限的服务或组件,使用Context.bindService()方法,绑定到该服务或组件,并获取其实例,并调用其方法。
例如,假设想在应用中使用上一节中定义的com.example.permission.CUSTOM_APP_PERMISSION权限,来访问CustomAppService服务,并调用其doSomething()方法。那么可以这样做:
- 在应用的清单文件中,引用该自定义权限:
<uses-permission android:name="com.example.permission.CUSTOM_APP_PERMISSION" />
这里我们告诉系统,我们的应用需要使用该自定义权限。
- 在应用中,调用提供该自定义权限的服务,并调用其方法:
public class CustomApp extends Activity { private ICustomAppService mCustomAppService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_custom_app); // Bind to the custom service Intent intent = new Intent("com.example.action.CUSTOM_APP_ACTION"); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // Get the custom service instance mCustomAppService = ICustomAppService.Stub.asInterface(service); // Call the custom service method try { mCustomAppService.doSomething(); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { // Unbind from the custom service mCustomAppService = null; } }; }
这里我们使用bindService()方法,根据服务的意图(这里是"com.example.action.CUSTOM_APP_ACTION"),绑定到服务,并传入一个服务连接对象。当服务连接成功时,我们获取服务的实例,并转换为接口类型。然后我们调用服务的方法,如果发生远程异常,我们捕获并处理它。当服务断开连接时,我们释放服务的实例。
权限的保护级别
Android权限的保护级别概述
Android权限的保护级别是一种属性,用来表示权限的风险程度和授权方式。Android提供了以下几种保护级别:
保护级别 | 描述 | 授权方式 | 示例 | 注意事项 |
正常 (normal) | 低风险,不涉及用户隐私或安全。 | 自动授权,仅需在AndroidManifest.xml 声明。 |
访问网络、设置壁纸。 | 无需运行时请求。 |
危险 (dangerous) | 涉及用户隐私或安全。 | 需要运行时用户授权。 | 使用相机、读取联系人。 | 从Android 6.0开始,需要运行时请求。 |
签名 (signature) | 仅相同签名的应用可用。 | 自动授权,但应用必须有相同的签名。 | 访问系统设置、使用指纹。 | 不同签名的应用无法使用此权限。 |
特殊 (special) | 仅系统应用或特定身份应用可用。 | 通常需要用户在设置中手动授予。 | 安装应用、重启设备。 | 普通应用通常无法使用,除非有特殊途径。 |
如何为自定义权限设置保护级别
当在Android系统或应用中自定义权限时,可以为自定义权限设置合适的保护级别,以便控制自定义权限的风险程度和授权方式。要为自定义权限设置保护级别,需要:
- 在自定义权限的声明中,使用android:protectionLevel属性,指定想要使用的保护级别。
- 根据选择的保护级别,遵循相应的规则和约束,例如是否需要用户授权、是否需要相同签名、是否需要特殊身份等。
例如,假设想为com.example.permission.CUSTOM_APP_PERMISSION权限设置正常级别的保护级别。那么可以这样做:
- 在自定义权限的声明中,指定正常级别的保护级别:
<permission android:name="com.example.permission.CUSTOM_APP_PERMISSION" android:protectionLevel="normal" android:label="@string/custom_app_permission_label" android:description="@string/custom_app_permission_description" />
这里我们使用android:protectionLevel属性,指定了正常级别(normal)作为我们自定义权限的保护级别。
- 遵循正常级别的规则和约束:
由于正常级别的权限不需要用户授权,所以我们只需要在清单文件中声明即可。我们不需要在运行时检查或请求该权限。我们也不需要担心签名或身份问题。
希望这篇文章能对您有所帮助。如果还有其他问题或建议,请留言与私信。