How to change an application icon programmatically in Android?

前端 未结 10 2141
闹比i
闹比i 2020-11-21 22:33

Is it possible to change an application icon directly from the program?
I mean, change icon.png in the res\\drawable folder.
I would like t

相关标签:
10条回答
  • 2020-11-21 23:14

    To get the solution by Markus working I needed the first Intent so be:

    Intent myLauncherIntent = new Intent(Intent.ACTION_MAIN);
                myLauncherIntent.setClassName(this,  this.getClass().getName());
                myLauncherIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    
    0 讨论(0)
  • 2020-11-21 23:16

    Try this, it works fine for me:

    1 . Modify your MainActivity section in AndroidManifest.xml, delete from it, line with MAIN category in 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 . Create <activity-alias>, for each of your icons. Like this

    <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 . Set programmatically: set ENABLE attribute for the appropriate activity-alias

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

    Note, At least one must be enabled at all times.

    0 讨论(0)
  • 2020-11-21 23:19

    Applying the suggestions mentioned, I've faced the issue of app getting killed whenever default icon gets changed to new icon. So have implemented the code with some tweaks. Step 1). In file AndroidManifest.xml, create for default activity with android:enabled="true" & other alias with android:enabled="false". Your will not contain but append those in with android:enabled="true".

           <activity
            android:name=".activities.SplashActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:theme="@style/SplashTheme">
    
        </activity>
        <!-- <activity-alias used to change app icon dynamically>   : default icon, set enabled true    -->
        <activity-alias
            android:label="@string/app_name"
            android:icon="@mipmap/ic_launcher"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:name=".SplashActivityAlias1" <!--put any random name started with dot-->
            android:enabled="true"
            android:targetActivity=".activities.SplashActivity"> <!--target activity class path will be same for all alias-->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity-alias>
        <!-- <activity-alias used to change app icon dynamically>  : sale icon, set enabled false initially -->
        <activity-alias
            android:label="@string/app_name"
            android:icon="@drawable/ic_store_marker"
            android:roundIcon="@drawable/ic_store_marker"
            android:name=".SplashActivityAlias" <!--put any random name started with dot-->
            android:enabled="false"
            android:targetActivity=".activities.SplashActivity"> <!--target activity class path will be same for all alias-->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity-alias>
    

    Step 2). Make a method that will be used to disable 1st activity-alias that contains default icon & enable 2nd alias that contains icon need to be changed.

    /**
     * method to change the app icon dynamically
     *
     * @param context
     * @param isNewIcon  : true if new icon need to be set; false to set default 
     * icon
     */
    
    public static void changeAppIconDynamically(Context context, boolean isNewIcon) {
        PackageManager pm = context.getApplicationContext().getPackageManager();
        if (isNewIcon) {
            pm.setComponentEnabledSetting(
                    new ComponentName(context,
                            "com.example.dummy.SplashActivityAlias1"), //com.example.dummy will be your package
                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                    PackageManager.DONT_KILL_APP);
    
            pm.setComponentEnabledSetting(
                    new ComponentName(context,
                            "com.example.dummy.SplashActivityAlias"),
                    PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                    PackageManager.DONT_KILL_APP);
        } else {
            pm.setComponentEnabledSetting(
                    new ComponentName(context,
                            "com.example.dummy.SplashActivityAlias1"),
                    PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                    PackageManager.DONT_KILL_APP);
    
            pm.setComponentEnabledSetting(
                    new ComponentName(context,
                            "com.example.dummy.SplashActivityAlias"),
                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                    PackageManager.DONT_KILL_APP);
        }
    }
    

    Step 3). Now call this method depending on your requirement, say on button click or date specific or occasion specific conditions, simply like -

    // Switch app icon to new icon
        GeneralUtils.changeAppIconDynamically(EditProfileActivity.this, true);
    // Switch app icon to default icon
                GeneralUtils.changeAppIconDynamically(EditProfileActivity.this, false);
    

    Hope this will help those who face the issue of app getting killed on icon change. Happy Coding :)

    0 讨论(0)
  • 2020-11-21 23:20

    @P-A's solution partially works for me. Detail my findings below:

    1) The first code snippet is incorrect, see below:

    <activity
        ...
        <intent-filter>
            ==> <action android:name="android.intent.action.MAIN" /> <== This line shouldn't be deleted, otherwise will have compile error
            <category android:name="android.intent.category.LAUNCHER" /> //DELETE THIS LINE
        </intent-filter>
    </activity>
    

    2) Should use following code to disable all icons before enabling another one, otherwise it will add a new icon, instead of replacing it.

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

    BUT, if you use code above, then shortcut on homescreen will be removed! And it won't be automatically added back. You might be able to programmatically add icon back, but it probably won't stay in the same position as before.

    3) Note that the icon won't get changed immediately, it might take several seconds. If you click it right after changing, you might get an error saying: "App isn't installed".

    So, IMHO this solution is only suitable for changing icon in app launcher only, not for shortcuts (i.e. the icon on homescreen)

    0 讨论(0)
提交回复
热议问题