2015-07-04 3 views
3

У меня есть приложение для Android, которое использует много родного кода C++. Приложение должно работать с файлами, расположенными на SD-карте (читать, создавать, добавлять). Но Kitkat + отказал в написании sdcard для сторонних приложений. Android 5 представил новый API, который позволяет это снова.Android lollipop написать sdcard из родного кода C++

How to use the new SD card access API presented for Android 5.0 (Lollipop)?

Все примеры и документация, что я нашел в основном для Java стороны. Примеры для собственного кода не существуют или очень неясны. Поэтому я хочу задать несколько вопросов.

Ссылка выше содержит ценный пример того, как получить DocumentFile, который может вернуть ParcelFileDescriptor. Из этого объекта я могу получить собственный дескриптор файла - ParcelFileDescriptor.getFd(). Это целое число, которое я отправляю на C++-код через jni.

В C++ открываем файл с fdopen (fd).

Мои вопросы:

  1. ли fdopen функция правильный способ, как открыть файл с новым API? Или DocumentFile уже открывает файл, и я должен использовать только fd в дальнейших операциях.
  2. Достаточно закрыть дескриптор файла внутри собственного кода с помощью fclose? или я должен закрыть его на стороне Java с помощью ParcelFileDescriptor.detachFd(). Или оба.

Спасибо

EDIT: Я getFD и detachFD работает. Но я никогда не находил ответ, как правильно заменить ftruncate, который необходим доступ на запись тоже, и я не нашел ftruncate версии, которая принимает дескриптор файла как вход

ответ

0

Try Ниже Ссылок:

Android - пишущий/сохранения файлов из нативный код только: Android - writing/saving files from native code only

Android NDK Запись файла: Android NDK Write File

Операции с файлами в Android NDK: File Operations in Android NDK

+0

Hi, спасибо. Эти ссылки очень полезны. Но, к сожалению, не актуально, если файловая система защищена SAF https://developer.android.com/guide/topics/providers/document-provider.html – user1063364

+0

В настоящее время я использую ParcelFileDescriptor.detachFd(), и я отправляю ее на собственный код. Затем файл закрывается функцией fclose(). Но я получаю это предупреждение: W/ParcelFileDescriptor: равносильный ожидаемый сигнал при закрытии; не удалось доставить после отсоединения .... – user1063364

0

1) да, использовать дескрипторы файлов и fdopen 2)

  1. Откройте ParcelFileDescriptor.
  2. getFd().
  3. Передайте Fd на собственный код.
  4. Закрыть ParcelFileDescriptor. (это закрывает вашу ссылку на java)

Fd - всего лишь int, представляющий идентификатор Linux для файла.В родной:

  1. Fdopen
  2. ли материал
  3. Fclose (обратите внимание на это закрывает свой родной указатель файла)

Два закрывается делают разные вещи.

Примечание. Вам еще нужно разрешение SAF для файла или более высокий корень.

+0

как я могу исправить ту же проблему для ftruncate? Нет версии ftruncate, которая принимает дескриптор файла – user1063364

+0

Единственный способ - использовать кеш в качестве места подкачки и передавать с помощью SAF. Я изначально должен был сделать это с помощью методов MTP, так как они также не имели FD. Отправьте отчет об ошибке, через три года они исправит его, они сделали для MTP. SAF был одним из самых плохо продуманных и выполненных рамок, которые я когда-либо видел. Они сломали половину своего кода и просто не интересовались годами. – Anthony

+0

За ночь я написал свою собственную версию ftruncate, используя fseek и копируя данные из одного файла в другой. Но ... мое приложение - эмулятор, который нуждается в производительности, а эмулированный ftruncate - медленный. Когда я говорю об этом, переход на java для файлового дескриптора тоже очень медленный. – user1063364

Смежные вопросы