Android 11 系统Settings代码移植
AndroidStudio 开发系统应用——Settings
第一步:准备工作:
1、AS开发环境
2、Settings二次开发的源码(android\packages\apps\Settings)
第二步:分析源码,创造AS项目
1、从Settings源码的 Android.bp(D:\android\packages\apps\Settings\Android.bp)分析依赖关系。
2、从Settings源码的 AndroidManifest.xml(D:\android\packages\apps\Settings\AndroidManifest.xml)得到项目包名。
3、创建AS项目,保留以下目录结构
├── app
│ ├── build.gradle
│ ├── libs
│ ├── proguard-rules.pro
│ └── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ └── android
│ │ └── settings
│ └── res
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
将Setting源码的AndroidManifest.xml,libs/,src/,res/下的源码移植到AS项目对应路径下。
因为Settings依赖了二十多个子模块,此时AS项目是编译不通过的,应先从Settings的子模块开始处理。
4、SettingsLib——Settings主要的依赖模块
分析SettingsLib源码的 Android.bp(D:\android\frameworks\base\packages\SettingsLib\Android.bp) 的依赖关系,从SettingsLib源码的 AndroidManifest.xml(D:\android\frameworks\base\packages\SettingsLib\AndroidManifest.xml) 得到模块包名,在AS项目创建SettingsLib模块,移植SettingsLib源码。
5、因为SettingsLib又依赖了14个子模块,继续分析各个模块的Android.bp和AndroidManifest.xml,AS项目创建14个子模块,移植源码。
6、提取依赖的本地jar包
//# Settings-core 模块依赖的的动态库列表 compileOnly files('../libs/unisoc_ims_common.jar')
libs: [
"unisoc_ims_common",
"telephony-common",
"ims-common",
"app-compat-annotations",
"unsupportedappusage",
"com.unisoc.sdk.common",
"radio_interactor_common",
"uniframework",
"unisoc_ims_common",
],
在out目录下搜索其关键字,可能会存在于下面两个位置
(1)out/target/common/obj/JAVA_LIBRARIES 目录下去搜索
(2)out/soong/.intermediates 目录下去搜索
framework.jar:(Z:\out\soong.intermediates\frameworks\base\framework\android_common\turbine-combined\framework.jar)
iconloader.jar:(Z:\out\soong.intermediates\frameworks\libs\systemui\iconloaderlib\iconloader\android_common\combined\iconloader.jar)
这个jar报找不到"com.android.launcher3.icons.IconFactory",使用iconloader.aar代替。
telephony-common:
在out目录下搜索其关键字字符串”telephony-common“,找到Z:\out\target\common\obj\JAVA_LIBRARIES\telephony-common_intermediates目录下的classes.jar,重命名成telephony-common.jar
ims-common
在out目录下搜索其关键字字符串”ims-common“,找到Z:\out\target\common\obj\JAVA_LIBRARIES\ims-common_intermediates目录下的classes.jar,重命名成ims-common.jar
unisoc_ims_common
在out目录下搜索其关键字字符串”unisoc_ims_common”,找到Z:\out\target\common\obj\JAVA_LIBRARIES\unisoc_ims_common_intermediates目录下的classes.jar,重命名成unisoc_ims_common.jar
app-compat-annotations
在out目录下搜索其关键字字符串”app-compat-annotations”,找到Z:\out\soong.intermediates\tools\platform-compat\java\android\compat\annotation\app-compat-annotations\android_common\turbine\app-compat-annotations.jar
** unsupportedappusage**
在out目录下搜索其关键字字符串”unsupportedappusage”,找到Z:\out\soong.intermediates\tools\platform-compat\java\android\compat\annotation\unsupportedappusage\android_common\turbine\unsupportedappusage.jar
com.unisoc.sdk.common
在out目录下搜索其关键字字符串”com.unisoc.sdk.common",找到
第三步:解决编译报错
1、Found item String/sdcard_unmount more than one time
:build.gradle目前尚不支持product属性,无法通过此属性来区分,所以出现资源重复,只能保留一项,
product="default",或者把product删除。
<string name="sdcard_unmount" product="nosdcard">Unmount USB storage</string>
<string name="sdcard_unmount" product="default">Unmount SD card</string>
2、The file name must end with .xml or .png
:删除0字节文件,用AS重新创建为XML文件。
3、找不到string/daltonizer_mode_deuteranomaly
:该资源在SettingsLib模块下,在Setting.app的build.gradle添加依赖
implementation project(':Settingslib')
4、错误:找不到符号 import android.content.IContentProvider;
:AS默认使用sdk中platforms里面的android.jar,这个jar包没有IContentProvider类,所以找不到。解决办法就是提高framework.jar的优先级,从源码framework.jar中查找。
5、错误:找不到资源sud_color_accent_light
error: resource color/sud_color_accent_light (aka com.android.settings:color/sud_color_accent_light) not found.
:在AS项目下查找关键字符串sud_color_accent_light,发现在setupdesign模块下,app依赖setupdesign模块
6、错误:找不到资源preferenceCategoryTitleTextColor
error: style attribute 'attr/preferenceCategoryTitleTextColor (aka com.android.settings:attr/preferenceCategoryTitleTextColor)' not found.
:这个属性在androidx.preference:preference:1.2.x以上版本才有,
方法一:升级API到1.2.0
方法二:Setting下res/values/attr.xml中添加一行代码
<attr format="reference" name="preferenceCategoryTitleTextColor"/>
7、
D:\ASworkspace\Settings\Setupdesign\src\main\java\com\google\android\setupdesign\span\LinkSpan.java:140: 错误: LinkSpan中的getId()无法覆盖ClickableSpan中的getId()
public String getId() {
^
返回类型String与int不兼容
:
8、
/home/szhou/Documents/note/Note-011_aosp_android-11-r39_settings/source_as/Settings/SettingsLibAdaptiveIcon/src/main/java/com/android/settingslib/widget/AdaptiveIcon.java:54: error: cannot find symbol
.getDimensionPixelSize(R.dimen.dashboard_tile_foreground_image_inset);
^
symbol: variable dashboard_tile_foreground_image_inset
location: class dimen
:查找关键字dashboard_tile_foreground_image_inset
szhou@bcsrv01:~/Documents/note/Note-011_aosp_android-11-r39_settings/source_as$ grep dashboard_tile_foreground_image_inset -rn .
./Settings/app/src/main/res/values/dimens.xml:120: <dimen name="dashboard_tile_foreground_image_inset">6dp</dimen>
此资源在app下,但通过import不能导入com.android.settings.R,因为settings.app模块的资源编译错误。应先解决Settings的资源错误
9、
D:\ASworkspace\Settings\Setupdesign\src\main\java\com\google\android\setupdesign\template\HeaderMixin.java:53: 错误: 找不到符号
.obtainStyledAttributes(attrs, R.styleable.SucHeaderMixin, defStyleAttr, 0);
^
符号: 变量 SucHeaderMixin
位置: 类 styleable
:搜索关键字SucHeaderMixin,此资源在Setupcompat模块下,依赖引入Setupcompat模块。
10、
D:\ASworkspace\Settings\SettingsLibLayoutPreference\src\main\java\com\android\settingslib\widget\LayoutPreference.java:104: 错误: 找不到符号
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Preference);
^
符号: 变量 styleable
位置: 类 R
:没编译通过,先解决资源报错。
11、
settings-logtags.jar error:com.android.tools.r8.internal.XI0: Absent Code attribute in method that is not native or abstract
:out下获取的jar错误,当前引入的jar中方法没有具体实现。使用正确的jar包:C:\out\soong.intermediates\packages\apps\Settings\settings-logtags\android_common\javac\settings-logtags.jar
12、
Caused by: java.lang.RuntimeException: Duplicate class android.hidl.base.V1_0.DebugInfo found in modules android.hardware.dumpstate-V1.1-java (android.hardware.dumpstate-V1.1-java.jar) and vendor.sprd.hardware.connmgr-V1.0-java (vendor.sprd.hardware.connmgr-V1.0-java.jar)
:jar包内android.hidl.base.V1_0.DebugInfo类重复,用压缩工具打开,删除重复的类
13、
D:\ASworkspace\Settings\Settingslib\src\main\java\com\android\settingslib\datetime\ZoneGetter.java:37: 错误: 程序包libcore.timezone不存在
import libcore.timezone.CountryTimeZones;
:out下搜索关键字“libcore”,导出libcore-xx.jar,只要它包含libcore.timezone.CountryTimeZones就行。
14、
error: no default product defined for resource com.android.settings:string/bluetooth_ask_enablement_and_lasting_discovery.
:项目中搜索关键字“bluetooth_ask_enablement_and_lasting_discovery”,得到
<string name="bluetooth_ask_enablement_and_lasting_discovery" product="tablet"><xliff:g id="app_name">%1$s</xliff:g> wants to turn on Bluetooth and make your tablet visible to other devices. You can change this later in Bluetooth settings.</string>
将 product="tablet"改成 product="default",也可以把product字段删除
15、
AGPBI: {"kind":"error","text":"Duplicate resources","sources":[
{"file":{"description":"layout/fingerprint_enroll_find_sensor","path":"D:\\ASworkspace\\Settings\\app\\src\\main\\res\\values\\aliases.xml"}},
{"file":{"description":"layout/fingerprint_enroll_find_sensor","path":"D:\\ASworkspace\\Settings\\app\\src\\main\\res_unisoc\\layout\\fingerprint_enroll_find_sensor.xml"}}
],"tool":"Resource and asset merger"}
:
16:
D:\ASworkspace\Settings\app\src\main\res_unisoc\values\strings.xml:342:5-346:20: AAPT: error: resource android:string/wfc_mode_ims_preferred_summary not found.
: 在源码中查找,frameworks\base\core\res\res\values下,这个是要直接贴过来吗?***
17、
D:\ASworkspace\Settings\app\src\main\res\layout-sw600dp\crypt_keeper_pattern_entry.xml:28: AAPT: error: resource dimen/crypt_keeper_pattern_separator (aka com.android.settings:dimen/crypt_keeper_pattern_separator) not found.
把前面删除的values添加回来
18、
Type com.android.settingslib.widget.BuildConfig is defined multiple times: D:\ASworkspace\Settings\SettingsLibAdaptiveIcon\build\.transforms\81accb8d2801b2e33f1f0ef5a7373e3c\classes\classes.dex, D:\ASworkspace\Settings\SettingsLibHelpUtils\build\.transforms\8bfc3e6d2c4f7428982822946ac79cb6\classes\classes.dex
19、找不到androidx.slice.widget.SliceView
Unable to start activity ComponentInfo{com.android.settings/com.android.settings.SubSettings}: android.view.InflateException: Binary XML file line #23: Error inflating class com.android.settings.slices.SlicePreference
Caused by: android.view.InflateException: Binary XML file line #18 in com.android.settings:layout/slice_preference_layout: Binary XML file line #18 in com.android.settings:layout/slice_preference_layout: Error inflating class androidx.slice.widget.SliceView
:SDK编译版本的问题,compileSdk 32改成compileSdk 30
20、Android Studio Entry name *.xml collided解决方案
:检查build下自动生成的debug.apk,AS自动生成的和我们手动生成的包冲突
21、编译报错
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.android.launcher3.icons.IconFactory"
::使用的iconloaderlib.jar错误。替换成iconloaderlib.aar
第四步:系统签名
生成系统签名文件:
原因:生成签名文件jks,直接放在AS里面,生成apk时候就已经是系统签名。这个时候直接install安装或者直接放到系统源码里面编译都行的。
前提条件:
工具:OpenSSL + KeyTool(jdk自带)
厂商提供的:platform.pk8 platform.x509.pem
一共分三步:
(1)命令生成临时文件platform.pem
openssl pkcs8 -inform DER -nocrypt -in D:\sign\platform.pk8 -out D:\sign\platform.pem
(2)生成platform.p12文件,它本质上应该就是一个数字证书
openssl pkcs12 -export -in D:\sign\platform.x509.pem -out D:\sign\platform.p12 -inkey D:\sign\platform.pem -password pass:superred2022 -name superred
其中superred 为alias名(app添加签名要用到),superred2022 为密码
(3) 生成签名文件 platform.jks
keytool -importkeystore -deststorepass superred2022 -destkeystore D:\sign\platform.jks -srckeystore D:\sign\platform.p12 -srcstoretype PKCS12 -srcstorepass superred2022
正在将密钥库 D:\sign\platform.p12 导入到 D:\sign\platform.jks...
已成功导入别名 superred 的条目。
已完成导入命令: 1 个条目成功导入, 0 个条目失败或取消
Warning:
<superred> 使用的 MD5withRSA 签名算法被视为存在安全风险而且被禁用。
JKS 密钥库使用专用格式。建议使用 "keytool -importkeystore -srckeystore D:\sign\platform.jks -destkeystore D:\sign\platform.jks -deststoretype pkcs12" 迁移到行业标准格式 PKCS12。
生成platform.jks (app打签名最终用到的文件),其中-srcstorepass superred2022设置的是这个签名的密码
第五步:编译打包
1、app/build.gradle 配置系统签名文件,使用AS打包生成apk,此时的apk已经是系统签名,可以直接 adb install 。
android{
signingConfigs {
debug {
storeFile file('D:\\sign\\platform.jks')
storePassword 'superred2022'
keyAlias 'superred'
keyPassword 'superred2022'
}
release {
storeFile file('D:\\sign\\platform.jks')
storePassword 'superred2022'
keyAlias 'superred'
keyPassword 'superred2022'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
}
2、命令安装Settings.apk
adb root
adb remount
adb shell
cd system_ext/priv-app/Settings
rm -rf *
adb push D:\ASworkspace\Settings\app\build\outputs\apk\debug\Settings.apk system_ext/priv-app/Settings/
adb reboot
posted on 2023-07-06 11:13 EthanDong 阅读(1801) 评论(0) 编辑 收藏 举报