赞
踩
最近公司有个动态修改APP桌面图标的需求,需要做一下技术调研,网上查了一下实现方案,然后参考网上的方案写了个实现demo,在这里记录一下。
题外话:由于图标切换都是本地配置的,产品问了一句:“图标能不能支持服务端动态下发?”,我想了一下回复他:“这是不可能的,设想一下,APP提交审核时候使用的是合规图片,过审之后,动态下发的时候突然下发了一张违规图片(比如:黄赌毒),应用市场怎么监管?所以这个是不可能的。”
废话少说,先上效果图
1.新建项目,实现一个MainActivity,layout布局中添加四个按钮,其中三个为切换图标按钮,最后一个为恢复默认图标按钮
- <?xml version="1.0" encoding="utf-8"?>
- <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity">
-
- <Button
- android:id="@+id/btn1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="B1"
- android:layout_marginTop="100dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
- <Button
- android:id="@+id/btn2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="B2"
- android:layout_marginTop="50dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/btn1" />
-
- <Button
- android:id="@+id/btn3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="B3"
- android:layout_marginTop="50dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/btn2" />
-
- <Button
- android:id="@+id/btn4"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="RESET"
- android:layout_marginTop="50dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/btn3" />
-
- </androidx.constraintlayout.widget.ConstraintLayout>
2.在AndroidManifest.xml中添加注册三个activity-alias,分别命名为A1,A2,A3
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.example.appicon2">
-
- <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
- <application
- android:allowBackup="true"
- android:dataExtractionRules="@xml/data_extraction_rules"
- android:fullBackupContent="@xml/backup_rules"
- android:icon="@mipmap/login_logo"
- android:label="@string/app_name"
- android:roundIcon="@mipmap/ic_launcher_round"
- android:supportsRtl="true"
- android:theme="@style/Theme.AppIcon2"
- tools:targetApi="31">
- <activity
- android:name=".MainActivity"
- android:exported="true"
- tools:ignore="">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
- <activity-alias
- android:name=".A1"
- android:targetActivity=".MainActivity"
- android:label="@string/app_name1"
- android:enabled="false"
- android:icon="@mipmap/ic_a1"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity-alias>
-
-
- <activity-alias
- android:name=".A2"
- android:targetActivity=".MainActivity"
- android:label="@string/app_name2"
- android:enabled="false"
- android:icon="@mipmap/ic_a2"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity-alias>
-
-
- <activity-alias
- android:name=".A3"
- android:targetActivity=".MainActivity"
- android:label="@string/app_name3"
- android:enabled="false"
- android:icon="@mipmap/ic_a3"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity-alias>
-
- </application>
-
- </manifest>
3.MainActivity中添加代码逻辑
- package com.example.appicon2;
-
- import android.app.ActivityManager;
- import android.content.ComponentName;
- import android.content.Intent;
- import android.content.pm.PackageManager;
- import android.content.pm.ResolveInfo;
- import android.os.Bundle;
-
- import androidx.appcompat.app.AppCompatActivity;
-
- import java.util.List;
-
- public class MainActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
-
- findViewById(R.id.btn1).setOnClickListener(v -> {
- changeIcon("com.example.appicon2.A1");
- });
- findViewById(R.id.btn2).setOnClickListener(v -> {
- changeIcon("com.example.appicon2.A2");
- });
- findViewById(R.id.btn3).setOnClickListener(v -> {
- changeIcon("com.example.appicon2.A3");
- });
- findViewById(R.id.btn4).setOnClickListener(v -> {
- changeIcon("com.example.appicon2.MainActivity");
- });
- }
-
- private void changeIcon(String name){
- PackageManager pm = getPackageManager();
- pm.setComponentEnabledSetting(getComponentName(),
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
- pm.setComponentEnabledSetting(new ComponentName(this, name),
- PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
-
- restart(pm);
- }
-
- public void restart(PackageManager pm){
- ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.addCategory(Intent.CATEGORY_HOME);
- intent.addCategory(Intent.CATEGORY_DEFAULT);
- List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
- for (ResolveInfo resolveInfo : resolveInfos) {
- if (resolveInfo.activityInfo != null) {
- am.killBackgroundProcesses(resolveInfo.activityInfo.packageName);
- }
- }
-
- }
- }
到这里,运行程序,就能看到文章开始提到的效果啦。
小米手机(小米9):版本升级时,新版本在AndroidManifest中删除A3,老版本切换图标到A3,为卸载直接覆盖安装新版本,手机桌面图标消失。
荣耀手机(magic 4):版本升级时,新版本在AndroidManifest中删除A3,老版本切换图标到A3,为卸载直接覆盖安装新版本,手机桌面图标切换到默认图标,但点击之后未能打开APP。
其他机型暂未测试。
APP进行版本更新之后,若删除已有的activity-alias,可能会对线上app产生影响,所以已配置的activity-alias最好不要轻易删除(原则上只增不减)。
大家测试发现问题,欢迎留言讨论。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。