You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity开发Android应用:动态更换图标重复问题求助

Android动态换图标重复问题解决方法

问题现象

开发Android动态换图标功能时,切换到自定义图标(非默认)会出现桌面图标重复,仅切换回默认图标时显示正常。已尝试清理缓存、重启设备,给MainActivity添加LAUNCHER intent-filter后问题仍存在。

核心原因

桌面图标重复的本质是同一应用中存在多个启用状态的带有android.intent.category.LAUNCHER的组件:

  • 切换到自定义别名时,MainActivity(若添加了LAUNCHER过滤)和目标activity-alias同时处于启用状态,两个组件都会被桌面识别为启动入口,导致重复图标;
  • 切换回MainActivity时,其他别名被禁用,只有MainActivity的LAUNCHER有效,所以显示正常。

解决方案

1. 修正AndroidManifest.xml配置

将默认图标的LAUNCHER intent-filter从MainActivity移到单独的activity-alias中,确保所有启动入口都通过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">

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:supportsRtl="true">
        <!-- 主Activity,移除LAUNCHER过滤 -->
        <activity
            android:name=".MainActivity"
            android:exported="true">
        </activity>

        <!-- 默认图标别名,默认启用 -->
        <activity-alias
            android:name=".DefaultLauncherAlias"
            android:enabled="true"
            android:exported="true"
            android:icon="@mipmap/ic_launcher" <!-- 替换为你的默认图标 -->
            android:label="@string/app_name"
            android:targetActivity=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity-alias>

        <!-- 自定义图标别名,默认禁用 -->
        <activity-alias
            android:name=".OneLauncherAlias"
            android:enabled="false"
            android:exported="true"
            android:icon="@drawable/testicon_1"
            android:label="@string/app_name"
            android:targetActivity=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity-alias>

        <activity-alias
            android:name=".TwoLauncherAlias"
            android:enabled="false"
            android:exported="true"
            android:icon="@drawable/testicon_2"
            android:label="@string/app_name"
            android:targetActivity=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity-alias>

        <activity-alias
            android:name=".ThreeLauncherAlias"
            android:enabled="false"
            android:exported="true"
            android:icon="@drawable/testicon_3"
            android:label="@string/app_name"
            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>

2. 修正MainActivity的ChangeIcon方法

确保每次切换时仅启用目标组件,其余所有带有LAUNCHER的组件(包括默认别名)都被禁用,同时优化代码避免重复创建ComponentName:

public class MainActivity extends AppCompatActivity {
    private static MainActivity instance;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        instance = this;
        // 其他初始化逻辑
    }

    public static MainActivity getInstance() {
        return instance;
    }

    public void ChangeIcon(Context context, String[] iconList, String iconType) {
        PackageManager manager = context.getPackageManager();

        for (String componentNameStr : iconList) {
            int actionType = componentNameStr.equals(iconType) 
                ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 
                : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;

            ComponentName componentName = new ComponentName(context, 
                String.format("%s.%s", getPackageName(), componentNameStr));
            
            manager.setComponentEnabledSetting(componentName,
                    actionType, PackageManager.DONT_KILL_APP);
        }
    }

    public void ShowToast(Context context, String message) {
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
    }
}

3. 修正Unity端TestScript代码

更新IconTypeArr,替换原来的MainActivity为默认别名DefaultLauncherAlias:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TestScript : MonoBehaviour
{
    public Button _toast;
    public Button _main;
    public Button _appIcon01;
    public Button _appIcon02;
    public Button _appIcon03;

    private AndroidJavaObject activityContext = null;
    private AndroidJavaClass javaClass = null;
    private AndroidJavaObject javaClassInstance = null;
    // 更新数组,用默认别名代替MainActivity
    private string[] IconTypeArr = { "DefaultLauncherAlias", "OneLauncherAlias", "TwoLauncherAlias", "ThreeLauncherAlias" };

    private void Awake()
    {
        using (AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            activityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
        }

        using (javaClass = new AndroidJavaClass("com.test.testApp.player.MainActivity"))
        {
            if (javaClass != null)
            {
                javaClassInstance = javaClass.CallStatic<AndroidJavaObject>("getInstance");
            }
        }

        _toast.onClick.AddListener(OnClickToast);
        _main.onClick.AddListener(OnClickChangeAppIcon_Main);
        _appIcon01.onClick.AddListener(OnClickChangeAppIcon_1);
        _appIcon02.onClick.AddListener(OnClickChangeAppIcon_2);
        _appIcon03.onClick.AddListener(OnClickChangeAppIcon_3);
    }

    private void OnClickToast()
    {
        javaClassInstance.Call("ShowToast", activityContext, "测试Toast消息输出 ^^");
    }

    private void OnClickChangeAppIcon_Main()
    {
        javaClassInstance.Call("ChangeIcon", activityContext, IconTypeArr, "DefaultLauncherAlias");
        javaClassInstance.Call("ShowToast", activityContext, "切换为默认图标");
    }

    private void OnClickChangeAppIcon_1()
    {
        javaClassInstance.Call("ChangeIcon", activityContext, IconTypeArr, "OneLauncherAlias");
        javaClassInstance.Call("ShowToast", activityContext, "切换为自定义图标1");
    }

    private void OnClickChangeAppIcon_2()
    {
        javaClassInstance.Call("ChangeIcon", activityContext, IconTypeArr, "TwoLauncherAlias");
        javaClassInstance.Call("ShowToast", activityContext, "切换为自定义图标2");
    }

    private void OnClickChangeAppIcon_3()
    {
        javaClassInstance.Call("ChangeIcon", activityContext, IconTypeArr, "ThreeLauncherAlias");
        javaClassInstance.Call("ShowToast", activityContext, "切换为自定义图标3");
    }
}

验证步骤

  1. 卸载旧版本应用,重新安装修改后的包(避免缓存残留);
  2. 测试切换各个图标,检查桌面是否仅显示一个图标;
  3. 若仍有问题,进入应用信息页面,清理缓存和数据后重启设备再测试。

内容的提问来源于stack exchange,提问作者TOMOU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 22:54:53