经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
Android动态更换应用图标详情
来源:jb51  时间:2022/7/4 8:51:15  对本文有异议

一、背景

近日,微博官方发布了一项新功能,即可以在App设置中动态更换微博的显示图标样式。根据微博官方的说法,除了最原始的图标外,微博还推出了另外10种不同的样式,既有3D微博、炫彩微博等保留了眼睛造型的新样式,也有奶酪甜馨、巧克力等以食物命名的“新口味”,还有梦幻紫、幻想星空等抽象派新造型,给了微博用户多种选择的自由。

不过需要注意的是,这一功能并不是面对所有人开放的,只有微博年费会员才能享受。此外,iOS 10.3及以上和Android 10及以上系统版本支持该功能,但是iPad与一加8Pro手机无法使用该功能。因部分手机存在系统差异,会导致该功能不可用,微博方面后续还会对该功能进行进一步优化。

二、技术实现

其实,说到底,上述功能用到的是动态更换桌面图标的技术。如果说多年以前,实现图标的切换还是一种时髦的技术,那么,我们可以直接使用PackageManager就可以实现动态更换桌面图标。

实现的细节是,在Manifest文件中使用标签准备多个Activity入口,没个activity都指向入口Activity,并且为每个拥有标签的activity设置单独的icon和应用名,最后调用SystemService 服务kill掉launcher,并执行launcher的重启操作。

首先,我们在AndroidManifest.xml文件中添加如下代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. package="com.xzh.demo">
  5.  
  6. <!-- 权限-->
  7. <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
  8.  
  9. <application
  10. android:allowBackup="true"
  11. android:icon="@mipmap/wb_default_logo"
  12. android:label="@string/app_name"
  13. android:roundIcon="@mipmap/wb_default_logo"
  14. android:supportsRtl="true"
  15. android:theme="@style/Theme.AndroidDemo">
  16.  
  17. ...//省略其他代码
  18.  
  19. <!-- 默认微博-->
  20. <activity-alias
  21. android:name="com.xzh.demo.default"
  22. android:targetActivity=".MainActivity"
  23. android:label="@string/app_name"
  24. android:enabled="false"
  25. android:icon="@mipmap/wb_default_logo"
  26. android:exported="true">
  27. <intent-filter>
  28. <action android:name="android.intent.action.MAIN" />
  29. <category android:name="android.intent.category.LAUNCHER" />
  30. </intent-filter>
  31. </activity-alias>
  32.  
  33. <!-- 3D微博-->
  34. <activity-alias
  35. android:name=".threedweibo"
  36. android:targetActivity=".MainActivity"
  37. android:label="@string/wb_3d"
  38. android:enabled="false"
  39. android:icon="@mipmap/wb_3dweibo"
  40. android:exported="true">
  41. <intent-filter>
  42. <action android:name="android.intent.action.MAIN" />
  43. <category android:name="android.intent.category.LAUNCHER" />
  44. </intent-filter>
  45. </activity-alias>
  46.  
  47. ... //省略其他
  48.  
  49. </application>
  50. </manifest>

上面配置中涉及到的属性如下:

  • android:name:注册的组件名字,启动组件的名称。
  • android:enabled:是否启用这个组件,也就是是否显示这个入口。
  • android:icon:图标
  • android:label:名称
  • android:targetActivity:默认的activity没有这个属性,指定目标activity,与默认的activity中的name属性是一样的,需要有相应的java类文件。

接着,我们在MainActivity触发Logo图标更换逻辑,代码如下:

  1. class MainActivity : AppCompatActivity() {
  2. var list: List<LogoBean> = ArrayList()
  3. var recyclerView: RecyclerView? = null
  4. var adapter: LogoAdapter? = null
  5. override fun onCreate(savedInstanceState: Bundle?) {
  6. super.onCreate(savedInstanceState)
  7. setContentView(R.layout.activity_main)
  8. initView()
  9. initData()
  10. initRecycle()
  11. }
  12. private fun initView() {
  13. recyclerView = findViewById(R.id.recycle_view)
  14. }
  15. private fun initData() {
  16. list = Arrays.asList(
  17. LogoBean(R.mipmap.wb_default_logo, "默认图标", true),
  18. LogoBean(R.mipmap.wb_3dweibo, "3D微博", false),
  19. LogoBean(R.mipmap.wb_cheese_sweetheart, "奶酪甜心", false),
  20. LogoBean(R.mipmap.wb_chocolate_sweetheart, "巧克力", false),
  21. LogoBean(R.mipmap.wb_clear_colorful, "清透七彩", false),
  22. LogoBean(R.mipmap.wb_colorful_sunset, "多彩日落", false),
  23. LogoBean(R.mipmap.wb_colorful_weibo, "炫彩微博", false),
  24. LogoBean(R.mipmap.wb_cool_pool, "清凉泳池", false),
  25. LogoBean(R.mipmap.wb_fantasy_purple, "梦幻紫", false),
  26. LogoBean(R.mipmap.wb_fantasy_starry_sky, "幻想星空", false),
  27. LogoBean(R.mipmap.wb_hot_weibo, "热感微博", false),
  28. )
  29. }
  30. private fun initRecycle() {
  31. adapter =LogoAdapter(this,list);
  32. val layoutManager = GridLayoutManager(this, 3)
  33. recyclerView?.layoutManager = layoutManager
  34. recyclerView?.adapter = adapter
  35. adapter?.setOnItemClickListener(object : OnItemClickListener {
  36. override fun onItemClick(view: View?, position: Int) {
  37. if(position==1){
  38. changeLogo("com.xzh.demo.threedweibo")
  39. }else if (position==2){
  40. changeLogo("com.xzh.demo.cheese")
  41. }else if (position==3){
  42. changeLogo("com.xzh.demo.chocolate")
  43. }else {
  44. changeLogo("com.xzh.demo.default")
  45. }
  46. }
  47. })
  48. }
  49.  
  50. fun changeLogo(name: String) {
  51. val pm = packageManager
  52. pm.setComponentEnabledSetting(
  53. componentName,
  54. PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP
  55. )
  56. pm.setComponentEnabledSetting(
  57. ComponentName(this, name),
  58. PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP
  59. )
  60. reStartApp(pm)
  61. }
  62. fun reStartApp(pm: PackageManager) {
  63. val am = getSystemService(ACTIVITY_SERVICE) as ActivityManager
  64. val intent = Intent(Intent.ACTION_MAIN)
  65. intent.addCategory(Intent.CATEGORY_HOME)
  66. intent.addCategory(Intent.CATEGORY_DEFAULT)
  67. val resolveInfos = pm.queryIntentActivities(intent, 0)
  68. for (resolveInfo in resolveInfos) {
  69. if (resolveInfo.activityInfo != null) {
  70. am.killBackgroundProcesses(resolveInfo.activityInfo.packageName)
  71. }
  72. }
  73. }
  74. }

注意上面的changeLogo()方法中的字符串需要和AndroidManifest.xml文件中的<activity-alias>的name相对应。运行上面的代码,然后点击应用中的某个图标,就可以更换应用的桌面图标,

如下图所示:

 不过,测试的时候也遇到

一些适配问题:

  • 小米9:版本升级时,新版本在AndroidManifest中删除A3,老版本切换图标到A3,为卸载直接覆盖安装新版本,手机桌面图标消失。
  • magic 4:版本升级时,新版本在AndroidManifest中删除A3,老版本切换图标到A3,为卸载直接覆盖安装新版本,手机桌面图标切换到默认图标,但点击之后未能打开APP。

到此这篇关于Android动态更换应用图标详情的文章就介绍到这了,更多相关Android更换图标内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号