170 votes

Comment changer l'icône d'une application de manière programmatique dans Android ?

Est-il possible de changer l'icône d'une application directement à partir du programme ?
Je veux dire, changer icon.png en el res\drawable dossier.
Je voudrais permettre aux utilisateurs de changer l'icône de l'application à partir du programme, de sorte que la prochaine fois, ils verront l'icône précédemment sélectionnée dans le lanceur.

149voto

P-A Points 461

Essayez ceci, ça marche bien pour moi :

1 . Modifiez votre MainActivity section dans AndroidManifest.xml en supprimant la ligne avec MAIN catégorie en intent-filter section

<activity android:name="ru.quickmessage.pa.MainActivity"
    android:configChanges="keyboardHidden|orientation"
    android:screenOrientation="portrait"
    android:label="@string/app_name"
    android:theme="@style/CustomTheme"
    android:launchMode="singleTask">
    <intent-filter>
        ==> <action android:name="android.intent.action.MAIN" /> <== Delete this line
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

2 . Créer <activity-alias> pour chacune de vos icônes. Par exemple

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

3 . Défini de manière programmatique : définir l'attribut ENABLE pour l'élément approprié. activity-alias

 getPackageManager().setComponentEnabledSetting(
        new ComponentName("ru.quickmessage.pa", "ru.quickmessage.pa.MainActivity-Red"), 
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

Remarque : au moins un doit être activé à tout moment.

83voto

jboi Points 2810

C'est une vieille question, mais toujours d'actualité car il n'y a pas de fonctionnalité Android explicite. Et les gars de Facebook ont trouvé une solution - d'une manière ou d'une autre. Aujourd'hui, j'ai trouvé un moyen qui fonctionne pour moi. Ce n'est pas parfait (voir les remarques à la fin de cette réponse) mais ça marche !

L'idée principale est de mettre à jour l'icône du raccourci de mon application, créé par le lanceur sur mon écran d'accueil. Lorsque je veux changer quelque chose sur l'icône du raccourci, je la supprime d'abord et la recrée avec un nouveau bitmap.

Voici le code. Il y a un bouton increment . Lorsqu'on appuie sur cette touche, le raccourci est remplacé par un autre qui a un nouveau numéro de comptage.

D'abord, vous avez besoin de ces deux permissions dans votre manifeste :

<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />

Vous avez alors besoin de ces deux méthodes pour installer et désinstaller les raccourcis. Le site shortcutAdd crée un bitmap contenant un nombre. Ceci est juste pour démontrer que cela change réellement. Vous voudrez probablement changer cette partie avec quelque chose que vous voulez dans votre application.

private void shortcutAdd(String name, int number) {
    // Intent to be send, when shortcut is pressed by user ("launched")
    Intent shortcutIntent = new Intent(getApplicationContext(), Play.class);
    shortcutIntent.setAction(Constants.ACTION_PLAY);

    // Create bitmap with number in it -> very default. You probably want to give it a more stylish look
    Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
    Paint paint = new Paint();
    paint.setColor(0xFF808080); // gray
    paint.setTextAlign(Paint.Align.CENTER);
    paint.setTextSize(50);
    new Canvas(bitmap).drawText(""+number, 50, 50, paint);
    ((ImageView) findViewById(R.id.icon)).setImageBitmap(bitmap);

    // Decorate the shortcut
    Intent addIntent = new Intent();
    addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
    addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
    addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);

    // Inform launcher to create shortcut
    addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
    getApplicationContext().sendBroadcast(addIntent);
}

private void shortcutDel(String name) {
    // Intent to be send, when shortcut is pressed by user ("launched")
    Intent shortcutIntent = new Intent(getApplicationContext(), Play.class);
    shortcutIntent.setAction(Constants.ACTION_PLAY);

    // Decorate the shortcut
    Intent delIntent = new Intent();
    delIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
    delIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);

    // Inform launcher to remove shortcut
    delIntent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
    getApplicationContext().sendBroadcast(delIntent);
}

Et enfin, voici deux écouteurs pour ajouter le premier raccourci et mettre à jour le raccourci avec un compteur incrémentiel.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.test);
    findViewById(R.id.add).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            shortcutAdd("changeIt!", count);
        }
    });
    findViewById(R.id.increment).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            shortcutDel("changeIt!");
            count++;
            shortcutAdd("changeIt!", count);
        }
    });
}

Remarques :

  • Cette méthode fonctionne également si votre application contrôle plus de raccourcis sur l'écran d'accueil, par exemple avec différents extras dans le menu de l'application. Intent . Ils ont juste besoin de noms différents pour que le bon soit désinstallé et réinstallé.

  • La gestion programmatique des raccourcis dans Android est une fonctionnalité bien connue, largement utilisée mais non prise en charge officiellement. Elle semble fonctionner sur le lanceur par défaut et je ne l'ai jamais essayée ailleurs. Donc ne me blâmez pas, lorsque vous recevez ces courriels d'utilisateurs "Cela ne fonctionne pas sur mon téléphone XYZ, doublement enraciné, super explosif".

  • Le lanceur écrit un Toast lorsqu'un raccourci est installé et un autre lorsqu'un raccourci est désinstallé. J'obtiens donc deux Toast s chaque fois que je change l'icône. Ce n'est pas parfait, mais bon, tant que le reste de mon application est parfait...

17voto

Markus Points 67

Vous pouvez aussi publier vous-même le lanceur d'applications :

Remarque : cette méthode ne fonctionne plus à partir d'Android 8.0 - Oreo.

Dans votre AndroidManifest.xml, ajoutez :

<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>

Ensuite, vous devez créer votre intention de lancement d'application :

Intent myLauncherIntent = new Intent();
myLauncherIntent.setClassName("your.package.name", "YourLauncherActivityName");
myLauncherIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Créez une intention de raccourci d'installation avec votre lanceur d'applications et une icône personnalisée :

Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, myLauncherIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Application Name");
intent.putExtra
       (
        Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
        Intent.ShortcutIconResource.fromContext
                                    (
                                         getApplicationContext(), 
                                         R.drawable.app_icon
                                    )
       );
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");

Et enfin, lancez l'intention de diffusion :

getApplicationContext().sendBroadcast(intent);

9voto

Marius Kjeldahl Points 4325

Si vous voulez dire changer l'icône affichée sur l'écran d'accueil, vous pouvez facilement le faire en créant un widget qui fait exactement cela. Voici un article qui démontre comment cela peut être accompli pour une application de type "nouveaux messages" similaire à celle de l'iPhone :

http://www.cnet.com/8301-19736_1-10278814-251.html

0voto

PuZZleDucK Points 1

Pour faire fonctionner la solution de Markus, j'avais besoin de la première intention :

Intent myLauncherIntent = new Intent(Intent.ACTION_MAIN);
            myLauncherIntent.setClassName(this,  this.getClass().getName());
            myLauncherIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X