Android 7.1.2 原始碼修改,使用自己的 app 作為預設桌面,不彈出桌面選擇彈窗
阿新 • • 發佈:2019-01-06
需求:使用自己開發的桌面 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
內容,以上。