南京证券项目最近的需求之一,在某一时间时应用图标icon显示4.0icon,春节时显示春节icon,当春节过后,app需还原为默认icon,也就是有三个icon需要变化更改,基于此需求设计开发。
1、配置Activity
<activity android:name=".tztCommHeadPageActivity" android:configChanges="orientation|keyboardHidden|fontScale|screenSize" android:label="@string/tzt_app_name" android:screenOrientation="portrait" android:theme="@style/tzt_HeadPage_Theme.White"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
一个程序可以配置多个category为LAUNCHER的activity,从而达到显示多个应用图标的效果,每个图标都是程序的一个入口,点击后显示的界面都不一样。
2、Activity设置引用
Android可以配置多个activity-alias标签 来为指定activity设置多个引用,targetActivity指定点击图标后响应的Activity, name属性为activity-alias唯一标识,java代码中通过该参数获得该activity引用。
如下配置中,为Activity设置三个引用,又因为只有tztCommHeadPageGenearlActivity的enable为true,因此,只有该图标会显示在应用程序列表中。
<activity android:name="com.zztzt.android.simple.activity.tztCommHeadPageActivity" android:configChanges="orientation|keyboardHidden|fontScale|screenSize" android:enabled="false" android:label="@string/tzt_app_name" android:screenOrientation="portrait" android:theme="@style/tzt_HeadPage_Theme.White"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity-alias android:name="com.zztzt.android.simple.activity.tztCommHeadPageGenearlActivity" android:targetActivity="com.zztzt.android.simple.activity.tztCommHeadPageActivity" android:configChanges="orientation|keyboardHidden|fontScale|screenSize" android:icon="@drawable/tzt_icon" android:enabled="true" android:label="@string/tzt_app_name" android:screenOrientation="portrait" android:theme="@style/tzt_HeadPage_Theme.White"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity-alias> <activity-alias android:name="com.zztzt.android.simple.activity.tztCommHeadPageAliasActivity" android:targetActivity="com.zztzt.android.simple.activity.tztCommHeadPageActivity" android:configChanges="orientation|keyboardHidden|fontScale|screenSize" android:icon="@drawable/tzt_icon_spring" android:enabled="false" android:label="@string/tzt_app_name" android:screenOrientation="portrait" android:theme="@style/tzt_HeadPage_Theme.White"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity-alias> <activity-alias android:name="com.zztzt.android.simple.activity.tztCommHeadPageV4AliasActivity" android:targetActivity="com.zztzt.android.simple.activity.tztCommHeadPageActivity" android:configChanges="orientation|keyboardHidden|fontScale|screenSize" android:icon="@drawable/tzt_icon_v4" android:enabled="false" android:label="@string/tzt_app_name" android:screenOrientation="portrait" android:theme="@style/tzt_HeadPage_Theme.White"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity-alias>
至于为何在此将tztCommHeadPageActivity的enable为false,因在如果tztCommHeadPageActivity的enable为true,第一次动态修改icon时,app在icon修改完成后kill掉。所以我们需要将某一如tztCommHeadPageGenearlActivity的activity-alias的enable为true,为默认组件入口,即默认icon。这里其实我也有疑问,只是暂未查出为何需如此,如有了解者还望告知。(E-mail:cr_wchf@sina.com)
3、动态禁用或启用组件
在java代码中,也可以通过ClassName来判断当前处于哪一个组件, 获得的mClassName即是在清单文件为activity或activity-alias配置的name属性,不过我此次没有用这个。
String mClassName = activity.getComponentName().getClassName();
在此,得到程序的PackageManager,通过禁止或启动对应的组件,即是重新设置activity-alias的enable属性。
String v4Path = "。。。.tztCommHeadPageV4AliasActivity"; String springPath = "。。。.tztCommHeadPageAliasActivity"; String genearlPath = "。。。.tztCommHeadPageGenearlActivity";private void changeIcon(Activity activity,String activityPath) { PackageManager pm = activity.getPackageManager(); pm.setComponentEnabledSetting(activity.getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); pm.setComponentEnabledSetting(new ComponentName(activity, activityPath), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); }
4、总结
通过预设activity的引用,可简单实现动态改变icon,但是还有其他问题:
1、必须写死在程序中,不能真正的动态改变;
2、程序禁止或启动组件时,需等待10秒左右时间(具体时间跟当前系统Launcher策略有关),桌面Launcher才会更新图标。
参考:
https://developer.android.google.cn/guide/topics/manifest/activity-alias-element.html