Is there any way to dynamically change an app icon like Calendar app does?
Asked Answered
P

7

44

I wanna create an Android application, and I want to dynamically and automatically update the app icon similarly to how the calendar icon updates on a user's homescreen.

The calendar changes its icon for each day showing day of month's number. There is also an Alarm clock app which changes its icon setting the current time, in other words, changing every minute.

That isn't a widget, but a real app icon. Then it must have a way to do so. How can I do it in my app?

Plinth answered 4/1, 2016 at 13:26 Comment(5)
Either you are looking at an app widget, or whatever your home screen is has special hooks for whatever your calendar app is. In general, apps cannot update their icons. "but mine is different" -- then please explain, in detail, what the other questions were and why your question is different.I
@I I've just changed my text. As you can see in the question, that's not actual a widget, but the app icon. And it changes in home screen and also in menu.Plinth
Then whatever your home screen is has special hooks for whatever your calendar app is and whatever your alarm clock app is. In general, apps cannot update their icons.I
@I What do you mean by hooks?Plinth
Possible duplicate of How to change an application icon programmatically in Android?Backpack
I
38

Whatever your home screen is has special hooks for whatever your calendar app is and whatever your alarm clock app is. In general, apps cannot update their icons.

What do you mean by hooks?

For example, Samsung can ship a Samsung calendar app on Samsung devices. Samsung's home screen on those same Samsung devices can have special rules for rendering an icon for Samsung's calendar app, rules that involve showing the day of the month. This is because Samsung wrote the home screen. If you install a third-party home screen, it may not do the same thing. After all, I can write a home screen in an hour or so, and I feel quite confident that I don't have to do anything special for Samsung's calendar app.

There's nothing stopping Samsung from exposing some sort of API to allow developers to hook into Samsung's home screen and notify it about this sort of thing. Whether Samsung intends for third parties to use that API, or whether it is somebody hacking into how Samsung does it for their own apps, I can't say.

(BTW, I am citing Samsung here as a possible example -- I don't know that they actually have this sort of feature, and if so on which devices they have it)

I seem to recall that somebody has a GitHub project that tries to wrap the proprietary APIs of various home screens. IIRC, some supported capabilities included either replacing the app icon or adding a badge (e.g., unread message count). However:

  • Only a small percentage of devices will support those proprietary APIs

  • Undocumented and unsupported APIs, discovered through reverse-engineering apps, are subject to change and may break in unexpected ways

I am quite certain that there is nothing in the Android SDK that supports dynamic app icons. The only thing that I know of, that people have tried, is using <activity-alias> to have N different "activities", all pointing to the same implementation, but having different icons. Using PackageManager and setComponentEnabledSetting(), the app disables the old launcher alias and enables a different one, in hopes that home screens will pick up on this and show the new icon. A few do. Others only would find out about the change on a reboot.

To flip the problem around, I can write a home screen. Perhaps I want to offer some way for apps to change their icons on the fly, even though there are no standards for it. Perhaps I don't. Perhaps I do not intend to use icons at all, as my home screen is optimized for the visually impaired, and so it is using text-to-speech and hardware key input. It's my home screen implementation, and I can do what I want.

I answered 5/1, 2016 at 17:41 Comment(3)
I do not think this is it. For example, calendar icon also works on Arrow launcher on my device. There are better solutions available that show it is possible with different methods (none official though). One of them is : https://mcmap.net/q/129807/-how-to-change-an-application-icon-programmatically-in-androidLarrainelarrie
@commonsware This feature is present in Google Calendar on Android Nougat and later. The question is is it available to all developers?Millard
@JPVentura: Not at present. Even if Google opens this up (say, in Android P), its availability would have to be opt-in by the developers of the home screen. There's simply nothing in the current API that would force a home screen to take on a different icon from what they may have cached.I
F
8

Indeed even in the app drawer in Android O, the Clock app icon shows the current time and the Calendar app icon shows the current day-of-month.

This article explains:

Chris Lacy, the developer behind the well-known Action Launcher, has uncovered something in the APK file of the Clock app that comes in Android O: the manifest.xml mentions hours, minutes, and seconds as layers with default values, and the icon has separate images for the background and different elements.

That logically lead him to deduce that starting with Android O, the Clock app's icon will be animated to show the current time. That will happen both when the Clock is placed as a shortcut on the homescreen and when it's inside the app drawer.

It sounds like the Pixel launcher selects different icon image layer resources depending on time and date.

Faustinafaustine answered 29/3, 2018 at 17:42 Comment(0)
S
5

I'm a launcher developer.

I did nothing related to dynamic icon hooks. I just get the activities' icons by the standard way provided by Android API.

And I found that my launcher do show the current time in the Clock app icon and the current date in the Calendar icon.

The device is a Nubia X which runs Android 8.

The operating system should have done something with the two apps and changed their icons dynamically without the launcher beings aware of it.

These two apps are developed by the device manufacturer. You should not be able to do the same thing in a normal way as a third party developer.

Soft answered 28/6, 2019 at 3:12 Comment(0)
G
4

you can define multiple activity-alias in your manifest file for each icon

<activity-alias
        android:name="OneLauncherAlias"
        android:enabled="true"
        android:icon="@drawable/one"
        android:label="One"
        android:targetActivity=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity-alias>

Enable and disable the activity-alias based on your requirement.

packageManager.setComponentEnabledSetting(ComponentName(this@MainActivity, com.misles.dynamiclaunchericon.OneLauncherAlias::class.java), PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP)
packageManager.setComponentEnabledSetting(ComponentName(this@MainActivity, com.misles.dynamiclaunchericon.TwoLauncherAlias::class.java), PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP)

for details refer this article https://medium.com/@simonmisles/dynamic-launcher-icon-and-name-for-android-e40bf0561715

Gomphosis answered 12/2, 2021 at 8:55 Comment(0)
C
4

Adding more context here to @commonsware's answer.

Did a bit more digging on how google does it with their calendar and clock app.

They seem to have special cases in the launcher code as seen here:

https://cs.android.com/android/platform/superproject/+/master:packages/apps/Launcher3/src/com/android/launcher3/icons/IconProvider.java;l=54;drc=337c81f6646e8d8351604ee2e1dd1884bc7d0452

and here: https://cs.android.com/android/platform/superproject/+/master:packages/apps/Launcher3/src/com/android/launcher3/icons/IconProvider.java;l=74;drc=337c81f6646e8d8351604ee2e1dd1884bc7d0452

So only workaround at this time to do this is to have multiple activity aliases with different icons and then switch between those aliases.

http://blog.jakelee.co.uk/programmatically-changing-app-icon/

Cq answered 7/7, 2021 at 20:59 Comment(0)
N
3

I have the same question but the answer provided here does not aswer it.
I have Google Pixel 2 with raw Android Ore 8.1 on the board and there are two apps that are changing over time: Calendar and Clock. The hands on the clock of Clock app show current time and the number on the Calendar icon correspond to today date of month.
So taking into account that it is default launcher probably there is some API to do similar thing.

For instance it might be the planetary app that reflects planets' positions on the icon. Or memory cleaner that shows percentage of used memory...

Noam answered 6/2, 2018 at 15:9 Comment(3)
Those apps use widget to do it, because they're updated time in time. However, if the point is only change the icon for a specific reason, it can be reach using <activity-alias>. I've used that in my projectPlinth
@LennonPetrick widgets appear only on desktop but I'm talking about launcher as well. And procedure of adding widget to the desktop is different than adding icon. So I'm 100% sure it is not widget.Noam
@Noam Yeah, it makes sense. They might have a different approach, cause if you use activity-alias> the shortcut in desktop tend to be removed when you active it. Perhaps is because the calendar and clock apps are from the device owner, like Samsung for example, I dunno.Plinth
B
3

The launcher handles the dynamic calendar by accessing an icon for each day from the calendar app. For example, with Google Calendar, a Launcher developer may do the following:

Resources res = activity.getPackageManager()
                            .getResourcesForApplication("com.google.android.calendar");
int resId = res.getIdentifier("logo_calendar_01_regular", "drawable"
                            , "com.google.android.calendar");
Drawable icon = res.getDrawable(resId);

This would access the calendar icon for Day 1 of the month. To access any other day, "logo_calendar_01_regular" would be changed for the current day. For example, day 7 would be "logo_calendar_07_regular". Also Google calendar has two styles, "logo_calendar_01_regular" and "logo_calendar_01_round".

Also Icon themes contain separate icons for each date as well.

Brother answered 31/10, 2018 at 7:30 Comment(2)
It only gives you access to the icon. I want to change my application's icon dynamically.Plinth
Right... In other words it doesn't look like it's possible without the launcher doing the logic. Another option would be a widget that updates. But of coarse that's not exactly what you are asking.Brother

© 2022 - 2024 — McMap. All rights reserved.