安卓程式碼動態切換APP啟動圖示
阿新 • • 發佈:2019-01-28
目錄
前言
每當雙11時,手機中的“天貓”的圖示就會變成雙11主題的圖示。這是怎麼實現的呢?
有人說是更新App,沒錯,可以實現。但是有些大材小用了,畢竟更新一個版本。
個人猜測是在雙11前的某次更新版本時已將節日圖片資源打包入內,根據伺服器提供的資料動態改變。所以就有了本文
需要用到的知識:activity-alias
alias 英 [ˈeɪliəs] 美 [ˈeliəs, ˈeljəs]
n. 別名,化名;顧名思義,activity-alias並不是代表一個Activity,而是代表一個已經存在的Activity的別名。
它使用在清單檔案中,類似Activity標籤。它可用來設定某個Activity的快捷入口
activity-alias基本用法
<activity-alias android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
android:name="string"
android:permission="string"
android:targetActivity="string" >
...
</activity-alias>
屬性解釋:
屬性 | 含義 |
---|---|
enabled | 是否生效。配置多個activity-alias時,如果只想一個生效,就設定一個為true |
exported | 是否可以被其他應用調起,配置intent-filter時預設為true,未配置intent-filter時預設為false,只能被應用自身調起 |
icon | 自定義生效時的icon |
label | 作用同Activity標籤中的label屬性,主要表現為桌面上的app名稱和activity的title的名稱 |
name | 該activity-alias的名字 |
permission | 指明通過別名宣告調起目標Activity所必需的許可權 |
targetActivity | 指明目標Activity,類似於Activity標籤中的name屬性,需寫明包類路徑。表明通過activity-alias調起的是哪個Activity |
程式碼範例:
- AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="Android ICON"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<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=".MainAliasActivity"
android:targetActivity=".MainActivity"
android:label="UNIQLO ICON"
android:icon="@mipmap/ic_launcher_change"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
</application>
這裡聲明瞭一個activity-alias,目標Activity為MainActivity,label為“UNIQLO ICON”,指定了一個與原icon不同的icon,目前未啟用
我們在MainActivity中增加兩個按鈕,用於切換icon
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<Button
android:layout_margin="10dp"
android:id="@+id/mChangeToAndroid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="安卓安卓" />
<Button
android:layout_margin="10dp"
android:id="@+id/mChangeToUniQlo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="一庫一庫" />
</LinearLayout>
在MainActivity中對按鈕的點選事件進行處理,並進行相應的切換操作
- MainActivity.class
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
Button mChangeToAndroid = (Button) findViewById(R.id.mChangeToAndroid);
Button mChangeToUniQlo = (Button) findViewById(R.id.mChangeToUniQlo);
mChangeToAndroid.setOnClickListener(this);
mChangeToUniQlo.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.mChangeToAndroid:
changeIcon("com.hansion.changelaunchericon.MainActivity");
break;
case R.id.mChangeToUniQlo:
changeIcon("com.hansion.changelaunchericon.MainAliasActivity");
break;
default:
break;
}
}
public void changeIcon(String activityPath) {
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(getComponentName(),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(new ComponentName(this, activityPath),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
//重啟桌面 加速顯示
// restartSystemLauncher(pm);
}
public void restartSystemLauncher(PackageManager pm) {
ActivityManager am = (ActivityManager) getSystemService(Activity.ACTIVITY_SERVICE);
Intent i = new Intent(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
i.addCategory(Intent.CATEGORY_DEFAULT);
List<ResolveInfo> resolves = pm.queryIntentActivities(i, 0);
for (ResolveInfo res : resolves) {
if (res.activityInfo != null) {
am.killBackgroundProcesses(res.activityInfo.packageName);
}
}
}
}
- 通過以上程式碼切換icon後,需在桌面等待數秒鐘後生效。如下圖:
- 如果需要加速生效,則需要在更改icon後重啟一下系統桌面。解開第34行程式碼的註釋,增加許可權
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
如下圖:
需要注意的是,更換icon會關閉App,所以切換icon要選擇一個合適的時機來進行操作。
個人認為本文中切換APP啟動方式一定不是最好的方式,圖片資源從伺服器動態獲取才更靈活。如果你有更好的實現方式,請留言給我,謝謝。