Android-приложение устанавливает две иконки запуска

Это не дубликат приложения Android, создающего две иконки запуска (у меня нет нескольких определений LAUNCHER в моем манифесте), ни Android-приложение, создающее два значка запуска вместо одного (перезагрузка устройства не удаляет второй значок запуска).

Мое приложение для Android создает два значка запуска, но один из них, похоже, исходит от самого приложения, а не от какой-либо активности. Я обрезал свой AndroidManifest.xml до минимально возможного (плюс очистил, перестроил и переустановил), и у меня все еще есть две иконки (как на моем физическом телефоне HTC One M8, так и на моем эмуляторе Nexus 5):

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app">

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

        <activity
            android:name=".SplashActivity"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

В моем манифесте нет ничего.

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

Если я перемещу функции android:label и android:icon в определение .SplashActivity, один из созданных значков запуска заменится значком маленького зеленого робота по умолчанию.


person Valkyrie Savage    schedule 24.01.2017    source источник
comment
Такое ощущение, что вы берете активность из какой-то библиотеки, которую используете. Если вы используете Android Studio 2.2 или более позднюю версию, откройте свой манифест и перейдите на вложенную вкладку «Объединенный манифест» внизу и посмотрите, не отображается ли там другая активность.   -  person CommonsWare    schedule 25.01.2017
comment
Я никогда не знал о таком взгляде! Я действительно нашел там еще одну активность LAUNCHER. Спасибо @CommonsWare. :)   -  person Valkyrie Savage    schedule 25.01.2017


Ответы (2)


Активности и другие проявления манифестного добра происходят из разных источников:

  • манифест в вашем main исходном наборе
  • манифест в любом исходном наборе типа сборки или вкуса продукта
  • манифест в любом библиотечном модуле или AAR
  • Gradle (например, minSdkVersion)

Android Studio 2.2 предоставила нам удобный инструмент для проверки настоящего манифеста, входящего в наши APK, объединенного из всех этих источников. Если вы открываете манифест в Android Studio, щелкните вложенную вкладку «Слияние манифеста» (в нижней части IDE). Это покажет, что находится в объединенном манифесте и кто в этом виноват, откуда он взялся.

Если вы видите там другие действия, кроме того, что в вашем манифесте, это источник вашего значка запуска. Затем вам нужно решить:

  • это то, что вы действительно хотите?
  • если нет, то является ли источник этой активности тем, что вам действительно нужно? (если нет, то взорви его)
  • если вам нужен источник, но не действие, вы можете настроить другой элемент действия в своем манифесте с атрибутом tools:replace, чтобы переопределить элемент из библиотеки и подавить <intent-filter>
person CommonsWare    schedule 24.01.2017
comment
У меня есть действие android.intent.action.MAIN, определенное для двух действий, но я хочу показать только одно из них. Могу ли я использовать инструменты: заменить, чтобы переопределить действие Main 1-го действия (только для чтения, как исходящего из библиотеки) - person Tushar Gogna; 25.09.2020
comment
@TusharGogna: Могу ли я использовать tools:replace, чтобы переопределить действие Main 1-го действия (только для чтения как исходящего из библиотеки) - да. Создайте элемент <activity>, android:name которого соответствует элементу действия из библиотеки, и оттуда вы сможете управлять записью манифеста этого конкретного действия. - person CommonsWare; 25.09.2020
comment
Я попробовал это, добавив <action android:name="android.intent.action.MAIN" tools:node="remove" /> в тег активности, сохранив то же имя, но, похоже, это не работает. Я сделал то же самое с <category android:name="android.intent.category.LAUNCHER" tools:node="remove" /> ! Название действий одинаковое: в основном весь path.ActivityName. Нужно ли мне делать что-то еще? - person Tushar Gogna; 25.09.2020
comment
@TusharGogna: я рекомендую вам задать отдельный вопрос о переполнении стека, где вы можете предоставить минимально воспроизводимый пример, показывающий ваш манифестные попытки, а также сведения о действиях, которые вы пытаетесь подавить. - person CommonsWare; 25.09.2020
comment
Да, вот вопрос: stackoverflow.com/questions/64066594/ - person Tushar Gogna; 25.09.2020

Моя проблема заключалась в том, что я добавил следующий фильтр намерений к нескольким действиям. Настроил его для одного действия, исправив проблему для меня.

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
person Manuel Schmitzberger    schedule 14.11.2019