Фон
Вплоть до Android Q, если бы мы хотели получить информацию о файле APK, мы могли бы использовать WRITE_EXTERNAL_STORAGE и READ_EXTERNAL_STORAGE для получить доступ к хранилищу, а затем использовать функцию PackageManager.getPackageArchiveInfo для пути к файлу.
Существуют аналогичные случаи, например, использование класса ZipFile для сжатого файла и, возможно, бесчисленное количество API-интерфейсов платформы и сторонних библиотек.
проблема
Google недавно объявил об огромном количестве ограничений для Android Q.
Один из них называется Scoped Storage , что лишает права доступа к хранилищу при доступе ко всем файлам, имеющимся на устройстве. Он позволяет вам обрабатывать медиа-файлы или использовать очень ограниченную Storage-Access-Framework ( SAF ), которая не позволяет приложениям получать доступ к файлам и использовать их с помощью File API и file- пути.
Когда была выпущена Android Q Beta 2, из-за этого было сломано множество приложений, в том числе Google. Причина заключалась в том, что он был включен по умолчанию, затрагивая все приложения, независимо от того, нацелены они на Android Q или нет.
Причина в том, что многие приложения, SDK и сама платформа Android - все они используют File API довольно часто. Во многих случаях они также не поддерживают InputStream или решения, связанные с SAF. Примером этого является именно пример парсинга APK, о котором я писал (PackageManager.getPackageArchiveInfo).
Однако в бета-версии Q 3 все немного изменилось, так что приложение, предназначенное для цели Q, будет иметь объемное хранилище, и есть флаг, чтобы отключить его и при этом использовать обычные разрешения для хранилища и File API как обычно. К сожалению, флаг является только временным (читай здесь ), поэтому он задерживает неизбежное.
Что я пробовал
Я попробовал и нашел следующие вещи:
Использование разрешения на хранение действительно не позволило мне прочитать любой файл, который не является медиа-файлом (я хотел найти APK-файлы). Как будто файлы не существуют.
Используя SAF, я мог найти файл APK, и с некоторым обходным путем, чтобы найти его реальный путь (ссылка здесь ), я заметил, что File API может скажите мне, что файл действительно существует, но он не может получить его размер, и фреймворк не может использовать свой путь, используя getPackageArchiveInfo
. Написал об этом здесь
Я попытался создать символическую ссылку на файл (ссылка здесь ), а затем прочитал символическую ссылку. Это не помогло.
В случае парсинга APK-файлов я попытался найти альтернативные решения. Я нашел 2 репозитория github, которые обрабатывают APK, используя класс File ( здесь и здесь ), и один, который использует InputStream вместо этого ( здесь ). К сожалению, тот, который использует InputStream, очень старый, в нем отсутствуют различные функции (например, получение имени и значка приложения), и он не будет обновляться в ближайшее время. Кроме того, наличие библиотеки требует обслуживания, чтобы не отставать от будущих версий Android, в противном случае это может привести к проблемам в будущем или даже к аварийному завершению.
Вопросы
Как правило, есть ли способ использовать File API при использовании SAF? Я не говорю о корневых решениях или просто копирую файл куда-то еще. Я говорю о более твердом решении.
В случае синтаксического анализа APK, есть ли способ преодолеть эту проблему, что платформа предоставляет только путь к файлу в качестве параметра? Любой обходной путь или способ использования InputStream возможно?