Android开发三年了,今天才知道,可以给一个应用设置多个应用图标(启动图标),可以在程序中动态更换应用图标,作为一枚有三年工作经验的程序猿,今天才知道这事,被严重鄙视了。
下面就来说说如何给一个应用设置多个应用图标?
1. 如何给一个应用设置多个入口,在launcher桌面上存在多个启动图标?
我们知道,设置一个应用的入口Activity,只需要在AndroidMainfest.xml文件中,在注册activity的节点下添加intent-filter,并设置action属性为acion.MAIN, category属性为category.LAUNCHER,应用就会将此activity作为应用程序的入口。
<activity android:name=".TestInputActivity"
android:windowSoftInputMode="adjustResize"
android:icon="@mipmap/f_homepage_affari_notice_icon"
android:label="TestInputActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
这样该Activity就为应用程序的入口Activity,点击应用图标首次进入的界面。
在该activity标签下可以设置android:icon作为应用的图标, 设置android:label作为应用名称,如果没有设置启动Activity的icon和label属性,会默认使用application节点下icon和label属性中设置的应用图标和应用名称。
如果一个应用设置多个Activity的intent-filter属性下的action为action.MAIN, category属性为category.LAUNCHER,则应用就会在launcher的生成多个应用图标,每个应用名称分别是我们在activity标签下定义的Activity的android:label的值。
使用场景:我们的Android手机一般在launcher上存在联系人应用图标、拨号应用图标,其实这两个应用图标对应的是同一个应用,只是设置了两个入口,进入不同的Tab页面。
2. 如何动态给应用更换图标
比如我们过春节时,会发现微博或是淘宝等应用会更换应用图标,如何在应用不重新发包的情况下,对应用图标进行更换呢?
我们可以通过以下两种方法来实现,其实原理是类似的。
2.1 方法一:根据开启或关闭组件进行更换应用图标
我们可以事先在AndroidMainfest.xml文件中定义多个应用的入口组件(启动图标),在代码运行时控制组件的显示与隐藏,从而达到更换应用图标目的。由于在每年春节或是双11时,一些商家可能需要列换应用图标,我们可以在程序中通过时间来控制应用图标更换目的。那如何控制组件的显示与隐藏呢。
在讲解更换应用图标之前,我们先来了解下Android中如何禁用一个组件。
2.1.1 如何关闭一个组件?
(1)关闭组件的使用场景
在用到组件时,有时候我们可能暂时性的不使用组件,但又不想把组件kill掉,比如创建了一个broadcastReceiver广播监听器,用来监听第一次开机启动后获得系统的许多相关信息,并保存在文件中,这样以后每次开机启动就不需要再去启动该服务了,也就是说如果没有把receiver关闭掉,就算是不做数据处理,但程序却还一直在后台运行会消耗电量和内存,这时候就需要把这个receiver给关闭掉。
(2)如何关闭组件?
关闭组件其实并不难,只要创建packageManager对象和ComponentName对象,并调用packageManager对象的setComponentEnabledSetting方法。
public void setComponentEnabledSetting (ComponentName componentName, int newState, int flags)
componentName:组件名称
newState:组件新的状态,可以设置三个值,分别是如下:
- 不可用状态:COMPONENT_ENABLED_STATE_DISABLED
- 可用状态:COMPONENT_ENABLED_STATE_ENABLED
- 默认状态:COMPONENT_ENABLED_STATE_DEFAULT
flags:行为标签,值可以是DONT_KILL_APP或者0。 0说明杀死包含该组件的app
public int getComponentEnabledSetting(ComponentName componentName)//获取组件的状态
2.1.2 通过关闭组件或是开启组件来达到应用图标列换目的
通过下面的方法,通过设置组件的状态,我们可以达到隐藏或是显示一个应用图标,从而达到更换应用图标的目的。
private void hideTest2() {
PackageManager packageManager = getPackageManager();
ComponentName componentName = new ComponentName(this, Test2Activtiy.class);
int res = packageManager.getComponentEnabledSetting(componentName);
if (res == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|| res == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
// 隐藏应用图标
packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
} else {
// 显示应用图标
packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
PackageManager.DONT_KILL_APP);
}
}
2.2 方法二:根据activity-alias来设置桌面可以存在多个icon,再设置某个activity-alias显示其他隐藏
2.2.1 在xml添加多个activity-alias、删除应用首次进入activity标签的category属性
<activity-alias
android:name=".icon_tag"
android:enabled="true"
android:icon="your icon"
android:label="your label"
android:targetActivity=".activity.WeChatLoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".icon_tag_1212"
android:enabled="false"
android:icon="your icon"
android:label="your label"
android:targetActivity=".activity.WeChatLoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
2.2.2 在代码中控制活动和普通图标的切换
/**
* @param useCode =1、为活动图标 =2 为用普通图标 =3、不启用判断
*/
private void switchIcon(int useCode) {
try {
//要跟manifest的activity-alias 的name保持一致
String icon_tag = "com.weechan.shidexianapp.icon_tag";
String icon_tag_1212 = "com.weechan.shidexianapp.icon_tag_1212";
if (useCode != 3) {
PackageManager pm = getPackageManager();
ComponentName normalComponentName = new ComponentName(
getBaseContext(),
icon_tag);
//正常图标新状态
int normalNewState = useCode == 2 ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
if (pm.getComponentEnabledSetting(normalComponentName) != normalNewState) {//新状态跟当前状态不一样才执行
pm.setComponentEnabledSetting(
normalComponentName,
normalNewState,
PackageManager.DONT_KILL_APP);
}
ComponentName actComponentName = new ComponentName(
getBaseContext(),
icon_tag_1212);
//正常图标新状态
int actNewState = useCode == 1 ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
if (pm.getComponentEnabledSetting(actComponentName) != actNewState) {//新状态跟当前状态不一样才执行
pm.setComponentEnabledSetting(
actComponentName,
actNewState,
PackageManager.DONT_KILL_APP);
}
}
} catch (Exception e) {
}
}
**总结:给应用设置多个启动图标,并不是什么难的知识点,但咱们平时都没有关注过,有时觉得还有点不可思议,不自觉想起毛主席的那句话“一切困难都是纸老虎”,哈哈。
还有如何关闭一个组件,通过packageManager对象的setComponentEnabledSetting方法设置ComponentStatus状态即可,通过它就可以动态更换应用图标。
当然以下两种方法都需要咱们先预先在应用的AndroidMainfest.xml中设置好相应的标签,设置启动模式,设置相应的图标。如果想要应用动态换成任意图标,则还是需要升级应用。