Gms定制中经常需要修改Gms app在launcher中的布局,通常有两个方法
一 修改gms_overlay
首先根据Launcher3/res/xml/device_profiles.xml中的defaultLayoutId值确定修改那个布局,比如下面定义
<grid-option
launcher:name="5_by_5"
launcher:numRows="5"
launcher:numColumns="5"
launcher:numFolderRows="4"
launcher:numFolderColumns="4"
launcher:numHotseatIcons="5"
launcher:dbFile="launcher.db"
launcher:defaultLayoutId="@xml/default_workspace_5x5" >
路径:/vendor/google/overlay/gms_overlay/packages/apps/Launcher3/res/xml/default_workspace_5x5.xml(注意:mtk平台的路径为:vendor/google/overlay/gms_overlay/vendor/mediatek/proprietary/packages/apps/Launcher3/res/xml/default_workspace_5x5.xml)
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
<appwidget packageName="com.handmark.expressweather" className="com.handmark.expressweather.widgets.Widget4x1_Clock" container="-100" screen="0" spanX="5" spanY="1" x="0" y="0" />
<appwidget packageName="com.google.android.googlequicksearchbox" className="com.google.android.apps.gsa.staticplugins.searchwidget.GoogleSearchWidgetProvider" container="-100" screen="0" spanX="5" spanY="1" x="0" y="3" />
<!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
<!-- Dialer Messaging [All Apps] Contacts Camera -->
<favorite container="-101" screen="0" x="0" y="0" packageName="com.android.dialer" className="com.android.dialer.main.impl.MainActivity"/>
<favorite container="-101" screen="1" x="1" y="0" packageName="com.google.android.apps.messaging" className="com.google.android.apps.messaging.ui.ConversationListActivity"/>
<favorite container="-101" screen="2" x="2" y="0" packageName="com.android.chrome" className="com.google.android.apps.chrome.Main"/>
<favorite container="-101" screen="3" x="3" y="0" packageName="com.smartphoton.camera" className="com.android.camera.CameraLauncher"/>
<favorite container="-101" screen="4" x="4" y="0" packageName="com.google.android.apps.photos" className="com.google.android.apps.photos.home.HomeActivity"/>
<!-- In Launcher3, workspaces extend infinitely to the right, incrementing from zero -->
<favorite screen="0" x="0" y="4" packageName="com.tracfone.generic.mysites" className="com.tracfone.generic.mysites.MainActivity"/>
<favorite screen="0" x="1" y="4" packageName="com.facebook.katana" className="com.facebook.katana.LoginActivity"/>
<favorite screen="0" x="2" y="4" packageName="com.google.android.apps.tachyon" className="com.google.android.apps.tachyon.MainActivity"/>
<favorite screen="0" x="3" y="4" packageName="com.android.vending" className="com.android.vending.AssetBrowserActivity"/>
<folder folderItems="@xml/folder_google" container="-100" screen="0" x="4" y="4" />
<favorite packageName="com.handmark.expressweather" className="com.handmark.expressweather.ui.activities.MainActivity" container="-100" screen="1" x="1" y="4" />
<favorite packageName="com.android.settings" className="com.android.settings.Settings" container="-100" screen="1" x="3" y="4" />
<folder folderItems="@xml/folder_media" container="-100" screen="2" x="1" y="4" />
<folder folderItems="@xml/folder_productivity" container="-100" screen="2" x="2" y="4" />
<folder folderItems="@xml/folder_tool" container="-100" screen="2" x="3" y="4" />
</favorites>
目录列表
folder_google.xml
<?xml version="1.0" encoding="utf-8"?>
<folder title="@string/google_folder_name">
<favorite packageName="com.google.android.googlequicksearchbox" className="com.google.android.googlequicksearchbox.SearchActivity" />
<favorite packageName="com.android.chrome" className="com.google.android.apps.chrome.Main" />
<favorite packageName="com.google.android.gm" className="com.google.android.gm.ConversationListActivityGmail" />
<favorite packageName="com.google.android.apps.maps" className="com.google.android.maps.MapsActivity" />
<favorite packageName="com.google.android.youtube" className="com.google.android.youtube.app.honeycomb.Shell$HomeActivity" />
<favorite packageName="com.google.android.apps.docs" className="com.google.android.apps.docs.app.NewMainProxyActivity" />
<favorite packageName="com.google.android.videos" className="com.google.android.youtube.videos.EntryPoint" />
<favorite packageName="com.google.android.apps.photos" className="com.google.android.apps.photos.home.HomeActivity" />
<favorite packageName="com.google.android.inputmethod.latin" className="com.google.android.apps.inputmethod.latin.preference.SettingsActivity" />
<favorite packageName="com.google.android.calendar" className="com.android.calendar.AllInOneActivity" />
<favorite packageName="com.google.android.apps.messaging" className="com.google.android.apps.messaging.ui.ConversationListActivity" />
</folder>
folder_media.xml
<?xml version="1.0" encoding="utf-8"?>
<folder title="@string/media_folder_name">
<favorite packageName="com.google.android.apps.photos" className="com.google.android.apps.photos.home.HomeActivity" />
<favorite packageName="com.google.android.videos" className="com.google.android.youtube.videos.EntryPoint" />
<favorite packageName="com.android.fmradio" className="com.android.fmradio.FmMainActivity" />
<favorite packageName="com.google.android.apps.youtube.music" className="com.google.android.apps.youtube.music.activities.MusicActivity" />
</folder>
folder_productivity.xml
<?xml version="1.0" encoding="utf-8"?>
<folder title="@string/productivity_folder_name">
<favorite packageName="com.google.android.gm" className="com.google.android.gm.ConversationListActivityGmail" />
<favorite packageName="com.google.android.calendar" className="com.android.calendar.AllInOneActivity" />
<favorite packageName="com.google.android.contacts" className="com.android.contacts.activities.PeopleActivity" />
<favorite packageName="com.google.android.apps.nbu.files" className="com.google.android.apps.nbu.files.home.HomeActivity" />
</folder>
folder_tool.xml
<?xml version="1.0" encoding="utf-8"?>
<folder title="@string/tool_folder_name">
<favorite packageName="com.handmark.expressweather" className="com.handmark.expressweather.ui.activities.MainActivity" />
<favorite packageName="com.android.settings" className="com.android.settings.Settings" />
<favorite packageName="com.google.android.deskclock" className="com.android.deskclock.DeskClock" />
<favorite packageName="com.google.android.calculator" className="com.android.calculator2.Calculator" />
<favorite packageName="com.celltick.lockscreen" className="com.celltick.lockscreen.LockerActivity2" />
<favorite packageName="com.tracfone.preload.accountservices" className="com.tracfone.preload.accountservices.MainActivity" />
<favorite packageName="com.google.android.apps.photos" className="com.google.android.apps.photos.home.HomeActivity" />
</folder>
效果图如下
二 GmsSampleIntegration中修改
GmsSampleIntegration中默认已经支持了setupwizard和launcher3的客户定制修改
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 Google Inc. All Rights Reserved. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.gmsintegration">
<application android:label="@string/app_label">
<!-- This isn't a real receiver, it's only used as a marker interface. -->
<receiver android:name=".LauncherCustomizationReceiver">
<intent-filter>
<action android:name="com.android.launcher3.action.PARTNER_CUSTOMIZATION" />
</intent-filter>
</receiver>
<receiver android:name=".SuwCustomizationReceiver">
<intent-filter>
<action android:name="com.android.setupwizard.action.PARTNER_CUSTOMIZATION" />
</intent-filter>
</receiver>
</application>
</manifest>
LauncherCustomizationReceiver.java
/* Copyright (C) 2017 Google Inc. All Rights Reserved. */
package com.google.android.gmsintegration;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class LauncherCustomizationReceiver extends BroadcastReceiver {
public LauncherCustomizationReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
}
}
通过注册com.android.launcher3.action.PARTNER_CUSTOMIZATION的广播监听,launcher定制生效,需要注意的是gmsintegration如果打包到项目中,gms-overlay会失效,优先使用gmsintegration的配置。不过要注意GmsSampleIntegration中的android.mk,因为GmsSampleIntegration下的res配置有几个,看下你需要编译哪个。
修改前的android.mk
###############################################################################
# Various GMS Sample Integration targets
LOCAL_PATH:= $(my-dir)
# GmsSampleIntegration
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsSampleIntegration
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_full $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsSampleIntegrationGo
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsSampleIntegrationGo
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_go $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsSampleIntegrationGo_2GB
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsSampleIntegrationGo_2GB
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_go_2gb $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsSampleIntegrationGo512M
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsSampleIntegrationGo512M
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_go_512m $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType2Integration (No GSA, Chrome)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType2Integration
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_no_gsa $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType2IntegrationGo (No GSA, Chrome)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType2IntegrationGo
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_no_search_go $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType3aIntegration (GSA, No Chrome, no placement)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType3aIntegration
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_min $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType3aIntegrationGo (GSA, No Chrome, no placement)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType3aIntegrationGo
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_min_go $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType3bIntegration (GSA, No Chrome, search placement)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType3bIntegration
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_no_chrome $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType3bIntegrationGo (GSA, No Chrome, search placement)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType3bIntegrationGo
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_no_chrome_go $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType4aIntegration (GSA, Chrome, no placement)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType4aIntegration
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_min $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType4aIntegrationGo (GSA, Chrome, no placement)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType4aIntegrationGo
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_min_go $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType4bIntegration (GSA, Chrome, search placement)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType4bIntegration
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_no_chrome $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType4bIntegrationGo (GSA, Chrome, search placement)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType4bIntegrationGo
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_no_chrome_go $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType4cIntegration (GSA, Chrome, search+chrome placement)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType4cIntegration
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_full $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType4cIntegrationGo (GSA, Chrome, search+chrome placement)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType4cIntegrationGo
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_go $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType4cIntegrationGo_2GB (GSA, Chrome, search+chrome placement)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType4cIntegrationGo_2GB
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_go_2gb $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# GmsEEAType1Integration (No GSA, No Chrome)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsEEAType1Integration
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_min $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
修改后的android.mk.我们项目中选第一个
###############################################################################
# Various GMS Sample Integration targets
LOCAL_PATH:= $(my-dir)
# GmsSampleIntegration
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := GmsSampleIntegration
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_TAGS := optional
LOCAL_PRODUCT_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res_dhs_full $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
关于launcher的默认布局加载流程可以参考下面这个文章:
https://blog.csdn.net/csdn_conda/article/details/79728651