Comment changer l’icône d’une application par programmation dans Android?

Est-il possible de changer une icône d’application directement depuis le programme?
Je veux dire, changez icon.png dans le dossier res\drawable .
Je voudrais laisser les utilisateurs modifier l’icône de l’application à partir du programme afin que la prochaine fois qu’ils voient l’icône précédemment sélectionnée dans le lanceur.

C’est une vieille question, mais toujours active car il n’y a pas de fonctionnalité Android explicite. Et les gars de facebook ont ​​trouvé un travail autour – en quelque sorte. Aujourd’hui, j’ai trouvé un moyen qui fonctionne pour moi. Pas parfait (voir les remarques à la fin de cette réponse) mais ça marche!

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

Voici le code Il a un increment bouton. Lorsque vous appuyez sur cette touche, le raccourci est remplacé par un autre avec un nouveau numéro de comptage.

Tout d’abord, vous avez besoin de ces deux permissions dans votre manifeste:

   

Ensuite, vous avez besoin de ces deux méthodes pour installer et désinstaller les raccourcis. La méthode shortcutAdd crée un bitmap avec un numéro. C’est juste pour démontrer que cela change réellement. Vous voulez probablement changer cette partie avec quelque chose que vous voulez dans votre application.

 private void shortcutAdd(Ssortingng 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(Ssortingng 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 append le premier raccourci et mettre à jour le raccourci avec un compteur incrémenté.

 @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 des options supplémentaires dans l’ Intent . Ils ont juste besoin de noms différents pour que le bon soit désinstallé et réinstallé.

  • Le traitement programmé des raccourcis dans Android est une fonctionnalité Android bien connue, largement utilisée mais pas officiellement prise en charge. Il semble fonctionner sur le lanceur par défaut et je ne l’ai jamais essayé ailleurs. Alors ne me blâmez pas, quand vous recevez cet email d’utilisateur “Ça ne marche pas sur mon XYZ, téléphone à double racine, super blasted”

  • Le lanceur écrit un Toast lorsqu’un raccourci est installé et un autre lorsqu’un désinstallation est effectué. Donc, je reçois deux Toast chaque fois que je change d’icône. Ce n’est pas parfait, mais bon, tant que le rest de mon application est parfait …

Essayez ceci, ça marche bien pour moi:

1 . Modifiez votre section MainActivity dans AndroidManifest.xml , supprimez-la, AndroidManifest.xml avec la catégorie MAIN dans la section AndroidManifest.xml intent-filter

   ==>  <== Delete this line    

2. Créez pour chacune de vos icons. Comme ça

       

3. Définir par programmation: définir l’atsortingbut ENABLE pour l’ activity-alias approprié

  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.

Vous ne pouvez pas modifier le manifeste ou la ressource dans l’APK signé et scellé, sauf via une mise à niveau logicielle.

Par programme, vous souhaiterez peut-être publier vous-même le lanceur d’application:

Dans votre fichier AndroidManifest.xml, ajoutez:

  

Ensuite, vous devez créer l’intention du lanceur de votre application:

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

Créez un raccourci d’installation avec votre lanceur d’applications et votre 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 lancer l’intention de diffusion:

 getApplicationContext().sendBroadcast(intent); 

En supposant que vous voulez dire changer l’icône affichée sur l’écran d’accueil, cela pourrait facilement être fait en créant un widget qui fait exactement cela. Voici un article qui montre comment cela peut être accompli pour une application de type “nouveaux messages” similaire à l’iPhone:

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

La solution de @ PA fonctionne partiellement pour moi. Détaillez mes résultats ci-dessous:

1) Le premier extrait de code est incorrect, voir ci-dessous:

  ==>  <== This line shouldn't be deleted, otherwise will have compile error  //DELETE THIS LINE   

2) Devrait utiliser le code suivant pour désactiver toutes les icons avant d’activer une autre, sinon il faudra append une nouvelle icône au lieu de la remplacer.

 getPackageManager().setComponentEnabledSetting( getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 

MAIS, si vous utilisez le code ci-dessus, le raccourci sur l’écran d’accueil sera supprimé! Et il ne sera pas automatiquement ajouté. Vous pourriez être en mesure d’append des icons par programme, mais cela ne restra probablement pas dans la même position qu’auparavant.

3) Notez que l’icône ne sera pas modifiée immédiatement, cela pourrait prendre plusieurs secondes. Si vous cliquez dessus juste après avoir changé, vous pourriez avoir une erreur en disant: “L’application n’est pas installée”.

Donc, à mon humble avis, cette solution ne convient que pour changer d’icône dans le lanceur d’applications uniquement, pas pour les raccourcis (c.-à-d. L’icône sur l’écran d’accueil)

Exemple avec AndroidManifest.xml :

                              

Ensuite, suivez ci-dessous le code donné dans MainActivity :

 ImageView imageView = (ImageView)findViewById(R.id.imageView); int imageResourceId; Ssortingng currentDateTimeSsortingng = DateFormat.getDateTimeInstance().format(new Date()); int hours = new Time(System.currentTimeMillis()).getHours(); Log.d("DATE", "onCreate: " + hours); getPackageManager().setComponentEnabledSetting( getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); if(hours == 13) { imageResourceId = this.getResources().getIdentifier("ic_android_red", "drawable", this.getPackageName()); getPackageManager().setComponentEnabledSetting( new ComponentName("com.pritesh.resourceidentifierexample", "com.pritesh.resourceidentifierexample.MainActivity-Red"), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); }else if(hours == 14) { imageResourceId = this.getResources().getIdentifier("ic_android_green", "drawable", this.getPackageName()); getPackageManager().setComponentEnabledSetting( new ComponentName("com.pritesh.resourceidentifierexample", "com.pritesh.resourceidentifierexample.MainActivity-Green"), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); }else { imageResourceId = this.getResources().getIdentifier("ic_android_blue", "drawable", this.getPackageName()); getPackageManager().setComponentEnabledSetting( new ComponentName("com.pritesh.resourceidentifierexample", "com.pritesh.resourceidentifierexample.MainActivity-Blue"), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); } imageView.setImageResource(imageResourceId); 

Pour que Markus puisse trouver une solution, il fallait que le premier objective soit:

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