Android 设置默认Launcher

用户有动态设置launcher的需求。
网上有各种五花八门的方法,复杂,好像也不是都起作用。
我这边实测下来,有一个很简单的方法就可以实现。

先上结论:
需要修改的文件为 frameworks\base\services\core\java\com\android\server\am ActivityManagerService.java

修改函数getHomeIntent如下:

Intent getHomeIntent() {
        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
        //修改设置的Component
        //intent.setComponent(mTopComponent);
        intent.setComponent(getDefaultActivity());
        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        return intent;
    }

可以看到,实际上只修改了一行代码,将intent.setComponent()的参数由mTopComponent替换为我们指定的default Activity。这样其实已经大功告成了。
但是,如何知道我们默认package的启动Activity呢, 所以添加了getDefaultActivity()这个函数,作用是根据package name 获得启动activity的名称:

private ComponentName getDefaultActivity() {
        ComponentName defComp = null;
        // 默认启动的apk,可以修改为任意包名。
        // 也可以修改为通过property或settings动态设置
        String pkgDef = "com.android.launcher";
        Slog.i(TAG, "defautl packageName = " + pkgDef);
        Intent launcherIntent = new Intent("android.intent.action.MAIN", null);
        launcherIntent.setPackage(pkgDef);
        List<ResolveInfo> localResolveInfo = mContext.getPackageManager().queryIntentActivities(launcherIntent, 0);
        if (!localResolveInfo.isEmpty()) {
            ActivityInfo activityInfo = localResolveInfo.get(0).activityInfo;
            if (activityInfo != null) {
                Log.d(TAG, "get default activity" + activityInfo.name);
                defComp = new ComponentName(pkgDef, activityInfo.name);
            }
        }
        return defComp;
    }

编译,测试,已经起作用了。

下面解释下为什么要这么改:
在函数startHomeActivityLocked中,如下两行代码决定默认启动的Activity:

Intent intent = getHomeIntent();
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);

跟踪到resolveActivityInfo这个函数

private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
        ActivityInfo ai = null;
        //下面的逻辑和此处获得的ComponentName有关
        ComponentName comp = intent.getComponent();
        try {
            if (comp != null) {
                // Factory test.
                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
            } else {

这个函数的逻辑是:如果intent.getComponent()为空,就会返回ResolverActivity,也就是装了多个launcher时,开机时弹出的选择框。
而默认的intent.getComponent返回的Component其实是getHomeIntent里设置的mTopComponent,搜索上下代码可以发现mTopComponent=NULL。所以默认会弹出选择框。

既然这样,要想不弹出选择框,而是直接进入默认应用,需要在intent.getComponent()返回我们需要的ComponentName。
也就是说在getHomeIntent()返回的Intent中,包含我们要启动的ComponentName。
故,修改getHomeIntent(),将mTopComponent替换为我们想启动的Activity。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值