版权声明:本文为博主原创文章,未经博主允许不得转载。 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
内容,以上。