I want to change app icon progrmatically how to do it in android

162 Views Asked by At

I am using the below code to change the app icon programmatically. but it's killing the app the first time we change the icon. how to avoid killing the app while changing the app icon.

    PackageManager packageManager = getPackageManager();
    packageManager.setComponentEnabledSetting(new ComponentName("package name", "class name"),
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);

    //enables the second icon
    packageManager.setComponentEnabledSetting(new ComponentName("package name", "class alias"),
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
1

There are 1 best solutions below

0
On

Unfortunately, the application has to kill. But as an alternative, I can make the following suggestion. You can change it after the application closes.

You can achieve this through a service.

Manifest.xml

<activity-alias
    android:name=".one"
    android:icon="@mipmap/ic_launcher_one"
    android:targetActivity=".ui.MainActivity"
    android:enabled="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=".two"
    android:icon="@mipmap/ic_launcher_two"
    android:targetActivity=".ui.MainActivity"
    android:enabled="false">

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

</activity-alias>

Service.kt

class AppIconChangeService: Service() {
    private val aliases = arrayOf(".one", ".two")

    override fun onBind(intent: Intent?): IBinder? = null

    override fun onTaskRemoved(rootIntent: Intent?) {
        changeAppIcon()
        stopSelf()
    }

    fun changeAppIcon() {
        val sp = getSharedPreferences("appSettings", Context.MODE_PRIVATE)

        sp.getString("activeActivityAlias", ".one").let { aliasName ->
            if (!isAliasEnabled(aliasName)) {
                setAliasEnabled(aliasName)
            }
        }
    }

    private fun isAliasEnabled(aliasName: String): Boolean {
        return packageManager.getComponentEnabledSetting(
            ComponentName(
                this,
                "${BuildConfig.APPLICATION_ID}$aliasName"
            )
        ) == PackageManager.COMPONENT_ENABLED_STATE_ENABLED
    }

    private fun setAliasEnabled(aliasName: String) {
        aliases.forEach {
            val action = if (it == aliasName)
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED
            else
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED
                
            packageManager.setComponentEnabledSetting(
                ComponentName(
                    this,
                    "${BuildConfig.APPLICATION_ID}$aliasName"
                ),
                action,
                PackageManager.DONT_KILL_APP
            )
        }
    }
}

Add Service Manifest

<service 
    android:name=".AppIconChangeService"
    android:stopWithTask="false"
    />

Service Added

class MainActivity: Activity {
    override fun onCreate(savedInstanceState: Bundle?) {
       startService(Intent(this, ChangeAppIconService::class.java))
    }
}