¿Cómo cambiar el ícono de una aplicación mediante programación en Android?

Resuelto systempuntoout asked hace 54 años • 12 respuestas

¿Es posible cambiar el ícono de una aplicación directamente desde el programa?
Quiero decir, cambio icon.pngen la res\drawablecarpeta.
Me gustaría permitir que los usuarios cambien el ícono de la aplicación desde el programa para que la próxima vez vean el ícono previamente seleccionado en el iniciador.

systempuntoout avatar Jan 01 '70 08:01 systempuntoout
Aceptado

Prueba esto, a mí me funciona bien:

1 . Modifique su MainActivitysección en AndroidManifest.xml, elimínela, alinee con MAINla categoría en intent-filterla sección

<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 . Crea <activity-alias>, para cada uno de tus íconos. Como esto

<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 . Establecer mediante programación: establezca el atributo ENABLE para el apropiadoactivity-alias

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

Tenga en cuenta que al menos uno debe estar habilitado en todo momento.

P-A avatar Mar 06 '2013 14:03 P-A

Es una pregunta antigua, pero sigue activa ya que no existe una función explícita de Android. Y los chicos de Facebook encontraron una solución, de alguna manera. Hoy encontré una manera que funciona para mí. No es perfecto (ver comentarios al final de esta respuesta) ¡pero funciona!

La idea principal es actualizar el ícono del acceso directo de mi aplicación, creado por el iniciador en mi pantalla de inicio. Cuando quiero cambiar algo en el ícono de acceso directo, primero lo elimino y lo vuelvo a crear con un nuevo mapa de bits.

Aquí está el código. Tiene un botón increment. Cuando se presiona, el acceso directo se reemplaza por uno que tiene un nuevo número de conteo.

Primero necesitas estos dos permisos en tu manifiesto:

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

Entonces necesitas estos dos métodos para instalar y desinstalar accesos directos. El shortcutAddmétodo crea un mapa de bits con un número. Esto es sólo para demostrar que realmente cambia. Probablemente quieras cambiar esa parte con algo que quieras en tu aplicación.

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);
}

Y finalmente, aquí hay dos oyentes para agregar el primer acceso directo y actualizar el acceso directo con un contador incremental.

@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);
        }
    });
}

Observaciones:

  • Esta forma también funciona si su aplicación controla más accesos directos en la pantalla de inicio, por ejemplo, con diferentes extras en el archivo Intent. Solo necesitan nombres diferentes para desinstalar y reinstalar el correcto.

  • El manejo programático de accesos directos en Android es una característica de Android bien conocida y ampliamente utilizada, pero que no cuenta con soporte oficial. Parece funcionar en el iniciador predeterminado y nunca lo probé en ningún otro lugar. Así que no me culpes cuando recibas este correo electrónico de usuario: "No funciona en mi teléfono XYZ, con doble raíz y súper arruinado".

  • El iniciador escribe Toastcuándo se instaló un acceso directo y otro cuando se desinstaló un acceso directo. Entonces obtengo dos Toasts cada vez que cambio el ícono. Esto no es perfecto, pero bueno, mientras el resto de mi aplicación sea perfecta...

jboi avatar Oct 25 '2013 15:10 jboi

No puede cambiar el manifiesto o el recurso en el APK firmado y sellado, excepto mediante una actualización de software.

CommonsWare avatar Jul 09 '2009 12:07 CommonsWare

De forma programática, es posible que desees publicar el iniciador de aplicaciones tú mismo:

Nota: este método ya no funciona a partir de Android 8.0 - Oreo

En su AndroidManifest.xml, agregue:

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

Luego necesitas crear la intención del iniciador de tu aplicación:

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

Cree una intención de acceso directo de instalación con su iniciador de aplicaciones y su ícono personalizado:

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");

Y finalmente lanza la intención de transmisión:

getApplicationContext().sendBroadcast(intent);
Andrei Mărcuţ avatar Mar 22 '2011 21:03 Andrei Mărcuţ