动态更换应用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

时间: 2024-10-19 01:46:28

动态更换应用Icon的相关文章

使用 css/less 动态更换主题色(换肤功能)

前言 说起换肤功能,前端应该是非常熟悉了?? 一般来说换肤的需求分为几种: 1. 纯前端,直接在页面前端通过点击自由切换限定的几种主题色,切换之后主题色变量存到本地浏览器 2. 在后台配置好色值,传到前端,前端从接口获取主题色在初始化的时候显示对应的主题色 3. 前面两者的结合,初始化的颜色设置,但也可通过前端的切换来更改主题色 拿到换肤需求后,就在思考该如何实现呢?? 先搜一下,看下有哪些方法 Ant Design 的更换主题色功能是用 less 提供的 modifyVars 的方式进行覆盖变

Android 动态更换桌面图标

每当双 11.12 来临之际,Android 手机 Launcher 中的淘宝.天猫图标就会变成双 11.12 主题的图标.实现了动态切换图标.名称 MainActivity package com.example.modifyappdemo; import android.app.Activity; import android.app.ActivityManager; import android.content.ComponentName; import android.content.p

Unity动态更换图片

博主写的是五秒倒计时后开始游戏,用图片显示倒计时数字,由于初学Unity所以方法可能不太好,但不失为一种解决方法. using UnityEngine; using System.Collections; using UnityEngine.UI;//别忘加了 public class GameController : MonoBehaviour { public Sprite five; public Sprite four; public Sprite three; public Sprit

WPF-模拟动态更换logo的过程(1),如何获取程序的根目录。

假设现在需要从网上下载一个图片到项目目录下,展示下载的图片,然后删除正在展示的图片(模拟更换logo的过程),替换新的图片. 下载图片之前需要确定图片应存的地址,图片不能存在本地(比如图片存在D盘的某个文件下,但是用户如果没有D盘就会出错),所以应该存在程序的根目录下. 有俩个方法可以获取程序的根目录. 1.这种方法比较灵活,可以获取根目录以及其之上的目录. public string GetProjectRootPath() { string rootPath = ""; strin

angular——话题精选(动态更换显示一条)

<!-------------------- 话题精选 -----------------------> <section class="white_bg topics "> <header class="fix_container "> <div class="fix_top_left" id="topics_mark"><i class="icon-topic

[ExtJS5学习笔记]第二十九节 sencha ext js 5.1.0中动态更换皮肤主题

本文地址:http://blog.csdn.net/sushengmiyan/article/details/42016107 本文作者:sushengmiyan ------------------------------------------------------------------------------------------------------------------------------------ 为方便起见,使用sencha cmd创建一个工程,使用app buil

编辑器下动态更换对象材质

1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 using UnityEditor; 5 6 [ExecuteInEditMode] 7 public class SetMaterial : MonoBehaviour { 8 9 #if UNITY_EDITOR 10 [ContextMenu("SetMaterial")] 11 void SetObjsMa

android.support.v4.view.ViewPager 如何动态更换显示内容

看一段简单的代码,在一个pager里面显示两个TextView List<View> items = new ArrayList<View>(); adapter = new MyPagerAdapter(); TextView tv = new TextView(getActivity()); tv.setText("第一页"); items.add(tv); tv = new TextView(getActivity()); tv.setText("

[ExtJS5学习笔记]sencha ext js 5.1.0中动态更换皮肤主题

本文地址:http://blog.csdn.net/sushengmiyan/article/details/42016107 本文作者:sushengmiyan ------------------------------------------------------------------------------------------------------------------------------------ 为方便起见,使用sencha cmd创建一个工程,使用app buil