赞
踩
当业务需求要求要主页面不显示特定的一个或多个apk时,我们需要在launcher中隐藏此apk。本文以隐藏 Aqua Mail,Calculator,FileCommander三个apk为例来详细讲解。
代码路径
packages\apps\Launcher3\src\com\android\launcher3\model\LoaderTask.java
packages\apps\Launcher3\quickstep\src\com\android\launcher3\appprediction\PredictionRowView.java
加载apk列表是在LoaderTask中进行加载的,我们只需要在加载所有apk列表的地方,屏蔽我们业务需要的apk即可实现此功能。看run()方法
- public void run() {
- synchronized (this) {
- // Skip fast if we are already stopped.
- if (mStopped) {
- return;
- }
- }
-
- Object traceToken = TraceHelper.INSTANCE.beginSection(TAG);
- TimingLogger logger = new TimingLogger(TAG, "run");
- LoaderMemoryLogger memoryLogger = new LoaderMemoryLogger();
- try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
- List<ShortcutInfo> allShortcuts = new ArrayList<>();
- Trace.beginSection("LoadWorkspace");
- try {
- loadWorkspace(allShortcuts, memoryLogger);
- } finally {
- Trace.endSection();
- }
- logASplit(logger, "loadWorkspace");
-
- // Sanitize data re-syncs widgets/shortcuts based on the workspace loaded from db.
- // sanitizeData should not be invoked if the workspace is loaded from a db different
- // from the main db as defined in the invariant device profile.
- // (e.g. both grid preview and minimal device mode uses a different db)
- if (mApp.getInvariantDeviceProfile().dbFile.equals(mDbName)) {
- verifyNotStopped();
- sanitizeData();
- logASplit(logger, "sanitizeData");
- }
-
- verifyNotStopped();
- mResults.bindWorkspace(true /* incrementBindId */);
- logASplit(logger, "bindWorkspace");
-
- mModelDelegate.workspaceLoadComplete();
- // Notify the installer packages of packages with active installs on the first screen.
- sendFirstScreenActiveInstallsBroadcast();
- logASplit(logger, "sendFirstScreenActiveInstallsBroadcast");
-
- // Take a break
- waitForIdle();
- logASplit(logger, "step 1 complete");
- verifyNotStopped();
-
- // second step
- Trace.beginSection("LoadAllApps");
- List<LauncherActivityInfo> allActivityList;
- try {
- allActivityList = loadAllApps();
- } finally {
- Trace.endSection();
- }
- logASplit(logger, "loadAllApps");
-
- verifyNotStopped();
- mResults.bindAllApps();
- logASplit(logger, "bindAllApps");
-
- verifyNotStopped();
- IconCacheUpdateHandler updateHandler = mIconCache.getUpdateHandler();
- setIgnorePackages(updateHandler);
- updateHandler.updateIcons(allActivityList,
- LauncherActivityCachingLogic.newInstance(mApp.getContext()),
- mApp.getModel()::onPackageIconsUpdated);
- logASplit(logger, "update icon cache");
-
- if (FeatureFlags.ENABLE_DEEP_SHORTCUT_ICON_CACHE.get()) {
- verifyNotStopped();
- logASplit(logger, "save shortcuts in icon cache");
- updateHandler.updateIcons(allShortcuts, new ShortcutCachingLogic(),
- mApp.getModel()::onPackageIconsUpdated);
- }
-
- // Take a break
- waitForIdle();
- logASplit(logger, "step 2 complete");
- verifyNotStopped();
-
- // third step
- List<ShortcutInfo> allDeepShortcuts = loadDeepShortcuts();
- logASplit(logger, "loadDeepShortcuts");
-
- verifyNotStopped();
- mResults.bindDeepShortcuts();
- logASplit(logger, "bindDeepShortcuts");
-
- if (FeatureFlags.ENABLE_DEEP_SHORTCUT_ICON_CACHE.get()) {
- verifyNotStopped();
- logASplit(logger, "save deep shortcuts in icon cache");
- updateHandler.updateIcons(allDeepShortcuts,
- new ShortcutCachingLogic(), (pkgs, user) -> { });
- }
-
- // Take a break
- waitForIdle();
- logASplit(logger, "step 3 complete");
- verifyNotStopped();
-
- // fourth step
- List<ComponentWithLabelAndIcon> allWidgetsList =
- mBgDataModel.widgetsModel.update(mApp, null);
- logASplit(logger, "load widgets");
-
- verifyNotStopped();
- mResults.bindWidgets();
- logASplit(logger, "bindWidgets");
- verifyNotStopped();
-
- updateHandler.updateIcons(allWidgetsList,
- new ComponentWithIconCachingLogic(mApp.getContext(), true),
- mApp.getModel()::onWidgetLabelsUpdated);
- logASplit(logger, "save widgets in icon cache");
-
- // fifth step
- if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
- loadFolderNames();
- }
-
- verifyNotStopped();
- updateHandler.finish();
- logASplit(logger, "finish icon update");
-
- mModelDelegate.modelLoadComplete();
- transaction.commit();
- memoryLogger.clearLogs();
- } catch (CancellationException e) {
- // Loader stopped, ignore
- logASplit(logger, "Cancelled");
- } catch (Exception e) {
- memoryLogger.printLogs();
- throw e;
- } finally {
- logger.dumpToLog();
- }
- TraceHelper.INSTANCE.endSection(traceToken);
- }
在此方法里面跟下去,找到loadAllApps(),这里就是具体执行加载所有apk的方法了,继续跟踪
- private List<LauncherActivityInfo> loadAllApps() {
- final List<UserHandle> profiles = mUserCache.getUserProfiles();
- List<LauncherActivityInfo> allActivityList = new ArrayList<>();
- // Clear the list of apps
- mBgAllAppsList.clear();
-
- List<IconRequestInfo<AppInfo>> iconRequestInfos = new ArrayList<>();
- for (UserHandle user : profiles) {
- // Query for the set of apps
- final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
- // Fail if we don't have any apps
- // TODO: Fix this. Only fail for the current user.
- if (apps == null || apps.isEmpty()) {
- return allActivityList;
- }
- boolean quietMode = mUserManagerState.isUserQuiet(user);
- // Create the ApplicationInfos
- for (int i = 0; i < apps.size(); i++) {
- LauncherActivityInfo app = apps.get(i);
- AppInfo appInfo = new AppInfo(app, user, quietMode);
-
- boolean isHideApk = HideApkUtils.getInstall().isHidedApkPackageName(app.getComponentName().getPackageName());
- if(isHideApk){
- continue;
- }
- iconRequestInfos.add(new IconRequestInfo<>(
- appInfo, app, /* useLowResIcon= */ false));
- mBgAllAppsList.add(
- appInfo, app, !FeatureFlags.ENABLE_BULK_ALL_APPS_ICON_LOADING.get());
- }
- allActivityList.addAll(apps);
- }
-
-
- if (FeatureFlags.PROMISE_APPS_IN_ALL_APPS.get()) {
- // get all active sessions and add them to the all apps list
- for (PackageInstaller.SessionInfo info :
- mSessionHelper.getAllVerifiedSessions()) {
- AppInfo promiseAppInfo = mBgAllAppsList.addPromiseApp(
- mApp.getContext(),
- PackageInstallInfo.fromInstallingState(info),
- !FeatureFlags.ENABLE_BULK_ALL_APPS_ICON_LOADING.get());
-
- if (promiseAppInfo != null) {
- iconRequestInfos.add(new IconRequestInfo<>(
- promiseAppInfo,
- /* launcherActivityInfo= */ null,
- promiseAppInfo.usingLowResIcon()));
- }
- }
- }
-
- if (FeatureFlags.ENABLE_BULK_ALL_APPS_ICON_LOADING.get()) {
- Trace.beginSection("LoadAllAppsIconsInBulk");
- try {
- mIconCache.getTitlesAndIconsInBulk(iconRequestInfos);
- iconRequestInfos.forEach(iconRequestInfo ->
- mBgAllAppsList.updateSectionName(iconRequestInfo.itemInfo));
- } finally {
- Trace.endSection();
- }
- }
-
- mBgAllAppsList.setFlags(FLAG_QUIET_MODE_ENABLED,
- mUserManagerState.isAnyProfileQuietModeEnabled());
- mBgAllAppsList.setFlags(FLAG_HAS_SHORTCUT_PERMISSION,
- hasShortcutsPermission(mApp.getContext()));
- mBgAllAppsList.setFlags(FLAG_QUIET_MODE_CHANGE_PERMISSION,
- mApp.getContext().checkSelfPermission("android.permission.MODIFY_QUIET_MODE")
- == PackageManager.PERMISSION_GRANTED);
-
- mBgAllAppsList.getAndResetChangeFlag();
- return allActivityList;
- }
这里面就是加载所有apk逻辑了,我们只需要添加我们需要隐藏的业务逻辑即可。
// Create the ApplicationInfos
for (int i = 0; i < apps.size(); i++) {
LauncherActivityInfo app = apps.get(i);
AppInfo appInfo = new AppInfo(app, user, quietMode);
boolean isHideApk = HideApkUtils.getInstall().isHidedApkPackageName(app.getComponentName().getPackageName());
if(isHideApk){
continue;
}
iconRequestInfos.add(new IconRequestInfo<>(
appInfo, app, /* useLowResIcon= */ false));
mBgAllAppsList.add(
appInfo, app, !FeatureFlags.ENABLE_BULK_ALL_APPS_ICON_LOADING.get());
}
allActivityList.addAll(apps);
}
标红的即我们加的业务逻辑,此功能就实现了。但是需要注意的是,在配每一屏显示与Hotseat显示的apk列表中,不要把我们需要隐藏的apk加入这表中即可(如何配置每一屏显示的apk与Hotseat显示的apk,请看系列文章会详细讲解)
以下是HideApkUtils.java类
- package com.android.launcher3.util;
-
- import java.util.LinkedList;
- import java.util.List;
-
- /**
- * by Hogan 2023.3.17
- * 功能:隐藏指定的apk列表
- */
-
- public class HideApkUtils {
-
- private static final List<String> mHiddenPackageMap = new LinkedList<>();
-
- private HideApkUtils() {
- addHideAppList();
- }
-
- //需要隐藏的apk包名,添加到这里
- private void addHideAppList() {
- mHiddenPackageMap.add("org.kman.AquaMail");
- mHiddenPackageMap.add("com.google.android.calculator");
- mHiddenPackageMap.add("com.mobisystems.fileman");
- // mHiddenPackageMap.add("com.mobisystems.office");
- // mHiddenPackageMap.add("com.hht.factory");
- }
-
- private static class HideApkUtilsHolder {
- private static final HideApkUtils INSTALL = new HideApkUtils();
- }
-
- public static HideApkUtils getInstall() {
- return HideApkUtilsHolder.INSTALL;
- }
-
- public boolean isHidedApkPackageName(String apkPkg) {
- return mHiddenPackageMap.contains(apkPkg);
- }
- }
1. 找到setPredictedApps()方法,此方法是用于设置预测选项的内容并更新视图的:
- public void setPredictedApps(List<ItemInfo> items) {
- if (!FeatureFlags.ENABLE_APP_PREDICTIONS_WHILE_VISIBLE.get()
- && !mActivityContext.isBindingItems()
- && isShown()
- && getWindowVisibility() == View.VISIBLE) {
- mPendingPredictedItems = items;
- return;
- }
- applyPredictedApps(items);
- }
在这个方法里面调用了 applyPredictedApps()方法
- private void applyPredictedApps(List<ItemInfo> items) {
- List<ItemInfo> itemInfoList =new ArrayList<>();
-
- for(int i=0;i<items.size();i++){
- String pkg = items.get(i).getTargetPackage();
- boolean isHideApk = HideApkUtils.getInstall().isHidedApkPackageName(pkg);
- if(isHideApk){
- continue;
- }
- itemInfoList.add(items.get(i));
- }
- mPendingPredictedItems = null;
- mPredictedApps.clear();
- mPredictedApps.addAll(itemInfoList.stream()
- .filter(itemInfo -> itemInfo instanceof WorkspaceItemInfo)
- .map(itemInfo -> (WorkspaceItemInfo) itemInfo).collect(Collectors.toList()));
- applyPredictionApps();
- }
这正是加载搜索预测apk,我们可以在这里加上业务逻辑代码即可:
private void applyPredictedApps(List<ItemInfo> items) {
List<ItemInfo> itemInfoList =new ArrayList<>();
for(int i=0;i<items.size();i++){
String pkg = items.get(i).getTargetPackage();
boolean isHideApk = HideApkUtils.getInstall().isHidedApkPackageName(pkg);
if(isHideApk){
continue;
}
itemInfoList.add(items.get(i));
}
mPendingPredictedItems = null;
mPredictedApps.clear();
mPredictedApps.addAll(itemInfoList.stream()
.filter(itemInfo -> itemInfo instanceof WorkspaceItemInfo)
.map(itemInfo -> (WorkspaceItemInfo) itemInfo).collect(Collectors.toList()));
applyPredictionApps();
}
标红的代码就是加入修改之处。
4.1 未隐藏前图,红线标注为需要隐藏的apk
4.2 隐藏后的效果图
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。