当前位置:   article > 正文

Android-动态修改APP桌面图标_android动态更换桌面图标

android动态更换桌面图标

背景

最近公司有个动态修改APP桌面图标的需求,需要做一下技术调研,网上查了一下实现方案,然后参考网上的方案写了个实现demo,在这里记录一下。

题外话:由于图标切换都是本地配置的,产品问了一句:“图标能不能支持服务端动态下发?”,我想了一下回复他:“这是不可能的,设想一下,APP提交审核时候使用的是合规图片,过审之后,动态下发的时候突然下发了一张违规图片(比如:黄赌毒),应用市场怎么监管?所以这个是不可能的。”

废话少说,先上效果图

实现

1.新建项目,实现一个MainActivity,layout布局中添加四个按钮,其中三个为切换图标按钮,最后一个为恢复默认图标按钮

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <Button
  9. android:id="@+id/btn1"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"
  12. android:text="B1"
  13. android:layout_marginTop="100dp"
  14. app:layout_constraintEnd_toEndOf="parent"
  15. app:layout_constraintStart_toStartOf="parent"
  16. app:layout_constraintTop_toTopOf="parent" />
  17. <Button
  18. android:id="@+id/btn2"
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:text="B2"
  22. android:layout_marginTop="50dp"
  23. app:layout_constraintEnd_toEndOf="parent"
  24. app:layout_constraintStart_toStartOf="parent"
  25. app:layout_constraintTop_toBottomOf="@+id/btn1" />
  26. <Button
  27. android:id="@+id/btn3"
  28. android:layout_width="wrap_content"
  29. android:layout_height="wrap_content"
  30. android:text="B3"
  31. android:layout_marginTop="50dp"
  32. app:layout_constraintEnd_toEndOf="parent"
  33. app:layout_constraintStart_toStartOf="parent"
  34. app:layout_constraintTop_toBottomOf="@+id/btn2" />
  35. <Button
  36. android:id="@+id/btn4"
  37. android:layout_width="wrap_content"
  38. android:layout_height="wrap_content"
  39. android:text="RESET"
  40. android:layout_marginTop="50dp"
  41. app:layout_constraintEnd_toEndOf="parent"
  42. app:layout_constraintStart_toStartOf="parent"
  43. app:layout_constraintTop_toBottomOf="@+id/btn3" />
  44. </androidx.constraintlayout.widget.ConstraintLayout>

2.在AndroidManifest.xml中添加注册三个activity-alias,分别命名为A1,A2,A3

  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.example.appicon2">
  5. <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
  6. <application
  7. android:allowBackup="true"
  8. android:dataExtractionRules="@xml/data_extraction_rules"
  9. android:fullBackupContent="@xml/backup_rules"
  10. android:icon="@mipmap/login_logo"
  11. android:label="@string/app_name"
  12. android:roundIcon="@mipmap/ic_launcher_round"
  13. android:supportsRtl="true"
  14. android:theme="@style/Theme.AppIcon2"
  15. tools:targetApi="31">
  16. <activity
  17. android:name=".MainActivity"
  18. android:exported="true"
  19. tools:ignore="">
  20. <intent-filter>
  21. <action android:name="android.intent.action.MAIN" />
  22. <category android:name="android.intent.category.LAUNCHER" />
  23. </intent-filter>
  24. </activity>
  25. <activity-alias
  26. android:name=".A1"
  27. android:targetActivity=".MainActivity"
  28. android:label="@string/app_name1"
  29. android:enabled="false"
  30. android:icon="@mipmap/ic_a1"
  31. android:exported="true">
  32. <intent-filter>
  33. <action android:name="android.intent.action.MAIN" />
  34. <category android:name="android.intent.category.LAUNCHER" />
  35. </intent-filter>
  36. </activity-alias>
  37. <activity-alias
  38. android:name=".A2"
  39. android:targetActivity=".MainActivity"
  40. android:label="@string/app_name2"
  41. android:enabled="false"
  42. android:icon="@mipmap/ic_a2"
  43. android:exported="true">
  44. <intent-filter>
  45. <action android:name="android.intent.action.MAIN" />
  46. <category android:name="android.intent.category.LAUNCHER" />
  47. </intent-filter>
  48. </activity-alias>
  49. <activity-alias
  50. android:name=".A3"
  51. android:targetActivity=".MainActivity"
  52. android:label="@string/app_name3"
  53. android:enabled="false"
  54. android:icon="@mipmap/ic_a3"
  55. android:exported="true">
  56. <intent-filter>
  57. <action android:name="android.intent.action.MAIN" />
  58. <category android:name="android.intent.category.LAUNCHER" />
  59. </intent-filter>
  60. </activity-alias>
  61. </application>
  62. </manifest>

3.MainActivity中添加代码逻辑

  1. package com.example.appicon2;
  2. import android.app.ActivityManager;
  3. import android.content.ComponentName;
  4. import android.content.Intent;
  5. import android.content.pm.PackageManager;
  6. import android.content.pm.ResolveInfo;
  7. import android.os.Bundle;
  8. import androidx.appcompat.app.AppCompatActivity;
  9. import java.util.List;
  10. public class MainActivity extends AppCompatActivity {
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.activity_main);
  15. findViewById(R.id.btn1).setOnClickListener(v -> {
  16. changeIcon("com.example.appicon2.A1");
  17. });
  18. findViewById(R.id.btn2).setOnClickListener(v -> {
  19. changeIcon("com.example.appicon2.A2");
  20. });
  21. findViewById(R.id.btn3).setOnClickListener(v -> {
  22. changeIcon("com.example.appicon2.A3");
  23. });
  24. findViewById(R.id.btn4).setOnClickListener(v -> {
  25. changeIcon("com.example.appicon2.MainActivity");
  26. });
  27. }
  28. private void changeIcon(String name){
  29. PackageManager pm = getPackageManager();
  30. pm.setComponentEnabledSetting(getComponentName(),
  31. PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
  32. pm.setComponentEnabledSetting(new ComponentName(this, name),
  33. PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
  34. restart(pm);
  35. }
  36. public void restart(PackageManager pm){
  37. ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
  38. Intent intent = new Intent(Intent.ACTION_MAIN);
  39. intent.addCategory(Intent.CATEGORY_HOME);
  40. intent.addCategory(Intent.CATEGORY_DEFAULT);
  41. List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
  42. for (ResolveInfo resolveInfo : resolveInfos) {
  43. if (resolveInfo.activityInfo != null) {
  44. am.killBackgroundProcesses(resolveInfo.activityInfo.packageName);
  45. }
  46. }
  47. }
  48. }

 到这里,运行程序,就能看到文章开始提到的效果啦。

发现问题

小米手机(小米9):版本升级时,新版本在AndroidManifest中删除A3,老版本切换图标到A3,为卸载直接覆盖安装新版本,手机桌面图标消失。

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

其他机型暂未测试。

APP进行版本更新之后,若删除已有的activity-alias,可能会对线上app产生影响,所以已配置的activity-alias最好不要轻易删除(原则上只增不减)。

END

大家测试发现问题,欢迎留言讨论。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/865705
推荐阅读
相关标签
  

闽ICP备14008679号