Android动态改变App在Launcher里面的icon



如果呆萌的产品童鞋让你动态更换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会自动刷新图标。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
如果你想在 Android 10 中的启动器图标上添加圆角,可以使用以下步骤: 1. 首先,在你的 `drawable` 文件夹中创建一个新的图标资源文件,并命名为 `ic_launcher_round.xml`。 2. 在文件中添加以下代码: ```xml <?xml version="1.0" encoding="utf-8"?> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <background android:drawable="@color/ic_launcher_background"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/> </adaptive-icon> ``` 这段代码定义了一个自适应图标,并将背景设置为 `ic_launcher_background` 资源文件中的颜色,将前景设置为 `ic_launcher_foreground` 资源文件中的图标。 3. 接下来,在 `values` 文件夹中的 `styles.xml` 文件中添加以下代码: ```xml <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:roundIcon">@drawable/ic_launcher_round</item> </style> ``` 这段代码将你的应用程序主题与新的启动器图标关联起来。 4. 最后,在 `AndroidManifest.xml` 文件中的 `application` 标签中添加以下代码: ```xml <application ... android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round"> ... </application> ``` 这段代码将应用程序的默认图标设置为 `ic_launcher` 资源文件中的图标,并将圆角图标设置为 `ic_launcher_round` 资源文件中的图标。 完成这些步骤后,你的应用程序的启动器图标应该具有圆角效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值