Last time I released a version, I changed only one line of code!

Last time I released a version, I changed only one line of code!

Dynamically change application icons

Product: Can we dynamically change the App Icon in the Launcher?

Development: No

Product: Can we dynamically change the App Icon in the Launcher?

Development: No

Product: Can we dynamically change the App Icon in the Launcher?

Development: No

Product: Can we dynamically change the App Icon in the Launcher?

Development: Let me think...

Principle 1 — activity-alias

In AndroidMainifest, there are two properties:

  1. //Determine the Activity that the application starts
  2.  
  3. android.intent.action.MAIN
  4.  
  5. // Determine whether the application is displayed in the program list
  6.  
  7. android.intent.category.LAUNCHER

In addition, there is an activity-alias attribute, which can be used to create multiple different entrances. I believe that developers who have developed system settings and launchers should have seen a lot of them in the system source code.

Principle 2——PM.setComponentEnabledSetting

PackageManager is a general class that can manage all system components. Of course, if you root your device, you can also manage all components of other apps. Some system optimization tools disable some background services in this way.

It is very easy to use:

  1. private void enableComponent(ComponentName componentName) {
  2.  
  3. mPm.setComponentEnabledSetting(componentName,
  4.  
  5. PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
  6.  
  7. PackageManager.DONT_KILL_APP);
  8.  
  9. }
  10.  
  11.   
  12.  
  13. private void disableComponent(ComponentName componentName) {
  14.  
  15. mPm.setComponentEnabledSetting(componentName,
  16.  
  17. PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
  18.  
  19. PackageManager.DONT_KILL_APP);
  20.  
  21. }

According to the two flags PackageManager.COMPONENT_ENABLED_STATE_ENABLED and PackageManager.COMPONENT_ENABLED_STATE_DISABLED and the corresponding ComponentName, you can control whether a component is enabled.

Dynamic Icon Change

With the above two principles, the only thing left to achieve dynamic icon replacement is the idea.

First, we create an Activity as the default entry with a default picture, then create an activity-alias for Double 11, pointing to the default Activity with a Double 11 picture, then create an activity-alias for Double 12, pointing to the default Activity with a Double 12 picture... and so on.

  1. <activity android: name = ".MainActivity" >
  2.  
  3. <intent-filter>
  4.  
  5. < action android: name = "android.intent.action.MAIN" />
  6.  
  7.   
  8.  
  9. <category android: name = "android.intent.category.LAUNCHER" />
  10.  
  11. </intent-filter>
  12.  
  13. </activity>
  14.  
  15.   
  16.  
  17. <activity-alias
  18.  
  19. android: name = ".Test11"  
  20.  
  21. android:enabled= "false"  
  22.  
  23. android:icon= "@drawable/s11"  
  24.  
  25. android:label= "Double 11"  
  26.  
  27. android:targetActivity= ".MainActivity" >
  28.  
  29. <intent-filter>
  30.  
  31. < action android: name = "android.intent.action.MAIN" />
  32.  
  33.   
  34.  
  35. <category android: name = "android.intent.category.LAUNCHER" />
  36.  
  37. </intent-filter>
  38.  
  39. </activity-alias>
  40.  
  41.   
  42.  
  43. <activity-alias
  44.  
  45. android: name = ".Test12"  
  46.  
  47. android:enabled= "false"  
  48.  
  49. android:icon= "@drawable/s12"  
  50.  
  51. android:label= "Double 12"  
  52.  
  53. android:targetActivity= ".MainActivity" >
  54.  
  55. <intent-filter>
  56.  
  57. < action android: name = "android.intent.action.MAIN" />
  58.  
  59.   
  60.  
  61. <category android: name = "android.intent.category.LAUNCHER" />
  62.  
  63. </intent-filter>
  64.  
  65. </activity-alias>

Wait, there is a problem with this, that is, this will display 3 entrances on the Launcher, so by default we will disable these activity-aliases first, and then enable them when they are needed. It takes a long time to train an army.

  1. public class MainActivity extends AppCompatActivity {
  2.  
  3.   
  4.  
  5. privateComponentName mDefault;
  6.  
  7. private ComponentName mDouble11;
  8.  
  9. private ComponentName mDouble12;
  10.  
  11. private PackageManager mPm;
  12.  
  13.   
  14.  
  15. @Override
  16.  
  17. protected void onCreate(Bundle savedInstanceState) {
  18.  
  19. super.onCreate(savedInstanceState);
  20.  
  21. setContentView(R.layout.activity_main);
  22.  
  23. mDefault = getComponentName();
  24.  
  25. mDouble11 = new ComponentName(
  26.  
  27. getBaseContext(),
  28.  
  29. "com.xys.changeicon.Test11" );
  30.  
  31. mDouble12 = new ComponentName(
  32.  
  33. getBaseContext(),
  34.  
  35. "com.xys.changeicon.Test12" );
  36.  
  37. mPm = getApplicationContext().getPackageManager();
  38.  
  39. }
  40.  
  41.   
  42.  
  43. public void changeIcon11( View   view ) {
  44.  
  45. disableComponent(mDefault);
  46.  
  47. disableComponent(mDouble12);
  48.  
  49. enableComponent(mDouble11);
  50.  
  51. }
  52.  
  53.   
  54.  
  55. public void changeIcon12( View   view ) {
  56.  
  57. disableComponent(mDefault);
  58.  
  59. disableComponent(mDouble11);
  60.  
  61. enableComponent(mDouble12);
  62.  
  63. }
  64.  
  65.   
  66.  
  67. private void enableComponent(ComponentName componentName) {
  68.  
  69. mPm.setComponentEnabledSetting(componentName,
  70.  
  71. PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
  72.  
  73. PackageManager.DONT_KILL_APP);
  74.  
  75. }
  76.  
  77.   
  78.  
  79. private void disableComponent(ComponentName componentName) {
  80.  
  81. mPm.setComponentEnabledSetting(componentName,
  82.  
  83. PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
  84.  
  85. PackageManager.DONT_KILL_APP);
  86.  
  87. }
  88.  
  89. }

OK, after disabling the default Activity, enable the Double 11 activity-alias, the result remains unchanged and still points to the default Activity, but the icon has changed.

Depending on the ROM, after disabling the component, you will wait for a while and the Launcher will automatically refresh the icon.

See the picture below for the effect.

[[180569]]

About the Columnist

eclipse_xu: Senior Android development engineer; author of "Android Heroes", "Android Heroes: Magic Weapons", Android lecturer at MOOC; CSDN blog expert

<<:  Android Permission Management Principles (including 6.0)

>>:  Experienced driver talks about racing technology: Android 7.0 adaptation experience

Recommend

Java Thread Interview Questions

[[147712]] Below are some Java thread-related int...

All the methods and techniques to make money quickly on Zhihu are here!

I had just come into contact with Zhihu at this t...

How to obtain information sources for bidding promotion?

We all know that all revenue-generating categorie...

The IP derivatives market is booming: is it a blue ocean or a bubble?

IP derivatives have become a new target for enter...

Six major tech failures of 2014: Google Glass and Bitcoin are among them

[[126680]] Google Glass Although we read about sc...

How to effectively increase user growth?

" User growth is a term that everyone in the...

Put music in your pocket: A comprehensive collection of Hi-Fi flagship models

Hi-Fi is the abbreviation of High-Fidelity in Eng...

Artifact recommendation! 10 niche, easy-to-use and high-end operation tools!

It is said that if the underwear is well chosen, ...

Beichen Asia Market: Analysis of Beijing’s Auto Market in January 2022

1. New car transaction situation In January, Beij...