如何程序化实现类似Telegram的应用图标切换功能?
实现类似Telegram的应用图标切换功能
Android 实现步骤
配置Manifest文件
在AndroidManifest.xml中为主Activity添加多个activity-alias,每个对应一个备选图标。主Activity保持默认启用状态,其他activity-alias默认禁用:<!-- 主Activity --> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 备选图标1 --> <activity-alias android:name=".IconAlias1" android:enabled="false" android:exported="true" android:icon="@drawable/icon_alternate_1" android:label="@string/app_name_alt1" android:targetActivity=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity-alias> <!-- 备选图标2 --> <activity-alias android:name=".IconAlias2" android:enabled="false" android:exported="true" android:icon="@drawable/icon_alternate_2" android:label="@string/app_name_alt2" android:targetActivity=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity-alias>编写切换逻辑
通过PackageManager启用选中的activity-alias,禁用其他备选项,并将用户选择保存到SharedPreferences:fun switchAppIcon(aliasName: String) { val packageManager = applicationContext.packageManager // 禁用所有备选图标对应的alias arrayOf(".IconAlias1", ".IconAlias2").forEach { alias -> packageManager.setComponentEnabledSetting( ComponentName(packageName, alias), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP ) } // 启用选中的alias packageManager.setComponentEnabledSetting( ComponentName(packageName, aliasName), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP ) // 保存用户选择 getSharedPreferences("AppSettings", MODE_PRIVATE) .edit() .putString("selected_icon", aliasName) .apply() // 提示用户重启应用生效 Toast.makeText(this, "请重启应用生效", Toast.LENGTH_SHORT).show() }启动时恢复选中图标
在Application类或主Activity的onCreate方法中读取保存的偏好,自动切换到用户选中的图标:val selectedAlias = getSharedPreferences("AppSettings", MODE_PRIVATE) .getString("selected_icon", null) selectedAlias?.let { switchAppIcon(it) }
iOS 实现步骤
配置Info.plist
添加CFBundleAlternateIcons字典,定义所有备选图标的信息:<key>CFBundleAlternateIcons</key> <dict> <!-- 备选图标1 --> <key>AlternateIcon1</key> <dict> <key>CFBundleIconFiles</key> <array> <string>icon_alternate_1</string> </array> <key>UIPrerenderedIcon</key> <false/> </dict> <!-- 备选图标2 --> <key>AlternateIcon2</key> <dict> <key>CFBundleIconFiles</key> <array> <string>icon_alternate_2</string> </array> <key>UIPrerenderedIcon</key> <false/> </dict> </dict>注意:确保图标文件已添加到项目中,且尺寸符合iOS官方规范。
编写切换逻辑
使用UIApplication的setAlternateIconName方法切换图标,同时保存用户选择到UserDefaults:func switchAppIcon(to iconName: String?) { guard UIApplication.shared.supportsAlternateIcons else { print("当前设备不支持图标切换") return } UIApplication.shared.setAlternateIconName(iconName) { error in if let error = error { print("图标切换失败: \(error.localizedDescription)") } else { // 保存用户选择 UserDefaults.standard.set(iconName, forKey: "selected_icon") } } }调用示例:切换到备选图标1用
switchAppIcon(to: "AlternateIcon1"),切换回默认图标传nil。启动时恢复图标
在AppDelegate的didFinishLaunchingWithOptions或SceneDelegate的scene(_:willConnectTo:options:)方法中恢复用户选中的图标:let selectedIcon = UserDefaults.standard.string(forKey: "selected_icon") switchAppIcon(to: selectedIcon)
注意事项
- Android:
activity-alias的name必须唯一,且targetActivity必须指向主Activity;切换后必须重启应用才能看到图标变化。 - iOS:仅支持iOS 10.3及以上版本;切换图标时系统会自动弹出提示(通过私有API隐藏提示可能导致审核不通过,不推荐)。
内容的提问来源于stack exchange,提问作者Алекс31
相关产品推荐
相关产品推荐

