The mobile app scene is evolving. Developers are constantly innovating with UI patterns, UX styles, and more to keep users hooked. Functionality is no longer the sole focus. The entire mobile app development landscape has shifted. Both developers and users now prioritize aesthetics and visual appeal. User experience is equally, if not more, crucial for an app's success.

One key element of exceptional UI/UX is the ability to dynamically change the logo without requiring a reinstall. You've likely observed some Android apps modify their logos on the fly to commemorate specific events.

For instance,

  • Zomato might ask if you want to switch the app's logo after purchasing Zomato Gold. If you agree, it changes seamlessly without a reinstall.

  • Many apps adjust their logos during Pride month in support of the movement.

Have you ever pondered how these Android apps manage to alter their logos without intervention from either the developer or the user?

Being a top mobile app development company, we felt it is our responsibility to share this to our developer community.

Step 1

Android system reads the manifest file and sets the app icon accordingly. Currently there is no way to change the app icon in runtime. But there is a workaround. That is to use a activity-alias (If you are not familiar with activity-alias, you can check the official documentation here)


    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools">
      <application
        ...
        android:icon="YOUR_ICON"
        android:roundIcon="YOUR_ICON">
        <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:icon="YOUR_ICON_2"
          android:roundIcon="YOUR_ICON_2"
          android:targetActivity=".MainActivity">
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
        </activity-alias>
      </application>
 </manifest>
  

Step 2

One is the main activity, and the other is the activity alias. The activity alias is disabled by default.


`
fun Activity.changeIcon() {
    packageManager.setComponentEnabledSetting(
        ComponentName(
            this,
            "$packageName.MainActivityAlias"
        ),
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP
    )

    packageManager.setComponentEnabledSetting(
        ComponentName(
            this,
            "$packageName.MainActivity"
        ),
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP
    )
}
`

Step 3

We are using the setComponentEnabledSetting method of the PackageManager class.


`
fun Activity.changeEnabledComponent(
       enabled: String,
       disabled: String,
     ) {
       packageManager.setComponentEnabledSetting(
         ComponentName(
           this,
           enabled
         ),
         PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
         PackageManager.DONT_KILL_APP
       )
   
     packageManager.setComponentEnabledSetting(
         ComponentName(
           this,
           disabled
         ),
         PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
         PackageManager.DONT_KILL_APP
     )
   }
`

Develop an Android mobile app today.Contact the Android app development experts. **Contact us **

Step 4

The app icon will be as simple as calling the function with the component names. For instance


`
changeEnabledComponent(
     enabled = "$packageName.MainActivityAlias",
     disabled = "$packageName.MainActivity"
   )
`

Step 5

We can use BuildConfig with manifestPlaceholders. In the app-level build.gradle file


`
private val mainActivity = "YOURPATH.MainActivity"
private val mainActivityAlias = "YOURPATH.MainActivityAlias"
android {
    defaultConfig {
        ...
        manifestPlaceholders.apply {
            set("main_activity", mainActivity)
            set("main_activity_alias", mainActivityAlias)
        }
    }
    buildTypes {
        release {
            isMinifyEnabled = false
            buildConfigField("String", "main_activity", "\${mainActivity}\")
            buildConfigField("String", "main_activity_alias", "\${mainActivityAlias}\")
        }
        debug {
            isDebuggable = true
            isMinifyEnabled = false
            buildConfigField("String", "main_activity", "\${mainActivity}\")
            buildConfigField("String", "main_activity_alias", "\${mainActivityAlias}\")
        }
    }
}
`

Step 6

Here we are setting the component names to the manifestPlaceholders and buildConfigField. So we can access them from the BuildConfig class.


`
private val mainActivity = "YOURPATH.MainActivity"
private val mainActivityAlias = "YOURPATH.MainActivityAlias"
android {
    defaultConfig {
        ...
        manifestPlaceholders.apply {
            set("main_activity", mainActivity)
            set("main_activity_alias", mainActivityAlias)
        }
    }
    buildTypes {
        release {
            isMinifyEnabled = false
            buildConfigField("String", "main_activity", "\${mainActivity}\")
            buildConfigField("String", "main_activity_alias", "\${mainActivityAlias}\")
        }
        debug {
            isDebuggable = true
            isMinifyEnabled = false
            buildConfigField("String", "main_activity", "\${mainActivity}\")
            buildConfigField("String", "main_activity_alias", "\${mainActivityAlias}\")
        }
    }
}
`

Step 7

You may now see some errors that says main_activity and/or main_activity_alias cannot be found. But you can ignore them, because they will be generated in sync with the build.gradle file.


`
changeEnabledComponent(
     enabled = BuildConfig.main_activity_alias,
     disabled = BuildConfig.main_activity
   )
`

Step 8

We can change the app icon in runtime by calling the changeEnabledComponent function with the component names.


`
val mainActivity = BuildConfig.main_activity
val mainActivityAlias = BuildConfig.main_activity_alias

class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)

     setContent {
        DynamicIconTheme {
           Surface(
              modifier = Modifier.fillMaxSize(),
              color = MaterialTheme.colorScheme.background
           ) {
              Screen(
                 on30Click = {
                    changeEnabledComponent(
                       enabled = mainActivityAlias,
                       disabled = mainActivity
                    )
                 },
                 on60Click = {
                    changeEnabledComponent(
                       enabled = mainActivityAlias,
                       disabled = mainActivity
                    )
                 }
              )
           }
        }
     }
  }
}
`

Conclusion

Want to create a special connection with your Android app users? Dynamic logos offer a powerful way to do just that. By changing your app's logo for specific events, you can foster user engagement and even a sense of exclusivity.  Consider incorporating this feature when developing your app. A top android app development company can help you explore ways to further enhance user engagement and create a truly dynamic experience.