動態更換應用Icon
產品:我們可以動態更換App在Launcher裡面的Icon嗎
開發:不可以
產品:我們可以動態更換App在Launcher裡面的Icon嗎
開發:不可以
產品:我們可以動態更換App在Launcher裡面的Icon嗎
開發:不可以
產品:我們可以動態更換App在Launcher裡面的Icon嗎
開發:讓我想想……
原理1——activity-alias
在AndroidMainifest中,有兩個屬性:
// 決定應用程式最先啟動的Activity
android.intent.action.MAIN
// 決定應用程式是否顯示在程式列表裡
android.intent.category.LAUNCHER複製程式碼
另外,還有一個activity-alias屬性,這個屬性可以用於建立多個不同的入口,相信做過系統Setting和Launcher開發的開發者在系統的原始碼中應該見過很多。
原理2——PM.setComponentEnabledSetting
PackageManager是一個大統領類,可以管理所有的系統元件,當然,如果Root了,你還可以管理其它App的所有元件,一些系統優化工具就是通過這個方式來禁用一些後臺Service的。
使用方式異常簡單:
private void enableComponent(ComponentName componentName) {
mPm.setComponentEnabledSetting(componentName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
private void disableComponent(ComponentName componentName) {
mPm.setComponentEnabledSetting(componentName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}複製程式碼
根據PackageManager.COMPONENT_ENABLED_STATE_ENABLED和PackageManager.COMPONENT_ENABLED_STATE_DISABLED這兩個標誌量和對應的ComponentName,就可以控制一個元件的是否啟用。
動態換Icon
有了上面的兩個原理,來實現動態更換Icon就只剩下思路問題了。
首先,我們建立一個Activity,作為預設的入口並帶著預設的圖片,再建立一個雙11的activity-alias,指向預設的Activity並帶有雙11的圖片,再建立一個雙12的activity-alias,指向預設的Activity並帶有雙12的圖片……等等等。
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity-alias
android:name=".Test11"
android:enabled="false"
android:icon="@drawable/s11"
android:label="雙11"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".Test12"
android:enabled="false"
android:icon="@drawable/s12"
android:label="雙12"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>複製程式碼
等等,這樣有個問題,那就是這樣會在Launcher上顯示3個入口,所以,預設我們會把這些activity-alias先禁用,等到要用的時候再啟用,養兵千日,用兵一時。
public class MainActivity extends AppCompatActivity {
private ComponentName mDefault;
private ComponentName mDouble11;
private ComponentName mDouble12;
private PackageManager mPm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDefault = getComponentName();
mDouble11 = new ComponentName(
getBaseContext(),
"com.xys.changeicon.Test11");
mDouble12 = new ComponentName(
getBaseContext(),
"com.xys.changeicon.Test12");
mPm = getApplicationContext().getPackageManager();
}
public void changeIcon11(View view) {
disableComponent(mDefault);
disableComponent(mDouble12);
enableComponent(mDouble11);
}
public void changeIcon12(View view) {
disableComponent(mDefault);
disableComponent(mDouble11);
enableComponent(mDouble12);
}
private void enableComponent(ComponentName componentName) {
mPm.setComponentEnabledSetting(componentName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
private void disableComponent(ComponentName componentName) {
mPm.setComponentEnabledSetting(componentName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
}複製程式碼
OK了,禁用預設的Activity後,啟用雙11的activity-alias,結果不變還是指向了預設的Activity,但圖示已經發生了改變。
根據ROM的不同,在禁用了元件之後,會等一會,Launcher會自動重新整理圖示。
效果參考下圖。
更多內容請關注我的微信公眾號: