So ändert man programmatisch das App-Icon und den Namen der Android-App

Bei einer Android wird das das Icon einer App normalerweise im AndroidManifest definiert und ändert sich bis zum nächsten Update der App nicht mehr. Es gibt aber Möglichkeiten, das App Icon und den App Namen zu ändern, ohne dass ein Update eingespielt werden muss.

Grundlage

In der Regel hat eine Android App immer eine Standard-Activity, die im Manifest wie folgt gekennzeichnet ist.

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

Durch diese Angabe wird Android mitgeteilt, dass dies die Activity ist, die vom Launcher aufgerufen werden soll.

Activity Alias im Android Manifest

Beim Activity-Alias handelt es sich um einen Symlink zu einer Activity die dazu verwendet werden kann, einen Alias für eine Aktivität zu erzeugen, der eine Ziel-Activity verlinkt. Das Ziel muss sich in der gleichen Anwendung wie der Alias befinden und muss vor dem Alias im Manifest deklariert werden.

Der Alias repräsentiert die Zielaktivität als unabhängige Einheit mit eigenem Icon und Namen. Er kann einen eigenen Satz von Intent-Filtern haben. Zum Beispiel können die Intent-Filter auf dem Alias die Flags „android.intent.action.MAIN“ und „android.intent.category.LAUNCHER“ angeben, was dazu führt, dass er im Anwendungsstarter dargestellt wird, obwohl keiner der Filter auf der Zielaktivität selbst diese Flags setzt.

Activity Alias als Main-Activity verwenden

Entfernt man nun das Tag <action android:name=“android.intent.action.MAIN“ /> aus dem Intent-Filter der Activity, und fügt für jede benötigte Kombination aus App-Namen und App-Icon einen Activity-Alias hinzu, der dann z.B. wie folgt aussieht, kann man im Java Code mit Hilfe der PackageManager Instanz den Activity-Alias aktivieren oder deaktivieren.

<activity-alias
        android:label="Alias 1"
        android:icon="@mipmap/ic_alias_1"
        android:name=".Alias1"
        android:enabled="true"
        android:targetActivity=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>

PackageManager
Klasse zum Abrufen verschiedener Arten von Informationen in Bezug auf die Anwendungspakete, die derzeit auf dem Gerät installiert sind. Die Instanz der Klasse kann über Context#getPackageManager gefunden werden.

https://developer.android.com/reference/android/content/pm/PackageManager

App-Icon und App-Name ändern

Zum Aktivieren/Deaktivieren eines Activity-Alias zu aktivieren, kann man die Methode setComponentEnabledSetting des PackageManagers verwenden.

context.getPackageManager().setComponentEnabledSetting(
    new ComponentName(BuildConfig.APPLICATION_ID, "com.app.package.Alias1"), 
    PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP
);

Mit der BuildConfig.APPLICATION_ID wird dem Paketmanager mitgeteilt, welche Komponente geändert werden soll. Dabei entsricht der Wert dem Paketname und dem Alias-Namen „com.app.package.Alias1“. Mit der State PackageManager.COMPONENT_ENABLED_STATE_ENABLED wird dem PackageManager mitgeteilt, dass diese Komponente oder Anwendung explizit aktiviert werden soll, unabhängig davon, was im Manifest angegeben ist. Mit dem Flag PackageManager.DONT_KILL_APP wird angegeben, dass die App, die die Komponente enthält, nicht beendet werden soll.

Mit dieser Methode kann man zwischen mehreren App-Icons und App-Namen hin und her wechseln. Es muss nur für jede Kombination aus App-Icon und App-Name ein Aliase für die einzelne Aktivität definiert werden.

Wichtig ist, dass immer nur eine Alias gleichzeitig aktiv ist, damit nicht plötzlich mehre App-Icons gleichzeitig aktiv sind. Daher ist immer sicher zu stellen, dass man den vorher aktiven Activity-Alias mit PackageManager.COMPONENT_ENABLED_STATE_DISABLED deaktiviert.

Beispiel App

Zum einfachen ausprobieren habe ich mal eine kleine App erstellt, die eigentlich keine echte Funktionalität enthält. Es gibt nur ein paar Buttons mit denen man das App-Icon wechseln kann. Die App kann man aus Google Play Store installieren oder das GitHub Repository clonen und selber ein wenig damit herumspielen.

Die verwendeten App-Icons sind Emojis aus den Google Noto Emoji Fonts (https://github.com/googlefonts/noto-emoji) die unter der Apache 2 Lizenz veröffentlicht sind.

Den Source-Code zu dieser Demo kann man unter https://github.com/msoftware/AppIconChanger herunterladen.

Youtube Demo der App mit dem Pixel Launcher

Leider sind nicht alle Launcher so gut programmiert wie der Pixel Launcher von Google und es ist möglich, dass ein installierter Launcher z.B. etwas länger braucht um das Icon zu ändern oder beim Ändern des Icons die Verknüpfung auf dem Startbildschirm verschwindet. Trotzdem ist die Möglichekt das App-Icon einer Android App programmatisch zu ändern möglich und sollte viel häufiger genutzt werden. Dann werden bestimmt auch die Launcher-Apps besser in dieser Hinsicht getestet.