Launcher3 实现桌面客制化---1

Launcher3 桌面布局一般加载default_workspace_xx.xml 。需要自定义自己的Launcher 布局会以静态overlay的形式来替换原始的default_workspace_xx.xml。这种方式局限是需要有源码的情况下去修改。

Launcher 提供了接口,可以预置一个apk, 来实现自定义。

Launcher#loadDefaultFavoritesIfNecessary  用来获取默认的布局文件。其中get方法是获取所需要信息

synchronized public void loadDefaultFavoritesIfNecessary() {
       ...
       if (loader == null) {
            final Partner partner = Partner.get(getContext().getPackageManager());
            if (partner != null && partner.hasDefaultLayout()) {
                final Resources partnerRes = partner.getResources();
                int workspaceResId = partnerRes.getIdentifier(Partner.RES_DEFAULT_LAYOUT,
                        "xml", partner.getPackageName());
                if (workspaceResId != 0) {
                    loader = new DefaultLayoutParser(getContext(), mOpenHelper.mAppWidgetHost,
                            mOpenHelper, partnerRes, workspaceResId);
                }
            }
        }
    
     ...
}

其中的关键方法findSystemApk , 判断系统apk中是否有action 为"com.android.launcher3.action.PARTNER_CUSTOMIZATION" 的应用,  如果有,则获取packagename 和resources

public static synchronized Partner get(PackageManager pm) {
    if (!sSearched) {
        Pair<String, Resources> apkInfo = Utilities.findSystemApk(ACTION_PARTNER_CUSTOMIZATION, pm);
        if (apkInfo != null) {
            sPartner = new Partner(apkInfo.first, apkInfo.second);
        }
        sSearched = true;
    }
    return sPartner;
}
 
 
static Pair<String, Resources> findSystemApk(String action, PackageManager pm) {
    final Intent intent = new Intent(action);
    for (ResolveInfo info : pm.queryBroadcastReceivers(intent, 0)) {
        if (info.activityInfo != null &&
                (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
            final String packageName = info.activityInfo.packageName;
            try {
                final Resources res = pm.getResourcesForApplication(packageName);
                return Pair.create(packageName, res);
            } catch (NameNotFoundException e) {
                Log.w(TAG, "Failed to find resources for " + packageName);
            }
        }
    }
    return null;
}

然后用hasDefaultLayout 去判断是否有这个partner_default_layout.xml ,若有,则以此文件作为默认layout

public boolean hasDefaultLayout() {
    int defaultLayout = getResources().getIdentifier(Partner.RES_DEFAULT_LAYOUT,
            "xml", getPackageName());
    return defaultLayout != 0;
}
以上是launcher 中获取默认桌面layout 的过程。

下面自定义一个apk,去自定义这个文件(可以参考GMS包里面的应用GmsSampleLayout,按照里面的方法写)。

创建个apk,AndroidManifast.xml中配置:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.custom.workspace.layout">
 <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="23" />
    <application android:label="@string/app_label">
        <receiver android:name=".PartnerCustomizationReceiver">
            <intent-filter>
                <action android:name="com.android.launcher3.action.PARTNER_CUSTOMIZATION" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

PartnerCustomizationReceiver.java 中创建广播接收,不做处理

public class PartnerCustomizationReceiver extends BroadcastReceiver {


    public PartnerCustomizationReceiver() {
    }


    public void onReceive(Context context, Intent intent) {


    }
}

然后在资源里添加自定义的layout布局,名字为partner_default_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<favorites>

<favorite
         packageName="com.android.settings"
         className="com.android.settings.wifi.WifiSettings"
         screen="3"
         x="0"
         y="3" />
    <favorite
         packageName="com.android.gallery3d"
         className="com.android.gallery3d.app.GalleryActivity"
         screen="3"
         x="1"
         y="3" />
    <favorite
         packageName="com.android.settings"
         className="com.android.settings.Settings"
         screen="3"
         x="2"
         y="3" />
<favorite
         packageName="com.android.music"
         className="com.android.music.MusicBrowserActivity"
         screen="3"
         x="3"
         y="3" />

    <!-- Far-right screen [4] -->
    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
    <!-- Contacts,Dialer,  [All Apps], Messaging, Browser -->    
    <resolve
         container="-101"
         screen="0"
         x="0"
         y="0" >
        <favorite  uri="\#Intent;action=android.intent.action.DIAL;end" />
        <favorite  uri="tel:123" />
        <favorite  uri="\#Intent;action=android.intent.action.CALL_BUTTON;end" />


        <favorite
             packageName="com.android.dialer"
             className="com.android.dialer.DialtactsActivity" />
    </resolve>

</favorites>

注意:

1.因为Launcher 的默认布局中有命名空间来规范属性,在这里需要把命名空间去除,并去除每个标签属性前面的launcher关键字;

2.<favorite  uri="\#Intent;action=android.intent.action.DIAL;end" /> 这个标签的#前面需要加个反斜杠

android.mk

# WorkSpaceStyle
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := WorkSpaceStyle
LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := platform
#LOCAL_OVERRIDES_PACKAGES := BullheadLayout
LOCAL_SRC_FILES := $(call all-java-files-under, src)
include $(BUILD_PACKAGE)

编译后install到手机上,在adb shell pm clear com.android.launcher3.

现在可以查看自定义的桌面了。

后面再更新一篇 在自己写的app上实现主题变更。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值