Android 8.1.0 之在 Launcher 中隐藏指定应用的图标

        有一些 工具应用 或者 测试应用,其实是预置到系统中的,但是肯定不能让它们在桌面( Launcher )中显示出来。所以提供 rom 的时候一般会有这种需求:隐藏指定应用图标。

        这里有两个方案(无论以下哪种方案,均可以在 设置 -> 应用和通知 -> 所有应用  中查看到被隐藏的应用,解决方案):

      【方案一】:在编译这个被指定的应用的时候,在该应用功能清单 AndroidManifest.xml 中入口 Activity 节点下,去掉:,添加上:  和    (去掉 之后,编译出来的应用安装到设备上就不会再有桌面 icon;之所以添加了   和    是想可以用 intent 携带 action 的方式可以启动起这个 Activity)。

 

        【方案二】:在 Launcher3 应用中做一些修改。当Launcher3 中加载显示系统中所有应用的 icon 的时候做判断:当应用的包名是指定的需要隐藏的应用的时候,不在 Launcher3 中加载该应用 icon (有坑:需要多处修改)。 

          因为方案一比较简单,不用在这里做过多的解释,下面说以下方案二的具体实现过程,以及最后,说一下方案一和方案二分别在什么情况下使用。

          首先,在 Launcher 源码中有一个类叫做 LoaderTask.java ,对于这个类的官方描述如下:

 Runnable for the thread that loads the contents of the launcher:
 - workspace icons
 - widgets
 - all apps icons
 - deep shortcuts within apps

简而言之:Launcher3 中桌面应用 icon、小部件 等快捷方式的加载,都是在这个Runnable 的实现类中去做的。

在这个类中找到方法:loadAllApps() 方法,修改如下:

    private void loadAllApps() {
        final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;

        final List profiles = mUserManager.getUserProfiles();

        // Clear the list of apps
        mBgAllAppsList.clear();
        for (UserHandle user : profiles) {
            // Query for the set of apps
            final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
            final List apps = mLauncherApps.getActivityList(null, user);
            if (DEBUG_LOADERS) {
                Log.d(TAG, "getActivityList took "
                        + (SystemClock.uptimeMillis() - qiaTime) + "ms for user " + user);
                Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user);
            }
            // Fail if we don't have any apps
            // TODO: Fix this. Only fail for the current user.
            if (apps == null || apps.isEmpty()) {
                return;
            }
            boolean quietMode = mUserManager.isQuietModeEnabled(user);
            // Create the ApplicationInfos
            for (int i = 0; i < apps.size(); i++) {
                LauncherActivityInfo app = apps.get(i);
                //关键代码
                //Modify by hgd,does not show some apps in launcher.
                if (!appNeedHideInLauncher(app.getComponentName().getPackageName())){
                    // This builds the icon bitmaps.
                    mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);
                }
                //end Modify by hgd
            }

            ManagedProfileHeuristic.onAllAppsLoaded(mApp.getContext(), apps, user);
        }

        //code...

    }

可以看到关键代码部分即对当前应用的包名做判断,具体方法是:

    /**
     * Check if app need hide in launcher.
     * @param packageName package name of app.
     * @return
     */
    private boolean appNeedHideInLauncher(String packageName){
        boolean needHideInLauncher = false;
        if (APP_XXXXX_PACKAGE_NAME.equals(packageName) ||
                APP_XXXXXX_PACKAGE_NAME.equals(packageName)){
            needHideInLauncher = true;
        }
        return needHideInLauncher;
    }

          修改了这处,即可实现在Launcher3 首次加载所有应用图标的时候,不加载指定应用的icon 到桌面。但是,到这里还没算完成。我们的设备是支持儿童模式的,有时候会发现在儿童模式和非儿童模式之间进行切换的时候,已经被隐藏掉的应用还会显示出来,经过代码跟踪,找到还需要在 PackageUpdatedTask.java 中的 execute()方法中的  case OP_UPDATE: 中做一下和上面一样的判断:当应用的包名是指定的需要隐藏的应用的时候,不在 Launcher3 中加载该应用 icon。

          这两个方案怎么选择其实一目了然:当我们可以touch 到 Launcher3 源码的情况下,最好还是在Launcher3 中进行修改,这样最保险;如果我们不能修改 Launcher3 的代码,那么我们可以选择方案一,并且最好是在这个指定的需要隐藏的应用的入口Activity 节点下添加一个约定好的 action,这样虽然这个应用图标在 Launcher3 中不可见,但是我们仍然可以通过其他应用的 intent 携带着这个约定好的 action 把这个隐藏了图标的应用启动起来。

 

        参考:

        https://blog.csdn.net/yxdspirit/article/details/78793179

        https://blog.csdn.net/u010784887/article/details/51598719

 

 

          

你可能感兴趣的:(Android 8.1.0 之在 Launcher 中隐藏指定应用的图标)