Android 利用动态改变线上 App 桌面图标
suiw9 2024-10-29 16:44 50 浏览 0 评论
最近看到「医生」写的一篇文章:上次发版我就改了一行代码!,真是脑洞大开,没想到安卓应用的桌面图标还能动态改变,涨知识了,接触安卓开发以来还是第一次知道这玩意儿,顿感无地自容。于是细细读来,着手实践,对其中涉及到的知识点对着官方文档了解一番,总结记录于此。
案例分析 & 需求来源
每逢双十一购物节,你会发现手淘 App 的桌面图标会发生改变,当然应用里面的主题色调也会改变,变得非常喜庆,营造出一种节日的氛围,用户体验极好。既然存在这样的产品运营方式,那么如何从技术上实现呢?修改应用主题色调在这里就不谈了,常见的效果有黑白主题切换、主题包下载等,关于对应开发实现方式的讲解,网上相关资料很多。这里聊聊如何修改桌面图标,毕竟这个点涉及到的知识还是很少见的。
其实很简单,利用 AndroidManifest.xml 文件中的 <activity-alias>
标签即可实现。
<activity-alias>
介绍
大家知道,对于 Activity 组件,使用时需要在 Manifest 文件中通过标签注册 name、theme、intent-filter 等相关属性信息,然后通过 Intent 操作便可以启动对应 Activity。殊不知,我们还能通过 <activity-alias>
标签为每个 Activity 注册一个“别名”,通过这个别名也能启动对应的目标 Activity。我们来看一下这个“别名”能够设置哪些属性:
<activity-alias android:enabled=["true" | "false"] android:exported=["true" | "false"] android:icon="drawable resource"
android:label="string resource"
android:name="string"
android:permission="string"
android:targetActivity="string" >
. . .</activity-alias>
可以看出,大部分属性与 <Activity>
标签的属性一致,简单分析一下
android:enabled
属性,布尔类型,是否开启别名设置,默认值为 true;android:exported
属性,布尔类型,是否支持其他应用通过这个别名访问目标 Activity,默认值为 true;android:icon
和label
属性:类似<activity>
标签,表示目标 Activity 的显示图标和标签;android:name
属性:Activity 别名,在<activity>
标签中, name 属性必须与对应 Activity 文件的名字保持一致,而这里的别名可任意设置,保证唯一性即可;android:permission
属性:权限设置,对别名的使用加以限制,详细属性值参考开发者官网对权限部分
的说明;android:targetActivity 属性:指定别名能够启动的目标 Activity,注意,属性值一定要对应到
<activity>
标签中的 name 属性,并且该<activity>
标签一定要位于<activity-alias>
标签前面;
实战演练
了解完<activity-alias>
的基本知识之后,就知道动态修改桌面图标和应用名称是怎么做到的了。其实就是给整个应用的入口 Activity 添加一个 <activity-alias>
标签,并设置预先设计好的替代桌面图标和应用名称,并配置相同的 <intent-filter>
属性,动态启动即可。举例说明一下,Manafest 文件关键代码如下:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="Samples"
android:supportsRtl="true"
android:name=".MyApplication"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity-alias
android:name=".MainAliasActivity"
android:targetActivity=".MainActivity"
android:label="Samples Alias"
android:icon="@mipmap/ic_launcher_alias"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
</application>
注意看,在别名设置中添加了 <intent-filter>
标签,与 targetActivity 的设置一致:android.intent.action.MAIN
表示这个别名设置是整个应用的入口,应用启动时第一个创建的就是这个 Activity;android.intent.category.LAUNCHER
表示这个别名设置将出现在桌面 Launcher 应用上;
至于其他属性,<activity>
标签中也有相应设置,只是通常我们在<application>
标签中统一设置而已,然后<activity>
标签默认继承<application>
标签中的设置。上述代码还有一点需要注意的是,android:enabled
属性设为 false,否则运行时将会在桌面上出现两个相同功能但不同显示的应用图标和名称。
然后在 Activity 中动态切换,通过 PackageManager 对象提供的 setComponentEnabledSetting()
方法关闭当前 Component 组件,并启动别名对应的 Component 组件即可,参考代码如下:
public void onClickOne(View v){
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(getComponentName(),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(new ComponentName(this, "com.yifeng.samples.AliasName"),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}
效果如图:
注意,修改之后,需要稍等片刻才能看到变化。如果想在修改完成之后立即看到变化,只能通过 Intent 重启 Launcher 应用。代码如下:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.addCategory(Intent.CATEGORY_DEFAULT);
List<ResolveInfo> resolves = pm.queryIntentActivities(intent, 0); for (ResolveInfo res : resolves) { if (res.activityInfo != null) {
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
am.killBackgroundProcesses(res.activityInfo.packageName);
}
}
然后不要忘了在 Manifest 文件中添加权限:<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
通过这些设置,基本上就能实现动态修改应用的桌面图标和名称。通常,可以提前将新的图标放置在应用中,待到特定时间段通过服务器端的消息推送等行为灵活触发 App 修改 Launcher 上显示的图标和名称,这样就不必为了改个图标单独迭代一个新版本。值得注意的是,从产品角度上讲,一般不会为了短期的一个活动修改应用名称,而是只修改桌面图标,并且新的桌面图标也只是在原有的基础样式上动动手脚,起到锦上添花的作用,万不可改得面貌全非,否则会让用户产生误解,那就得不偿失了。遗留问题
第一个,以上这种设置只能修改 Launcher 上的应用图标和名称,属于应用级别(application level)的,无法达到系统级别(OS level)的修改,比如改完之后,使用 menu 物理键打开 multi-task 窗口,或者打开设置查看应用列表,你会发现,对应应用的图标和名称还是显示之前默认的那些。不过,对于普通用户来说,主要还是在于桌面 Launcher 上的显示,毕竟这里才是最直观也是最常用到的地方。第二个,这里我们将新的桌面图标提前放置在应用资源文件中,然后通过在 <activity-alias>
标签中指定对应引用即可,有没有一种方式能够在 Java 代码中设置 Icon 属性呢?如果可以的话,那就更加完美了,将图标文件放置在服务器,使用起来岂不是更加灵活?一番努力之后,还是没能找到对应解决方案,如果你们有知道的话,请关注我的博客留言告知,与我交流,谢谢。
可供拓展
你有没有发现,其实利用<activity-alias>
标签也能实现给 App 添加桌面快捷方式的功能,实现步骤和上面所讲的内容大同小异。不过官方给了另外一种实现,可以参考官网相关介绍:App Shortcuts
。备注:由于头条不支持外链,文中相关参考链接无法点击,欢饮访问我的博客原文,地址如下:
http://yifeng.studio/2016/12/30/android-change-app-launcher-icon-dynamically/
相关推荐
- 5款Syslog集中系统日志常用工具对比推荐
-
一、为何要集中管理Syslog?Syslog由Linux/Unix系统及其他网络设备生成,广泛分布于整个网络。因其包含关键信息,可用于识别网络中的恶意活动,所以必须对其进行持续监控。将Sys...
- 跨平台、多数据库支持的开源数据库管理工具——DBeaver
-
简介今天给大家推荐一个开源的数据库管理工具——DBeaver。它支持多种数据库系统,包括Mysql、Oracle、PostgreSQL、SLQLite、SQLServer等。DBeaver的界面友好...
- 强烈推荐!数据库管理工具:Navicat Premium 16.3.2 (64位)
-
NavicatPremium,一款集数据迁移、数据库管理、SQL/查询编辑、智能设计、高效协作于一体的全能数据库开发工具。无论你是MySQL、MariaDB、MongoDB、SQLServer、O...
- 3 年 Java 程序员还玩不转 MongoDB,网友:失望
-
一、什么场景使用MongoDB?...
- 拯救MongoDB管理员的GUI工具大赏:从菜鸟到极客的生存指南
-
作为一名在NoSQL丛林中披荆斩棘的数据猎人,没有比GUI工具更称手的瑞士军刀了。本文将带你围观五款主流MongoDB管理神器的特性与暗坑,附赠精准到扎心的吐槽指南一、MongoDBCompass:...
- mongodb/redis/neo4j 如何自己打造一个 web 数据库可视化客户端?
-
前言最近在做neo4j相关的同步处理,因为产线的可视化工具短暂不可用,发现写起来各种脚本非常麻烦。...
- solidworks使用心得,纯干货!建议大家收藏
-
SolidWorks常见问题...
- 统一规约-关乎数字化的真正实现(规范统一性)
-
尽管数字化转型的浪潮如此深入人心,但是,对于OPCUA和TSN的了解却又甚少,这难免让人质疑其可实现性,因为,如果缺乏统一的语义互操作规范,以及更为具有广泛适用的网络与通信,则数字化实际上几乎难以具...
- Elasticsearch节点角色配置详解(Node)
-
本篇文章将介绍如下内容:节点角色简介...
- 产前母婴用品分享 篇一:我的母婴购物清单及单品推荐
-
作者:DaisyH8746在张大妈上已经混迹很久了,有事没事看看“什么值得买”已渐渐成了一种生活习惯,然而却从来没有想过自己要写篇文章发布上来,直到由于我产前功课做得“太过认真”(认真到都有点过了,...
- 比任何人都光彩照人的假期!水润、紧致的肌肤护理程序
-
图片来源:谜尚愉快的假期临近了。身心振奋的休假季节。但是不能因为这种心情而失去珍贵的东西,那就是皮肤健康。炙热的阳光和强烈的紫外线是使我们皮肤老化的主犯。因此,如果怀着快乐的心情对皮肤置之不理,就会使...
- Arm发布Armv9边缘AI计算平台,支持运行超10亿参数端侧AI模型
-
中关村在线2月27日消息,Arm正式发布Armv9边缘人工智能(AI)计算平台。据悉,该平台以全新的ArmCortex-A320CPU和领先的边缘AI加速器ArmEthos-U85NPU为核心...
- 柔性——面向大规模定制生产的数字化实现的基本特征
-
大规模定制生产模式的核心是柔性,尤其是体现在其对定制的要求方面。既然是定制,并且是大规模的定制,对于制造系统的柔性以及借助于数字化手段实现的柔性,就提出了更高的要求。面向大规模定制生产的数字化业务管控...
- 创建PLC内部标准——企业前进的道路
-
作者:FrankBurger...
- 标准化编程之 ----------- 西门子LPMLV30测试总结
-
PackML乃是由OMAC开发且被ISA所采用的自动化标准TR88.00.02,能够更为便捷地传输与检索一致的机器数据。PackML的主要宗旨在于于整个工厂车间倡导通用的“外观和感觉”,...
你 发表评论:
欢迎- 一周热门
-
-
Linux:Ubuntu22.04上安装python3.11,简单易上手
-
宝马阿布达比分公司推出独特M4升级套件,整套升级约在20万
-
MATLAB中图片保存的五种方法(一)(matlab中保存图片命令)
-
别再傻傻搞不清楚Workstation Player和Workstation Pro的区别了
-
Linux上使用tinyproxy快速搭建HTTP/HTTPS代理器
-
如何提取、修改、强刷A卡bios a卡刷bios工具
-
Element Plus 的 Dialog 组件实现点击遮罩层不关闭对话框
-
日本组合“岚”将于2020年12月31日停止团体活动
-
SpringCloud OpenFeign 使用 okhttp 发送 HTTP 请求与 HTTP/2 探索
-
tinymce 号称富文本编辑器世界第一,大家同意么?
-
- 最近发表
-
- 5款Syslog集中系统日志常用工具对比推荐
- 跨平台、多数据库支持的开源数据库管理工具——DBeaver
- 强烈推荐!数据库管理工具:Navicat Premium 16.3.2 (64位)
- 3 年 Java 程序员还玩不转 MongoDB,网友:失望
- 拯救MongoDB管理员的GUI工具大赏:从菜鸟到极客的生存指南
- mongodb/redis/neo4j 如何自己打造一个 web 数据库可视化客户端?
- solidworks使用心得,纯干货!建议大家收藏
- 统一规约-关乎数字化的真正实现(规范统一性)
- Elasticsearch节点角色配置详解(Node)
- 产前母婴用品分享 篇一:我的母婴购物清单及单品推荐
- 标签列表
-
- dialog.js (57)
- importnew (44)
- windows93网页版 (44)
- yii2框架的优缺点 (45)
- tinyeditor (45)
- qt5.5 (60)
- windowsserver2016镜像下载 (52)
- okhttputils (51)
- android-gif-drawable (53)
- 时间轴插件 (56)
- docker systemd (65)
- slider.js (47)
- android webview缓存 (46)
- pagination.js (59)
- loadjs (62)
- openssl1.0.2 (48)
- velocity模板引擎 (48)
- pcre library (47)
- zabbix微信报警脚本 (63)
- jnetpcap (49)
- pdfrenderer (43)
- fastutil (48)
- uinavigationcontroller (53)
- bitbucket.org (44)
- python websocket-client (47)