最近使用 Todoist 做任務管理時發現,App 內有提供自選圖標的功能,也就是動態更換 App 的 Launcher Icon。
Step 0 | Step 1 | Step 2 | Step 3 |
---|---|---|---|
按下按鈕啟用自選圖標功能。 | 原本 App 預設是紅色的 App Icon。 | 在 App 內設定指定的 Icon 後。 | Launcher 上的 Todoist Icon 就真的換剛才所選的 App Icon 了! |
另外一個 App DuckDuckGo 也有一樣的功能。不過操作流程上不太一樣。DuckDuckGo 不需要特別啟用自選圖標,但在每次更換 Icon 時,App 都會在設定完成後自動關閉,使用者必須自動重啟 App 才能繼續使用。
🚩 兩者使用體驗差異整理:
如果想直接看怎麼做,可以跳到 三、解決方案。
搜尋幾個關鍵字其實滿快就找到相關的解法了,基本上分成使用 AndroidManifest.xml
的 activity-alias
更換 App 進入點的參數,或是使用 App Shortcuts。
Shortcuts 比較代表性的 App 是 Instagram。但仔細觀察兩個 App 所呈顯出來的效果,可以確定不是透過建立 Shortcut 的方式更換 Icon,比較接近第一種方式。
activity-alias
有關activity-alias
的操作方式 StackOverflow 都有,但我最後選擇跟著 Dynamic App Icon In Android 這篇文章一起實作,發現確實可以更換 App Icon。
這個方法是透過,在 AndroidManifest.xml
中建立 MainActivity
的 activity-alias
,每一個版本的 Icon 都會需要一個對應的 activity-alias
。
💡 什麼是 activity-alias
?
顧名思義,就是 Activity
的別名(alias)。
activity-alias
在 AndroidManifest
中的順序,必須在它的目標 Activity
之後。activity
tag 有的屬性欄位它都有。activity-alias
裡的屬性可以視為是 activity
tag 的子集(subset),設定完成後,在程式中動態的啟用與關閉 activity-alias
來達到更換 Icon 的效果。
🚨 前面所完成的版本,雖然可以動態改 Icon,但是會有以下幾個問題:
activitiy-alias
的狀態下,透過 IDE 是沒辦法重新 Install App 的。會出現 Error running 'app': Activity class {tw.dh46.dynamicicon/tw.dh46.dynamicicon.MainActivity} does not exist
的錯誤。如果要透過 IDE Reinstall,就必須換回原本的 activity
tag。細讀 StackOverflow: Change Android Launcher Icon like Instagram/Todoist 裡的討論,與 Github oguzhanaslann/DynamicIcon 專案,並查看反編譯 Todoist 後得到的 AndroidManifest.xml
。
整理出最終的設計流程大概是下方這樣。
AndroidManifest.xml
activity-alias
AndroidManifest
中的 activitiy-alias
除了要更換的種類外,要再建立兩個特殊的 activitiy-alias
。
activity-alias
。(後面用 BuildIn
代稱)activity-alias
。(後面用 Default
代稱)activity-alias
AppIconManager
封裝更換的邏輯activateFeature()
首次啟用更換 Icon 功能時執行,App 會自動關閉,需要使用者自行重開 App。
BuildIn
設為 COMPONENT_ENABLED_STATE_DISABLED
Default
設為 COMPONENT_ENABLED_STATE_ENABLED
setActiveAppIcon()
啟用後更換 Icon 時執行,App 不會自動關閉,且 Icon 已換成設定的樣式。
Default
設為 COMPONENT_ENABLED_STATE_DEFAULT
activity-alias
設為 COMPONENT_ENABLED_STATE_ENABLED
deactivateFeature()
要停用切換功能時執行。
BuildIn
設為 COMPONENT_ENABLED_STATE_ENABLED
Default
設為 COMPONENT_ENABLED_STATE_DEFAULT
改成其他 Alias 後,透過 IDE 重 build App 會出現
這部分是因為 ADB 執行的指令會是:
但是更換 Icon 後,activity-alias
已經不再是 MainActivityBuiltIn
,所以才會無法透過 IDE 啟動 App。
activity-alias
新图标的启动在代码中控制,之后发版不要轻易删除别名列表,否则覆盖安装时,当前展示的别名图标被删除了会引发找不到activity崩溃