Ошибка android:exported для Activity в Android 12 и выше: как исправить?
Причина ошибки
Начиная с Android 12 (API 31), Google ужесточил требования безопасности. Если в вашем AndroidManifest.xml для компонента (Activity, Service, BroadcastReceiver или ContentProvider) объявлен intent-filter, вы обязаны явно указать атрибут android:exported. Раньше система подставляла значение по умолчанию (если есть intent-filter — true, иначе — false), но теперь это поведение запрещено.
Что означает android:exported?
android:exported="true"— компонент может быть запущен из других приложений (или системой).android:exported="false"— компонент доступен только внутри вашего приложения.
Как исправить для MainActivity (Launcher)
Главная Activity, которая запускается по нажатию на иконку приложения, обязательно должна иметь android:exported="true". Иначе система не сможет запустить ваше приложение.
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Как исправить для SecondActivity (без intent-filter)
Для SecondActivity у вас нет intent-filter. В этом случае атрибут android:exported можно не указывать (ошибка не возникнет), но для единообразия и явности кода лучше добавить android:exported="false":
<activity
android:name=".SecondActivity"
android:exported="false" />
Если вы планируете, чтобы SecondActivity запускалась из других приложений (например, через явный Intent), поставьте true.
Общий алгоритм для всех компонентов
- Проверьте, есть ли у компонента
<intent-filter>. - Если есть — обязательно добавьте
android:exported="true"(если компонент должен быть доступен извне) илиandroid:exported="false"(если только для внутреннего использования). - Если intent-filter нет — атрибут не обязателен, но рекомендуется явно указать
android:exported="false"для безопасности.
Пример полного исправления
<application ...>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SecondActivity"
android:exported="false" />
<!-- Для BroadcastReceiver с intent-filter -->
<receiver
android:name=".MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
Совет для Kotlin-разработчиков
Если вы используете Compose Navigation или Activity Result API, это не отменяет требования к манифесту. Проверьте все Activity, Service, Receiver и Provider в вашем проекте, включая библиотеки (например, Firebase, Google Sign-In). Если библиотека добавляет свои компоненты с intent-filter, она должна сама указывать android:exported — но лучше перепроверить.
Что будет, если поставить false для MainActivity?
Приложение не сможет запуститься из лаунчера. Система не найдёт точку входа. Вы получите ошибку во время выполнения (или приложение просто не появится в списке приложений).
<<Альтернативный подход: использование инструментов автоматической проверки
Если у вас много компонентов и вы боитесь что-то пропустить, можно использовать Lint или Gradle-задачу для автоматического поиска проблем.
1. Запуск Lint в Android Studio
Откройте Analyze → Inspect Code и выберите профиль Android Lint. Lint подсветит все Activity, Service, Receiver и Provider, у которых отсутствует android:exported.
2. Использование Gradle-задачи
Добавьте в build.gradle.kts (уровень модуля):
android {
lint {
checkReleaseBuilds = true
abortOnError = true
// Включите проверку exported
check "MissingExportedAttribute"
}
}
Теперь при сборке (например, ./gradlew lintRelease) вы получите отчёт со всеми проблемными местами.
3. Быстрое исправление через поиск
В Android Studio нажмите Ctrl+Shift+F и найдите все вхождения <activity, <service, <receiver. Просмотрите каждый блок и добавьте атрибут. Это скучно, но надёжно.
4. Если вы используете модули библиотек
Иногда ошибка возникает из-за сторонних библиотек, которые объявляют Activity с intent-filter, но не указывают android:exported. В таком случае добавьте атрибут через merge rule в вашем манифесте:
<activity
android:name="com.some.library.LibraryActivity"
android:exported="true"
tools:node="merge" />
Не забудьте добавить xmlns:tools="http://schemas.android.com/tools" в корневой элемент <manifest>.
Этот способ не заменяет понимание логики android:exported, но помогает быстро найти и исправить все пропуски.