Android系统 修改无源码普通应用为默认Launcher和隐藏Settings中应用信息图标

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Android系统 修改无源码普通应用为默认Launcher和隐藏Settings中应用信息图标

在Android系统定制开发中,有时我们需要实现一些特殊的功能,比如修改应用为默认的launcher,或者隐藏应用的图标,让用户无法直接启动或卸载应用。这些功能在一些定制化的场景中可能会用到,比如智能电视、数字标牌等。但如果我们没有源码的话,要实现这些功能就不是那么容易了(主要是沙笔客户不愿意改)。因为Android系统对这些功能有一些限制和保护机制,我们需要绕过这些限制才能达到我们的目的。

在本文中,我将介绍如何在Android系统修改应用为默认launcher和隐藏应用图标的方法。这些方法是基于无源码的情况下进行的,只需要修改系统pms解析Androidmanifes.xml解析部分逻辑即可。当然这些方法可能并不是通用的,可能在不同的设备和系统版本上有所差异,需要根据具体情况进行调整和测试,我在这里只是提供思路。

参考学习:

Android 11 PackageManagerService源码分析(一):PMS启动的总体流程

PMS工作原理解析——app目录的解析流程(Android12)

PMS解析部分简单分析

PMS(PackageManagerService)是Android系统中负责管理应用程序的核心服务,它的主要功能包括:

  • 解析和安装应用程序的apk文件,包括系统应用和用户应用
  • 维护应用程序的信息和状态,包括包名、版本、权限、签名、组件等
  • 根据Intent过滤器匹配合适的组件,如Activity、Service、Provider和Receiver等
  • 检查应用程序的权限和签名,保证系统的安全性和一致性
  • 提供PackageManager接口供其他应用或服务调用,获取或修改应用程序的相关信息

android11+对pms的解析部分做了一些重构和优化,将一些类和方法从PackageManagerService和PackageParser中分离出来,放到了parsing包和component包下。

frameworks/base/core/java/android/content/pm/ 文件夹下

parsing包下主要有以下几个类:

  • ParsingPackage:这是一个接口定义了一个应用程序的基本信息和组件的集合,相当于原来的Package对象。
  • ParsingPackageImpl:这是ParsingPackage接口的实现类提供了一些构造方法和辅助方法。
  • ParsingPackageRead:这是一个抽象类继承自ParsingPackageImpl,提供了一些只读的方法,用于获取应用程序的信息和组件。
  • ParsingPackageUtils:这是一个工具类提供了一些静态方法,用于从ParsingPackage对象中获取或转换一些数据。
  • ParsingUtils:这是一个工具类提供了一些静态方法,用于解析或校验一些数据。

component包下主要有以下几个类:

  • ParsedComponent:这是一个抽象类定义了一个应用程序组件的基本信息,相当于原来的Component对象。
  • ParsedComponentUtils:这是一个工具类提供了一些静态方法,用于从ParsedComponent对象中获取或转换一些数据。
  • ParsedActivity、ParsedService、ParsedProvider、ParsedInstrumentation:这些都是ParsedComponent的子类,分别对应Activity、Service、Provider和Instrumentation组件 。
  • ParsedActivityUtils、ParsedServiceUtils、ParsedProviderUtils、ParsedInstrumentationUtils:这些都是工具类,提供了一些静态方法,用于从相应的组件对象中获取或转换一些数据 。
  • ParsedIntentInfo:这是一个类,定义了一个Intent过滤器的信息,相当于原来的IntentFilter对象。
  • ParsedIntentInfoUtils:这是一个工具类提供了一些静态方法,用于解析或校验Intent过滤器。
  • ParsedMainComponent:这是一个抽象类,继承自ParsedComponent,并实现了Parcelable接口,用于表示可以通过Intent启动的组件。
  • ParsedMainComponentUtils:这是一个工具类,提供了一些静态方法,用于从ParsedMainComponent对象中获取或转换一些数据。
  • ParsedPermission、ParsedPermissionGroup:这些都是类,分别对应Permission和PermissionGroup组件 。
  • ParsedPermissionUtils:这是一个工具类提供了一些静态方法,用于解析或校验权限组件。
  • ParsedProcess:这是一个类,定义了一个进程的信息。
  • ParsedProcessUtils:这是一个工具类,提供了一些静态方法,用于从ParsedProcess对象中获取或转换一些数据。

以上就是parsing包和component包下的主要文件的作用和关系。

修改应用为默认Launcher

Launcher是Android系统的桌面应用,负责显示和启动其他应用。通常情况下,系统会有一个默认的Launcher,客户也可以从应用商店下载并安装其他的Launcher。当客户安装了多个Launcher时,系统会弹出一个选择框,让客户选择要使用哪个Launcher,并且可以设置是否记住这个选择。

如果我们想要让我们自己开发的应用成为默认的Launcher,而不让用户选择或者更改,我们可以通过以下步骤实现:

  1. 在我们的应用的AndroidManifest.xml文件中,为主Activity添加以下Intent过滤器:
<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.HOME" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

这样就可以让我们的应用响应HOME键和启动器图标的点击事件。

  1. 在我们系统源码mk或prop文件添加以下内容:
persist.custom_package.launcher=true
persist.custom_package.name=com.example.myapp

persist.custom_package.launcher是一个开关属性,表示是否启用无源码修改Launcher的功能;persist.custom_package.name是我们的应用的包名。


如果要修改无源码应用实现设置添加HOME属性,在frameworks/base/core/java/android/content/pm/parsing/component/ParsedIntentInfoUtils.java文件中,找到parseIntentInfo方法,并在其中添加以下代码:

launcherProperty = SystemProperties.get("persist.custom_package.launcher", "");
customPackageProperty = SystemProperties.get("persist.custom_package.name", "");
customClassNameProperty = SystemProperties.get("persist.custom_package.classname", "");
// ...
case "category": {
    String value = parser.getAttributeValue(PackageParser.ANDROID_RESOURCES,
            "name");
    // 添加的代码在这里
    if (launcherProperty.equals("true") && customPackageProperty.equals(className)) {
        intentInfo.addCategory("android.intent.category.HOME");
        intentInfo.addCategory("android.intent.category.DEFAULT");
        intentInfo.setPriority(1000);
    }
    // 到此为止
    if (value == null) {
        result = input.error("No value supplied for <android:name>");
    } else if (value.isEmpty()) {
        result = input.error("<android:name> has empty value");
    } else {
        intentInfo.addCategory(value.intern());
    }
    break;
}

这段代码的作用是读取系统属性,并根据属性值判断是否要为指定包名的Activity添加HOME和DEFAULT类别,并设置优先级为1000(最高)。这样就可以让该Activity成为添加HOME成为的Launcher。

这样就可以让该应用响应Home键和开机事件,再配合我这篇文章( Android系统 设置第三方应用为默认Launcher实现和原理分析)并且不会被其他Launcher替换。

就算不加我另外一篇设置默认强制锁launcher 也会弹出让你手动选择的。

隐藏应用图标

有时候,我们可能需要隐藏一些应用的图标,让它们不出现在Launcher中。例如,一些系统服务或者辅助功能等。这种情况下,我们可以通过以下步骤实现:

  1. 在我们的应用的AndroidManifest.xml文件中,为主Activity添加以下属性:
android:enabled="false"
 <activity
            android:name=".view.MainActivity"
            android:exported="true" android:theme="@style/Theme.AppCompat.Light.NoActionBar"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
               <!-- 添加-->
                <data android:name="com.custom.package.CustomActivity" ></data>
            </intent-filter>
        </activity>

这样就可以让我们的应用不显示。

2.在我们系统源码mk或prop文件添加以下内容或者手动setprop设置:

persist.custom_package.hide_icon=true
persist.custom_package.name=com.example.myapp

persist.custom_package.hide_icon是一个开关属性,表示是否启用无源码隐藏图标的功能;persist.custom_package.name是我们的应用的包名。

  1. frameworks/base/core/java/android/content/pm/parsing/component/ParsedIntentInfoUtils.java文件中,找到parseIntentInfo方法,并在其中添加以下代码:
launcherProperty = SystemProperties.get("persist.custom_package.launcher", "");
hideIconProperty = SystemProperties.get("persist.custom_package.hide_icon", "");
customPackageProperty = SystemProperties.get("persist.custom_package.name", "");
excludeFromRecentsProperty = SystemProperties.get("persist.custom_package.exclude_from_recents", "");
screenOrientationProperty = SystemProperties.get("persist.custom_package.screen_orientation", "");
customClassNameProperty = SystemProperties.get("persist.custom_package.classname", "");
Log.d("pms_test", "launcherProperty:"+launcherProperty+","+hideIconProperty+","+hideIconProperty+","+customPackageProperty+","+screenOrientationProperty);
// ...
case "data":
    /*if (hideIconProperty.equals("true") && customClassNameProperty.equals(className)) {
        intentInfo.addDataScheme("com.custom.package");
        intentInfo.addDataAuthority("CustomActivity", null);
        intentInfo.addDataAttribute("android:name", "com.custom.package.CustomActivity");
    }*/
    result = parseData(intentInfo, res, parser, allowGlobs, input);
    break;

这段代码的作用是读取系统属性,并根据属性值判断是否要为指定类名的Activity添加一个自定义的数据过滤器。这样就可以让该Activity不被Launcher匹配到,并且不显示图标。注意,这段代码是被注释掉的,因为它会导致一些问题,比如无法启动该Activity或等。所以这个功能只是作为一个演示,不建议使用(还没研究明白。。)。

隐藏Settings应用管理的应用显示

除了隐藏应用图标和通知,我们还可能需要隐藏一些应用的信息,让它们不出现在应用管理的列表中。例如一些系统服务或者辅助功能等。这种情况下,我们可以通过以下步骤实现:

  1. 在我们系统源码mk或prop文件添加以下内容或者手动setprop设置:
persist.custom_package.hide_icon=true
persist.custom_package.name=com.example.myapp

persist.custom_package.hide_icon是一个开关属性,表示是否启用无源码隐藏图标和信息的功能;persist.custom_package.name是我们的应用的包名。

  1. 在packages/apps/Settings/src/com/android/settings/applications/manageapplications/ManageApplications.java文件中,找到updateState方法,并在其中添加以下代码:
// 导入SystemProperties类
import android.os.SystemProperties;
// 定义两个静态变量,分别存储系统属性的值
private static String hideIconProperty;
private static String customPackageProperty;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...
    // 在onCreate方法中读取系统属性,并赋值给静态变量
    hideIconProperty = SystemProperties.get("persist.custom_package.hide_icon", "true");
    customPackageProperty = SystemProperties.get("persist.custom_package.name", "com.btf.rk3568_11_fw");
}
private void updateState() {
    // ...
    if (filterType == FILTER_APPS_POWER_WHITELIST ||
            filterType == FILTER_APPS_POWER_WHITELIST_ALL) {
        entries = removeDuplicateIgnoringUser(entries);
    }
    // 遍历应用列表,如果某个应用的包名与系统属性指定的包名相同,并且开关属性为true,则从列表中移除该应用
    for (int i = 0; i < entries.size(); i++) {
        AppEntry appEntry = entries.get(i);
        if (hideIconProperty.equals("true") && customPackageProperty.equals(appEntry.info.packageName)) {
            entries.remove(i);
            i--;
        }
    }
    mEntries = entries;
    mOriginalEntries = entries;
    notifyDataSetChanged();
}

这段代码的作用是读取系统属性,并根据属性值判断是否要移除指定包名的应用,不将其添加到应用管理的列表中。

  1. 在packages/apps/Settings/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java文件中,找到displayRecentApps方法,并在其中添加以下代码:
// 导入SystemProperties类
import android.os.SystemProperties;
// 定义两个静态变量,分别存储系统属性的值
private static String hideIconProperty;
private static String customPackageProperty;
public RecentNotifyingAppsPreferenceController(Context context, NotificationBackend backend,
        IUsageStatsManager usageStatsManager, UserManager userManager,
        Application app, Fragment host) {
    this(context, backend, usageStatsManager, userManager,
            app == null ? null : ApplicationsState.getInstance(app), host);
    // 在构造方法中读取系统属性,并赋值给静态变量
    hideIconProperty = SystemProperties.get("persist.custom_package.hide_icon", "");
    customPackageProperty = SystemProperties.get("persist.custom_package.name", "");
}
private void displayRecentApps() {
    // ...
    for (int i = 0; i < recentAppsCount; i++) {
        final NotifyingApp app = recentApps.get(i);
        // Bind recent apps to existing prefs if possible, or create a new pref.
        final String pkgName = app.getPackage();
        // 如果某个应用的包名与系统属性指定的包名相同,并且开关属性为true,则跳过该应用,不显示在最近通知应用列表中
        if (hideIconProperty.equals("true") && customPackageProperty.equals(pkgName)) {
            continue;
        }
        final ApplicationsState.AppEntry appEntry =
                mApplicationsState.getEntry(app.getPackage(), app.getUserId());
        if (appEntry == null) {
            continue;
        }
        // ...
    }
    // ...
}

这段代码的作用是读取系统属性,并根据属性值判断是否要跳过指定包名的应用,不将其显示在最近通知应用的列表中。

总结

本文介绍了如何在Android 11上无源码修改应用为默认Launcher和隐藏应用图标。这些功能可以通过设置一些系统属性和修改一些配置文件来实现,而不需要修改源码或者重新编译整个系统。当然,这些功能是学习PMS的一部分 实际要用需要大量测试修改的部分会不会影响到系统? 所以在使用这些功能时,需要根据具体的需求和场景进行权衡和选择。

希望本文对你有所帮助。谢谢!

目录
打赏
0
0
0
0
75
分享
相关文章
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
175 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
54 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
107 14
Android源码下载
Android源码下载
748 0
【Binder 机制】分析 Android 内核源码中的 Binder 驱动源码 binder.c ( googlesource 中的 Android 内核源码 | 内核源码下载 )(一)
【Binder 机制】分析 Android 内核源码中的 Binder 驱动源码 binder.c ( googlesource 中的 Android 内核源码 | 内核源码下载 )(一)
235 0
【Binder 机制】分析 Android 内核源码中的 Binder 驱动源码 binder.c ( googlesource 中的 Android 内核源码 | 内核源码下载 )(一)
【Android 安装包优化】p7zip 源码交叉编译 Android 平台可执行程序 ( 下载 p7zip 源码 | 交叉编译 Android 中使用 7z 可执行程序 )(二)
【Android 安装包优化】p7zip 源码交叉编译 Android 平台可执行程序 ( 下载 p7zip 源码 | 交叉编译 Android 中使用 7z 可执行程序 )(二)
280 0
【Android 安装包优化】p7zip 源码交叉编译 Android 平台可执行程序 ( 下载 p7zip 源码 | 交叉编译 Android 中使用 7z 可执行程序 )(二)
【Android 安装包优化】p7zip 源码交叉编译 Android 平台可执行程序 ( 下载 p7zip 源码 | 交叉编译 Android 中使用 7z 可执行程序 )(一)
【Android 安装包优化】p7zip 源码交叉编译 Android 平台可执行程序 ( 下载 p7zip 源码 | 交叉编译 Android 中使用 7z 可执行程序 )(一)
315 0
【Android 安装包优化】p7zip 源码交叉编译 Android 平台可执行程序 ( 下载 p7zip 源码 | 交叉编译 Android 中使用 7z 可执行程序 )(一)
【Android 安装包优化】WebP 应用 ( libwebp 源码下载 | Android.mk 和 Application.mk 构建脚本修改 | libwebp 函数库编译 )(二)
【Android 安装包优化】WebP 应用 ( libwebp 源码下载 | Android.mk 和 Application.mk 构建脚本修改 | libwebp 函数库编译 )(二)
287 0
【Android 安装包优化】WebP 应用 ( libwebp 源码下载 | Android.mk 和 Application.mk 构建脚本修改 | libwebp 函数库编译 )(二)

热门文章

最新文章

  • 1
    Android历史版本与APK文件结构
    13
  • 2
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    20
  • 3
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    9
  • 4
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    5
  • 5
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    7
  • 6
    escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
    3
  • 7
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    10
  • 8
    Android实战经验之Kotlin中快速实现MVI架构
    12
  • 9
    即时通讯安全篇(一):正确地理解和使用Android端加密算法
    9
  • 10
    android FragmentManager 删除所有Fragment 重建
    3
  • 1
    android FragmentManager 删除所有Fragment 重建
    20
  • 2
    Android实战经验之Kotlin中快速实现MVI架构
    36
  • 3
    即时通讯安全篇(一):正确地理解和使用Android端加密算法
    37
  • 4
    escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
    43
  • 5
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    151
  • 6
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    47
  • 7
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    64
  • 8
    Android历史版本与APK文件结构
    168
  • 9
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    51
  • 10
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    50
  • AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等