运行时更改Android应用程序图标

设想一下,当我们正在开发一款应用。随着某个节日的临近,我们可能希望通过更改应用图标来增强用户的节日氛围,例如在图标上添“新年特惠”或者“龙年大吉”等标签。

这种小小的改变看似不经意,却能够吸引用户的注意。

运行时更改应用程序图标

首先,应用程序图标是从清单文件设置的,就像任何其他应用程序组件一样。 Android系统读取manifest文件并相应地设置应用程序图标。

目前无法直接使用相关的代码在运行时更改应用程序图标,但有一个解决方案,就是使用activity-alias。

步骤1:准备图标资源🖼️

应用程序图标图片资源

步骤2:修改AndroidManifest.xml📄

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher1"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.TestAndroid"tools:targetApi="31"><activityandroid:name=".MainActivity"android:exported="true"android:theme="@style/Theme.TestAndroid"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activity-aliasandroid:name=".MainActivityAlias"android:enabled="false"android:exported="true"android:icon="@mipmap/ic_launcher2"android:targetActivity=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity-alias></application></manifest>

我们定义了一个activity 和一个activity-alias, 并在activity-alias中设置了新的icon。默认情况下disable activity-alias,也就是设置android:enabled=“false”。
应用安装时,启动的是MainActivity,然后我们可以调用代码将主Activity设置成MainActivityAlias,就可以实现运行时更改Android 应用程序图标的内容了。(即disable MainActivity,enable MainActivityAlias。)
如何设置呢,就要使用到PackageManager 这个类了。

步骤3:编写更改图标的代码🔀 (假设我们使用Compose)

// 编写Activity的扩展方法
fun Activity.changeEnabledComponent(enabledPkgName: String,disabledPkgName: String,
) {packageManager.setComponentEnabledSetting(ComponentName(this, enabledPkgName),PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP)packageManager.setComponentEnabledSetting(ComponentName(this, disabledPkgName),PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP)
}@Composable
fun ChangeIconViews(activity: Activity, enabledPkgName: String, disabledPkgName: String) {Column(horizontalAlignment = Alignment.CenterHorizontally) {val btnModifier = Modifier.padding(vertical = 2.5.dp)Button(modifier = btnModifier, onClick = {activity.changeEnabledComponent(enabledPkgName = enabledPkgName,disabledPkgName = disabledPkgName)}) {Text(text = "切换成Test 1")}Button(modifier = btnModifier, onClick = {activity.changeEnabledComponent(enabledPkgName = disabledPkgName,disabledPkgName = enabledPkgName)}) {Text(text = "切换成Test 2")}}
}class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {TestAndroidTheme {Surface(modifier = Modifier.fillMaxSize().padding(vertical = 5.dp),color = MaterialTheme.colorScheme.background) {Box(contentAlignment = Alignment.Center) {ChangeIconViews(activity = this@MainActivity,enabledPkgName = "com.example.testandroid.MainActivity",disabledPkgName = "com.example.testandroid.MainActivityAlias")}}}}}
}
  1. 函数 changeEnabledComponent用于启用或禁用指定的组件,使用 packageManager 对象的 setComponentEnabledSetting 方法来设置组件的启用状态。
  2. 函数 ChangeIconViews 是一个Composable函数,用于显示一个列(Column)布局,并包含两个按钮。
  3. 最后在MainActivity的 onCreate 方法中放置ChangeIconViews。

然后就能够实现在运行时更改Android应用程序图标这个需求了。

步骤4:优化我们的代码📚

但是作为一名开发人员,我们想要我们的代码更整洁更灵活的话,我们就应该考虑优化我们的代码,比如硬编码就不是很合适:

ChangeIconViews(activity = this@MainActivity,enabledPkgName = "com.example.testandroid.MainActivity",disabledPkgName = "com.example.testandroid.MainActivityAlias"
)

假设我们使用最新版的Android Studio工具开发,使用build.gradle.kts编写我们的编译脚本(使用build.gradle的话其实也差不多,就是语法不大一样),就可以像下面这样:

...
private val mainActivity = "com.example.testandroid.MainActivity"
private val mainActivityAlias = "com.example.testandroid.MainActivityAlias"
android {...defaultConfig {...buildConfigField("String", "main_activity", "\"${mainActivity}\"")buildConfigField("String", "main_activity_alias", "\"${mainActivityAlias}\"")}...buildFeatures {...// 使用自定义的buildConfig需要开启这个功能buildConfig = true}...
}

所以我们的MainActivity的onCreate就可以换成下面的代码:

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {TestAndroidTheme {Surface(modifier = Modifier.fillMaxSize().padding(vertical = 5.dp),color = MaterialTheme.colorScheme.background) {Box(contentAlignment = Alignment.Center) {ChangeIconViews(activity = this@MainActivity,enabledPkgName = BuildConfig.main_activity,disabledPkgName = BuildConfig.main_activity_alias)}}}}}
}

除此之外我们发现AndroidManifest.xml中也有关于mainActivity和mainActivityAlias的硬编码,比如下面的代码:

<activityandroid:name=".MainActivity"...>...
</activity><activity-aliasandroid:name=".MainActivityAlias"...android:targetActivity=".MainActivity">...
</activity-alias>

所以我们做一下优化:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher1"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.TestAndroid"tools:targetApi="31"><activityandroid:name="${main_activity}"android:exported="true"android:theme="@style/Theme.TestAndroid"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activity-aliasandroid:name="${main_activity_alias}"android:enabled="false"android:exported="true"android:icon="@mipmap/ic_launcher2"android:targetActivity="${main_activity}"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity-alias></application></manifest>
android {...defaultConfig {...manifestPlaceholders.apply {set("main_activity", mainActivity)set("main_activity_alias", mainActivityAlias)}buildConfigField("String", "main_activity", "\"${mainActivity}\"")buildConfigField("String", "main_activity_alias", "\"${mainActivityAlias}\"")}...
}

完整代码地址

感谢阅读,Best Regards!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/204446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows离线安装Node-Red

在线安装Node-Red 参考文章 步骤 安装Nodejs使用nmp安装Node-Red先在本地安装Node-red将本地的Node-red拷贝到远程 安装Nodejs 在nodejs中文网下载长期支持的Windows安装包&#xff0c;并进行安装 安装完成后为nodej添加环境变量&#xff0c;环境变量的地址为安装目录。 …

深度学习/机器学习中关于Ubuntu/Linux常用命令

这里写目录标题 Ubuntu命令1. 列出用户和用户组2. 修改用户组权限3. 用户组添加删除用户4. 查看文件夹大小 Anconda相关1. Ubuntu多用户情况下共用同一个anaconda2. 查看conda环境3. 创建环境4. 删除环境5. 查看第三方库6. 给当前环境安装第三方库7. 给指定环境安装第三方库&am…

哔哩哔哩自动引流软件,其成果展示与开发流程和代码分享

先来看实操成果&#xff0c;↑↑需要的同学可看我名字↖↖↖↖↖&#xff0c;或评论888无偿分享 哔哩哔哩自动引流软件的开发流程和代码分享 一、开发背景 随着互联网的发展&#xff0c;越来越多的用户喜欢在哔哩哔哩平台寻找感兴趣的内容。为了更好地满足这部分用户的需求&a…

js vue form表单层级过深,层级太深了,form检测不到form的变化

form表单层级过深&#xff0c;层级太深了&#xff0c;form检测不到form的变化&#xff0c;这个时候要么change事件里面强制更新dom触发&#xff08;视图更新&#xff09;&#xff0c;要么再change事件里面对form表单绑定的数据进行拷贝 this.addForm JSON.parse(JSON.stringif…

关系数据库和非关系数据库相机

目录 1、数据库介绍2、关系数据库2.1 Mysql2.2 PostgreSQL2.3 Mysql和PostgreSQL的区别 3、非关系数据库3.1 Redis3.2 MongoDB3.3 MongoDB和Redis的区别3.4 MongoDB和Mysql的区别 4、结构化数据、非结构化数据和半结构化数据5、 后端技术群 1、数据库介绍 关系数据库和非关系数…

【2023年网络安全优秀创新成果大赛专刊】医疗机构临床数据合规共享解决方案(美创科技)

“2023年网络安全优秀创新成果大赛”由中央网信办网络安全协调局指导&#xff0c;中国网络安全产业联盟&#xff08;CCIA&#xff09;主办。本次大赛由3场分站赛、3场专题赛、1场大学生创新创业作品赛组成。 在杭州分站赛&#xff0c;美创科技—“医疗机构临床合规共享解决方案…

Docker的数据卷、数据卷容器,容器互联

数据卷&#xff08;容器与宿主机之间数据共享&#xff09; 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机的目录挂载到数据卷上&#xff0c;对数据卷的修改操作立刻可见&#xff0c;并且更新数据不会影响镜像&#xff0c;从而实现数据在宿主机与容器之…

借用gpt帮自己写个抓取某网站房源信息,业绩翻倍

作为一名销售不可怕&#xff0c;作为一个程序员不可怕&#xff0c;但作为一个会写代码的房产销售就很可怕了。不管是做什么都需要动脑筋&#xff0c;会使很多事情相对简单&#xff0c;这不&#xff0c;最近这业绩搞的自己扛不住&#xff0c;主要是平时很懒&#xff0c;都是坐等…

简单易懂:Axios 如何取消请求的两种方法

在前端开发中&#xff0c;网络请求是非常常见的操作。而有时候&#xff0c;我们可能需要在发送请求后取消它&#xff0c;比如用户在请求还未完成时离开了当前页面或者执行了其他操作&#xff0c;本文将介绍如何在使用 Axios 发送请求时取消这些请求。 基本概念 在 Axios 中&am…

Ui自动化概念 + Web自动化测试框架介绍!

1.UI自动化测试概念:我们先明确什么是UI UI&#xff0c;即(User Interface简称UI用户界面)是系统和用户之间进行交互和信息交换的媒介 UI自动化测试: Web自动化测试和移动自动化测试都属于UI自动化测试&#xff0c;UI自动化测试就是借助自动化工具对程序UI层进行自动化的测试 …

详解JAVA中的@ApiModel和@ApiModelProperty注解

目录 前言1. ApiModel注解2. ApiModelProperty注解3. 实战 前言 在Java中&#xff0c;ApiModel和ApiModelProperty是Swagger框架&#xff08;用于API文档的工具&#xff09;提供的注解&#xff0c;用于增强API文档的生成和展示。这两者搭配使用更佳 使用两者注解&#xff0c;…

【java之~】两个date时间比较大小

//获取当前时间 Date now DateUtil.date(); //获取工单的计划完成时间 Date planCompleteTime o.getPlanCompleteTime(); //当前时间小于计划完成时间 if (!this.betweenDate(now, planCompleteTime)) {continue; } /*** 比较时间** param now 开始* param endDate 结束…

JREBEL 热部署原理

JRebel&#xff08;Java Rebel&#xff09;是一个Java开发工具&#xff0c;它提供了一种在不重启应用服务器的情况下进行Java应用程序的热部署的方式。通过JRebel&#xff0c;开发者可以在修改Java代码后立即看到变化&#xff0c;加速开发和调试过程。 以下是JRebel实现热部署…

通过K8S安装人大金仓数据库

1. 离线下载镜像&#xff0c;请点击 2. 官网下载镜像 https://www.kingbase.com.cn/xzzx/index.htm&#xff0c;根据自己的需求下载对应版本。 3. K8S需要的yaml清单 cat > kingbase.yaml << EOF apiVersion: apps/v1 kind: Deployment metadata:name: kingbase-…

Django + Matplotlib:实现数据分析显示与下载为PDF或SVG

写作背景 首先&#xff0c;数据分析在当前的信息时代中扮演着重要的角色。随着数据量的增加和复杂性的提高&#xff0c;人们对于数据分析的需求也越来越高。 其次&#xff0c;笔者也确确实实曾经接到过一个这样的开发需求&#xff0c;甲方是一个医疗方面的科研团队&#xff0…

ROS——回旋函数与时间

目录 一、回旋函数 C 1.spinOnce() 2.spin() python 二、时间 C 1、时刻 2、持续时间 3、时间运算 4、设置运行频率 5、定时器 python 1、时刻 2、持续时间 3、时间运算 4、设置运行频率 5、定时器 一、回旋函数 C 1.spinOnce() 一般应用场景:* 在循环…

详细解读python里的列表

一、列表的创建与删除 1、使用赋值运算符直接创建列表 listname [element1, element2, element3, … , element n] 2、创建空列表 emptylist [] 3、创建数值列表 list(data) Age: list(range(10, 20 ,2)) 4、删除列表 del listname 二、访问列表元素 1、直接用print(…

记录一下本地源码安装部署ThingsBoard可能踩到的坑

使用git下载源码后, 必须运行 mvn clean install -DskipTests这一步很重要, 有很多文件需要初始化, 如果直接放入idea可能存在各种问题, 最好是用命令行执行 初始化时, 可能报错停止, 这个一般是网络问题, 可以尝试修改maven镜像, 这是我成功构建的镜像 <!--阿里云仓库--…

Python-调试

左下角有相关的操作 断点&#xff1a;鼠标右键点击行 左下角为函数的调用栈 单步按F7

codeforces E - Good Triples

分析 易得总和总是大于等于每一位之和。如果左边的每一位之和有进位那么对于两边总和的贡献不影响&#xff0c;对于左边的位之和不影响&#xff0c;对于右边的位之和有影响。有进位相当于左边位之和加 10 10 10 &#xff0c;右边位之和加 1 1 1 。两边贡献不等&#xff0c;所…