Android13 系统签名应用编译调试说明
Android13 系统签名应用编译调试说明
文章目录
- Android13 系统签名应用编译调试说明
- 一、前言
- 二、系统签名应用调试步骤
- 1、新建一个应用,确保可以正常编译出APK
- 2、获取系统签名文件
- 3、Android Studio 编译安装系统权限应用
- (1)导入签名文件生成apk安装验证
- (2)AndroidManifest中添加
- 4、添加系统的Jar包
- (1)编译framework 的Jar包
- (2)添加SettingsLib 的Jar包
- (3)app\build.gradle中导入依赖的包
- (4)app\build.gradle添加framework中特殊声明
- 三、其他
- 1、Android Studio系统签名应用编译调试小结
- 2、系统Jar包适配
- (1)framework jar包
- ① 大概配置:Android Studio新版本 + Gradle8.7 + 编译版本34 + JDK8
- ②导入的Android14 的framework.jar,但是Gradle版本是6.5 会编译报错:
- ③Android Studio 配置SDK33和配置Android14 的framework.jar包,运行报错
- (2)SettingsLib jar包
- 删除无费用的包
- 3、如何查看安装的应用是否是系统应用
一、前言
Android11之前一直可以用系统的签名文件编译系统签名apk,
但是开发Android13 的系统应用后,就有点问题了,
发现使用系统签名文件编译的系统签名apk安装到设备上会失败,
以为搞不了了,但是看到有的同事是OK的,等了一段时间后分析处理了。
本文记录一下这种系统签名应用调试的过程。
我之前安装的Android Studio 版本是2021年的,Android Gradle 版本是6.5;
后面发现安装2024年的Android Studio,并且使用Gradle8.7 就ok,
可以正常打包Android13 或者更新版本的系统签名apk了。
二、系统签名应用调试步骤
1、新建一个应用,确保可以正常编译出APK
这个是确保当前系统SDK、JDK、Gradle环境与Android Studio是否匹配;
只有环境ok才能继续下一步。
2、获取系统签名文件
从源码中获取签名文件步骤:
https://blog.csdn.net/wenzhi20102321/article/details/134898404
配置签名文件的账户,密码后会生成 platform.jks系统签名文件。
并不是所有源码都可以生成签名文件,有些是被供应商加密处理的,如果不行可以咨询供应商了解。
生成的platform.jks系统签名文件就可以导入到Android Studio进行签名处理。
3、Android Studio 编译安装系统权限应用
(1)导入签名文件生成apk安装验证
查看是否可以正常编译出APK并且是否可以正常安装到运行的设备;
能编译出apk说明,签名文件的账号和密码是匹配签名文件的;
如果账号和密码不匹配签名文件是无法编译出apk的;
jks文件放到app目录下,然后配置一下签名文件的信息:
app\build.gradle
android {
buildToolsVersion "33.0.0"
compileSdkVersion 33
defaultConfig {
applicationId "com.demo.android14demo"
minSdkVersion 30
targetSdkVersion 33
versionCode 1
versionName "1.0"
}
//系统签名文件配置----stat
signingConfigs {
println "---------------------signingConfigs"
main {
storeFile file("./platform.jks") //签名文件路径,根目录
storePassword "skg202302p"
keyAlias "skg"
keyPassword "skg202302p"
}
}
buildTypes {
println "---------------------buildTypes"
release {
println "release start"
minifyEnabled false
signingConfig signingConfigs.main //添加这一行
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
println "release end"
}
debug {
println "debug"
minifyEnabled false
signingConfig signingConfigs.main //添加这一行
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//系统签名文件配置----end
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
中间那段代码就是配置打包系统签名到apk的代码。
但是要注意,普通签名的apk也是可以直接安装的,只是没有系统权限而已;
所以要成为系统签名的应用,还有添加uid的权限。
(2)AndroidManifest中添加
android:sharedUserId="android.uid.system"
如果导入签名文件,并且设置uid可以,生成apk并且安装到设备,
说明已经成功的把系统签名应用编译运行到设备上了。
后面就可以进行系统权限代码的相关逻辑调用了。
4、添加系统的Jar包
添加系统代码开发需要的JAR包,
比如framework、SettingsLib、一些三方或者自定义的JAR包
导入系统jar包的作用:
导入framework :
是为了调用一些系统类/方法,比如 SystemProperties 或者热点设置相关的方法;
还有就是开发中对于系统原生类添加的类或者新接口,需要使用。
导入SettingsLib:
是为了调用一些 SettingsLib 封装的方法,
比如wifi、蓝牙的很多逻辑在 SettingsLib 都是有比较完善的封装处理可以直接拿来用,
原生Settings 里面非常多的逻辑都是使用了SettingsLib的。
(1)编译framework 的Jar包
//编译framework jar包的命令
make -j64 framework
//framework jar生成的目录
release\out\target\common\obj\java_libraries\framework_intermediates\classes.jar
(2)添加SettingsLib 的Jar包
//编译 SettingsLib jar包的命令
make -j64 SettingsLib
//SettingsLib jar生成的目录
release\out\target\common\obj\java_libraries\settingslib_intermediates\classes.jar
上面的classes.jar包修改一下命名后,复制到Studio的libs目录
(3)app\build.gradle中导入依赖的包
dependencies {
//这个是旧版本Gradle的依赖,新版本是兼容的
//implementation 'androidx.appcompat:appcompat:1.3.1'
//新版本的版本管理是统一在 Demo\gradle\libs.versions.toml
implementation libs.appcompat
implementation libs.material
implementation libs.activity
implementation libs.constraintlayout
//导入framework和SettingsLib包
implementation files('libs\\framework.jar')
implementation files('libs\\SettingsLib.jar')
}
如果未导入framework 包,有些系统的类就无法识别,比如 SystemProperties
会报错:
import android.os.SystemProperties; //Cannot resolve symbol 'SystemProperties'
(4)app\build.gradle添加framework中特殊声明
添加配置的代码如下:
dependencies { }
//dependencies 下方配置 framework
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
Set<File> fileSet = options.bootstrapClasspath.getFiles()
List<File> newFileList = new ArrayList<>();
//"../framework.jar" 为相对位置,需要参照着修改,或者用绝对位置
newFileList.add(new File("libs/framework.jar"))
newFileList.addAll(fileSet)
options.bootstrapClasspath = files(newFileList.toArray())
}
}
配置上面的代码说明优先从framework.jar 的代码中获取相关的类;
否则只从Studio SDK版本中获取到的类,会导致很多方法和内部类无法调用。
如果未配置上面的 framework ,会造成下面常见影响:
import static android.net.wifi.WifiManager.WIFI_AP_STATE_CHANGED_ACTION; // WIFI_AP_STATE_CHANGED_ACTION 无法识别
//获取热点配置,找不到 getSoftApConfiguration()方法
SoftApConfiguration softApConfiguration = wifiManager.getSoftApConfiguration();
上面只是举例的一部分,还有些不常用的Java类,
所以最好导入framework.jar后再添加framework的声明,防止造成系统代码报错。
到这里Android Studio系统签名应用的配置大致完成了。
其实上面只是分析和操作的大致步骤,实际开发中可能还会有其他问题;
比如jar包兼容性问题。jar包兼容性问题只能一个个包的排查,替换成不会造成兼容的jar包。
后面有介绍framework.jar 和 SettingsLib.jar兼容问题的处理参考。
可以不同的项目方案有所差别,所以仅供参考。
三、其他
1、Android Studio系统签名应用编译调试小结
大致步骤:
1、新建一个应用,确保可以正常编译出APK
2、源码中获取系统签名文件
3、Android Studio 编译安装系统权限应用查看是否成功
4、添加系统的Jar包
上面三步OK,证明运行环境和系统签名证书匹配的。
最好使用比较新的Gradle版本,我之前就是使用Gradle6.5 一直无法正常生成系统签名应用,换成最新的Gradle8.7就OK了。
上面的调试步骤,我为啥把添加jar包放在最后,
是因为对于复杂的系统应用来说第4步才是最麻烦的,比如导入SettingsLib包会报很多错误。
下面讲一下导入framework和SettingsLib 的简单经验。
2、系统Jar包适配
后面验证发现关联的情况很多,比如AndroidStudio版本,选择的SDK版本,Gradle版本,具体的Gradle配置,运行的系统环境等等都要有影响。
不同系统环境可能有所差异,这里仅供参考。
(1)framework jar包
下面是一些情况的验证测试情况,
① 大概配置:Android Studio新版本 + Gradle8.7 + 编译版本34 + JDK8
311D2 Android14 的 framework的jar包,不需要适配就可以直接导入使用。
9679 Android14的 framework的jar包,不会编译报错,但是会运行一会后崩溃。
刚开始我以为是系统环境问题,但是后面发现是jar包问题,
因为9679方案的framework.jar 编译的apk 安装在311D2方案的设备上也会有这个问题;
所以有的方案的framework的jar会有兼容性问题!
估计是供应商有修改适配framework代码有关系。
报错如下:
部分日志如下:
2024-12-18 20:41:56.792 25793-25891 AndroidRuntime com.example.android14 E FATAL EXCEPTION: pool-2-thread-1
Process: com.example.android14, PID: 25793
java.lang.IncompatibleClassChangeError: Class 'android.app.PendingIntent$$ExternalSyntheticLambda0'
does not implement interface 'java.util.concurrent.Executor'
in call to 'void java.util.concurrent.Executor.execute(java.lang.Runnable)'
(declaration of 'androidx.profileinstaller.DeviceProfileWriter'
appears in /data/app/~~SM7I1l6Vc5y6uQofWqnX2w==/com.example.android14-yUgXUvcu7KYWoFgznszrLQ==/base.apk!classes6.dex)
at androidx.profileinstaller.DeviceProfileWriter.result(DeviceProfileWriter.java:87)
at androidx.profileinstaller.DeviceProfileWriter.deviceAllowsProfileInstallerAotWrites(DeviceProfileWriter.java:119)
at androidx.profileinstaller.ProfileInstaller.transcodeAndWrite(ProfileInstaller.java:440)
at androidx.profileinstaller.ProfileInstaller.writeProfile(ProfileInstaller.java:575)
at androidx.profileinstaller.ProfileInstaller.writeProfile(ProfileInstaller.java:515)
at androidx.profileinstaller.ProfileInstaller.writeProfile(ProfileInstaller.java:479)
at androidx.profileinstaller.ProfileInstallerInitializer.lambda$writeInBackground$2(ProfileInstallerInitializer.java:145)
at androidx.profileinstaller.ProfileInstallerInitializer$$ExternalSyntheticLambda2.run(D8$$SyntheticClass:0)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at java.lang.Thread.run(Thread.java:1012)
---------------------------- PROCESS ENDED (25793) for package com.example.android14 ----------------------------
主要报错是:
IncompatibleClassChangeError:
Class 'android.app.PendingIntent$$ExternalSyntheticLambda0'
does not implement interface 'java.util.concurrent.Executor'
in call to 'void java.util.concurrent.Executor.execute(java.lang.Runnable)'
(declaration of 'androidx.profileinstaller.DeviceProfileWriter'
但是好像看不出啥,不好解决啊。
只能看出 android.app.PendingIntent 的代码有问题,
还有 重复定义的 androidx.profileinstaller.DeviceProfileWriter;
其实Jar包可以删除里面的东西。
我最后的处理是删除了报错的地方:
我最后的处理是 删除了jar包里面的android下面的app 整个目录。
发现是OK的。
其实这个是瞎试的,反正jar包可以多备份一个,删错了恢复回来就行。
②导入的Android14 的framework.jar,但是Gradle版本是6.5 会编译报错:
Unsupported class file major version 61
Java 17 对应的类文件主版本号是 61。
所以当出现 “Unsupported class file major version 61” 提示时,
大概率是你当前运行代码的环境(比如 JRE)所支持的 Java 版本低于 Java 17,
导致其无法识别这个用 Java 17 编译出来的类文件。
我目前的Java环境是1.8,也就是Java8,有可能更新JDK可以解决这个问题;
但是不想搞了,比较麻烦。
首先使用新的Gradle版本尝试吧,不行再更新JDK版本;我是用Gradle8.7就OK了的。
③Android Studio 配置SDK33和配置Android14 的framework.jar包,运行报错
编译出apk,但是运行报错:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.demo.android14demo/com.demo.android14demo.MainActivity}:
java.lang.ClassNotFoundException: Didn't find class "com.demo.android14demo.MainActivity"
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3693)
。。。
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.demo.android14demo.MainActivity"
on path: DexPathList[[zip file "/data/app/~~hsBPlkD_QBZzxoDWdGBYVg==/com.demo.android14demo-ZynohvbL1ZaBZUvw2iu5hA==/base.apk"],
nativeLibraryDirectories=[/data/app/~~hsBPlkD_QBZzxoDWdGBYVg==/com.demo.android14demo-ZynohvbL1ZaBZUvw2iu5hA==/lib/arm64, /system/lib64, /system_ext/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
。。。
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)
Suppressed: java.io.IOException: Failed to open dex files from
/data/app/~~hsBPlkD_QBZzxoDWdGBYVg==/com.demo.android14demo-ZynohvbL1ZaBZUvw2iu5hA==/base.apk
because: Failure to verify dex file '/data/app/~~hsBPlkD_QBZzxoDWdGBYVg==/com.demo.android14demo-ZynohvbL1ZaBZUvw2iu5hA==/base.apk':
Method 2285(Landroid/animation/PropertyValuesHolder;.-$$Nest$smnCallFloatMethod) has code, but is marked native or abstract
at dalvik.system.DexFile.openDexFileNative(Native Method)
这里看出看出framework 的jar包导入需要注意:
不同源码环境的framework.jar 可能会有差异;
导入的framework.jar 的Android版本要和运行环境的版本一致,否则会运行报错;
Gradle 版本可能也会有影响
肯定还有其他差异,或者其他情况,报的错误可能也不同
比如Gradle版本,JDK版本,这里无法一一进行验证测试。
(2)SettingsLib jar包
SettingsLib.jar 就比较好适配了,就是嘎嘎嘎一段删就行。
SettingsLib.jar 无论是哪个方案都是要处理的。
编译就报错,报错太多了,就不一一展示了。
主要处理如下:
删除无费用的包
只留下com.android下面的包就行,其实有用的就是下面的settinngslib包而已。
如果没有Beyond Compare工具,使用普通的解压包工具打开jar包后直接删除里面的文件也是OK的。
3、如何查看安装的应用是否是系统应用
方法有很多,比如运行环境下,
dumpsys package XXX 查看appid的信息
如果是uid签名的系统应用,appid=1000