Android 利用 <activity-alias> 动态改变 App 桌面图标
来源:互联网 发布:淘宝模版导航页图片 编辑:程序博客网 时间:2024/06/05 18:00
案例分析 & 需求来源
每逢双十一购物节,你会发现手淘 App 的桌面图标会发生改变,当然应用里面的主题色调也会改变,变得非常喜庆,营造出一种节日的氛围,用户体验极好。既然存在这样的产品运营方式,那么如何从技术上实现呢?修改应用主题色调在这里就不谈了,常见的效果有黑白主题切换、主题包下载等,关于对应开发实现方式的讲解,网上相关资料很多。这里聊聊如何修改桌面图标,毕竟这个点涉及到的知识还是很少见的。
其实很简单,利用 AndroidManifest.xml 文件中的 <activity-alias>
标签即可实现。
<activity-alias>
介绍
大家知道,对于 Activity 组件,使用时需要在 Manifest 文件中通过 标签注册 name、theme、intent-filter 等相关属性信息,然后通过 Intent 操作便可以启动对应 Activity。殊不知,我们还能通过<activity-alias>
标签为每个 Activity 注册一个“别名”,通过这个别名也能启动对应的目标 Activity。我们来看一下这个“别名”能够设置哪些属性:
123456789
<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 文件关键代码如下:
12345678910111213141516171819202122232425262728293031
<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 组件即可,参考代码如下:
1234567
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 应用。代码如下:
12345678910
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 文件中添加权限:
1
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
通过这些设置,基本上就能实现动态修改应用的桌面图标和名称。通常,可以提前将新的图标放置在应用中,待到特定时间段通过服务器端的消息推送等行为灵活触发 App 修改 Launcher 上显示的图标和名称,这样就不必为了改个图标单独迭代一个新版本。值得注意的是,从产品角度上讲,一般不会为了短期的一个活动修改应用名称,而是只修改桌面图标,并且新的桌面图标也只是在原有的基础样式上动动手脚,起到锦上添花的作用,万不可改得面貌全非,否则会让用户产生误解,那就得不偿失了。
遗留问题
第一个,以上这种设置只能修改 Launcher 上的应用图标和名称,属于应用级别(application level)的,无法达到系统级别(OS level)的修改,比如改完之后,使用 menu 物理键打开 multi-task 窗口,或者打开设置查看应用列表,你会发现,对应应用的图标和名称还是显示之前默认的那些。不过,对于普通用户来说,主要还是在于桌面 Launcher 上的显示,毕竟这里才是最直观也是最常用到的地方。
第二个,这里我们将新的桌面图标提前放置在应用资源文件中,然后通过在 <activity-alias>
标签中指定对应引用即可,有没有一种方式能够在 Java 代码中设置 Icon 属性呢?如果可以的话,那就更加完美了,将图标文件放置在服务器,使用起来岂不是更加灵活?一番努力之后,还是没能找到对应解决方案,如果你们有知道的话,请留言告知,或者关注我的微信公众号(搜索:NiaoTech),与我交流,谢谢。
可供拓展
你有没有发现,其实利用 <activity-alias>
标签也能实现给 App 添加桌面快捷方式的功能,实现步骤和上面所讲的内容大同小异。不过官方给了另外一种实现,可以参考官网相关介绍:App Shortcuts
- Android 利用 <activity-alias> 动态改变 App 桌面图标
- Android 利用 <activity-alias> 动态改变 App 桌面图标
- Android 利用 <activity-alias> 动态改变 App 桌面图标
- Android 利用 <activity-alias> 动态改变 App 桌面图标
- Android 利用 <activity-alias> 动态改变 App 桌面图标
- Android动态来改变App桌面图标
- android动态改变桌面图标
- Android利用activity-alias动态修改应用图标和名称
- Android利用activity-alias动态更新图标icon,标题label
- 利用activity-alias 动态更换应用Icon
- Android动态来改变App桌面图标--根据不同节日显示不同logo
- (Android) Android中改变Activity的不同icon:activity-alias
- Android中动态更换App的桌面icon图标和activity-alias的使用
- Android中改变Activity的不同icon:activity-alias
- Android中改变Activity的不同icon:activity-alias
- Android API Guides 之 App Manifest(4) - <activity-alias>
- Android 动态改变app图标
- Android 轻松打造一个APP动态切换桌面图标Launcher
- 【堂二皇之】微信小程序,是风口吗?
- sem_init函数用法
- typeScript
- poj_3301 Texas Trip(三分解单峰函数)
- [Gradle中文教程系列]-跟我学Gradle-附录-2.Gradle的日志级别
- Android 利用 <activity-alias> 动态改变 App 桌面图标
- SnowFlake 分布式ID生成Java实现
- android_57_service_通过服务器启动屏幕状态接收者
- Android 开发,测试环境换app icon ,在小米手机上无效。
- IDEA控制台输出中文乱码
- JAVA如何通过正则表达式获取文本中数字
- 正式部署elastalert
- hive字符串函数
- Redis RabbitMQ启动