孟村县网站建设,工厂视频网站建设,代理网关app未运行怎么办,创建蛋糕网站建设方案Android 应用添加系统签名权限的几种方式实现介绍 文章目录 Android 应用添加系统签名权限的几种方式实现介绍一、前言二、Android 应用添加系统签名权限的几种方式介绍1、在Android Studio添加系统签名文件2、源码编译apk添加系统签名Android.mkAndroid.bp 3、源码编译app代码…Android 应用添加系统签名权限的几种方式实现介绍 文章目录 Android 应用添加系统签名权限的几种方式实现介绍一、前言二、Android 应用添加系统签名权限的几种方式介绍1、在Android Studio添加系统签名文件2、源码编译apk添加系统签名Android.mkAndroid.bp 3、源码编译app代码添加系统签名Android.mkAndroid.bp 三、缺少系统权限报错示例1、设置Settings属性报错2、设置Wifi开关状态失败3、Settings属性设置为啥需要系统权限4、设置Wifi开关状态为啥失败 四、其他1、系统权限介绍1普通权限normal2运行时权限dangerous3签名权限signature4特殊权限privileged 2、如何查看一个应用的权限情况3、系统权限级别总结Android中不同应用权限级别从低到高总结场景 4、Android APEX系统新篇章的应用扁平化技术 一、前言
Android 应用添加系统签名就能获取到系统权限调用一些系统接口
添加系统签名的方式主要包括
在Android Studio中配置签名文件生成apk 和 在源码目录编译添加系统签名生成apk。
本文介绍的都是一些基础的签名知识后续延伸介绍相关权限内容。有兴趣的可以进行了解。
二、Android 应用添加系统签名权限的几种方式介绍
1、在Android Studio添加系统签名文件
源码中生成 jks 签名文件
https://blog.csdn.net/wenzhi20102321/article/details/134898404
Studio 在对应需要签名的module默认是app的build.gradle中添加如下代码
android {compileSdkVersion 30buildToolsVersion 30.0.0compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}
。。。//证书信息在这里配置signingConfigs {main {storeFile file(./platform.jks) //签名文件路径根目录storePassword skg202302keyAlias skgkeyPassword skg202302}}buildTypes {release {minifyEnabled falsesigningConfig signingConfigs.main //添加这一行proguardFiles getDefaultProguardFile(proguard-android.txt), proguard-rules.pro}debug {minifyEnabled falsesigningConfig signingConfigs.main //添加这一行proguardFiles getDefaultProguardFile(proguard-android.txt), proguard-rules.pro}}}只是添加了系统签名是不行的还需要在AndroidManifest.xml中声明系统权限
AndroidManifest.xml 配置uid系统权限
manifest xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:toolshttp://schemas.android.com/toolscoreApptruepackagecom.xxx.xxxandroid:sharedUserIdandroid.uid.system2、源码编译apk添加系统签名
如果apk没有签名文件和为添加签名信息那么添加uid.system后该应用是无法安装到对应系统上的
如果要安装可以在源码里面编译生成的apk就会加入签名的信息的。
Android.mk
# 编译的目录默认写法
include $(CLEAR_VARS)# 设置模块名
LOCAL_MODULE : mymodule# 设置预构建文件的源路径和目标路径
LOCAL_SRC_FILES : path/file.apk# 设置系统权限和目录
LOCAL_CERTIFICATE : platform
LOCAL_PRIVATE_PLATFORM_APIS : true
# 设置是否编译在 priv-app,如果没有指定目录默认为 system/priv-app
LOCAL_PRIVILEGED_MODULE : true include $(BUILD_PREBUILT)
Android.bp
android_app_import {name: FileManager,apk: FileManager.apk,//生成到priv-app目录下privileged: true,//使用系统签名certificate: platform,
}
3、源码编译app代码添加系统签名
Android.mk
LOCAL_PATH : $(call my-dir)
include $(CLEAR_VARS)# 设置模块名为myapp
LOCAL_MODULE : myapp
# 添加需要编译的Java源文件
LOCAL_SRC_FILES : $(wildcard *.java)
# 添加需要编译的资源文件
LOCAL_RESOURCE_DIR : $(LOCAL_PATH)/res
# 设置输出APK的路径和名称
LOCAL_PACKAGE_NAME : myapp# 设置系统权限和目录
LOCAL_CERTIFICATE : platform
LOCAL_PRIVATE_PLATFORM_APIS : true
# 设置是否编译在 priv-app,如果没有指定目录默认为 system/app
LOCAL_PRIVILEGED_MODULE : true include $(BUILD_PACKAGE)Android.bp
android_app {name: myapp,srcs: [path/to/your/app/src/**/*.java,],resource_dirs: [path/to/your/app/res,],manifest: path/to/your/app/AndroidManifest.xml,//加载类库static_libs: [mylibrary,],//是否系统签名certificate: platform,platform_apis: true,//是否生成到priv-app目录privileged: true,}上面是代码的情况编译apk获取系统签名的
Android13或者更新的源代码大多都是使用Android.bp进行编译。
上面就是本文的主要内容下面是一些相关内容知识。
三、缺少系统权限报错示例
这里以Settings设置属性为示例讲解。
Settings属性获取是不需要权限的Settings属性设置是需要权限的为啥会这样
其实是因为代码里面定义的具体是哪个类的哪行代码限制的有兴趣的可以往下看看
//Settings 获取属性值不用权限和签名
int value Settings.Global.getInt(getContentResolver(), Settings.Global.WIFI_ON, -1);//Settings 设置属性值需要系统签名或者系统权限否则会异常
boolean value Settings.Global.putInt(getContentResolver(), Settings.Global.WIFI_ON, 1);//Wifi开关控制需要系统签名或者系统权限否则返回false但是不会异常
WifiManager wifiManager (WifiManager) getSystemService(Context.WIFI_SERVICE);
boolean value wifiManager.setWifiEnabled(true);1、设置Settings属性报错
设置wifi开关状态报错 Caused by: java.lang.SecurityException: Permission denial: writing to settings requires:android.permission.WRITE_SECURE_SETTINGSat android.os.Parcel.createExceptionOrNull(Parcel.java:3011)at android.os.Parcel.createException(Parcel.java:2995)at android.os.Parcel.readException(Parcel.java:2978)at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:190)at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)at android.content.ContentProviderProxy.call(ContentProviderNative.java:732)at android.provider.Settings$NameValueCache.putStringForUser(Settings.java:3021)at android.provider.Settings$Global.putStringForUser(Settings.java:16753)at android.provider.Settings$Global.putString(Settings.java:16594)at android.provider.Settings$Global.putInt(Settings.java:16824)at com.demo.systemapp.MainActivity.setSettingsValue(MainActivity.java:29)at java.lang.reflect.Method.invoke(Native Method) 从报错日志看是缺少了权限WRITE_SECURE_SETTINGS。这个权限是需要签名或者系统应用才能拥有的权限。
如果要规避应用崩溃可以通过try {}catch捕获异常避免崩溃。
2、设置Wifi开关状态失败
调用wifi开关接口日志
2024-01-20 17:09:04.193 638-1052/system_process I/WifiService: setWifiEnabled packageName com.demo.systemapp, enable true
2024-01-20 17:09:04.195 638-1052/system_process I/WifiService: setWifiEnabled not allowed for uid10084上面的日志都是 WifiServiceImpl.java 里面的日志。
显示了是哪个应用调用了wifi开关的什么状态后续显示not allowed 因为uid 100084相当于啥都没做。
这种情况没有报错也不会崩溃但是就是调用了没效果。
所以大概可以猜测出需要设置Settings属性或者调用Wifi开关状态的接口都是要系统权限或者系统签名。
3、Settings属性设置为啥需要系统权限
看看代码就知道了
frameworks\base\core\java\android\provider\Settings.java
//Settings.XXX.Put属性需要权限的原因代码这里定义了的。
SystemApi
RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
public static boolean putString(ContentResolver resolver,String name,String value,。。。){return putStringForUser(resolver, name, value, tag, makeDefault,resolver.getUserId(), DEFAULT_OVERRIDEABLE_BY_RESTORE);
}代码这里已经声明了必须要系统应用和 WRITE_SECURE_SETTINGS权限
才能调用后续的put方法所以未获取到权限就会抛出异常。
4、设置Wifi开关状态为啥失败
根据下面代码的具体判断就可以看得出
packages\modules\Wifi\service\java\com\android\server\wifi\WifiServiceImpl.java
//WifiManager.setWifiEnabled 失败原因这里判断后返回了false
public synchronized boolean setWifiEnabled(String packageName, boolean enable) {//这里判断的是三方应用主要是uid三方应用不具有系统签名所以返回false不往下走if (isThirdParty !isTargetSdkLessThanQ) {mLog.info(setWifiEnabled not allowed for uid%).c(callingUid).flush();return false;}//这里判断是否是飞行模式并且是否不是系统应用priv-app目录下的应用//如果是飞行模式并且不是priv-app目录的系统应用返回false// If Airplane mode is enabled, only privileged apps are allowed to toggle Wifiif (mSettingsStore.isAirplaneModeOn() !isPrivileged) {mLog.err(setWifiEnabled in Airplane mode: only Settings can toggle wifi).flush();return false;}//如果不是priv-app目录应用并且热点开启的情况返回false// If SoftAp is enabled, only privileged apps are allowed to toggle wifiif (!isPrivileged mTetheredSoftApTracker.getState() WIFI_AP_STATE_ENABLED) {mLog.err(setWifiEnabled with SoftAp enabled: only Settings can toggle wifi).flush();return false;}...
}上面是Android13 中wifi开关状态返回false的几种情况分析。
四、其他
1、系统权限介绍
framework 定义的所有 权限都是有定义包含 protectionLevel 等级的主要权限等级有普通运行时系统签名特殊 。
1普通权限normal
此类权限允许访问超出应用沙盒的数据和执行超出应用沙盒的操作。但这些数据和操作对用户隐私及对其他应用的操作带来的风险非常小。
比如上网权限wifi 状态监听蓝牙获取后台任务等待大概有一百多个。
2运行时权限dangerous
运行时权限也称为危险权限此类权限授予应用对受限数据的额外访问权限并允许应用执行对系统和其他应用具有更严重影响的受限操作。因此需要先在应用中请求运行时权限然后才能访问受限数据或执行受限操作。当应用请求运行时权限时系统会显示运行时权限弹窗提示。
比如文件读写权限日历读取和设置权限等待总共不到一百个。
3签名权限signature
当应用声明了其他应用已定义的签名权限时如果两个应用使用同一证书进行签名系统会在安装时向前者授予该权限。否则系统无法向前者授予该权限。注意有些签名权限不适合第三方应用使用。
该权限只需要在manifest中声明使用同时应用和这类权限定义者拥有一样的签名系统就会默认授予应用这类权限系统授予这类权限后应用无需像运行时权限一样动态申请。
比如Android11 新增的文件管理权限对wifi热点Camera一些特殊操作权限比较多大概有五百多个。
4特殊权限privileged
特殊权限与特定的应用操作相对应。只有平台和原始设备制造商 (OEM) 可以定义特殊权限。此外如果平台和 OEM 想要防止有人执行功能特别强大的操作例如通过其他应用绘图通常会定义特殊权限。系统设置中的特殊应用访问权限页面包含一组用户可切换的操作。其中的许多操作都以特殊权限的形式实现。每项特殊权限都有自己的实现细节。系统会为特殊权限分配“appop”保护级别。
比如本文的 允许应用程序在所有用户之间进行交互 权限启动前台服务权限可通过overlay形式覆盖属性权限应用主题更改监听等等大概有三百多个。
一般情况下特殊权限大部分与系统签名文件同时使用。
我们常用的广播都定义在framework\base\core\res\AndroidManifest.xml里面如果要新增可以在里面新增
值得注意的是系统签名文件是比系统应用权限大的比如 //MANAGE_CAMERA 权限必须要系统签名才能获取到permission android:nameandroid.permission.MANAGE_CAMERAandroid:protectionLevelsignature ///CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS 权限系统签名或者priv-app应用都可以获取到permission android:nameandroid.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONSandroid:protectionLevelsignature|privileged /上面的是 Android13 上比较新的权限定义有兴趣的可以看看。
在线查看权限定义网址
http://aospxref.com/android-13.0.0_r3/xref/frameworks/base/core/res/AndroidManifest.xml
2、如何查看一个应用的权限情况
dumpsys package XXX包名可以查看apk信息
E:\Studio\project\test\SystemAppadb shell
rk3588_t:/ $ ^C
130|rk3588_t:/ $ dumpsys package com.demo.systemappPackages:Package [com.demo.systemapp] (6e1e98c): //1、应用包名userId10083 //uidsystem.uid 10000pkgPackage{1a148d5 com.demo.systemapp}codePath/system/app/SystemAppDemo //2、apk路径resourcePath/system/app/SystemAppDemotimeStamp2024-01-20 11:45:31lastUpdateTime2024-01-20 11:45:31requested permissions: //3、AndroidManifest中声明的权限android.permission.WRITE_SECURE_SETTINGSandroid.permission.POST_NOTIFICATIONSUser 0: ceDataInode9991 installedtrue hiddenfalse suspendedfalse distractionFlags0 stoppedfalse notLaunchedfalse enabled0 instantfalse virtualfalseinstallReason0firstInstallTime2024-01-20 11:45:31uninstallReason0runtime permissions: //4、获取到的权限grantedtrue 才算获取到android.permission.POST_NOTIFICATIONS: grantedfalse, flags[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]rk3588_t:/ $
E:\Studio\project\test\SystemApp从dumpsys package XXX 命令的日志可以看到包名应用对应的Uid信息版本信息apk安装位置安装时间AndroidManifest声明的权限实际获取到的权限等等信息。
requested permissions 下面的权限是应用声明的权限runtime permissions的权限是当前获取到的权限。
值得注意的是即使是系统应用或者系统签名应用也是要在 AndroidManifest 中声明需要的权限。
3、系统权限级别总结
Android中不同应用权限级别从低到高总结场景
1普通应用。只用到了普通权限比如上网权限等等。
2system/app 系统应用用来可以限制无法手动卸载对系统权限没有要求的情况无法调用系统api
3system/priv-app 系统应用未设置uid.system无法手动卸载可以调用部分系统api
4系统签名应用普通安装的方式可以调用系统相关api同时也可以被手动卸载,可以添加privileged特殊权限
5system/priv-app 系统应用设置uid.system无法手动卸载可以调用全部系统api可以添加privileged特殊权限了解到不同的权限需求应用要安装/编译在什么目录心里就有个底了。
4、Android APEX系统新篇章的应用扁平化技术
Android13 和更新的版本编译你会发现package/modules下面的代码模块都是编译到了目录 /system/apex/XXXPackage/XXX.apk
这里面的apk有些是系统签名应用有些是普通应用这个和具体的bp里面的编译规则相关。
APEX 的相关介绍
https://blog.csdn.net/u011897062/article/details/133122565
https://blog.csdn.net/u010164190/article/details/122324409
这块知识看起来还是比较复杂。
对于普通应用开发者和一般的系统应用开发者其实没啥研究价值。
可以简单的理解一下模块化的概念比如把一个apk的某些模块编译成一个apk这些模块可以接收广播处理事务或者启动服务处理事务等功能。
这个和应用开发中的模块化是同样的原理只是源码中Android13 以前很少这样开发后续更新的源码应该是会更多这样的模块。