Что произойдет при попытке открыть PDF ридер, отсутствующий в системе Android
Что проверяют
Знаете ли вы, что делает система, когда обработчика неявного интента нет, и умеете ли вы закрывать этот случай. Заодно проверка на знание ограничений видимости пакетов.
Как отвечать
Приложение отправляет неявный интент ACTION_VIEW с типом application/pdf, система ищет активити с подходящим фильтром. Если такой нет, startActivity бросает ActivityNotFoundException и приложение падает. Никакого системного диалога при этом не появляется: сообщение «нет приложений для этого действия» показывает только Intent.createChooser.
Отсюда рабочие варианты:
- обернуть вызов в
try/catch ActivityNotFoundExceptionи показать понятное объяснение с запасным действием; - отправлять через
createChooser, тогда пустой выбор отрисует система; - заранее спросить
resolveActivityилиqueryIntentActivities, но тогда в манифесте обязателен блок<queries>: начиная с одной из свежих версий Android видимость чужих пакетов ограничена, и без объявления проверка вернёт пусто даже при установленном ридере; - не зависеть от чужого приложения и отрисовать документ у себя через
PdfRenderer.
Не забыть про доступ к файлу: наружу отдаётся content:// от FileProvider с FLAG_GRANT_READ_URI_PERMISSION. Путь вида file:// на современных версиях приведёт к FileUriExposedException, и это соседний частый вопрос.
Где спотыкаются
Уверены, что система сама покажет заглушку. Без chooser или перехвата исключения это крах в продакшене, который не воспроизводится на устройстве разработчика: там ридер стоит, а на чистой прошивке или на эмуляторе без сервисов его нет.
Проверяют resolveActivity и не объявляют <queries>. Получается обратная ошибка: приложение честно сообщает, что ридера нет, на устройстве, где он установлен, и пользователь остаётся без файла.
Отвечают по схеме «ситуация, задача, действие, результат», как на поведенческом вопросе. Технический вопрос ждёт механику: кто бросает исключение, чем его закрыть, какой провайдер и какой флаг. Сюда же относится совет «предложим установить из магазина»: переход в магазин это тоже внешнее приложение, и его точно так же надо оборачивать в перехват.