java.lang.SecurityException: что за ошибка и как её исправить

Исключение java.lang.SecurityException выбрасывается в тот момент, когда код пытается выполнить операцию, на которую у него нет разрешения: запустить защищённый сервис, получить доступ к местоположению без объявленного разрешения или вызвать API, требующий системной подписи. Текст сообщения после имени исключения — ключевая подсказка: в нём обычно указано, какого именно разрешения не хватает (например, Permission Denial: ... requires android.permission.ACCESS_FINE_LOCATION) или какой компонент отклонил вызов.

Ошибка встречается в двух основных сценариях. Первый — вы разработчик и видите исключение в Logcat при тестировании своего приложения. Второй — вы пользователь, и приложение на Android падает с сообщением об этой ошибке после обновления системы или установки из неофициального источника. Подход к исправлению в этих случаях различается, поэтому ниже разберём оба.

Что означает java.lang.SecurityException

SecurityException — это проверка безопасности, встроенная в виртуальную машину и фреймворк. В Java она возникает при работе SecurityManager (в устаревших версиях платформы), а в Android — при проверке разрешений на уровне системы: каждый вызов защищённого API проходит через диспетчер разрешений, и если манифест приложения не содержит нужного <uses-permission> или пользователь не выдал разрешение во время выполнения, система выбрасывает исключение.

Важно понимать: это не сбой железа и не повреждение системы. Это штатная реакция на нарушение правил доступа. Соответственно, исправление всегда сводится к одному из трёх действий — добавить недостающее разрешение, запросить его у пользователя в рантайме или устранить несоответствие подписи/сертификата.

Основные причины возникновения

Прежде чем что-то менять, определите сценарий. Наиболее частые причины выглядят так:

  • 🔐 Отсутствует разрешение в манифесте — в AndroidManifest.xml не объявлен нужный <uses-permission>.
  • 📱 Не запрошено runtime-разрешение — начиная с Android 6 опасные разрешения (местоположение, камера, контакты) нужно запрашивать у пользователя во время работы приложения.
  • ✍️ Конфликт подписей — приложение обновлено сборкой с другим сертификатом, либо вызывается компонент, защищённый разрешением уровня signature.
  • 🚫 Ограничения фоновой работы — попытка запустить foreground service или получить данные датчиков из фона на современных версиях Android.
  • 🧩 Неэкспортированный компонент — обращение к Activity или Service другого приложения без корректного android:exported и разрешений.
⚠️ Внимание: если ошибка появилась после обновления приложения через APK-файл из стороннего источника поверх версии из магазина, наиболее вероятная причина — несовпадение сертификатов подписи. Не пытайтесь «подменить» подпись — удалите приложение и установите нужную версию начисто, предварительно сохранив данные.

Диагностика: читаем стектрейс

Первый шаг для разработчика — открыть Logcat в Android Studio и найти полное сообщение исключения. Строка вида java.lang.SecurityException: Permission Denial: starting Intent ... requires android.permission.CALL_PHONE прямо указывает и на проблемный вызов, и на недостающее разрешение.

Обратите внимание на строку стектрейса, где указан ваш класс и метод — именно там происходит запрещённый вызов. Если сообщение содержит фразу Neither user ... nor current process has ..., речь идёт о разрешении, которого нет ни в манифесте, ни в выданных пользователем правах.

📊 В каком сценарии вы столкнулись с SecurityException?
При запуске собственного приложения в разработке
После обновления приложения на телефоне
При работе с геолокацией или датчиками
При вызове системных API или сервисов

Исправление для разработчиков

Последовательность действий зависит от текста ошибки, но общий алгоритм такой. Сначала добавьте разрешение в манифест:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Затем, если разрешение относится к категории опасных, запросите его во время выполнения через requestPermissions() или современный ActivityResultLauncher с контрактом RequestPermission. Проверку перед вызовом защищённого API выполняйте через ContextCompat.checkSelfPermission() — это предотвратит падение, если пользователь отказал в доступе.

☑️ Проверка перед исправлением SecurityException

Выполнено: 0 / 5

Отдельный случай — foreground service: на современных версиях Android для его запуска требуется разрешение FOREGROUND_SERVICE, а для отдельных типов — специализированные разрешения вида FOREGROUND_SERVICE_LOCATION с указанием android:foregroundServiceType в манифесте. Точный набор зависит от целевой версии SDK, поэтому сверяйтесь с официальной документацией Android для вашего targetSdkVersion.

Почему ошибка появляется только на новых версиях Android

С каждой версией Android ужесточает модель разрешений: появляются ограничения на фоновый доступ к местоположению, запуск активностей из фона, доступ к буферу обмена и датчикам. Код, работавший на старой версии, может начать выбрасывать SecurityException после обновления targetSdkVersion или прошивки устройства. Решение — адаптировать код под новые правила, а не понижать целевую версию надолго.

Исправление для пользователей Android

Если вы не разрабатываете приложение, а просто видите его падение с этой ошибкой, начните с простых шагов. Откройте настройки приложения и проверьте выданные разрешения — путь обычно выглядит как Настройки → Приложения → [имя приложения] → Разрешения, хотя названия пунктов могут отличаться в зависимости от оболочки производителя.

Далее попробуйте очистить кэш приложения и перезапустить его. Если ошибка появилась после обновления из APK-файла, удалите приложение полностью и установите его заново из официального источника — это устранит конфликт подписей. Когда ничего не помогает, а ошибка массовая, имеет смысл проверить наличие обновления приложения: разработчик мог уже выпустить исправление под новую версию системы.

Типичные сообщения об ошибке и их смысл

Фрагмент сообщенияВероятная причинаНаправление решения
Permission Denial: requires android.permission.XРазрешение не объявлено или не выданоДобавить в манифест, запросить в рантайме
Neither user ... nor current process has permissionНет разрешения у процессаПроверить манифест и runtime-запрос
Permission Denial: not exported from uidКомпонент не экспортированПроверить android:exported и intent-filter
Requires android.permission.FOREGROUND_SERVICEСервис запущен без нужного разрешенияОбъявить разрешение и тип сервиса
UID ... does not have android.permission.INTERACT_ACROSS_USERSВызов системного API без системной подписиОбычному приложению недоступно, искать публичный API
⚠️ Внимание: разрешения уровня signature и system (например, управление другими пользователями устройства) недоступны обычным приложениям независимо от манифеста. Если стектрейс указывает на такое разрешение, ищите альтернативный публичный API — обходить ограничение через root небезопасно и ломает гарантии системы.

Когда проблема в самом коде вызова

Иногда разрешения в порядке, но исключение всё равно возникает. Проверьте контекст вызова: запуск сервиса из фонового состояния, обращение к ContentProvider другого приложения без grantUriPermission, передача PendingIntent без флагов изменяемости на новых версиях Android — всё это может приводить к отказу в доступе.

Также полезно обернуть потенциально опасный вызов в try-catch по SecurityException и предусмотреть деградацию функциональности: например, если нет доступа к точной геолокации, предложить пользователю приблизительную или ручной ввод. Это не устраняет причину, но превращает падение приложения в управляемый сценарий.

Часто задаваемые вопросы

Может ли java.lang.SecurityException появиться из-за вируса?

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

Почему разрешение есть в манифесте, но ошибка остаётся?

Наиболее вероятные причины: разрешение относится к опасным и не запрошено во время выполнения, пользователь отозвал его в настройках, либо вызов выполняется в запрещённом контексте (например, из фона). Проверьте полный текст сообщения об ошибке — он укажет конкретную причину отказа.

Что делать, если ошибка появилась после обновления Android?

Новая версия системы могла ужесточить правила доступа. Пользователю стоит проверить разрешения приложения в настройках и обновить само приложение. Разработчику — изучить изменения поведения для соответствующей версии Android и адаптировать код.

Поможет ли переустановка приложения?

Да, если причина в конфликте подписей после установки APK поверх магазинной версии или в повреждённых данных. Перед удалением сохраните важные данные, так как локальные файлы приложения будут удалены.

Опасно ли давать приложению все запрашиваемые разрешения?

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