我想创建一个Android应用程序,并希望能够动态自动更新应用程序图标,就像日历图标在用户的主屏幕上更新一样。
日历会根据每天显示当月日期的数字更改其图标。还有一个闹钟应用程序,它会根据当前时间更改其图标设置,换句话说,每分钟都会更改。
这不是一个小部件,而是一个真正的应用程序图标。因此它必须有一种方法来实现。我该如何在我的应用程序中做到这一点?
我想创建一个Android应用程序,并希望能够动态自动更新应用程序图标,就像日历图标在用户的主屏幕上更新一样。
日历会根据每天显示当月日期的数字更改其图标。还有一个闹钟应用程序,它会根据当前时间更改其图标设置,换句话说,每分钟都会更改。
这不是一个小部件,而是一个真正的应用程序图标。因此它必须有一种方法来实现。我该如何在我的应用程序中做到这一点?
无论你的主屏幕是什么,都有专门针对你的日历应用和闹钟应用的特殊钩子。一般来说,应用程序不能更新它们的图标。
什么是钩子?
例如,三星可以在三星设备上预装三星日历应用。在这些同样的三星设备上,三星的主屏幕可以有特殊的规则来呈现三星日历应用的图标,规则包括显示月份的日期。这是因为三星编写了主屏幕。如果你安装第三方主屏幕,可能不会做同样的事情。毕竟,我可以在一个小时左右内编写一个主屏幕,并且我非常自信我不必为三星的日历应用做任何特殊处理。
没有什么可以阻止三星暴露某种API,以允许开发人员钩入三星的主屏幕,并通知它关于这种事情。无论三星是否打算让第三方使用该API,或者是某个人在黑客攻击三星如何为他们自己的应用程序做到这一点,我无法说。
(顺便说一句,在此引用三星作为一个可能的例子--我不知道他们是否真的有这种功能,如果有,在哪些设备上拥有)
我记得有人有一个 GitHub 项目,试图包装各种主屏幕的专有API。如果我没记错的话,一些支持的功能包括替换应用程序图标或添加徽章(例如未读消息计数)。但是:
只有少数设备支持这些专有API
通过反向工程应用程序发现的未记录和不受支持的API可能会发生变化,并且可能以意想不到的方式失效。
我非常确定Android SDK中没有支持动态应用程序图标的内容。我所知道的唯一方法是使用<activity-alias>
,创建N个不同的“活动”,它们都指向相同的实现,但具有不同的图标。应用程序使用PackageManager
和setComponentEnabledSetting()
,禁用旧的启动器别名并启用不同的别名,以期望主屏幕能够识别并显示新图标。有些主屏幕可以成功,而其他的则只能在重新启动后才能发现变化。
反过来说,我可以编写一个自己的主屏幕。也许我想要提供一些方式,使应用程序可以随时更改其图标,即使没有标准可以遵循。也许我不想这样做。也许我根本不打算使用图标,因为我的主屏幕针对视觉受损者进行了优化,因此它使用文本转语音和硬件键输入。这是我的主屏幕实现,我想要怎么做就怎么做。
http://blog.jakelee.co.uk/programmatically-changing-app-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>
根据需要启用和禁用基于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
我有同样的问题,但这里提供的答案并不能回答我的问题。
我使用的是原生安卓Ore 8.1操作系统的Google Pixel 2手机,并且有两个应用程序随时间而改变:日历和时钟。在时钟应用程序的指针显示当前时间,在日历图标上的数字与今天的日期相对应。
因此考虑到这是默认启动器,可能有一些API可以做类似的事情。
例如,它可以是反映图标上行星位置的行星应用程序,或者显示已使用内存百分比的内存清理程序...
<activity-alias>
来实现。我在我的项目中使用过它。 - Lennon Spirlandelliactivity-alias>
,则在激活它时桌面上的快捷方式 tend to be removed。也许是因为日历和时钟应用程序来自设备所有者,例如三星之类的公司,我不知道。 - Lennon SpirlandelliResources 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”。
另外,图标主题还包含每个日期的单独图标。