前言

动态更换App图标,网上可以收搜到很多,这里也是参考前人经验,读完本文可以得到,如何动态更换桌标(非网络获取桌标图片),标志位的阐述,更加透彻的理解.

用到的知识

activity-alias并不是代表一个Activity,而是代表一个已经存在的Activity的别名。

它使用在清单文件中,类似Activity标签。它可用来设置某个Activity的快捷入口

activity-alias基本用法

android:exported=["true" | "false"]

android:icon="drawable resource"

android:label="string resource"

android:name="string"

android:permission="string"

android:targetActivity="string" >

...

属性解释:

属性

含义

enabled

是否生效。配置多个activity-alias时,如果只想一个生效,就设置一个为true

exported

是否可以被其他应用调起,配置intent-filter时默认为true,未配置intent-filter时默认为false,只能被应用自身调起

icon

自定义生效时的icon

label

作用同Activity标签中的label属性,主要表现为桌面上的app名称和activity的title的名称

name

该activity-alias的名字

permission

指明通过别名声明调起目标Activity所必需的权限

targetActivity

指明目标Activity,类似于Activity标签中的name属性,需写明包类路径。表明通过activity-alias调起的是哪个Activity

使用

首先配置AndroidManifest.xml,设置别名

android:name=".activitys.WelcomeActivity"

android:configChanges="keyboard|keyboardHidden|orientation"

android:hardwareAccelerated="true"

android:label="@string/app_name"

android:screenOrientation="portrait"

android:theme="@style/Acrivity_Fullscreen">

android:name=".changeLauncherIconActivity"

android:configChanges="keyboard|keyboardHidden|orientation"

android:enabled="false"

android:icon="@drawable/yishijie_logo"

android:label="@string/app_name"

android:screenOrientation="portrait"

android:targetActivity=".activitys.WelcomeActivity">

这里要注意的是

android:name 标识:主要用于在代码中获取此组件enable的状态;

android:targetActivity标识,targetActivity标识就是点击后跳转的Activity;

icon和lable分别是启动图标和桌面名称

代码配置

思路是首先获取服务端下发接口,缓存到本地,等用户退出主页的时候执行更换图标的逻辑

获取服务端接口,接口提示更换节日图标

判断要显示组件的状态是否为显示状态COMPONENT_ENABLED_STATE_ENABLED

private boolean isComponentState(ComponentName componentName) {

return mPackageManager.getComponentEnabledSetting(componentName) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED;

}

注意:这里的标示位

属性

含义

COMPONENT_ENABLED_STATE_DEFAULT

默认状态,xml预设的状态

COMPONENT_ENABLED_STATE_ENABLED

此组件或应用程序已明确启用,无论其清单中指定了什么。

COMPONENT_ENABLED_STATE_DISABLED

此组件或应用程序已明确禁用,无论其清单中指定了什么。

COMPONENT_ENABLED_STATE_DISABLED_USER

用户已明确禁用该应用程序,无论其在清单中指定了什么。

COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED

his application should be considered, until the point where the user actually wants to use it. (这个不清楚怎么翻才好,没有使用过)

如果不是则设置其可见,否则不变

注意这里设置标志位是永久性的,即使App升级获取此组件状态时,也是之前的值

private void enableComponent(ComponentName componentName) {

//此方法用以启用和禁用组件,会覆盖Androidmanifest文件下定义的属性

mPackageManager.setComponentEnabledSetting(componentName,

PackageManager.COMPONENT_ENABLED_STATE_ENABLED,

PackageManager.DONT_KILL_APP);

}

完整代码

public class ChangeAppIconUtils {

private PackageManager mPackageManager;

//默认桌标

private static final String DEFAULT_ICON = "com.x.x.activitys.WelcomeActivity";

//活动桌标

private static final String ANTHER_ICON = "com.x.x.changeLauncherIconActivity";

//缓存文件键值

public static final String KEY_LAUNCHER_ICON = "key_launcher_icon";

public ChangeAppIconUtils(PackageManager mPackageManager) {

this.mPackageManager = mPackageManager;

}

/**

* 启动组件

*

* @param componentName 组件名

*/

private void enableComponent(ComponentName componentName) {

//此方法用以启用和禁用组件,会覆盖Androidmanifest文件下定义的属性

mPackageManager.setComponentEnabledSetting(componentName,

PackageManager.COMPONENT_ENABLED_STATE_ENABLED,

PackageManager.DONT_KILL_APP);

}

/**

* 禁用组件

*

* @param componentName 组件名

*/

private void disableComponent(ComponentName componentName) {

mPackageManager.setComponentEnabledSetting(componentName,

PackageManager.COMPONENT_ENABLED_STATE_DISABLED,

PackageManager.DONT_KILL_APP);

}

/**

* 当前组件的状态,判断当前enable状态

* 即使xml里面设置enable=false 标志位第一次获取时 还是COMPONENT_ENABLED_STATE_DEFAULT

* 所以这里判断是否为enable

*

* @param componentName return true 未被应用为可显示

*/

private boolean isComponentState(ComponentName componentName) {

//默认图标且为默认状态则返回false

return !(DEFAULT_ICON.equals(componentName.getClassName()) && mPackageManager.getComponentEnabledSetting(componentName) == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT)

&& mPackageManager.getComponentEnabledSetting(componentName) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED;

}

/**

* 更换app 图标

*

* @param context context

* @param changeIcon changeIcon

*/

private void changeIconState(Context context, String changeIcon) {

ComponentName defaultIcon = new ComponentName(context, DEFAULT_ICON);

ComponentName otherIcon = new ComponentName(context, ANTHER_ICON);

//判断状态

if (DEFAULT_ICON.equals(changeIcon)) {//设置默认icon

boolean componentState = isComponentState(defaultIcon);

if (componentState) {//如果不一样则设置

enableComponent(defaultIcon);

disableComponent(otherIcon);

// restartSystemLauncher(context, mPackageManager);

}

} else {//其它icon

boolean componentState = isComponentState(otherIcon);

if (componentState) {

enableComponent(otherIcon);

disableComponent(defaultIcon);

// restartSystemLauncher(context, mPackageManager);

}

}

}

/**

* 没啥用,有的rom不会让你杀掉Launcher进程,例如华为,VIVO

* @param context

* @param pm

*/

private void restartSystemLauncher(Context context, PackageManager pm) {

ActivityManager am = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);

Intent i = new Intent(Intent.ACTION_MAIN);

i.addCategory(Intent.CATEGORY_HOME);

i.addCategory(Intent.CATEGORY_DEFAULT);

List resolves = pm.queryIntentActivities(i, 0);

for (ResolveInfo res : resolves) {

if (res.activityInfo != null && am != null) {

am.killBackgroundProcesses(res.activityInfo.packageName);

}

}

}

public void setAppLauncherIcon(Context context, String tagName) {

if (!TextUtils.isEmpty(tagName)) {

if ("icon2".equals(tagName)) {

changeIconState(context, ANTHER_ICON);

} else {

changeIconState(context, DEFAULT_ICON);

}

}

}

}

使用的时候只需要

new ChangeAppIconUtils(getPackageManager()).setAppLauncherIcon(getApplicationContext(), sharePreUtils.getStringValue(ChangeAppIconUtils.KEY_LAUNCHER_ICON, ""));

这里的sharepreUtils是工具类获取接口中下发的状态值,icon1默认图标,icon2为节日图标,因为之前有人说会导致app的重启,所以这里的操作时放在主Activity onDestory里面执行的.

问题

目前已知的问题,当改完图标之后,使用AS再次启动会无法启动,把快速启动关掉就可以了

Error while executing: am start -n "in.myinnos.changeappiconandname/in.myinnos.changeappiconandname.MainActivity-settings" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=in.myinnos.changeappiconandname/.MainActivity-settings }

Error type 3

Error: Activity class {in.myinnos.changeappiconandname/in.myinnos.changeappiconandname.MainActivity-settings} does not exist.

Error while Launching activity

这里我使用打包的方式覆盖安装没有出现这个问题

改过图标后,会过一会儿图标才会改变,有的(华为)改变之前点击会提示,但是桌面更新后就可以点进去了

使用重启桌面的方法,加快图标的切换,1.会被系统禁用例如华为 Vivo Oppo则无法重启桌面2.小米可以,但是还是会在1~3秒的时候关闭应用一次

仅仅修改的是启动图标,如果有快捷方式那么快捷方式不会发生改变,当然可以使用代码动态更新快捷方式

无法动态加载网络图片,还是仅仅是本地资源修改的桌标

参考

android activity alias,动态更换桌标 Activity-alias相关推荐

  1. android手机apk动态替换桌面的logo和laber

    具体操作如下: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android= ...

  2. Android在Activity中动态增加xml自定义样式布局控件(引用xml布局文件和循环增加控件)

    工程目录: MainActivity package com.example.test1121;import androidx.appcompat.app.ActionBar; import andr ...

  3. Android之在Activity中动态得到Adapter类中数据

    1.问题 Activity中动态得到Adapter数据 2.解决办法 在Adapter中写入接口 Class Adapter {Interface A {void onClick(int a, int ...

  4. (4.6.25)Android动态更换应用Icon之玩转桌面图标

    一原理解析 1 原理1activity-alias 2 原理2PMsetComponentEnabledSetting 二动态更换桌面icon 三远程控制图标的实现方式 四多入口实现方式 快捷方式入口 ...

  5. Android如何动态更换桌面图标(巨坑)

    转载https://blog.csdn.net/pangjl1982/article/details/83308512 1.Android如何动态更换桌面图标 1.1使用场景       APP,在中 ...

  6. 从微博个性图标里学Android动态更换

    一.背景 前不久,微博官方发布了一项新功能,微博年费会员可以在App设置中动态更换微博的显示图标样式,但由于部分手机存在系统差异,会导致该功能不可用,微博方面后续还会对该功能进行进一步优化. 我们可以 ...

  7. Android之动态更换桌面图标

    Android之动态更换桌面图标 文章链接:http://blog.csdn.net/qq_16628781/article/details/69054325 知识点 动态更换APP 桌面icon的引 ...

  8. android+动态更改app图标,Android开发:如何动态更换APP图标

    在Android开发中,通常会有这样的需求,逢年过节UI的小伙伴们都会做出节日或活动相关的APP图标让我们更换,可是每次更换都要发版实现.那么,如何在不发版的情况下动态地更换我们的图标呢?本篇文章就来 ...

  9. 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

最新文章

  1. 王者荣耀全栈项目部署到阿里云服务器笔记
  2. python简单词频统计_python简单词频统计
  3. React v15.0 正式版发布
  4. 【Linux系统编程】线程的基本操作
  5. canvas 文字颜色_canvas 中普通动效与粒子动效的实现
  6. 使用命令导入、导出mysql数据
  7. Java高级语法笔记-文件及目录操作
  8. 【零基础学Java】—递归(五十一)
  9. RPM中SPEC宏定义对应路径
  10. 建立数据挖掘的用户画像
  11. 转载:ESP系统——ABS、TCS、VDC及VAF功能介绍
  12. 昨天晚上看了冰川时代三
  13. VMware安装windows7x64时提示找不到CD/DVD驱动器
  14. EasyGUI-2:函数基础
  15. Red Team之Empire渗透工具介绍和使用
  16. ios swift 纯代码自定义view(控件) XYswitchView
  17. mac如何查看wifi密码
  18. 利用Isight软件优化matlab程序的一点心得
  19. 小屁孩的超可爱新年祝福铃声 小屁孩的超可爱新年祝福手机铃声...
  20. 2014年中国十大移动O2O热门服务!

热门文章

  1. 机器学习——深度学习之卷积神经网络(CNN)——AlexNet卷积神经网络结构
  2. 学习笔记(38):Python实战编程-窗体显示
  3. mac电脑下Tomcat和Apach配置流程(超详细)
  4. mysql教程详解之多表联合查询,MYSQL教程mysql多表联合查询返回一张表的内容实现代码...
  5. python语言打印菱形_Python打印菱形
  6. 页面调用系统window打印
  7. 将给定数据源生成静态HTML页面持久化到项目之外的硬盘
  8. 查询大于2分钟的数据
  9. 使用阿里云docker加速器
  10. Android——实现欢迎界面的自动跳转(转)