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

news2025/4/27 4:45:07

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

文章目录

  • 修改文件路径-实现方式
  • 基础-源码模块配置
    • Launcher3 源码位置
    • 编译模块配置
      • 配置如下参数 属性配置:
        • 默认的Launcher3 选项配置
        • GMS的Launcher3 配置
    • 第三方Launcher需要默认为Launcher时候-系统Launcher3 的配置
  • 参考资料
  • 实现方案
  • 源码分析
    • Launcher
    • LauncherModel
      • addCallbacksAndLoad 方法
      • startLoader
    • LoaderResults
    • BaseLoaderResults
      • bindAllApps
    • AllAppsList
  • 修改实现-举例说明
  • 总结


修改文件路径-实现方式

/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 源码路径如下:

/vendor/mediatek/proprietary/packages/apps/Launcher3

MTK 平台 GMS包 下

/vendor/google/apps/SearchLauncher
/vendor/google/overlay/gms_overlay/vendor/google/apps/SearchLauncher

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

编译模块配置

路径:

\device\mediatek\system\common\device.mk   

配置如下参数 属性配置:

默认的Launcher3 选项配置
#PRODUCT_PACKAGES += Launcher3

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

#PRODUCT_PACKAGES += MtkLauncher3QuickStep

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

/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

\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 相关

   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 方法

   /**
     * 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

    看这个方法里面的注释:
	    // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
 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 位置了:

  loaderResults.bindWorkspace(bindAllCallbacks);
  loaderResults.bindAllApps();
  loaderResults.bindDeepShortcuts();
  loaderResults.bindWidgets();

LoaderResults

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

/**
 * 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

我们看看这个类的定义:

/**
 * Stores the list of all applications for the all apps view.
 */
public class AllAppsList {

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

在这里插入图片描述

bindAllApps

   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 在哪里定义的:

    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嘛。

  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 相关基础知识,对业务和流程分析非常有好处的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2343765.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PostgreSQL 数据库备份与恢复全面指南20250424

PostgreSQL 数据库备份与恢复全面指南 在数据库管理中&#xff0c;备份与恢复操作对于确保数据安全性、可用性和完整性至关重要。PostgreSQL 作为一款开源关系型数据库系统&#xff0c;广泛应用于各行各业&#xff0c;尤其在现代 AI 和大数据应用中&#xff0c;作为数据存储的…

专家系统的知识获取、检测与组织管理——基于《人工智能原理与方法》的深度解析

前文我们已经了解了专家系统的基本概念和一般结构&#xff0c;系统中有专业的知识才是专家系统的关键&#xff0c;接下来对专家系统中的知识是如何获取、检测、组织和管理的进行探讨。 1.专家系统的基本概念&#xff1a;专家系统的基本概念解析——基于《人工智能原理与方法》…

让Editplus支持squirrel语言

用EditPlus配置完实现关键字、函数、高光代码、自动完成、代码调试。先看看效果&#xff1a; 主要是由 nut.stx &#xff08;语法文件&#xff09;和 nut.acp &#xff08;自动完成&#xff09;两个文件 实现 Nut.stx文件内容&#xff1a; ---------------------------------…

Leetcode 2845 题解

还是要把自己做题的思路写出来的&#xff0c;但是结果可能还是得去观摩一下题解&#xff0c;无论是大佬写的题解还是leetcode官方写的题解&#xff0c;看完题解后再去反思才能有收获&#xff0c;即使下次遇见一样的题不见得能写出来&#xff0c;但有思路比没思路更重要。 今天写…

【爬虫】DrissionPage-获取douyim用户下的视频

之前看过DrissionPage&#xff0c;觉得很厉害&#xff0c;比selenium简单&#xff0c;适合新手。因为盲目跟风逆向&#xff0c;今天看了一个DrissionPage案例直播&#xff0c;学习一下&#xff0c;真香哈。 DrissionPage官网&#xff1a;&#x1f6f0;️ 概述 | DrissionPage官…

【Python爬虫基础篇】--3.cookie和session

目录 1.cookie 1.1.定义 1.2.参数 1.3.分类 2.session 3.使用cookie登录微博 4.使用session登录 1.cookie 由于http是一个无状态的协议&#xff0c;请求与请求之间无法相互传递或者记录一些信息&#xff0c;cookie和session正是为了解决这个问题而产生。 例子&#xff1…

分数线降低,25西电马克思主义学院(考研录取情况)

1、马克思主义学院各个方向 2、马克思主义学院近三年复试分数线对比 学长、学姐分析 由表可看出&#xff1a; 1、马克思主义理论25年相较于24年下降10分&#xff0c;为355分 3、25vs24推免/统招人数对比 学长、学姐分析 由表可看出&#xff1a; 1、 马克思主义学院25年共接…

Cancer Cell|scRNA-seq + scTCR + 空间多组学整合分析,揭示CD8⁺ T细胞在免疫治疗中的“双路径” | 临床问题的组学解答

Cancer Cell&#xff5c;scRNA-seq scTCR 空间多组学整合分析&#xff0c;揭示CD8⁺ T细胞在免疫治疗中的“双路径” &#x1f44b; 欢迎关注我的生信学习专栏~ 如果觉得文章有帮助&#xff0c;别忘了点赞、关注、评论&#xff0c;一起学习 近日&#xff0c;《Cancer Cell》…

C# 下 using 块的作用 + VS2022 下 using 语法糖怎样工作

&#x1f50d; using 的本意是什么&#xff1f; using 是 C# 中用于 自动释放资源 的语法糖&#xff0c;适用于实现了 IDisposable 接口的对象&#xff08;比如数据库连接、文件、网络流等&#xff09;。 &#x1f9d0; 首先看下SqlSugarClient类部分源码&#xff1a; SqlSug…

实体店的小程序转型之路:拥抱新零售的密码-中小企实战运营和营销工作室博客

实体店的小程序转型之路&#xff1a;拥抱新零售的密码-中小企实战运营和营销工作室博客 在当今数字化浪潮的冲击下&#xff0c;实体店面临着前所未有的挑战&#xff0c;但小程序的出现为实体店转型新零售带来了新的曙光。先来看一组惊人的数据&#xff0c;据相关统计&#xff…

UML 类图基础和类关系辨析

UML 类图 目录 1 概述 2 类图MerMaid基本表示法 3 类关系详解 3.1 实现和继承 3.1.1 实现&#xff08;Realization&#xff09;3.1.2 继承/泛化&#xff08;Inheritance/Generalization&#xff09; 3.2 聚合和组合 3.2.1 组合&#xff08;Composition&#xff09;3.2.2 聚…

15.三数之和(LeetCode)java

个人理解&#xff1a; 1.使用双指针做法&#xff0c;首先对数组进行排序 第一重for循环控制第一个数&#xff0c;对数组进行遍历。双指针初始化为lefti1, rigthnums.length-1。然后使用while循环移动双指针寻找合适的数。因为返回的是数&#xff0c;不是下标&#xff0c;数不能…

如何通过 Websoft9 应用自托管平台一键安装任意版本 Odoo?

手工安装 Odoo 的复杂流程 环境准备阶段&#xff1a;安装 Docker 需熟悉 Linux 系统操作&#xff0c;需配置软件源、解决依赖冲突&#xff1b; 镜像获取阶段&#xff1a;从 Docker Hub 拉取官方镜像时可能因网络问题失败&#xff0c;且需自行验证版本兼容性&#xff1b; 容器…

VRRP与防火墙双机热备实验

目录 实验一&#xff1a;VRRP负载均衡与故障切换 实验拓扑​编辑一、实验配置步骤 1. 基础网络配置 2. VRRP双组配置 二、关键验证命令 1. 查看VRRP状态 2. 路由表验证 三、流量分析 正常负载均衡场景&#xff1a; 故障切换验证&#xff1a; 实验二&#xff1a;防火…

win11什么都不动之后一段时间黑屏桌面无法显示,但鼠标仍可移动,得要熄屏之后才能进入的四种解决方法

现象&#xff1a; 1. 当时新建运行的资源管理器的任务卡了或者原本资源管理器卡了 比如&#xff1a;当时在文本框中输入explorer 注&#xff1a;explorer.exe是Windows的文件资源管理器&#xff0c;它用于管理Windows的图形外壳&#xff0c;包括桌面和文件管理 按住CtrlAltEs…

基于LAB颜色空间的增强型颜色迁移算法

本文算法使用Grok完成所有内容&#xff0c;包含算法改进和代码编写&#xff0c;可大大提升代码编写速度&#xff0c;算法改进速度&#xff0c;提供相关idea&#xff0c;提升效率&#xff1b; 概述 本文档描述了一种基于LAB颜色空间的颜色迁移算法&#xff0c;用于将缩略图D的…

基于SIMMECHANICS的单自由度磁悬浮隔振器PID控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 单自由度磁悬浮减振器工作原理简介 4.2 SIMMECHANICS工具箱 5.完整工程文件 1.课题概述 基于SIMMECHANICS的单自由度磁悬浮隔振器PID控制系统simulink建模与仿真。其中&#xff0c;SIMMECHANICS是M…

C++初登门槛

多态 一、概念 多态是指不同对象对同一消息产生不同响应的行为。例如&#xff0c;蓝牙、4G、Wi-Fi 对“发送数据”指令有不同的具体实现。 二、核心理解 本质&#xff1a;通过基类指针或引用操作子类对象&#xff0c;实现运行时动态绑定。 表现形式&#xff1a; 接口统一&a…

红队系列-网络安全知识锦囊-CTF(持续更新)

CTF CTF系列-AWD专题篇CTF-比赛培训基础1 CTF 介绍HTTP协议分析进阶001.CTF简介_宽字节注入高级 2018CTF——黑客大赛特训CTF-PWNPWNCTF竞赛中的主要题型之一了解CTF Capture The Flag 夺旗描述:# gets从标准输入设备读字符串函数#下面是对main函数中的汇编代码的解释:modifi…

Windows环境下常用网络命令使用

ipconfig命令使用&#xff1a; ipconfig可用于显示当前的TCP/IP配置的设置值&#xff0c;通常是用来检验人工配置的TCP/IP设置是否正确。在网络连接出现问题时&#xff0c;可以使用ipconfig /release和ipconfig /renew命令来刷新IP地址&#xff0c;这通常能解决因IP地址冲突或…