Dynamically replace the application Icon

Product: Can we dynamically change the Icon in the App Launcher? Development: No product: Can we dynamically change the Icon in the App Launcher? Development: No product: Can we dynamically change the Icon of the App Launcher?

Principle 1 – activity – alias

In AndroidMainifest, there are two properties:

// Determines which Activity the application starts first
android.intent.action.MAIN 
// Determines whether the application should be displayed in the list of applications
android.intent.category.LAUNCHERCopy the code

In addition, there is an activity-alias attribute, this attribute can be used to create a number of different entry, BELIEVE that do system Setting and Launcher developers in the system source should see a lot of.

Principle 2 – PM. SetComponentEnabledSetting

PackageManager is a master class, can manage all the system components, of course, if the Root, you can also manage all the components of other apps, some system optimization tools is through this way to disable some background Service.

Surprisingly simple to use:

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);
}Copy the code

According to PackageManager.COMPONENT_ENABLED_STATE_ENABLED and PackageManager.COMPONENT_ENABLED_STATE_DISABLED and corresponding ComponentName, You can control whether a component is enabled.

The dynamic change Icon

With the above two principles, it is only a matter of thought to achieve dynamic Icon replacement.

First, we create an Activity with a default entry and a default image. Then we create a double-11 activity-alias that points to the default Activity with a double-11 image. Then we create a double-12 activity-alias. An image pointing to the default Activity with a double 12… And so on and so on.

<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=" double 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>Copy the code

Wait, the problem with this is that it displays three entries in the Launcher, so by default we disable the activity-alias and then enable it when we need to use it.

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 voiddisableComponent(ComponentName componentName) { mPm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); }}Copy the code

If the default Activity is disabled and the activity-alias is enabled on double 11, the result still points to the default Activity, but the icon has been changed.

Depending on the ROM, after the component is disabled, the Launcher waits for its icon to refresh automatically.

The effect is shown below.

For more content, please follow my wechat official account: