Ошибка attempt to invoke virtual method 'java.lang.String android.os.storage.StorageVolume.getPath()' on a null object reference возникает в момент, когда приложение пытается вызвать метод у объекта, который равен null, — чаще всего это происходит при работе с API хранилища Android: StorageVolume, StorageManager или Environment.getExternalStorageDirectory(). Система сообщает, что виртуальный метод, возвращающий java.lang.String, вызван на несуществующем объекте, и приложение аварийно завершается с NullPointerException.
Такая ошибка встречается в двух сценариях: у пользователя — когда стороннее приложение падает при обращении к SD-карте или внутренней памяти, и у разработчика — когда код не проверяет результат системного вызова перед использованием. Ниже разберём оба случая: как определить источник сбоя и что предпринять в каждой ситуации.
Что означает текст ошибки
Сообщение attempt to invoke virtual method — стандартная формулировка виртуальной машины Android (ART) при попытке вызвать метод у null-ссылки. Фрагмент java.lang.String android.os.storage... указывает, что метод принадлежит пакету android.os.storage и должен вернуть строку — например, путь к каталогу хранилища, UUID тома или его описание.
Ключевая часть — on a null object reference. Она означает, что сам объект, у которого вызывается метод, не был создан или система вернула null. Например, StorageManager.getStorageVolumes() может вернуть пустой список, а обращение к элементу по индексу без проверки приведёт к падению. Аналогично методы вроде getExternalFilesDirs() могут содержать null-элементы, если съёмный носитель отсутствует или недоступен.
Типичные причины появления
Причины делятся на две группы: программные (в коде приложения) и системные (состояние устройства). Чтобы понять, с чем вы имеете дело, обратите внимание на момент возникновения: ошибка появляется только в одном приложении или сразу в нескольких.
- 🔍 Отсутствующая или отключённая SD-карта — приложение запрашивает путь к съёмному тому, которого нет в системе.
- 🔍 Непроверенный результат системного вызова — разработчик не добавил проверку на
nullперед вызовом метода. - 🔍 Изменения в API хранилища — начиная с Android 10 действует Scoped Storage, и старые способы получения путей могут возвращать
nullили устаревшие значения. - 🔍 Отсутствие разрешений — приложение не получило доступ к хранилищу, и вызов завершается некорректно.
- 🔍 Повреждённый или неподдерживаемый носитель — карта отформатирована в файловой системе, которую устройство не монтирует.
Обратите внимание: точный полный текст ошибки (какой именно метод вызван — getPath(), getUuid(), getDescription()) указывает на конкретное место сбоя. Если вы видите только общий фрагмент, полный стек-трейс можно посмотреть в логах устройства.
Если вы пользователь: что проверить на устройстве
Когда ошибка возникает в чужом приложении, исправить код вы не можете, но можете устранить системные факторы, которые провоцируют null-ответ от системы. Начните с простых обратимых проверок.
Первая проверка — состояние накопителя. Откройте Настройки → Хранилище (точный путь зависит от оболочки и версии Android) и убедитесь, что SD-карта определяется и смонтирована. Если карта отображается как «не поддерживается» или не отображается вовсе — извлеките её, проверьте на другом устройстве или в картридере. Возможная причина сбоя — повреждённая файловая система карты.
☑️ Базовая диагностика для пользователя
Второй шаг — разрешения. Откройте Настройки → Приложения → [имя приложения] → Разрешения и проверьте, предоставлен ли доступ к файлам и мультимедиа. Если разрешение отозвано, приложение может получать пустые ответы от системы и падать. После выдачи разрешения перезапустите приложение.
⚠️ Внимание: очистка данных приложения (в отличие от очистки кэша) удалит его настройки и локальные файлы. Перед этим шагом убедитесь, что важные данные сохранены в другом месте или синхронизированы с аккаунтом.
Если приложение давно не обновлялось, а система устройства получила крупное обновление Android — вероятна несовместимость. Проверьте наличие обновлений в магазине приложений. Если обновлений нет и разработчик забросил проект, единственный вариант — найти альтернативу, поддерживающую вашу версию Android.
Если вы разработчик: диагностика кода
Со стороны разработчика эта ошибка почти всегда означает отсутствие защитной проверки. Откройте стек-трейс в Logcat и найдите первую строку, указывающую на ваш пакет, — именно там вызывается метод у null-объекта.
Типичный проблемный паттерн выглядит так: код получает список томов или путей и сразу обращается к элементу без проверок:
File[] dirs = context.getExternalFilesDirs(null);
// dirs[1] может быть null, если SD-карта отсутствует
String path = dirs[1].getAbsolutePath();
Безопасный вариант — проверять каждый элемент перед использованием и обрабатывать ситуацию, когда съёмного хранилища нет:
File[] dirs = context.getExternalFilesDirs(null);
for (File dir : dirs) {
if (dir != null) {
String path = dir.getAbsolutePath();
// работаем с путём
}
}
То же относится к StorageManager: методы, возвращающие тома или их атрибуты, могут дать null в зависимости от версии Android, состояния монтирования и разрешений. Учитывайте, что часть API (например, прямой доступ к пути тома) со временем была ограничена или переведена в категорию скрытых — полагаться на такие методы нельзя, поведение будет отличаться между устройствами.
Сравнение сценариев возникновения ошибки
Таблица ниже поможет быстро сориентироваться, к какому сценарию относится ваш случай, и какое действие будет первым.
| Сценарий | Вероятная причина | Первое действие |
|---|---|---|
| Падает одно приложение при работе с SD-картой | Карта не смонтирована или повреждена | Проверить карту в настройках хранилища |
| Ошибка после обновления Android | Несовместимость приложения с новой версией API | Обновить приложение или искать альтернативу |
| Ошибка в собственном коде | Вызов метода у null без проверки | Изучить стек-трейс в Logcat |
| Падают несколько приложений сразу | Системная проблема с накопителем | Проверить карту на другом устройстве |
| Ошибка только на конкретной модели устройства | Особенности реализации API у производителя | Тестировать на этой модели, добавить проверки |
Заметьте: если сбой воспроизводится только на одной модели устройства, это указывает на особенности прошивки производителя. Поведение системных вызовов хранилища заметно различается между вендорами, поэтому код, работающий на одном смартфоне, может падать на другом.
Scoped Storage и современные версии Android
Начиная с Android 10, Google ввёл модель Scoped Storage, которая ограничивает прямой доступ приложений к файловой системе. Методы, которые раньше возвращали реальные пути к каталогам, теперь могут вести себя иначе или считаться устаревшими. Приложения, написанные под старые версии Android и не адаптированные разработчиком, — частый источник подобных падений на современных устройствах.
Для разработчиков корректный подход сегодня — использовать API, предназначенные для конкретных задач: MediaStore для медиафайлов, Storage Access Framework для доступа к документам по выбору пользователя, каталоги приложения через getFilesDir() и getExternalFilesDir() для приватных данных. Прямое построение путей к произвольным каталогам — ненадёжная практика, результат которой зависит от версии системы.
Почему Environment.getExternalStorageDirectory() считается устаревшим
Этот метод возвращал путь к корню общего хранилища, и многие приложения использовали его для свободного доступа к файлам. С переходом на Scoped Storage такой подход перестал соответствовать модели разрешений Android: метод помечен как deprecated, а приложения, ориентированные на новые версии API, должны работать через MediaStore, SAF или собственные каталоги. Код, который продолжает полагаться на старые пути без проверок, и становится источником NullPointerException на новых устройствах.
⚠️ Внимание: не пытайтесь «исправить» ошибку выдачей приложению root-прав или изменением системных настроек через ADB без понимания последствий. Это не устраняет причину в коде приложения и может ослабить безопасность устройства.
Когда проблема в самом накопителе
Отдельный случай — физическое состояние SD-карты. Если карта периодически отваливается, определяется через раз или устройство предлагает её отформатировать, системные вызовы будут возвращать пустые результаты, и приложения начнут падать именно с ошибками обращения к хранилищу. В этом случае виновато не приложение, а носитель: замена карты решает проблему полностью.
Проверка проста: извлеките карту и понаблюдайте за работой устройства без неё. Если падения прекратились, подключите карту к компьютеру через картридер и скопируйте важные данные. Дальше возможны два пути: форматирование карты (предварительно сохранив данные) или замена на новую, если наблюдаются ошибки чтения. Дешёвые и изношенные карты — частый источник подобных сбоев.
Частые вопросы
Опасна ли эта ошибка для данных на устройстве?
Сама по себе ошибка — это аварийное завершение приложения, она не повреждает файлы. Однако если причина в неисправной SD-карте, данные на ней действительно под угрозой: скопируйте важное на другое устройство как можно скорее.
Поможет ли переустановка приложения?
Иногда да: переустановка сбрасывает повреждённые настройки и кэш. Но если причина в несовместимости кода приложения с вашей версией Android или в неисправном накопителе, переустановка не поможет — ошибка вернётся при первом же обращении к хранилищу.
Почему ошибка появилась после обновления системы?
Обновление Android меняет поведение API хранилища и правила разрешений. Приложение, не адаптированное разработчиком под новую версию, может получать null там, где раньше получало корректные значения. Решение — обновление самого приложения или обращение к его разработчику.
Как разработчику быстро найти строку с ошибкой?
В Logcat найдите полный стек-трейс NullPointerException и спуститесь до первой строки с именем вашего пакета — это и есть место вызова метода у null-объекта. Добавьте проверку на null и обработку случая отсутствия хранилища.
Может ли ошибка возникать без SD-карты?
Да. Если код обращается к съёмному тому, которого нет в устройстве, системный вызов вернёт null или список без соответствующего элемента. Именно поэтому любые обращения к внешним томам должны сопровождаться проверками на null и на состояние монтирования.