动态更换手机图标 揭秘双十一手机淘宝图标怎样被动态更换
pangjl1982 人气:01、Android如何动态更换桌面图标
1.1使用场景
APP,在中国电商行业中,某宝和某东是行业的标杆。其中有一点挺让人好奇的,那就是在双十一临近之时,他们的APP桌面图标突然变成了带有双十一字样的图标。可能就是本来就内置了双十一的图标,等快到双十一的时候在动态更换,然后过了双十一那段时间,又将APP的桌面图标变成普通的icon。
1.2知识点
动态更换APP 桌面icon的引述;
activity组件及定义“同盟”组件activity-alias;
PackageManager类进行启用/禁用组件;
PackageInfo的简介;
新名词记录{PackageInfo:Androidmanifest.xml文件描述类}
1.3使用Activity-alias
<activity android:name="com.aliasicon.MainActivity" android:enabled="false" android:exported="true" > <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:configChanges="orientation|keyboardHidden|fontScale|screenSize" android:enabled="true" android:exported="true" android:icon="@drawable/tzt_icon" android:label="@string/app_general_name" android:screenOrientation="portrait" 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="com.zztzt.android.simple.activity.tztCommHeadPageLicaiActivity" android:configChanges="orientation|keyboardHidden|fontScale|screenSize" android:enabled="false" android:exported="true" android:icon="@drawable/tzt_icon_licai" android:label="@string/app_licai_name" android:screenOrientation="portrait" android:targetActivity=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity-alias>
String systemPath = "com.aliasicon.MainActivity"; String springPath = "com.zztzt.android.simple.activity.tztCommHeadPageAliasActivity"; String licaiPath = "com.zztzt.android.simple.activity.tztCommHeadPageLicaiActivity"; String genearlPath = "com.zztzt.android.simple.activity.tztCommHeadPageGenearlActivity"; String finalPath = ""; ComponentName genearlComponent; ComponentName licaiComponent; ComponentName springComponent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); genearlComponent = new ComponentName(getApplication(), genearlPath); licaiComponent = new ComponentName(getApplication(), licaiPath); springComponent = new ComponentName(getApplication(), springPath); //第一个默认按钮 Button btnDefault = (Button) findViewById(R.id.tztToDefault); btnDefault.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { disableComponent(MainActivity.this, licaiComponent); disableComponent(MainActivity.this, springComponent); enableComponent(MainActivity.this, genearlComponent); } }); //理财按钮 Button btnLiCai = (Button) findViewById(R.id.tztToLiCai); btnLiCai.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { disableComponent(MainActivity.this, genearlComponent); disableComponent(MainActivity.this, springComponent); enableComponent(MainActivity.this, licaiComponent); } }); //春节按钮 Button btnSpring = (Button) findViewById(R.id.tztToSpring); btnSpring.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { disableComponent(MainActivity.this, genearlComponent); disableComponent(MainActivity.this, licaiComponent); enableComponent(MainActivity.this, springComponent); } }); } /** * 启用组件 * * @param componentName * 重要方法 */ private void enableComponent(Activity activity, ComponentName componentName) { PackageManager pm = activity.getPackageManager(); int state = pm.getComponentEnabledSetting(componentName); if (PackageManager.COMPONENT_ENABLED_STATE_ENABLED == state) { //已经启用 return; } pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); } /** * 禁用组件 * * @param componentName * 重要方法 */ private void disableComponent(Activity activity, ComponentName componentName) { PackageManager pm = activity.getPackageManager(); int state = pm.getComponentEnabledSetting(componentName); if (PackageManager.COMPONENT_ENABLED_STATE_DISABLED == state) { //已经禁用 return; } pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); } public void saveData(String savePath) { SharedPreferences sp = getSharedPreferences("Icon", Context.MODE_PRIVATE); //获取到edit对象 SharedPreferences.Editor edit = sp.edit(); //通过editor对象写入数据 edit.putString("Value", savePath); //提交数据存入到xml文件中 edit.commit(); } public String getData() { SharedPreferences sp = getSharedPreferences("Icon", Context.MODE_PRIVATE); return sp.getString("Value", ""); }
2、巨坑
通过上面的程序能够实现却换图标;如果代码里通过节假日的时间进行控制,则客户打开app会自动的切换图标;
是不是很神奇?先别高兴太早。
2.1App的覆盖
任何App都会更新,进行覆盖安装。覆盖安装的Manifest的配置不当导致出现难以挽回的问题。
1、从上面的xml里配置可见,一个Activity和两个Activity-alisa的配置情况:
Activity的android:enabled="false"
第一个Activity-alias的android:enabled="true"
第二个Activity-alias的android:enabled="false"
所以App打开,桌面上默认的就是使用第一个Activity-alias的名字和图标。
2、如果新版本的配置还是按照这个配置(即使添加了新的alias,只要默认的Activity-alias不发生变化)客户端额升级覆盖安装,是不会出现错误的。
3、我们称之为“方案一”
2.2桌面上出现两个图标的问题
1、如果新版本把Activity的enable设置为true(方案二),则桌面上除了原来的Activity-alias图标之外,还拥有了该Activity的图标,即有了两个图标;
Activity的android:enabled="true"
第一个Activity-alias的android:enabled="false"
第二个Activity-alias的android:enabled="false"
3、如果试图使用使用上面的代码里的disableComponent方法或者android:enabled="false"隐藏显示的Activity-alias图标,则导致两个图标都消失;
2.3桌面上图标消失的问题
1、方案二会出现两个图标,如果再使用方案一进行覆盖,则两个图标都消失。
2、如果再次使用方案二进行覆盖,则图标还是能重新显示出来的。
2.4总结
1、如果使用方案一进行覆盖安装,不管图标怎么动态的变换,再使用方案一进行覆盖安装,是正常的;
2、如果使用方案二进行覆盖安装,不管配置的图标是什么样的,再使用方案二进行覆盖安装,也是正常的;
3、如果使用方案一进行覆盖安装,如果图标没有动态切换的情况下,再使用方案二进行覆盖安装,也是正常的;
4、如果使用方案一进行覆盖安装,如果图标已经经过动态切换的情况下,再使用方案二进行覆盖安装,会出现双图标的;
5、如果使用方案一进行覆盖安装,如果图标已经经过动态切换的情况下,再使用方案二进行覆盖安装,会出现双图标的;如果在进行使用代码试图隐藏其中一个,则两个图标都消失;
6、如果使用方案一进行覆盖安装,如果图标没有动态切换的情况下,再使用方案二进行覆盖安装,也是正常的,再使用方案一进行覆盖安装,也是正常的;
2.5最终方案(方案一)
采用方案一的方案,即通过代码动态变动图标,一定要注意以下事项:
1、Activity的android:enabled="false"
如果设置为true了,则会出现双图标;
2、Activity-alias的android:enabled="true"的默认显示的项不要中途进行变动,如果确实需要使用新的默认值,则使用代码进行动态变换;
3、Activity-alias的android:enabled="true"的不要设置为多个,否则会出现多个图标,如果试图通过代码进行隐藏其中的一个或者几个,可能会出现图标消失的情况。
加载全部内容