Blog Infos
Author
Published
Topics
, , , ,
Published
Introduction

Have you ever glanced at your mobile screen and noticed an app’s icon looking fresh and different from before? This isn’t just visual flair; it’s the magic of dynamic app icons at play. This fascinating feature allows Android apps to change their icons dynamically, all without needing updates from the Play Store! It’s a subtle yet powerful strategy to engage users and add vibrancy to your app. Though it might seem like advanced wizardry, mastering dynamic app icons is absolutely within your reach. Let’s embark on this learning journey together!

If you’re new to Android development or even if you’ve been in the game for years, you might not have explored the intriguing world of dynamic app icons yet. But fear not! This guide is designed to demystify the process, offering a step-by-step journey into creating dynamic app icons in Android. Whether you’re just starting your coding adventure or looking to add another skill to your toolkit, this post is here to guide you through enhancing your app’s user experience in a unique way.

Why Dynamic App Icons?

Imagine, for instance, your app’s icon changing to celebrate a holiday, additionally adapting to user-preferred themes, or perhaps indicating a new feature. It’s not just about looking pretty — it’s about creating a dynamic interaction between your app and its users. Let’s dive into how you can make this happen.

Implement Icon Change Logic

Before we jump into the code, let’s clarify a few things to ensure everyone is on the same page. In the world of Android, your app’s front door is represented by its icon. It’s the first thing users interact with, so making it dynamic can significantly enhance their experience.

In this section, we’ll dive into the core of dynamic app icons in Android by implementing the logic responsible for changing the app’s icon dynamically. We’ll walk through the code step by step, explaining what each part does.

Setting the Stage in Your AndroidManifest.xml

There’s an essential step we need to address in your AndroidManifest.xml file. If you want your app to strut its stuff with dynamic icon changes, you’ve got to set up an activity alias for your main activity.

Understanding Activity Aliases

In Android, you can create activity aliases to the main activity in your manifest file to enable dynamic app icon changes. These aliases allow you to associate different icons with the same main activity, and you can enable or disable them programmatically to change the app’s icon dynamically.

Think of it as a decoy or a stand-in for your main app icon. It allows your app to switch between different icons under the same name.

Here’s an example of how you would define an activity alias in your AndroidManifest.xml file:

<application
    android:icon="icon"
    android:roundIcon="icon">
    <activity
       // ...
    </activity>

    <activity-alias
        android:name=".MainActivityAlias"
        android:icon="icon_2"
        android:roundIcon="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>

In this example, .MainActivityAlias is the name of the alias, and .MainActivity is the target activity that the alias points to. The <intent-filter> is like telling your app, “Hey, this alias is also a way to launch the app!”

Remember, swap out MainActivityAlias in the code with the actual name you’ve christened your activity alias in your AndroidManifest.xml file. This ensures that your code and your configuration are singing the same tune when it comes to dynamic icon changes.

Now, to create dynamic app icons in Android, follow these steps:

1. Creating a BroadcastReceiver

We’ll start by creating a BroadcastReceiver that will listen for a specific broadcast event and take care of the icon switcheroo. Let’s create a new IconChangeReceiver class:

class IconChangeReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        if (intent?.action == "com.example.app.ACTION_CHANGE_ICON") {
            changeAppIcon(context)
        }
    }
    
    private fun changeAppIcon(context: Context?) {
        context?.let {
            // This is where the magic happens. We'll get to this in a bit!
        }
    }
}

In this code, IconChangeReceiver acts as your diligent listener, meanwhile eagerly awaiting the signal"com.example.app.ACTION_CHANGE_ICON". When it hears this, it calls changeAppIcon – that’s your cue to switch up the icon.

2. Register the BroadcastReceiver

In your AndroidManifest.xml file, be sure to register the IconChangeReceiver with an intent filter to listen for the custom action:

<receiver
    android:name=".IconChangeReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="com.example.app.ACTION_CHANGE_ICON" />
    </intent-filter>
</receiver>
3. Implement Icon Change Logic

Inside the onReceive method of your IconChangeReceiver, implement the logic to change the app icon dynamically. You can use conditional statements to select different icons based on specific criteria. Here’s a simplified example:

class IconChangeReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        if (intent?.action == "com.example.app.ACTION_CHANGE_ICON") {
            changeAppIcon(context)
        }
    }
    
    private fun changeAppIcon(context: Context?) {
        context?.let { ctx ->
            // Example: Conditionally select a different alias based on some criteria
            val aliasToEnable = when (someCondition) {
                true -> ctx.getString(R.string.alias_1)
                false -> ctx.getString(R.string.alias_2)
            }
            
            val aliasToDisable = when (aliasToEnable) {
                ctx.getString(R.string.alias_1) -> ctx.getString(R.string.alias_2)
                else -> ctx.getString(R.string.alias_1)
            }
            
            // Change the app icon by enabling one alias and disabling the other
            val packageManager = ctx.packageManager
            enableComponent(ctx, packageManager, aliasToEnable)
            disableComponent(ctx, packageManager, aliasToDisable)
        }
    }

    private fun enableComponent(
        context: Context, 
        packageManager: PackageManager, 
        componentNameString: String
    ) {
        val componentName = ComponentName(context, componentNameString)
        
        packageManager.setComponentEnabledSetting(
            componentName,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP
        )
    }

    private fun disableComponent(
        context: Context, 
        packageManager: PackageManager, 
        componentNameString: String
    ) {
        val componentName = ComponentName(context, componentNameString)
        
        packageManager.setComponentEnabledSetting(
            componentName,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP
        )
    }
}

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

, ,

Migrating to Jetpack Compose – an interop love story

Most of you are familiar with Jetpack Compose and its benefits. If you’re able to start anew and create a Compose-only app, you’re on the right track. But this talk might not be for you…
Watch Video

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer for Jetpack Compose
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engin ...
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer f ...
Google

Jobs

Here we are first checking if the context (the current state of the app) is not null. We need the context because it gives us access to app-specific resources and classes.

Then we decide which icon to show based on certain conditions. This is where you can get creative. For example, you might change the icon based on the time of day, a holiday, or a special event in your app.

Lastly, with the chosen icon resource, we proceed to the crucial step: changing the app icon. We use the PackageManager to enable the activity alias representing the new icon and disable the current one. Think of it like telling Android, “Hey, stop using this icon and start using this one instead.”

We achieve this by calling setComponentEnabledSetting on our main activity and its alias. Enabling the alias with the new icon and disabling the current one effectively switches the icons.

4. Trigger Icon Change

To actually trigger the icon change, we send a broadcast with the specific action that our IconChangeReceiver is listening for. This is done by creating an Intent with the action "com.example.app.ACTION_CHANGE_ICON" and then calling sendBroadcast on our context. Here’s how it’s typically done:

If you’re calling it within an Activity or another component that holds a Context, you can use:

val iconChangeIntent = Intent("com.example.app.ACTION_CHANGE_ICON")
sendBroadcast(iconChangeIntent)

And if you’re in a different part of your app and have a reference to a Context, you’d do:

val iconChangeIntent = Intent("com.example.app.ACTION_CHANGE_ICON")
context.sendBroadcast(iconChangeIntent)

Remember, the broadcast will be received by our IconChangeReceiver, which will then proceed to change the app’s icon based on the logic we’ve set up.

Conclusion

In the ever-evolving world of Android app development, making your app stand out is all about engaging your users and sprinkling in some personal flair. Dynamic app icons are your ticket to an immersive, fresh user experience. They let your app’s icon evolve on the fly, no updates or reinstalls needed. The sky’s the limit: celebrate special occasions, switch themes, or show off new features, all with a dynamic twist!

Happy coding! 🚀

Originally published at https://josiassena.com on January 20, 2024.

This article is previously published on proandroiddev.com

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
Using annotations in Kotlin has some nuances that are useful to know
READ MORE
blog
One of the latest trends in UI design is blurring the background content behind the foreground elements. This creates a sense of depth, transparency, and focus,…
READ MORE
blog
Now that Android Studio Iguana is out and stable, I wanted to write about…
READ MORE
blog
The ModalBottomSheet in Jetpack Compose is easy to use, it just pops up at…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu