This project demonstrates how to implement dynamic app launcher icons in Android applications using Jetpack Compose. Popular apps like Swiggy, Zomato, and Twitter use this feature to dynamically change their app icons, enhancing user engagement and branding.
Changed the implementation a little to make sure not to kill the app with every icon change. The app will still get killed once when changing from the default icon. Thank you Avinav Srivastava for suggesting this change.
---- Switch between multiple app launcher icons dynamically.
- Uses
ActivityAlias
to manage app icons. - Includes a Jetpack Compose-based UI to select and apply app icons seamlessly.
- Android Studio Arctic Fox or later.
- Minimum SDK version: 21.
- Recommended target SDK version: 31 or higher.
- Clone the repository:
git clone https://github.com/SamriddhaS/DynamicAppLauncherDemo.git
- Open the project in Android Studio.
- Build and run the project on a physical device or emulator.
We define ActivityAlias
entries in the AndroidManifest.xml
to manage multiple app icons. Each alias is mapped to the main activity but uses a different icon. We can add activity alias for each of the launcher icon that we want to configure.
<!-- This is enabled by default -->
<activity-alias
android:name=".DefaultTheme"
android:enabled="true"
android:icon="@mipmap/ic_launcher"
android:targetActivity=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<!-- Icon one: disabled by default -->
<activity-alias
android:name=".MyIconOne"
android:enabled="false"
android:icon="@mipmap/my_launch_icon_one"
android:targetActivity=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<!-- Icon two: disabled by default -->
<activity-alias
android:name=".MyIconTwo"
android:enabled="false"
android:icon="@mipmap/my_launch_icon_two"
android:targetActivity=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
The MainActivity
uses the PackageManager
API to enable or disable ActivityAlias
entries dynamically.
packageManager.setComponentEnabledSetting(
ComponentName(
this,
"$packageName${selectedIcon.themeName}"
),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP
)
packageManager.setComponentEnabledSetting(
ComponentName(
this,
"$packageName${currentIcon}"
),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP
)
We store the currently active icon in SharedPreferences
to persist user preferences.
sharedPref.edit {
putString(CURRENT_ICON_KEY, selectedIcon.themeName)
apply()
}
A Compose-based UI allows users to select and preview the app icons dynamically.
@Composable
fun ImageSelector(
onImageClick: (AppLauncherIcons) -> Unit,
modifier: Modifier
) {
val imageList = listOf(
AppLauncherIcons.Default_Theme,
AppLauncherIcons.Theme_One,
AppLauncherIcons.Theme_Two,
AppLauncherIcons.Theme_Three,
)
LazyColumn(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
items(imageList.size) { index ->
val imageRes = imageList[index]
GlideImage(
model = imageRes.imageRes,
contentDescription = "Image $index",
contentScale = ContentScale.Crop,
modifier = Modifier
.size(100.dp)
.clickable { onImageClick(imageRes) }
.padding(4.dp)
)
}
}
}
- Launch the app.
- Browse through the available launcher icons using the provided UI.
- Select an icon to apply it as the app launcher icon.
- Confirm the selection in the modal bottom sheet.
Here are some helpful blogs that inspired and guided the implementation of this feature:
Contributions are welcome! Please fork the repository, make your changes, and submit a pull request.
Enjoy experimenting with dynamic app icons! 🚀