MTKAndroid13-Launcher3 屏蔽部分app不让显示

实现Launcher3 桌面屏蔽部分内容,不让显示

文章目录


修改文件路径-实现方式

java 复制代码
/vendor/mediatek/proprietary/packages/apps/Launcher3/src/com/android/launcher3/model/AllAppsList.java


在copyData 方法中过滤

    public AppInfo[] copyData() {
        AppInfo[] result = data.toArray(EMPTY_ARRAY);
       /* Arrays.sort(result, COMPONENT_KEY_COMPARATOR);
        return result;*/
		
	
		 List<AppInfo> updatedAppInfos = new ArrayList<>();
        for(AppInfo info:result){
            if(info.componentName!=null){
                if(info.componentName.getPackageName().equals("com.android.documentsui")){
                    Log.d(TAG,"info. filter  :"+info.componentName.getPackageName());
                }else{
                    Log.d(TAG,"info  nofilter:"+info.componentName.getPackageName());
                    updatedAppInfos.add(info);
                }
            }
        }
        AppInfo[] result1= updatedAppInfos.toArray(new AppInfo[0]);
        Arrays.sort(result1, COMPONENT_KEY_COMPARATOR);
        return result1;
    }

基础-源码模块配置

源码里面的Launcher3 有 非GMS的和GMS的,特别对于MTK、高通、展讯 手机相关平台方案,两个类型Launcher3 模块共存的。 对于 RK 、全志下的大多工控产品下,源码是没有 GMS一说的。

Launcher3 源码位置

MTK 平台 非GMS 源码路径如下:

java 复制代码
/vendor/mediatek/proprietary/packages/apps/Launcher3

MTK 平台 GMS包 下

java 复制代码
/vendor/google/apps/SearchLauncher
/vendor/google/overlay/gms_overlay/vendor/google/apps/SearchLauncher

在GMS 情况下,为什么会有两个 SearchLauncher, 这是系统的机制而已, gms_overlay 文件夹下的app 包会覆盖非GMS的软件包。

编译模块配置

路径:

java 复制代码
\device\mediatek\system\common\device.mk   

配置如下参数 属性配置:

默认的Launcher3 选项配置
java 复制代码
#PRODUCT_PACKAGES += Launcher3

如果要使用MTK的GMS 包的 Launcher ,可以配置如下

java 复制代码
#PRODUCT_PACKAGES += MtkLauncher3QuickStep

对应的源码位置是如下两个,具体可以查阅下并进行实验:

java 复制代码
/vendor/google/apps/SearchLauncher
/vendor/google/overlay/gms_overlay/vendor/google/apps/SearchLauncher

其实这样配置的Launcher3 本身是属于GMS的,所以发现实际跑起来的Launcher是gms包,还带有开机向导。

GMS的Launcher3 配置

GMS 情况下,配置好GMS编译环境即可, 这样就会加载 gms 文件下的所有app 包,里面就有gms 包的Launcher3

java 复制代码
\device\mediatek\system\mssi_64_cn\SystemConfig.mk 文件下,配置BUILD_GMS = yes 

第三方Launcher需要默认为Launcher时候-系统Launcher3 的配置

实际工控产品或者消费产品非GMS产品中,客户自定义的Launcher 软件,那么如何配置默认的Launcherne ?

一般有两种解决方案:

  • 系统默认Launcher存在,在源码Framework层默认第三方Launcher为系统Launcher
  • 系统原生Launcher3 也编译到系统里面去,但是去掉Home 属性。
    如下:

参考资料

Android11.0内置第三方Launcher并设置为默认,保留Launcher3并可切换
设置三方应用为默认Launcher
动态设置默认Launcher
android 13.0-launcher3中workspaceapp列表页不显示某个app图标
Android13设置默认Launcher分析

其它相关Launcher 资料相关参考:

Launcher3 相关资料参考
菜鸟成长之路-源码分析专栏
Android Launcher3 简介
Launcher3 高端定制
Launcher3 开发
Launcher3 Android Code Search在线源码查看
Launcher3 xref 在线源码查看
Launcher3 RK 源码查看
Launcher3 解析
Launcher3 AndroidP AS版本
谷歌Launcher3 Android13源码修改
Launcher3 和 Launcher3QuickStep 区别
Android14 不分Launcher3修改
Launcher3 LoaderTask 的数据加载
Android14 浅析Launcher
Android O Launcher3-Workspace加载

  • 上面参考资料都是两种Launcher情况下默认其中一个Launcher 作为默认Launcher; 我们上面分析的是保证一个Launcher 即可,系统Launcher 其实去掉了HOME属性。
  • 系统Launcher3 开发,强烈建议多了解下Launcher3 相关的基础知识,数据架子-布局加载-框架相关基本内容,方便分析代码、实现功能,有相关思路。

实现方案

源码分析

Launcher

在onCreate 方法中,有下面这段代码,见名知意 module 相关

java 复制代码
   private LauncherModel mModel;

   @Override
    @TargetApi(Build.VERSION_CODES.S)
    protected void onCreate(Bundle savedInstanceState) {

    ...
	        mModel = app.getModel();

           if (!mModel.addCallbacksAndLoad(this)) {
            if (!internalStateHandled) {
                // If we are not binding synchronously, show a fade in animation when
                // the first page bind completes.
                mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0);
            }
        }
	...
	

}	

LauncherModel

addCallbacksAndLoad 方法

java 复制代码
   /**
     * Adds a callbacks to receive model updates
     * @return true if workspace load was performed synchronously
     */
    public boolean addCallbacksAndLoad(Callbacks callbacks) {
        synchronized (mLock) {
            addCallbacks(callbacks);
            return startLoader(new Callbacks[] { callbacks });

        }
    }

startLoader

复制代码
    看这个方法里面的注释:
java 复制代码
	    // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
java 复制代码
 private boolean startLoader(Callbacks[] newCallbacks) {
        // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
        ItemInstallQueue.INSTANCE.get(mApp.getContext())
                .pauseModelPush(ItemInstallQueue.FLAG_LOADER_RUNNING);
        synchronized (mLock) {
            // If there is already one running, tell it to stop.
            boolean wasRunning = stopLoader();
            boolean bindDirectly = mModelLoaded && !mIsLoaderTaskRunning;
            boolean bindAllCallbacks = wasRunning || !bindDirectly || newCallbacks.length == 0;
            final Callbacks[] callbacksList = bindAllCallbacks ? getCallbacks() : newCallbacks;

            if (callbacksList.length > 0) {
                // Clear any pending bind-runnables from the synchronized load process.
                for (Callbacks cb : callbacksList) {
                    MAIN_EXECUTOR.execute(cb::clearPendingBinds);
                }

                LoaderResults loaderResults = new LoaderResults(
                        mApp, mBgDataModel, mBgAllAppsList, callbacksList);
                if (bindDirectly) {
                    // Divide the set of loaded items into those that we are binding synchronously,
                    // and everything else that is to be bound normally (asynchronously).
                    loaderResults.bindWorkspace(bindAllCallbacks);
                    // For now, continue posting the binding of AllApps as there are other
                    // issues that arise from that.
                    loaderResults.bindAllApps();
                    loaderResults.bindDeepShortcuts();
                    loaderResults.bindWidgets();
                    return true;
                } else {
                    stopLoader();
                    // 数据加载 调用工作线程,规避主线程阻塞
                    mLoaderTask = new LoaderTask(
                            mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, loaderResults);

                    // Always post the loader task, instead of running directly
                    // (even on same thread) so that we exit any nested synchronized blocks
                    MODEL_EXECUTOR.post(mLoaderTask);
                }
            }
        }
        return false;
    }

这里找到相关的加载App 位置了:

java 复制代码
  loaderResults.bindWorkspace(bindAllCallbacks);
  loaderResults.bindAllApps();
  loaderResults.bindDeepShortcuts();
  loaderResults.bindWidgets();

LoaderResults

源码如下: 它是一个中间方法,暂未实质性功能,应该后面方便系统扩展和用户自己扩展了

java 复制代码
/**
 * Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.
 */
public class LoaderResults extends BaseLoaderResults {

    public LoaderResults(LauncherAppState app, BgDataModel dataModel,
            AllAppsList allAppsList, Callbacks[] callbacks) {
        super(app, dataModel, allAppsList, callbacks, MAIN_EXECUTOR);
    }

    @Override
    public void bindDeepShortcuts() {
    }

    @Override
    public void bindWidgets() {
    }
}

BaseLoaderResults

我们看看这个类的定义:

java 复制代码
/**
 * Stores the list of all applications for the all apps view.
 */
public class AllAppsList {

存储app 界面所有应用的集合。

bindAllApps

java 复制代码
   public void bindAllApps() {
        // shallow copy
        AppInfo[] apps = mBgAllAppsList.copyData();
        int flags = mBgAllAppsList.getFlags();
        executeCallbacksTask(c -> c.bindAllApplications(apps, flags), mUiExecutor);
    }

这里看到 AppInfo[] apps = mBgAllAppsList.copyData();,下面看到的 bindAllApplications 绑定所有app ,我们最好从顶层来处理拦截 部分不想显示的应用

那就看一下 mBgAllAppsList 在哪里定义的:

java 复制代码
    private final AllAppsList mBgAllAppsList;


  public BaseLoaderResults(LauncherAppState app, BgDataModel dataModel,
            AllAppsList allAppsList, Callbacks[] callbacksList, LooperExecutor uiExecutor) {
      。。。。
        mBgAllAppsList = allAppsList;
    。。。。
    }

所以继续找到 它的子类,上面我们说了它的子类LoadResults 只是一个中间类,再次贴出它的部分代码:

public class LoaderResults extends BaseLoaderResults {

    public LoaderResults(LauncherAppState app, BgDataModel dataModel,
            AllAppsList allAppsList, Callbacks[] callbacks) {
        super(app, dataModel, allAppsList, callbacks, MAIN_EXECUTOR);
    }


那么我们再次回到如上  LauncherModel 的startLoader 方法

 private boolean startLoader(Callbacks[] newCallbacks) {
    ........................
        synchronized (mLock) {
            // If there is already one running, tell it to stop.
            boolean wasRunning = stopLoader();
            boolean bindDirectly = mModelLoaded && !mIsLoaderTaskRunning;
            boolean bindAllCallbacks = wasRunning || !bindDirectly || newCallbacks.length == 0;
            final Callbacks[] callbacksList = bindAllCallbacks ? getCallbacks() : newCallbacks;

            if (callbacksList.length > 0) {
             ...............

                LoaderResults loaderResults = new LoaderResults(
                        mApp, mBgDataModel, mBgAllAppsList, callbacksList);
                if (bindDirectly) {
                    // Divide the set of loaded items into those that we are binding synchronously,
                    // and everything else that is to be bound normally (asynchronously).
                    loaderResults.bindWorkspace(bindAllCallbacks);
                    // For now, continue posting the binding of AllApps as there are other
                    // issues that arise from that.
                    loaderResults.bindAllApps();
                    loaderResults.bindDeepShortcuts();
                    loaderResults.bindWidgets();
                    return true;
                } else {
                    stopLoader();
                    // 数据加载 调用工作线程,规避主线程阻塞
                    mLoaderTask = new LoaderTask(
                            mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, loaderResults);

                    // Always post the loader task, instead of running directly
                    // (even on same thread) so that we exit any nested synchronized blocks
                    MODEL_EXECUTOR.post(mLoaderTask);
                }
            }
        }
        return false;
    }

那就继续追 LoaderResults 构造方法里面的第三个参数  mBgAllAppsList


找到变量定义如下:

    // < only access in worker thread >
    private final AllAppsList mBgAllAppsList;


找到它初始化地方:

    LauncherModel(Context context, LauncherAppState app, IconCache iconCache, AppFilter appFilter,
            boolean isPrimaryInstance) {
        mApp = app;
        mBgAllAppsList = new AllAppsList(iconCache, appFilter);
        mModelDelegate = ModelDelegate.newInstance(context, app, mBgAllAppsList, mBgDataModel,
                isPrimaryInstance);
    }


那么接下来要分析的就是 AllAppsList

AllAppsList

如上在分析 BaseLoaderResults 类的时候 ,已经分析到了 AllAppsList ,然后在bindAllApps 方法里面找到了 mBgAllAppsList.copyData(); ,最后反推到 AllAppsList , 这里需要分析的不就是 如上提到的 copyData嘛。

java 复制代码
  public AppInfo[] copyData() {
        AppInfo[] result = data.toArray(EMPTY_ARRAY);
        Arrays.sort(result, COMPONENT_KEY_COMPARATOR);
        return result;
    }

返回的是AppInfo 数组,那么我们过滤掉 我们不让显示的 App 不就解决了需求了嘛。 先看看 AppInfo

如类注释说明:它代表的就是一个展示在所有AppView 中的一个App . 我们可以通过它的属性类ComponentName 的包名来过滤掉我们想要隐藏的App

修改实现-举例说明

在第一个内容模块,已经说明了修改路径和修改方法,里面其实已经举例了修改的隐藏文件App

修改前:

修改之后,编译固件,开机后查看日志如下:说明修改已经起作用了。

最后看实际界面效果:可以看到文件app 已经被隐藏了,没有显示出来,但是这个app 是安装成功了的。

去系统设置看看,有木有这个app:看到是有这个app,已经安装过了的。 说明 隐藏成功了...

总结

  • 这个需求解决方案,完全根据代码找到并进行修改实现,思路还是很清晰的
  • 建议多看看Launcher 相关基础知识,对业务和流程分析非常有好处的。
相关推荐
毛豆的毛豆Y3 天前
AOSP Android14 Launcher3——动画核心类QuickstepTransitionManager详解
aosp·launcher3·android14
毛豆的毛豆Y8 天前
AOSP Android14 Launcher3——RecentsView最近任务数据加载
aosp·launcher3·android14
毛豆的毛豆Y8 天前
AOSP Android14 Launcher3——点击桌面图标启动应用动画流程
aosp·launcher3·android14
毛豆的毛豆Y9 天前
AOSP Android14 Launcher3——远程窗口动画关键类SurfaceControl详解
aosp·launcher3·android14
毛豆的毛豆Y15 天前
AOSP Android14 Launcher3——底部任务栏Taskbar详解
aosp·launcher3·android14
Sgq丶5 个月前
Android 13 aosp Launcher 隐藏“壁纸和样式“入口
android·aosp·launcher3
ItJavawfc6 个月前
Launcher3 去掉桌面搜索索框
launcher3·去掉搜索框·谷歌搜索框
Kwanvin8 个月前
Android13 Hotseat客制化--Hotseat修改布局、支持滑动、去掉开机弹动效果、禁止创建文件夹
android·java·launcher3·hotseat
Kwanvin8 个月前
仿华为车机UI--图标从Workspace拖动到Hotseat同时保留图标在原来位置
android·java·ui·华为·launcher3