运行时更改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;环境变量的地址为安装目录。 …

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

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

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

目录 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层进行自动化的测试 …

通过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…

记录一下本地源码安装部署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;所…

QML与C++之间自定义对象输出

1.定义暴露的C类 Message.h #ifndef MESSAGE_H #define MESSAGE_H#include "QObject" #include "MessageAuthor.h"class Message : public QObject {Q_OBJECTQ_PROPERTY(MessageAuthor* author READ author )public:explicit Message(QObject *parent nu…

跨境电商平台投资智谋:全球化布局的策略之道

随着全球数字化浪潮的涌动&#xff0c;跨境电商平台在全球商业舞台上扮演着越来越重要的角色。其全球化布局的策略之道成为业界瞩目的焦点。 本文将深入探讨跨境电商平台投资的智谋&#xff0c;分析其全球化布局的关键策略&#xff0c;以及在这个竞争激烈的领域中脱颖而出的成…

基于若依的ruoyi-nbcio流程管理系统支持支持定时边界事件和定时捕获事件

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 1、定时边界事件 <template><div class"panel-tab__content"><!--目前只处理定…

【EI会议征稿-ACM出版】2023年信息化教育与人工智能国际学术会议(ICIEAI 2023)

2023年信息化教育与人工智能国际学术会议&#xff08;ICIEAI 2023&#xff09; 2023 International Conference on Information Education and Artificial Intelligence 2023年12月22-24日 中国-厦门 2023年信息化教育与人工智能国际学术会议&#xff08;ICIEAI 2023&#xf…

用23种设计模式打造一个cocos creator的游戏框架----(四)装饰器模式

1、模式标准 模式名称&#xff1a;装饰器模式 模式分类&#xff1a;结构型 模式意图&#xff1a;动态地给一个对象添加一些额外的职责。就增加功能来说&#xff0c;装饰器模式比生成子类更为灵活。 结构图&#xff1a; 适用于&#xff1a; 当需要给一个对象在运行时添加更…

Native Drawing 开发指导,实现 HarmonyOS 基本图形和字体的绘制

场景介绍 Native Drawing 模块提供了一系列的接口用于基本图形和字体的绘制。常见的应用场景举例&#xff1a; ● 2D 图形绘制。 ● 文本绘制。 接口说明 详细的接口说明请参考Drawing。 2D 图形绘制开发步骤 以下步骤描述了如何使用 Native Drawing 模块的画布画笔绘制一…

OpenCV交叉编译

1.下载代码解压 tar -zxvf opencv-4.8.1.tar.gz cd cd opencv-4.8.1 sudo mkdir chmod 777 build cd build 2.配置交叉编译工具 根据自己的板子进行修改 -D CMAKE_C_COMPILERaarch64-mix210-linux-gcc -D CMAKE_CXX_COMPILERaarch64-mix210-linux-g 3.cmake生成makefi…