Android Framework-Launcher-Partner

Partner是什么呢? 嗯 很好,鉴于我贫瘠的文学功底,我借鉴了一下AI的文本。

Partner 机制是一种允许设备制造商(OEM)、运营商或其他合作伙伴通过标准化方式定制和扩展 Android 系统功能的框架。它主要用于在不直接修改 AOSP 核心代码的前提下,实现厂商特定的定制需求,同时保持系统的兼容性和可维护性。

好的,说人话,就是你可以通过覆盖的方式,达到修改Laucher布局的效果。

实现方法

  • 编写一个BroadcastReceiver
java 复制代码
public  class LauncherPartner extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

    }
}
  • AndroidMainfest.xml里添加
xml 复制代码
<receiver
            android:name=".LauncherPartner"
            android:exported="true">
            <intent-filter>
                <action android:name="com.android.launcher3.action.PARTNER_CUSTOMIZATION" />
            </intent-filter>
        </receiver>

res/xml包下下构建 partner_default_layout.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>

<favorites  xmlns:launcher="http://schemas.android.com/apk/res-auto">


    <appwidget

        className="com.android.alarmclock.DigitalAppWidgetProvider"
        packageName="com.android.deskclock"
        screen="0"
        spanX="2"
        spanY="2"
        x="3"
        y="0"


        />

    <favorite

        className="com.android.settings.Settings"
        packageName="com.android.settings"
        screen="0"
        spanX="1"
        spanY="1"
        x="4"
        y="4"

        />
    <favorite

        className="com.android.settings.Settings"
        packageName="com.android.settings"
        screen="0"
        spanX="1"
        spanY="1"
        x="4"
        y="3"

        />
    <favorite
        className="com.android.settings.Settings"
        packageName="com.android.settings"
        screen="1"
        spanX="1"
        spanY="1"
        x="3"
        y="2"

        />

    <folder
        screen="0"
        title="test"
        x="0"
        y="3">
        <favorite
            className="com.android.settings.Settings"
            packageName="com.android.settings"/>


        <favorite
            className="com.android.settings.Settings"
            packageName="com.android.settings"/>

        <favorite
            className="com.android.settings.Settings"
            packageName="com.android.settings"/>


        <favorite
            className="com.android.settings.Settings"
            packageName="com.android.settings"/>

    </folder>


    <favorite
        className="com.android.settings.Settings"
        packageName="com.android.settings"
        x="0"
        y="0"
        screen="0"
        container="-101"
       />

    <favorite
        className="com.android.settings.Settings"
        packageName="com.android.settings"
        container="-101"
        screen="1"
        x="1"
        y="0" />

    <favorite
        className="com.android.settings.Settings"
        packageName="com.android.settings"
        container="-101"
        screen="2"
        x="2"
        y="0" />

</favorites>

然后构建apk 或者直接编译到系统中就可以了。

原理解析

Android Framework-Launcher-默认布局的加载 在调用 loadWorkspace方法里

java 复制代码
LauncherSettings.Settings.call(contentResolver,
        LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES);

中会执行到 LauncherProviderloadDefaultFavoritesIfNecessary 方法 如果partner 不为null,就会去解析 partner_default_layout.xml。其实就是去匹配符合 actioncom.android.launcher3.action.PARTNER_CUSTOMIZATION的系统apk

java 复制代码
//packages/apps/Launcher3/src/com/android/launcher3/LauncherProvider.java

public static final String RES_PARTNER_DEFAULT_LAYOUT = "partner_default_layout";
loadDefaultFavoritesIfNecessary(){


if (loader == null) {
    final Partner partner = Partner.get(getContext().getPackageManager());
    if (partner != null) {
        int workspaceResId = partner.getXmlResId(RES_PARTNER_DEFAULT_LAYOUT);
        if (workspaceResId != 0) {
            loader = new DefaultLayoutParser(getContext(), widgetHolder,
                    mOpenHelper, partner.getResources(), workspaceResId);
        }
    }
}
}
  • Partner
java 复制代码
private static final String
        ACTION_PARTNER_CUSTOMIZATION = "com.android.launcher3.action.PARTNER_CUSTOMIZATION";
public static Partner get(PackageManager pm) {
    return get(pm, ACTION_PARTNER_CUSTOMIZATION);
}

public static Partner get(PackageManager pm, String action) {
    Pair<String, Resources> apkInfo = findSystemApk(action, pm);
    return apkInfo != null ? new Partner(apkInfo.first, apkInfo.second) : null;
}
相关推荐
BINGCHN18 分钟前
NSSCTF每日一练 SWPUCTF2021 include--web
android·前端·android studio
fundroid26 分钟前
Androidify:谷歌官方 AI + Android 开源示例应用
android·人工智能·开源
4z331 小时前
Android15 Framework(2):应用进程的孵化器 Zygote 进程解析
android·源码阅读
00后程序员张2 小时前
iOS 抓不到包怎么办?从 HTTPS 解密、QUIC 排查到 TCP 数据流分析的完整解决方案
android·tcp/ip·ios·小程序·https·uni-app·iphone
李斯维3 小时前
布局性能优化利器:ViewStub 极简指南
android·性能优化
循环不息优化不止4 小时前
Ktor Pipeline 机制深度解析
android
q***56384 小时前
Springboot3学习(5、Druid使用及配置)
android·学习
q***64974 小时前
SpringSecurity踢出指定用户
android·前端·后端
q***76665 小时前
SpringSecurity 实现token 认证
android·前端·后端
Chejdj5 小时前
ViewModel#onCleared的实现原理
android·源码阅读