有没有办法动态更改日历应用程序的应用程序图标?

时间:2016-01-04 13:26:00

标签: android dynamic icons android-calendar

我想创建一个Android应用程序,我想动态地自动更新应用程序图标,类似于日历图标在用户主屏幕上的更新方式。

日历会更改每天显示某月份数字的图标。还有一个闹钟应用程序可以更改其图标设置当前时间,换句话说,每分钟更改一次。

这不是一个小部件,而是一个真正的应用程序图标。然后它必须有办法这样做。我怎么能在我的应用程序中做到这一点?

7 个答案:

答案 0 :(得分:18)

无论您的主屏幕是什么,都有特殊的挂钩,无论您的日历应用程序是什么,以及您的闹钟应用程序是什么。通常,应用无法更新其图标。

  

钩子是什么意思?

例如,三星可以在三星设备上发布三星日历应用程序。三星在同一台三星设备上的主屏幕可以为三星日历应用程序呈现图标的特殊规则,这些规则涉及显示当月的日期。这是因为三星写了主屏幕。如果您安装第三方主屏幕,它可能不会做同样的事情。毕竟,我可以在一个小时左右的时间内写一个主屏幕,我觉得我不必为三星的日历应用做任何特别的事情。

没有什么可以阻止三星暴露某种API以允许开发人员进入三星的主屏幕并通知它这类事情。无论三星是否打算让第三方使用该API,或者是否有人侵入三星如何为自己的应用程序执行此操作,我都不能说。

(顺便说一句,我在这里引用三星作为一个可能的例子 - 我不知道他们实际上有这种功能,如果有的话,他们有哪些设备)

我似乎记得有人有一个GitHub项目试图包装各种主屏幕的专有API。 IIRC,一些支持的功能包括替换应用程序图标或添加徽章(例如,未读消息计数)。但是:

  • 只有一小部分设备会支持这些专有API

  • 通过逆向工程应用程序发现的未记录和不受支持的API可能会发生变化,并可能以意想不到的方式中断

我非常确定Android SDK中没有任何内容支持动态应用图标。我所知道的,人们已经尝试过的唯一一件事就是使用<activity-alias>来创建N个不同的“活动”,所有这些都指向相同的实现,但是具有不同的图标。使用PackageManagersetComponentEnabledSetting(),该应用程序会禁用旧的启动器别名并启用另一个别名,希望主屏幕会在此处显示并显示新图标。一些。其他人只会发现重启时的变化。

要解决问题,我可以写一个主屏幕。也许我想为应用程序提供一些动态更改图标的方法,即使它没有标准。也许我没有。也许我根本不想使用图标,因为我的主屏幕针对视障人士进行了优化,因此它使用文本到语音和硬件键输入。这是我的主屏幕实现,我可以做我想做的事。

答案 1 :(得分:4)

确实,即使在Android O的应用程序抽屉中,时钟应用程序图标显示当前时间,日历应用程序图标显示当前日期。

This article explains

  着名的Action Launcher背后的开发人员Chris Lacy在Android O中的Clock应用程序的APK文件中发现了一些内容:manifest.xml提到小时,分钟和秒作为具有默认值的图层,并且图标具有背景和不同元素的单独图像。

     

这在逻辑上导致他推断出从Android O开始,Clock应用程序的图标将动画显示当前时间。当时钟作为主屏幕上的快捷方式放置在应用程序抽屉内时,就会发生这种情况。

听起来像Pixel启动器根据时间和日期选择不同的图标图像层资源。

答案 2 :(得分:2)

我有同样的问题,但这里提供的答案并没有贬低它 我在主板上安装了原始Android Ore 8.1的 Google Pixel 2 ,并且有两个应用随着时间的推移而变化:日历时钟 Clock 应用程序时钟上的指针显示当前时间,日历图标上的数字对应于今天的月份日期。
因此,考虑到它是默认启动器,可能有一些API可以做类似的事情。

例如,它可能是反映行星的行星应用程序&#39;图标上的位置。或显示已用内存百分比的内存清理器......

答案 3 :(得分:2)

启动器通过访问日历应用程序中每天的图标来处理动态日历。例如,对于Google日历,启动器开发人员可以执行以下操作:

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);

这将访问该月第一天的日历图标。要访问其他任何一天,当天的“ logo_calendar_01_regular”将被更改。例如,第7天将是“ logo_calendar_07_regular”。此外,Google日历具有两种样式,即“ logo_calendar_01_regular”和“ logo_calendar_01_round”。

“图标”主题还包含每个日期的单独图标。

答案 4 :(得分:0)

我是启动器开发人员。

我没有做任何与动态图标挂钩相关的事情。我只是通过Android API提供的标准方式来获取活动的图标。

我发现启动器的确在“时钟”应用程序图标中显示了当前时间,在“日历”图标中显示了当前日期。

设备是运行Android 8的Nubia X。

操作系统应该对这两个应用做了一些操作,并在启动器不知道的情况下动态更改了它们的图标。

这两个应用程序是由设备制造商开发的。您应该不能以正常方式做与第三方开发人员相同的事情。

答案 5 :(得分:0)

您可以在清单文件中为每个图标定义多个活动别名

<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>

根据您的要求启用和禁用活动别名。

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)

详情参考这篇文章 https://medium.com/@simonmisles/dynamic-launcher-icon-and-name-for-android-e40bf0561715

答案 6 :(得分:0)

在此处为 @commonsware's 答案添加更多上下文。

对谷歌如何使用他们的日历和时钟应用程序进行了更多的挖掘。

他们似乎在启动器代码中有特殊情况,如下所示:

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

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

所以此时唯一的解决方法是拥有多个 具有不同图标的活动别名,然后在这些别名之间切换。

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