1. 程式人生 > >Android 7.1.2 原始碼修改,使用自己的 app 作為預設桌面,不彈出桌面選擇彈窗

Android 7.1.2 原始碼修改,使用自己的 app 作為預設桌面,不彈出桌面選擇彈窗

需求:使用自己開發的桌面 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 內容,以上。