Android 7.1.2 源码修改,使用自己的 app 作为默认桌面,不弹出桌面选择弹窗

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ganfanzhou/article/details/85250780

需求:使用自己开发的桌面 app 作为默认,不再出现桌面选择

在不修改源码前提下,可以设置自己的app为桌面,但是如果自己的应用出现崩溃,则在 Android 启动机制下会弹出桌面选择弹窗,如果在定制的系统中,这个是不能接受的,但本身在开发也需要使用默认 launcher 进行其他的一些设置,所以需要保留多个桌面启动器。

1、解决思路

在没有自己的启动器时候,由系统自己处理,即弹出弹窗选择或者使用自带的 Launcher3 桌面;在自己app存在情况下,使用自身app,拒绝弹窗选择。

2、分析

从启动器弹窗我们可以知道,假如只有一个启动器的情况下,是不会出现列表选择的,直接作为默认,所以我们只需判断已安装应用是否存在我们自身的app,如果存在,则清空显示的列表,只添加我们的app进去,如果不存在,默认处理。

3、处理

修改的源码为 ResolverActivity.class 代码位置 /frameworks/base/core/java/com/android/internal/app/ResolverActivity.java ,我这里只处理 Android 7.1.2,其他版本可能存在差异,但处理逻辑是一致的。

首先定位到适配器 ResolveListAdapter,直接在它数据更新的地方做我们的数据处理,修改的方法是 private void rebuildList() (重建数据源),修改如下:

	private void rebuildList() {
            //··· 省略代码
            // Clear the value of mOtherProfile from previous call.
            mOtherProfile = null;
            mDisplayList.clear();
            //第一次进来一定是null,可以看 onCreate 的调用
            if (mBaseResolveList != null) {
                currentResolveList = mOrigResolveList = new ArrayList<>();
                addResolveListDedupe(currentResolveList, getTargetIntent(), mBaseResolveList);
            } else {
                final boolean shouldGetResolvedFilter = shouldGetResolvedFilter();
                final boolean shouldGetActivityMetadata = shouldGetActivityMetadata();
                for (int i = 0, N = mIntents.size(); i < N; i++) {
                    final Intent intent = mIntents.get(i);
                    //根据 intent 来查询完全匹配的应用
                    final List<ResolveInfo> infos = mPm.queryIntentActivities(intent,
                            PackageManager.MATCH_DEFAULT_ONLY
                            | (shouldGetResolvedFilter ? PackageManager.GET_RESOLVED_FILTER : 0)
                            | (shouldGetActivityMetadata ? PackageManager.GET_META_DATA : 0));
                    // Remove any activities that are not exported.
                    int totalSize = infos.size();
                    for (int j = totalSize - 1; j >= 0 ; j--) {
                        ResolveInfo info = infos.get(j);
                        if (info.activityInfo != null && !info.activityInfo.exported) {
                            infos.remove(j);
                        }

                        //********************
                        //增加的部分代码
                        //如果包名是我们自己的应用,就清空,只保留我们自己的app
                        //如果没有我们的应用,系统默认处理
                        //********************
                        if(info.activityInfo != null && "com.package.xxx".equals(info.activityInfo.packageName)){
                            infos.clear();
                            infos.add(info);
                            break;
                        }

                    }
                    if (infos != null) {
                        if (currentResolveList == null) {
                            currentResolveList = mOrigResolveList = new ArrayList<>();
                        }
                        addResolveListDedupe(currentResolveList, intent, infos);
                    }
                }
                //···省略代码
            }

4、总结

以上重编译系统即可。查其他文章有说到去修改 ActivityManagerService 里面的 getHomeIntent(),但感觉影响不大,我这边没修改,只修改上面已符合我的需求,如果有需要可以自己尝试修改 ActivityManagerService 内容,以上。

猜你喜欢

转载自blog.csdn.net/ganfanzhou/article/details/85250780