Как изменить значок приложения программно для более высокой версии, например, oreo [duplicate]

Если у вас есть только один параметр «bar», вы можете назвать его «значение». В этом случае вам не обязательно писать имя параметра вообще, когда вы его используете следующим образом:

  @Foos ({@ Foo ("one"), @Foo ("two")}  ) public void haha ​​() {}  

немного короче и аккуратно, imho ..

113
задан systempuntoout 12 November 2010 в 12:17
поделиться

9 ответов

Это старый вопрос, но он все еще активен, поскольку нет явной функции Android. И ребята из facebook нашли работу вокруг - как-то. Сегодня я нашел способ, который работает для меня. Не идеально (см. Примечания в конце этого ответа), но он работает!

Основная идея заключается в том, что я обновляю значок ярлыка моего приложения, созданного с помощью пусковой установки на моем главном экране. Когда я хочу что-то изменить на ярлыке, я сначала удаляю его и воссоздаю его с помощью нового растрового изображения.

Вот код. Он имеет кнопку increment. Когда вы нажимаете, ярлык заменяется на тот, у которого есть новый счетный номер.

Сначала вам нужны эти два разрешения в вашем манифесте:

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

Затем вам нужны эти два метода для установка и удаление ярлыков. Метод shortcutAdd создает растровое изображение с числом в нем. Это просто, чтобы продемонстрировать, что оно действительно меняется. Вероятно, вы захотите изменить эту часть с чем-то, чего хотите в своем приложении.

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

И, наконец, вот два слушателя, чтобы добавить первый ярлык и обновить ярлык с помощью счетчика с добавлением.

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

Замечания:

  • Этот способ также работает, если ваше приложение контролирует больше ярлыков на главном экране, например с различными дополнительными в Intent. Они просто нуждаются в разных именах, так что правый удаляется и переустанавливается.
  • Программная обработка ярлыков в Android - это хорошо известная, широко используемая, но не официально поддерживаемая функция Android. Кажется, что он работает с пусковой установкой по умолчанию, и я никогда не пробовал ее нигде. Так что не обвиняйте меня в том, что когда вы получаете это сообщение от пользователя «Это не работает на моем XYZ, двойном корневом, супер взорванном телефоне»
  • Лаунчер пишет Toast, когда ярлык был установлен, и один, когда ярлык был удален. Поэтому каждый раз, когда я меняю значок, я получаю два Toast s. Это не идеально, но хорошо, если остальное приложение отлично ...
60
ответ дан jboi 16 August 2018 в 14:26
поделиться
  • 1
    Сегодняшнее приложение «Календарь» позволяет загружать значки каждый день без тоста. – Jim McKeeth 2 December 2014 в 02:03
  • 2
    @ Джим (я думаю), это на самом деле виджет, тогда – JacksOnF1re 5 December 2014 в 21:12
  • 3
    @jboi. Как изменить положение ярлыков после удаления? Ярлык теряет свое положение, указанное пользователем. И помещается в любую пустую ячейку. – Mixer 17 January 2015 в 02:00
  • 4
    shortcutDel , к сожалению, больше не работает в Marshmallow, см. также stackoverflow.com/a/33731620/1545993 – Taifun 30 July 2016 в 18:21
  • 5
    это заменяет значок ярлыка, а не значок запуска – user1506104 16 May 2018 в 05:19

Вы не можете изменить манифест или ресурс в подписанном и закрытом APK, за исключением обновления программного обеспечения.

33
ответ дан CommonsWare 16 August 2018 в 14:26
поделиться
  • 1
    Я знаю, что это старомодно, сомневаясь в том, что вы открываете новый вопрос и спрашиваете здесь, но здесь идет: это все еще так. ? По умолчанию программа «mail» (не знаю, является ли это «смысл») на 2.2.1 меняет значок (или, по крайней мере, рекламу накладывается на количество непрочитанных сообщений) – Nanne 22 March 2011 в 18:48
  • 2
    @Nanne: Это виджет приложения или функция главного экрана, а не значок приложения. Вы по-прежнему не можете изменить манифест или ресурс, кроме как с помощью обновления программного обеспечения. – CommonsWare 23 March 2011 в 00:46
  • 3
    ? Нет, я имею в виду другой путь: его нет (рекламируемый как) виджет. Я добавляю его как ярлык приложения. Но, как вы говорите, только потому, что этот материал без использования подразумевает его просто значок, это не значит, что это :) – Nanne 23 March 2011 в 11:50
  • 4
    @NeTeInStEiN: он не будет работать для всех домашних экранов (например, те, которые не обращают внимания на изменения, связанные с компонентами). – CommonsWare 8 August 2013 в 18:29
  • 5
    Неправда. Календарь Google на Android 6+ изменяется в режиме запуска на ежедневной основе. Сегодня значок является «2», вчера он был «1». Как правило, существовала "31" на иконке. Но это уже не так. Кто-нибудь знает, как это возможно? – Bobby 2 January 2017 в 22:56
  • 6
    – CommonsWare 2 January 2017 в 23:00

Решение P-A частично работает для меня. Подробно мои выводы ниже:

1) Первый фрагмент кода неверен, см. Ниже:

<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) Должен использовать следующий код для отключения всех значков до включения другого, иначе он добавит новый значок вместо его замены.

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

НО, если вы используете код выше, то ярлык на главном экране будет удален! И он не будет автоматически добавлен обратно. Возможно, вы сможете программно добавить значок обратно, но он, вероятно, не останется в том же положении, что и раньше.

3) Обратите внимание, что значок не будет изменен немедленно, это может занять несколько секунд. Если вы нажмете его сразу после изменения, вы можете получить сообщение об ошибке: «Приложение не установлено».

Итак, IMHO это решение подходит только для изменения значка только в приложении запуска, а не для быстрого доступа ( т.е. значок на рабочем столе)

5
ответ дан Deqing 16 August 2018 в 14:26
поделиться

AndroidManifest.xml пример:

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name="com.pritesh.resourceidentifierexample.MainActivity"
                  android:label="@string/app_name"
                  android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <!--<category android:name="android.intent.category.LAUNCHER"/>-->
            </intent-filter>
        </activity>

        <activity-alias android:label="RED"
                        android:icon="@drawable/ic_android_red"
                        android:name="com.pritesh.resourceidentifierexample.MainActivity-Red"
                        android:enabled="true"
                        android:targetActivity="com.pritesh.resourceidentifierexample.MainActivity">
            <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 android:label="GREEN"
                        android:icon="@drawable/ic_android_green"
                        android:name="com.pritesh.resourceidentifierexample.MainActivity-Green"
                        android:enabled="false"
                        android:targetActivity="com.pritesh.resourceidentifierexample.MainActivity">
            <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 android:label="BLUE"
                        android:icon="@drawable/ic_android_blue"
                        android:name="com.pritesh.resourceidentifierexample.MainActivity-Blue"
                        android:enabled="false"
                        android:targetActivity="com.pritesh.resourceidentifierexample.MainActivity">
            <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>

    </application>

Затем следуйте ниже приведенному коду в MainActivity:

ImageView imageView = (ImageView)findViewById(R.id.imageView);
            int imageResourceId;
            String currentDateTimeString = 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);
1
ответ дан GabLeRoux 16 August 2018 в 14:26
поделиться
  • 1
    Я получаю исключение com.pritesh.resourceidentifierexample.MainActivity-Red doesn't exist in com.pritesh.resourceidentifierexample. здесь я использовал ваше манифестное имя, чтобы продемонстрировать свою проблему – Tejas Pandya 19 December 2017 в 07:44

Попробуйте, это отлично работает для меня:

1. Измените раздел MainActivity в AndroidManifest.xml, удалите его, строку с MAIN в разделе intent-filter

<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. Создайте <activity-alias> для каждого из ваших значков. Подобно этому

<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. Установите программно: установите атрибут ENABLE для соответствующего activity-alias

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

Примечание. По крайней мере один должен быть включен в любое время.

101
ответ дан jaySf 16 August 2018 в 14:26
поделиться
  • 1
    что на самом деле делает код? пожалуйста, объясните – cafebabe1991 13 September 2013 в 09:10
  • 2
    печально работает по-разному на устройствах, которые я пробовал. Работает на HTC Desire 2.2, но ненадежна в Galaxy Nexus 4.2.2 и Nexus 7 4.3. На Galaxy Nexus может привести к исчезновению всех значков для приложения, а также удалению всех виджетов. Жаль, поэтому мне пришлось удалить эту функцию на более поздних устройствах. – Richard Le Mesurier 17 November 2013 в 11:55
  • 3
    я не могу запустить мое приложение, так как я удалил это: & lt; action android: name = & quot; android.intent.action.MAIN & quot; / & GT; & lt; category android: name = & quot; android.intent.category.LAUNCHER & quot; / & GT; – noobProgrammer 2 March 2014 в 17:36
  • 4
    Это отлично работает для переключения между значками запуска в панели задач и на рабочем столе, но я обнаружил, что значок, используемый на уровне ОС (например, для многозадачности, всплывающего окна удаления или в списке приложений) остается оригинал или станет стандартным значком Android по умолчанию, если вы не установили его на уровне приложения в манифесте. Вы нашли решение для этого, или вы просто терпите несоответствие (или отсутствие) в значке на уровне ОС? – jokeefe 3 October 2014 в 02:22
  • 5
    это должно быть отмечено как правильное – Korniltsev Anatoly 3 April 2015 в 23:58

Предполагая, что вы имеете в виду изменение значка, отображаемого на главном экране, это легко сделать, создав виджет, который делает именно это. Вот статья, демонстрирующая, как это можно сделать для приложения типа «новые сообщения», похожего на iPhone:

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

9
ответ дан Marius Kjeldahl 16 August 2018 в 14:26
поделиться

Программно, вы можете захотеть опубликовать приложение launcher самостоятельно:

В вашем AndroidManifest.xml добавьте:

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

Затем вам нужно создать намерение запуска приложения:

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

Создайте намерение ярлыка установки с помощью панели запуска приложения и пользовательского значка:

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

И, наконец, запустите трансляцию:

getApplicationContext().sendBroadcast(intent);
16
ответ дан ohhorob 16 August 2018 в 14:26
поделиться

Чтобы получить решение с помощью работы Маркуса, мне понадобилось первое намерение, поэтому:

Intent myLauncherIntent = new Intent(Intent.ACTION_MAIN);
            myLauncherIntent.setClassName(this,  this.getClass().getName());
            myLauncherIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
0
ответ дан PuZZleDucK 16 August 2018 в 14:26
поделиться
1
ответ дан Faxriddin Abdullayev 29 October 2018 в 13:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: