在 aosp 中启用 Material You design

由于项目原因,近期研究了一下如何在 aosp 中启用 Material You design,在把踩过的坑记录一下,方便后续有厂商可以快速集成。

本文基于 aosp 最新代码,版本号为 Android 13,并使用 Cuttlefish 快速验证。

Material You design 是什么

Material You design 是 Google 2021年5月18日宣布的最新视觉设计风格,我经常把它简单描述成"你一眼看上去那种扁扁的,彩色的,都是矢量图形的风格",下面这张图大家看一眼就明白了。

Google 对自己的这套视觉风格一直很自信。这套主题最大的特点就是,它有一个"主题色"的概念。用户选择了一个主题色之后,系统里的大部分控件,只要应用了这套主题,颜色都会跟着变成这个主题色。而除了应用,框架里比如 SystemUI 这样的模块,由于也应用了这套主题,因此也会跟着主题色走。

aosp 在 2021年8月也导入了这套主题,但不知道为什么一直没有默认启用,这篇文章就教大家如何启用。

在框架中启用 Material You design

配置 SystemUI

打开 frameworks/base/packages/SystemUI/res/values/flags.xml,确保 flag_monet值为 true。这一点 aosp 最新版本现在默认值已经为 true 了,作为厂商可以二次确认一下,防止编译时被 overlay 了。

ThemePicker 配置权限

Google 把 Pixel 的壁纸选择器脱敏之后,开源在了 packages/apps/ThemePicker,但是他们似乎把权限配置文件忘记开源了,如果我们直接把 ThemePicker 编进系统,开机之后 system_server 会一直报错如下:

javascript 复制代码
 java.lang.IllegalStateException: Signature|privileged permissions not in privapp-permissions allowlist: {com.android.wallpaper (/system_ext/priv-app/ThemePicker): android.permission.SET_WALLPAPER_COMPONENT, com.android.wallpaper (/system_ext/priv-app/ThemePicker): android.permission.BIND_WALLPAPER, com.android.wallpaper (/system_ext/priv-app/ThemePicker): android.permission.WRITE_SECURE_SETTINGS, com.android.wallpaper (/system_ext/priv-app/ThemePicker): android.permission.READ_WALLPAPER_INTERNAL, com.android.wallpaper (/system_ext/priv-app/ThemePicker): android.permission.MODIFY_DAY_NIGHT_MODE, com.android.wallpaper (/system_ext/priv-app/ThemePicker): android.permission.CHANGE_OVERLAY_PACKAGES}
      at com.android.server.pm.permission.PermissionManagerServiceImpl.onSystemReady(PermissionManagerServiceImpl.java:4389)
      at com.android.server.pm.permission.PermissionManagerService$PermissionManagerServiceInternalImpl.onSystemReady(PermissionManagerService.java:739)
      at com.android.server.SystemServer.startOtherServices(SystemServer.java:2719)
      at com.android.server.SystemServer.main(SystemServer.java:651)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

解决方案也简单,我们只需要把权限配置补上就行。在 packages/apps/ThemePicker下面新建一个 privapp_whitelist_com.android.wallpaper.xml,内容如下:

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<permissions>
    <privapp-permissions package="com.android.wallpaper">
        <permission name="android.permission.CHANGE_OVERLAY_PACKAGES"/>
        <permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
        <permission name="android.permission.SET_WALLPAPER_COMPONENT"/>
        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
        <permission name="android.permission.BIND_WALLPAPER"/>
        <permission name="android.permission.READ_WALLPAPER_INTERNAL"/>
    </privapp-permissions>
</permissions>

接着打开 packages/apps/ThemePicker/Android.bp,找到 android_app ,在里面做如下改动:

yaml 复制代码
android_app {
    name: "ThemePicker",
    defaults: ["ThemePicker_defaults"],

    platform_apis: true,
    manifest: "AndroidManifest.xml",
    additional_manifests: [":WallpaperPicker2_Manifest"],
    overrides: ["WallpaperPicker2"],
    required: ["privapp_whitelist_com.android.wallpaper"],
    privileged: true,
}

prebuilt_etc {
    name: "privapp_whitelist_com.android.wallpaper",
    system_ext_specific: true,
    src: "privapp_whitelist_com.android.wallpaper.xml",
    sub_dir: "permissions",
    filename_from_src: true,
}

添加 ThemePicker、ThemesStub 到 PRODUCT_PACKAGES

由于计划用 Cuttlefish 验证,因此打开 device/google/cuttlefish/vsoc_x86_64/phone/aosp_cf.mk,在末尾添加:

makefile 复制代码
PRODUCT_PACKAGES += \
    ThemePicker \
    ThemesStub \

ThemePicker、ThemesStub 是两个不同的 Apk,前者实现了原生 WallpaperPicker2 模块的部分接口,后者是 Material You design 在 aosp 的默认颜色方案,具体介绍可以在这里查看。

Material You design 效果验证

启动 Cuttlefish,依次进入Settings ->Wallpaper,可以看到多出来一个 Wallpaper & style 应用,这个就是我们上面集成的 ThemePicker。

打开之后,可以在下面看到主题色选项:

切换一个颜色,然后拉下通知中心查看,可以看到整个系统的控件都变成了对应的颜色:

再换一套其它的颜色看看:

厂商定制 FAQ

Q:我一定要用 aosp 的这个 ThemePicker 吗?

A:不一定,aosp 的 ThemePicker 也只是 Pixel 里"抠"出来的,目的是告诉你对应的颜色值需要怎么设置,本质其实是向 Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES写入了一些配置,具体可以参考 ColorCustomizationManager,把里面的逻辑抽到厂商自己的主题美化 App 或其他职能模块去。

cs.android.com/android/pla...

Q:ThemesStub 是一定需要的吗?

A:取决于你是否用原生的 ThemePicker,如果决定用原生的 ThemePicker,就必须要。ThemesStub 包含了一套预先定义好的主题色方案,厂商可以通过 RRO 的方式来修改这些色值,或者也可以参考 Stub APK format 来开发自己的 ThemesStub。注意,如果选择原生 ThemePicker + 自己开发 ThemesStub,需要修改 /packages/apps/ThemePicker/res_override/values/override.xml,告诉 ThemePicker 你的 ThemesStub 包名是什么。

xml 复制代码
    <!-- Package of the stub apk containing the themes descriptions -->
    <!-- 下面包名是原生 ThemesStub 的包名 -->
    <string name="themes_stub_package" translatable="false">
        com.android.customization.themes
    </string>

Q:为什么第三方 App 装到我的手机上,还是没办法跟随主题色?

A:可能是你的厂商不在 Google 的 Material Design 库白名单,你需要提单请他们加上。(搞不明白为啥要这么麻烦)

参考资料

source.android.com/docs/core/d...

gist.github.com/zhaofengli/...

相关推荐
雨白2 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
9527华安2 小时前
FPGA实现40G网卡NIC,基于PCIE4C+40G/50G Ethernet subsystem架构,提供工程源码和技术支持
fpga开发·架构·网卡·ethernet·nic·40g·pcie4c
kk爱闹3 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空5 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭5 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日6 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安6 小时前
Android Library Maven 发布完整流程指南
android
guojl6 小时前
深度解决大文件上传难题
架构
岁月玲珑6 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
DemonAvenger6 小时前
Go语言中的TCP编程:基础实现与最佳实践
网络协议·架构·go