揭秘双十一手机淘宝图标如何被动态更换
作者:pangjl1982 发布时间:2022-06-05 20:14:04
目录
1、Android如何动态更换桌面图标
1.1使用场景
1.2知识点
1.3使用Activity-alias
2、巨坑
2.1App的覆盖
2.2桌面上出现两个图标的问题
2.3桌面上图标消失的问题
2.4总结
2.5最终方案(方案一)
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"的不要设置为多个,否则会出现多个图标,如果试图通过代码进行隐藏其中的一个或者几个,可能会出现图标消失的情况。
来源:https://blog.csdn.net/pangjl1982/article/details/83308512


猜你喜欢
- 一个发送验证码的需求:包括限制文本框输入长度和只允许输入数字按惯例 先上图:class MyBody extends StatefulWid
- 1. F1弹出帮助文档先找个后缀是pdf、docx等格式的的帮助文档,将它放在项目的helpDoc下。设置其“复制到输出
- CyclicBarrier 接着讲多线程下的其他组件,第一个要讲的就
- Spring Data Elasticsearch提供了ElasticsearchTemplate工具类,实现了POJO与elasticse
- TimeSpan 结构 表示一个时间间隔。命名空间:System 程序集:mscorlib(在 mscorlib.dll 中)说
- java synthetic关键字。有synthetic标记的field和method是class内部使用的,正常的源代码里不会出现synt
- gradle文件执行流程做过Android开发的同学都知道 ,Android项目中存在三个gradle文件,那你是否知道他们的执行流程呢?请
- 本文实例为大家分享了Android实现弹幕效果的具体代码,供大家参考,具体内容如下首先分析一下,他是由三层布局来共同完成的,第一层视频布局,
- package com.cq2022.zago.base.util;import java.io.FileReader;import jav
- 一、创建资源文件可以将字符串、图像或对象数据等资源包含在资源文件中,方便应用程序使用。创建资源文件的方法:1、手动或使用IDE工具自动生成X
- 写在最前端1.SpringAOP中共有六种通知类型,只要我们自定义一个类实现对应的接口,它们全都是org.springframework.a
- 1.类的6个默认成员函数默认成员函数:用户没有显示实现,编译器会生成的成员函数称为默认成员函数。如果一个类中什么成员都没有,简称为空类。但空
- 可以用于简单的过期订单取消支付、7天自动收货场景中1、Spring Boot整合redis 参考https://www.jb51.net/a
- 本文主要介绍在SpringMVC框架整合Junit框架进行单元测试。闲话少述,让我们直入主题。系统环境软件版本spring-webmvc4.
- seata的部署和集成1.部署Seata的tc-server1)下载首先我们要下载seata-server包,地址在http/seata.i
- 让我们来看看这段代码: import java.util.BitSet;import java.util.concurrent.C
- 一、简单介绍Unity 游戏实例开发集合,使用简单易懂的方式,讲解常见游戏的开发实现过程,方便后期类似游戏开发的借鉴和复用。本节介绍,Fly
- 为帮助开发者更方便、更安全地开发和调试基于微信的网页,微信推出了 web 开发者工具。它是一个桌面应用,通过模拟微信客户端的表现,使得开发者
- 最近回顾了一下java继承中的问题,下面贴代码:public class Base {protected String temp = &qu
- 本文实例为大家分享了Unity3D实现相机跟随控制的具体代码,供大家参考,具体内容如下跟随算法要实现3D摄像机的控制第一步就是先实现摄像机跟