Как система Android определяет, какой компонент обрабатывает Intent
Что проверяют
Понимаете ли вы разницу между явным и неявным Intent и знаете ли правила сопоставления с intent-фильтрами. Следом обычно спрашивают, что изменилось в последних версиях Android: package visibility, обязательный android:exported, ограничения неявных интентов.
Как отвечать
Явный Intent (Intent(context, DetailActivity::class.java) или setComponent()) доставляется прямо указанному компоненту, фильтры не проверяются. Неявный разрешает PackageManager, сравнивая его с <intent-filter> из манифестов по трём тестам:
- action: действие интента должно совпасть с одним из
<action>фильтра. Фильтр без действий не пропускает ничего; - category: каждая категория интента должна быть в фильтре. Для
startActivity()система добавляетCATEGORY_DEFAULT, поэтому активность безandroid.intent.category.DEFAULTнеявный интент не получит; - data: сверяются схема, хост, порт, путь и MIME-тип. Если в интенте есть и URI, и тип, совпасть должны оба.
Подошло несколько активностей: система показывает диалог выбора или открывает приложение, выбранное пользователем по умолчанию, а Intent.createChooser() показывает выбор всегда. Не подошло ничего: startActivity() бросает ActivityNotFoundException. android:priority важен для упорядоченных broadcast, у активностей обычных приложений он не учитывается.
Изменения по версиям:
- Android 5.0:
bindService()с неявным интентом бросает исключение; - Android 11: package visibility,
queryIntentActivities()видит только приложения из<queries>; - Android 12: компонент с фильтром обязан явно указать
android:exported; - Android 14: неявный интент доходит только до экспортированных компонентов, свои внутренние запускают явно.
Где спотыкаются
Забывают категорию DEFAULT в фильтре. Активность объявлена, но неявный интент до неё не доходит.
Проверяют resolveActivity() без <queries> на Android 11 и выше. Метод возвращает null, и кнопка «Открыть в картах» пропадает, хотя приложение установлено.
Считают, что priority в фильтре заставит систему выбрать их активность. Для обычных приложений это так не работает.