如果呆萌的产品童鞋让你动态更换App在Launcher里面的Icon,你怎么回答他,下文就提出一种实现该效果的方法。

原理1——activity-alias

在AndroidMainifest中,有两个属性:

// 决定应用程序最先启动的Activity

android.intent.action.MAIN

// 决定应用程序是否显示在程序列表里

android.intent.category.LAUNCHER

另外,还有一个activity-alias属性,这个属性可以用于创建多个不同的入口,相信做过系统Setting和Launcher开发的开发者在系统的源码中应该见过很多。

原理2——PM.setComponentEnabledSetting

PackageManager是一个大统领类,可以管理所有的系统组件,当然,如果Root了,你还可以管理其它App的所有组件,一些系统优化工具就是通过这个方式来禁用一些后台Service的。

使用方式异常简单:

private void enableComponent(ComponentName componentName) {

mPm.setComponentEnabledSetting(componentName,

PackageManager.COMPONENT_ENABLED_STATE_ENABLED,

PackageManager.DONT_KILL_APP);

}

private void disableComponent(ComponentName componentName) {

mPm.setComponentEnabledSetting(componentName,

PackageManager.COMPONENT_ENABLED_STATE_DISABLED,

PackageManager.DONT_KILL_APP);

}

根据PackageManager.COMPONENT_ENABLED_STATE_ENABLED和PackageManager.COMPONENT_ENABLED_STATE_DISABLED这两个标志量和对应的ComponentName,就可以控制一个组件的是否启用。

动态换Icon

有了上面的两个原理,来实现动态更换Icon就只剩下思路问题了。

首先,我们创建一个Activity,作为默认的入口并带着默认的图片,再创建一个双11的activity-alias,指向默认的Activity并带有双11的图片,再创建一个双12的activity-alias,指向默认的Activity并带有双12的图片……等等等。

<activity android:name=".MainActivity">

<intent-filter>

<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>

</intent-filter>

</activity>

<activity-alias

android:name=".Test11"

android:enabled="false"

android:icon="@drawable/s11"

android:label="双11"

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=".Test12"

android:enabled="false"

android:icon="@drawable/s12"

android:label="双12"

android:targetActivity=".MainActivity">

<intent-filter>

<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>

</intent-filter>

</activity-alias>

等等,这样有个问题,那就是这样会在Launcher上显示3个入口,所以,默认我们会把这些activity-alias先禁用,等到要用的时候再启用,养兵千日,用兵一时。

public class MainActivity extends AppCompatActivity {

private ComponentName mDefault;

private ComponentName mDouble11;

private ComponentName mDouble12;

private PackageManager mPm;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mDefault = getComponentName();

mDouble11 = new ComponentName(

getBaseContext(),

"com.xys.changeicon.Test11");

mDouble12 = new ComponentName(

getBaseContext(),

"com.xys.changeicon.Test12");

mPm = getApplicationContext().getPackageManager();

}

public void changeIcon11(View view) {

disableComponent(mDefault);

disableComponent(mDouble12);

enableComponent(mDouble11);

}

public void changeIcon12(View view) {

disableComponent(mDefault);

disableComponent(mDouble11);

enableComponent(mDouble12);

}

private void enableComponent(ComponentName componentName) {

mPm.setComponentEnabledSetting(componentName,

PackageManager.COMPONENT_ENABLED_STATE_ENABLED,

PackageManager.DONT_KILL_APP);

}

private void disableComponent(ComponentName componentName) {

mPm.setComponentEnabledSetting(componentName,

PackageManager.COMPONENT_ENABLED_STATE_DISABLED,

PackageManager.DONT_KILL_APP);

}

}

OK了,禁用默认的Activity后,启用双11的activity-alias,结果不变还是指向了默认的Activity,但图标已经发生了改变。

根据ROM的不同,在禁用了组件之后,会等一会,Launcher会自动刷新图标。

产品:我们可以动态更换App在Launcher里面的Icon吗

开发:让我想想……

原理1——activity-alias

在AndroidMainifest中,有两个属性:

// 决定应用程序最先启动的Activity

android.intent.action.MAIN

// 决定应用程序是否显示在程序列表里

android.intent.category.LAUNCHER

另外,还有一个activity-alias属性,这个属性可以用于创建多个不同的入口,相信做过系统Setting和Launcher开发的开发者在系统的源码中应该见过很多。

原理2——PM.setComponentEnabledSetting

PackageManager是一个大统领类,可以管理所有的系统组件,当然,如果Root了,你还可以管理其它App的所有组件,一些系统优化工具就是通过这个方式来禁用一些后台Service的。

使用方式异常简单:

private void enableComponent(ComponentName componentName) {

mPm.setComponentEnabledSetting(componentName,

PackageManager.COMPONENT_ENABLED_STATE_ENABLED,

PackageManager.DONT_KILL_APP);

}

private void disableComponent(ComponentName componentName) {

mPm.setComponentEnabledSetting(componentName,

PackageManager.COMPONENT_ENABLED_STATE_DISABLED,

PackageManager.DONT_KILL_APP);

}

根据PackageManager.COMPONENT_ENABLED_STATE_ENABLED和PackageManager.COMPONENT_ENABLED_STATE_DISABLED这两个标志量和对应的ComponentName,就可以控制一个组件的是否启用。

动态换Icon

有了上面的两个原理,来实现动态更换Icon就只剩下思路问题了。

首先,我们创建一个Activity,作为默认的入口并带着默认的图片,再创建一个双11的activity-alias,指向默认的Activity并带有双11的图片,再创建一个双12的activity-alias,指向默认的Activity并带有双12的图片……等等等。

<activity android:name=".MainActivity">

<intent-filter>

<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>

</intent-filter>

</activity>

<activity-alias

android:name=".Test11"

android:enabled="false"

android:icon="@drawable/s11"

android:label="双11"

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=".Test12"

android:enabled="false"

android:icon="@drawable/s12"

android:label="双12"

android:targetActivity=".MainActivity">

<intent-filter>

<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>

</intent-filter>

</activity-alias>

等等,这样有个问题,那就是这样会在Launcher上显示3个入口,所以,默认我们会把这些activity-alias先禁用,等到要用的时候再启用,养兵千日,用兵一时。

public class MainActivity extends AppCompatActivity {

private ComponentName mDefault;

private ComponentName mDouble11;

private ComponentName mDouble12;

private PackageManager mPm;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mDefault = getComponentName();

mDouble11 = new ComponentName(

getBaseContext(),

"com.xys.changeicon.Test11");

mDouble12 = new ComponentName(

getBaseContext(),

"com.xys.changeicon.Test12");

mPm = getApplicationContext().getPackageManager();

}

public void changeIcon11(View view) {

disableComponent(mDefault);

disableComponent(mDouble12);

enableComponent(mDouble11);

}

public void changeIcon12(View view) {

disableComponent(mDefault);

disableComponent(mDouble11);

enableComponent(mDouble12);

}

private void enableComponent(ComponentName componentName) {

mPm.setComponentEnabledSetting(componentName,

PackageManager.COMPONENT_ENABLED_STATE_ENABLED,

PackageManager.DONT_KILL_APP);

}

private void disableComponent(ComponentName componentName) {

mPm.setComponentEnabledSetting(componentName,

PackageManager.COMPONENT_ENABLED_STATE_DISABLED,

PackageManager.DONT_KILL_APP);

}

}

OK了,禁用默认的Activity后,启用双11的activity-alias,结果不变还是指向了默认的Activity,但图标已经发生了改变。

根据ROM的不同,在禁用了组件之后,会等一会,Launcher会自动刷新图标。

Android动态改变App在Launcher里面的icon的更多相关文章

  1. Android 动态改变高度以及计算长度的EditText

    前段时间项目需求,需要做一个有限制长度的输入框并动态显示剩余文字,同时也要动态改变EditText的高度来增加用户体验.现整理出来与大家分享. 先来看看效果图 看了效果就分享一下布局 <Rela ...

  2. Android动态改变布局

    遇到这么个需求,先看图:      其实是一个软件的登录界面,初始是第一个图的样子,当软键盘弹出后变为第二个图的样子,因为登录界面有用户名.密码.登录按钮,不这样的话软键盘弹出后会遮住登录按钮(其实之 ...

  3. android 动态改变屏幕方向

    LANDSCAPE与PORTRAIT 范例说明 要如何通过程序控制Activity的显示方向?在Android中,若要通过程序改变屏幕显示的方向,必须要覆盖 setRequestedOrientati ...

  4. android 动态改变listview的内容

    本文模拟:点击一个按钮,为已有的listview添加一行数据 <?xml version="1.0" encoding="utf-8"?> < ...

  5. 【转】Android动态改变对 onCreateDialog话框值 -- 不错不错!!!

    原文网址:http://www.111cn.net/sj/android/46484.htm 使用方法是这样的,Activity.showDialog()激发Activity.onCreateDial ...

  6. 我的Android进阶之旅------>关于使用Android Studio替换App的launcher图标之后仍然显示默认的ic_launcher图标的解决方法

    前言 最近做了一个App,之前开发该App的时候一直以来都是默认的launcher图标启动的, 今天美工换了一个App的launcher 图标,因此在Android Studio中将默认的lanche ...

  7. Android 动态改变布局属性RelativeLayout.LayoutParams.addRule()

    我们知道,在 RelativeLayout 布局中有很多特殊的属性,通常在载入布局之前,在相关的xml文件中进行静态设置即可. 但是,在有些情况下,我们需要动态设置布局的属性,在不同的条件下设置不同的 ...

  8. 动态改变APP图标

    一.iOS动态更换App图标(一):基础使用 该功能应用的场景 1.白天/夜间模式切换,在切换App主色调同时切换App图标. 2.各类皮肤主题(淘宝就可换肤),附带App图标一块更换. 3.利用Ap ...

  9. android 动态改变控件位置和大小 .

    动态改变控件位置的方法: setPadding()的方法更改布局位置. 如我要把Imageview下移200px:             ImageView.setPadding( ImageVie ...

随机推荐

  1. chrome disable-web-security 关闭安全策略 解决跨域

    Chrome 跨域访问线上接口 时间:2016-04-21 作者:zhongxia 前后端分离之后,联调的时候就会出现问题,那就是Ajax跨域问题. 跨域问题的解决方案有很多种比如常规的 后端使用CR ...

  2. PHP可以通过类名调用非静态方法

    今日有兄弟遇上一个问题,就是可以通过class名称直接调用该类中的函数,我测试了一下,确实可以,概念中是只有静态方法才可以这样调用的,现在 被刷新了,于是我在方法中加入一行$this相关的操作,再运行 ...

  3. apache 限制IP访问

    <Directory "/var/www"> Options All AllowOverride None Order Deny,Allow Deny From all ...

  4. apr-util的安装

    下载软件 下载链接: http://pan.baidu.com/s/1o6sOwgM http://pan.baidu.com/s/1hqIdcA4 ########安装apr######### ta ...

  5. BZOJ 3624: [Apio2008]免费道路 [生成树 并查集]

    题意: 一张图0,1两种边,构造一个恰有k条0边的生成树 优先选择1边构造生成树,看看0边是否小于k 然后保留这些0边,补齐k条,再加1边一定能构成生成树 类似kruskal的证明 #include ...

  6. DaemonSet 典型应用场景 - 每天5分钟玩转 Docker 容器技术(129)

    Deployment 部署的副本 Pod 会分布在各个 Node 上,每个 Node 都可能运行好几个副本.DaemonSet 的不同之处在于:每个 Node 上最多只能运行一个副本. DaemonS ...

  7. 用Markdown写微信公众号文章

    目前微信公众号的编辑器是不支持Markdown语法的,那怎么办呢? 有一款叫Markdown Here的插件可以解决这个问题(支持Chrome.Firefox.Safari). 官方网站:http:/ ...

  8. Java经典编程题50道之十五

    输入三个整数x,y,z,请把这三个数由小到大输出. public class Example15 {    public static void main(String[] args) {       ...

  9. return的新思考

    <!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" ...

  10. HDU 5060

    题意略. 这个题目最关键的是在于计算球冠的体积.令球冠体积为V. 我们可以用祖暅原理来计算V, 这里,可以看出,球冠的体积等于左图的上半个圆柱减去那个倒扣的圆台. 祖暅原理:界于两个平行平面之间的两个 ...