问题描述
Android13-EDLA 项目中,按照认证需求,需要验证 M56 - Monochrome App icon ,具体需求如下图,可通过 Wallpaper & Style 打开/关闭 Themed Icon功能。测试发现Wallpaper & Style中没有此项设置,无法开关 Themed Icon功能 。
原因分析:
因为项目中使用的是原生的壁纸(com.android.wallpaper),一开始怀疑是原生的壁纸没有Theme icon的功能设置,需要预置Google Wallpaper。
解决方案:
-
预置Google Wallpaper
1. partner_gms/apps/ 目录下添加GoogleWallpaper 目录
GoogleWallpaper.apk 可自行官网下载,Android.mk 内容如下
###############################################################################
# GoogleWallpaper
LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := GoogleWallpaper
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
#LOCAL_PRIVILEGED_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SYSTEM_EXT_MODULE := true
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_USES_LIBRARIES := org.apache.http.legacy
LOCAL_OPTIONAL_USES_LIBRARIES := androidx.window.extensions androidx.window.sidecar
#LOCAL_OVERRIDES_PACKAGES :=
#LOCAL_REQUIRED_MODULES :=
include $(BUILD_PREBUILT)
LOCAL_SYSTEM_EXT_MODULE := true 预置到 system_ext 下,若没有设置此项,默认编译生成的apk会在system 分区。在system分区时需要额外添加权限白名单,不然会崩溃报错。
2. vendor/partner_gms/products/gms.mk 添加 DeskClockGoogle,添加后编包时才会编译DeskClockGoogle。
PRODUCT_PACKAGES += \
DeskClockGoogle \
3. 预置应用后还需要修改Launcher3 和Setting 的配置。
- /device/xxx/common/products/tablet/overlay/packages/apps/Launcher3/res/values/config.xml
-- <string name="wallpaper_picker_package" translatable="false">com.android.wallpaper</string>
++ <string name="wallpaper_picker_package" translatable="false">com.google.android.apps.wallpaper</string>
将wallpaper_picker_package 配置成 com.google.android.apps.wallpaper。
Launcher3默认的配置文件位置在 packages/apps/Launcher3/res/values/config.xml ,因为存在overlay类,所以需要修改overlay类 才起作用。
- device/xxx/common/products/tablet/overlay/packages/apps/Settings/res/values/config.xml
-- <string name="config_wallpaper_picker_package" translatable="false">com.android.wallpaper</string>
++ <string name="config_wallpaper_picker_package" translatable="false">com.google.android.apps.wallpaper</string>
将config_wallpaper_picker_package 设置为 com.google.android.apps.wallpaper,跟前面一起,需要修改overlay 类才起作用
4. 编译大包升级系统后,检查 Wallpaper & Style 界面是否是Google Wallpaper 的。
进入 Wallpaper & Style 界面 (Launcher3 或者Setting 进入), 串口执行指令: dumpsys window | grep “mCurrentFocus”现在是 com.google.android.apps.wallpaper 则说明替换成功。
5. 替换成GoogleWallpaper 后发现,Wallpaper & Style 中 不显示 Wallpaper colors 。如下图所示,红框部分不显示。
查阅官方文档发现,GoogleWallpaper 显示 Wallpaper colors 需要满足两个条件。
- frameworks/base/packages/SystemUI/res/values/flags.xml 中的 flag_monet 必须设置为true。
- 必须安装 com.google.android.apps.customization.pixel 。
6.预置 com.google.android.apps.customization.pixel
预置方法跟 GoogleWallpaper 一致,参考修改即可。
Android.mk
###############################################################################
# GoogleWallpaper
LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := CustomizationPixel
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
#LOCAL_PRIVILEGED_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SYSTEM_EXT_MODULE := true
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
#LOCAL_USES_LIBRARIES := org.apache.http.legacy
#LOCAL_OPTIONAL_USES_LIBRARIES := androidx.window.extensions androidx.window.sidecar
#LOCAL_OVERRIDES_PACKAGES :=
#LOCAL_REQUIRED_MODULES :=
include $(BUILD_PREBUILT)
vendor/partner_gms/products/gms.mk 添加 CustomizationPixel
PRODUCT_PACKAGES += \
CustomizationPixel\
整编大包后验证有效。
7. Theam icon 不显示的问题。
由于预置的GoogleWallpaper无源码,且没有相关的文档,我们可以从Android版wallpaper分析,ThemePicker(com.android.wallpaper)。
1. 从Theam icon 字符入手,ThemePicker 中检索 Theam icon.
Theam icon —>themed_icon_title(string.xml )–>themed_icon_section_view.xml(layout)—>ThemedIconSectionView.java -->ThemedIconSectionController.java
2. ThemedIconSectionController.java 中定义了 isAvailable方法,按字面意思就是获取 Themed Icon 是否可用。
...
@Override
public boolean isAvailable(@Nullable Context context) {
return context != null && mThemedIconOptionsProvider.isThemedIconAvailable();
}
...
3. ThemedIconSwitchProvider.java
...
/** Returns {@code true} if themed icon feature is available. 如果themed icon 功能可用返回true */
public boolean isThemedIconAvailable() {
return mThemedIconUtils.isThemedIconAvailable();
}
...
4. ThemedIconUtils.java (重点类)
private ProviderInfo mProviderInfo;
public ThemedIconUtils(Context context, String authorityMetaKey) {
mContext = context;
Intent homeIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME);
ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA);
if (resolveInfo != null && resolveInfo.activityInfo.metaData != null) {
mProviderAuthority = resolveInfo.activityInfo.metaData.getString(authorityMetaKey);
} else {
mProviderAuthority = null;
}
mProviderInfo = TextUtils.isEmpty(mProviderAuthority) ? null :
mContext.getPackageManager().resolveContentProvider(mProviderAuthority, 0);
if (mProviderInfo != null && !TextUtils.isEmpty(mProviderInfo.readPermission)) {
if (mContext.checkSelfPermission(mProviderInfo.readPermission)
!= PackageManager.PERMISSION_GRANTED) {
mProviderInfo = null;
}
}
}
...
/**
* Returns if themed icon is available.
*
* @return true if themed icon feature is available, false otherwise.
*/
boolean isThemedIconAvailable() {
return mProviderInfo != null;
}
...
Themed Icon 功能是否可用是 通过判断mProviderInfo是否为空,而 mProviderInfo 是在 ThemedIconUtils 构造方法中创建。在构造函数中获取满足 CATEGORY_HOME 、MATCH_DEFAULT_ONLY 、GET_META_DATA 的 的Activity组件(resolveInfo );并获取key为authorityMetaKey的值。
ThemedIconSwitchProvider.java
...
/** Returns the {@link ThemedIconSwitchProvider} instance. */
public static ThemedIconSwitchProvider getInstance(Context context) {
if (sThemedIconSwitchProvider == null) {
Context appContext = context.getApplicationContext();
sThemedIconSwitchProvider = new ThemedIconSwitchProvider(
appContext.getContentResolver(),
new ThemedIconUtils(appContext,
appContext.getString(R.string.themed_icon_metadata_key)),
(CustomizationPreferences) InjectorProvider.getInjector()
.getPreferences(appContext));
}
return sThemedIconSwitchProvider;
}
...
string.xml
<!--Name of metadata in the main launcher Activity which values contains the authority
corresponding to a ContentProvider in launcher to query or change themed icon option -->
<string name="themed_icon_metadata_key" translatable="false">com.android.launcher3.themedicon.option</string>
6. 也就是说,Themed Icon 功能是否支持,由满足 CATEGORY_HOME 、MATCH_DEFAULT_ONLY 、GET_META_DATA 的 的Activity组件, 是否定义的了 key值为 com.android.launcher3.themedicon.option 的 metaData 标签。而满足这个要求的Activity就是Launcher3 的Home Activity 。满足要求的有两个Activity。
- packages/apps/Launcher3/AndroidManifest.xml 的 com.android.launcher3.Launcher
<activity
android:name="com.android.launcher3.Launcher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.SHOW_WORK_APPS" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
<category android:name="android.intent.category.LAUNCHER_APP" />
</intent-filter>
<meta-data
android:name="com.android.launcher3.grid.control"
android:value="${packageName}.grid_control" />
++ <meta-data
++ android:name="com.android.launcher3.themedicon.option"
++ android:value="${packageName}.grid_control" />
</activity>
- packages/apps/Launcher3/quickstep/AndroidManifest-launcher.xml 的 com.android.launcher3.uioverrides.QuickstepLauncher
<activity
android:name="com.android.launcher3.uioverrides.QuickstepLauncher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.SHOW_WORK_APPS" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
<category android:name="android.intent.category.LAUNCHER_APP" />
</intent-filter>
<meta-data
android:name="com.android.launcher3.grid.control"
android:value="${packageName}.grid_control" />
++ <meta-data
++ android:name="com.android.launcher3.themedicon.option"
++ android:value="${packageName}.grid_control" />
</activity>
编译验证发现Theme Icon 正常显示,且功能正常。
总结
-其实Theme icon不显示问题跟Google Wallpaper 无关,应该在 Launcher3 的HomeActivity 配置 meta-data 即可,
感兴趣的可以自行验证测试,如有纰漏或分析错误,欢迎指出。文章来源:https://www.toymoban.com/news/detail-828249.html
参考
在 aosp 中启用 Material You design文章来源地址https://www.toymoban.com/news/detail-828249.html
到了这里,关于Android13-EDLA 预装使用GoogleWallpaper并打开壁纸Themed icon 功能(M56 - Monochrome App icon)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!