细心的朋友会发现,现在火热的京东,天猫等app的icon 在手机中不知道什么时候发生了改变,尤其是在618,818等活动,改变了图标,但是奇怪的是我们并没有更新软件,这个图标怎么就变了,作为android开发者就来分析实现下。
在android 开发过程中有一个重要的文件 AndroidManifest这个xml文件,它包含了很多标签元素,application、activity、service、receiver等,其中有一个标签 activity-alias 这个标签就可以实现不更新app的情况下,动态修改app的icon,label,我们先来看看activity-alias的一些解释。
activity-alias:意思是activity的别名,在开发过程中,必须在manifest文件中静态声明activity,同时还会一些配置比如:name,label,icon等属性,还可以配置intent-filter。对于activity-alias 有一个属性叫:targetActivity,这个属性用来为该标签设置目标activity,这个就是为一个已经存在的activity创建的别名。
activity-alias作为一个已经存在Activity的别名,可以通过这个别名快速打开目标activity,可以放在桌面或者其他其他组件通过别名调起目标activity,该标签也有icon、label等标签,这就可以修改app的icon和label,先看下代码
<activity-alias
android:name=".icon_tag"
android:enabled="true"
android:icon="@drawable/ic_appipc"
android:label="@string/app_name"
android:targetActivity=".AppIconActivity">
<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_new"
android:enabled="false"
android:icon="@drawable/ic_video_default"
android:label="@string/app_name_1"
android:targetActivity=".AppIconActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
1、enable:该属性用来决定目标activity可否通过该别名被系统实例化,默认为true
2、android:icon 该属性就比较好玩了,允许自定义icon,可以不同于应用本身在桌面的icon。如果需要在桌面上创建快捷入口,也许产品会要求换个不同的icon。
3、android:label 该属性类似于android:icon,图标都换了,换个名称也合情合理吧,此属性就是为此而生的。
4、android:name 该属性可以为任意字符串,但最好符合类名命名规范。activity元素的name属性实质上都会指向一个具体的Activity类,而activity-alias的name属性仅作为一个唯一标识而已。
5、android:targetActivity 该属性指定了目标Activity,即通过activity-alias调起的Activity是哪个,此属性其实类似于activity标签中的name属性,需要规范的Activity包名类名。
这个是在manifest文件中的配置,还需要使用java实现动态配置:
// 别名 icon_tag 对应的classname = getpackageName()+name
String componentName = "com.example.xinlai_001.camerademo.icon_tag";
// 别名 icon_tag_new 对应的classname
String componentNewN = "com.example.xinlai_001.camerademo.icon_tag_new";
// 根据classname 来创建组件
ComponentName icon_tag = new ComponentName(getApplication(),componentName);
ComponentName icon_tag_new = new ComponentName(getApplication(),componentNewN);
ComponentName currentName = getComponentName();
PackageManager manager = getPackageManager();
Log.e(TAG, "updateIcon: "+currentName.getClassName());
/**
* 根据获取的当前组件的classname 来动态修改 用哪个别名来调用目标activity
*/
if (currentName.getClassName().equals(componentName)){
manager.setComponentEnabledSetting(icon_tag,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);
manager.setComponentEnabledSetting(icon_tag_new,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);
}else {
manager.setComponentEnabledSetting(icon_tag,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);
manager.setComponentEnabledSetting(icon_tag_new,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);
}
注意setComponentEnableSetting()方法就可以动态设置component 可用状态,这个方法的第三个参数有两个值供选择:1(DONT_KILL_APP)和0,当设置为1时,切换app图标时,会有几秒钟的延迟,在延迟期间不能点击图标进入app,设置为0时,当切换app图标时,会立刻更换,但是应用会被强制退出被清理掉。