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编辑  收藏  举报

导航