Android如何动态更换桌面图标(巨坑)
转载https://blog.csdn.net/pangjl1982/article/details/83308512
1、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"的不要设置为多个,否则会出现多个图标,如果试图通过代码进行隐藏其中的一个或者几个,可能会出现图标消失的情况
Android如何动态更换桌面图标(巨坑)相关推荐
- Android之动态更换桌面图标
Android之动态更换桌面图标 文章链接:http://blog.csdn.net/qq_16628781/article/details/69054325 知识点 动态更换APP 桌面icon的引 ...
- Android中动态更换桌面图标Icon(记录)
问题描述:支付宝.美团.淘宝之类的在某些节日的时候,桌面图标会进行自动进行变化,但是并没有进行APP更新之类的,想做这样的效果,怎么弄? 解决方案: (1)使用activity-alias来定义多个程 ...
- Android动态修改桌面图标新坑总结
一.优秀文章概述 下面的文章描述动态修改桌面图标的基本方法,并且总结了很多坑及解决方案,以下是在此文章基础上的补充 <Android动态修改应用图标和名称> 二.第一个新坑 Android ...
- android实现动态图标,android实现动态更换应用图标
1.配置activity别名 android:enabled 属性,布尔类型,是否开启别名设置,默认值为 true: android:exported 属性,布尔类型,是否支持其他应用通过这个别名访问 ...
- Android 动态改变桌面图标
其实很简单,利用 AndroidManifest.xml 文件中的 <activity-alias> 标签即可实现. <activity-alias> 介绍 大家知道,对于 A ...
- Unity动态更换APP图标及名称
Unity动态更换APP图标及名称 参考链接:https://blog.csdn.net/fu908323236/article/details/78813136 本文环境:(本文为安卓版) Unit ...
- (0042) iOS 开发之iOS10.3新特性:如何动态更换APP图标
iOS新特性: iOS10.3教你如何动态更换APP图标? 1.iOS 10.3 开放了更换 app 图标的 API,核心方法是下面这个: [[UIApplication sharedApplicat ...
- 计算机更换桌面图标,Win10系统如何更换桌面图标呢?电脑更换桌面程序图标的操作方法...
Win10系统电脑桌面上的图标对于熊孩子来说简介就是"秀色可餐"十分美观,在家里使用电脑时,有时候一不小心,熊孩子就在电脑上面乱点击,在日常工作中,其实我们可以将电脑桌面图标更改的 ...
- Android动态更换APP图标及名称
前言 本来想研究一加手机上的天气APP,会随着每天的天气.温度不同动态的改变APP的图标是如何实现的,但始终没有想出和查阅到相关方法,毕竟是人家自己的系统APP.但是也找到了一种能动态改变图标的方法, ...
最新文章
- 分享实录|区块链技术与智能合约入门(开发实例)
- Android系统的进程分类
- oracle01507报错,oracle报错ORA-01507
- 【十二省联考2019】希望【点边容斥】【换根dp】【长链剖分】【线性数据结构】【回退数据结构】【离线逆元】
- C语言 按位或 正整数与负整数 之间
- SQL批量提交修改业务
- HTML5中volume样式自定义,html5中关于volume属性的使用详解
- 技术改变生活,统一通信走向深度融合
- android mtk平台,android mtk平台默认输入法
- 利用WaitForInputIdle等待初始化完成CreateProcess
- html4多文件上传,jQuery h5拖拽多文件上传
- spring-第七篇之深入理解容器中的bean
- canvas 加载图片
- JAVA全栈工程师学习线路
- UWB测距及定位原理
- openresty实现隧道代理
- 超低功耗MCU的选择方法
- html5游戏防止作弊,html5 canvas模拟的小球躲避小游戏
- Exchange 2019数据库切换
- 1262: 魔法宝石 (“玲珑杯”河南工业大学ACM程序设计大赛)