Статьи

Сохранение данных в файл в вашем приложении Android

Это второй пост в моей серии о хранении в приложениях Android. Другой пост доступен здесь:

http://www.javacodegeeks.com/2014/06/introduction-how-to-save-data-in-your-android-application.html

Этот пост посвящен сохранению в файл из приложения Android, что является самым простым способом хранения данных. Существует множество ситуаций, когда вам может понадобиться сохранить файл: вы можете использовать существующий формат файла для создания файлов, которые могут быть открыты пользователем в другом приложении, или данные достаточно просты, чтобы их можно было представить в виде текстового файла. или формат как XML или YAML. Для сложных данных база данных может быть лучшим вариантом, так как доступ к большому файлу и его анализ могут быть медленными, и нет проверки целостности, если вы не кодируете их вручную. С другой стороны, здесь меньше накладных расходов, и с файлами проще работать, чем отлаживать данные в базе данных. В зависимости от того, как пользователь будет взаимодействовать (или нет) с вашими файлами, вам сначала нужно будет решить, какой тип хранилища использовать.

Внутренняя память

Каждое приложение имеет свое собственное внутреннее хранилище для сохранения файлов. Этот тип хранилища используется, если пользователь не должен иметь возможность изменять файл извне вашего приложения и если другое приложение не должно иметь доступа к этим файлам. Поскольку внутреннее хранилище является приватным для вашего приложения, файлы будут удалены, если ваше приложение будет удалено. Внутреннее хранилище также там, где ваше приложение установлено по умолчанию, поэтому ваши файлы всегда будут доступны. На некоторых старых или более дешевых устройствах внутреннее хранилище довольно ограничено, поэтому вам нужно быть осторожным с размером сохраняемых данных, если вам требуется поддержка этих устройств.

Вы никогда не должны жестко указывать путь к каталогам хранилища, так как каталог может меняться в зависимости от версии используемой ОС Android. Кроме того, в Android 4.4 представлена ​​концепция нескольких пользователей: в этом случае внутреннее и внешнее хранилище зависят от пользователя, вошедшего в систему, и файлы других пользователей будут невидимы. Вот некоторые методы, используемые для получения путей к внутренней памяти:

  • android.content.Context.getFilesDir (): возвращает объект java.io.File, представляющий корневой каталог внутреннего хранилища для вашего приложения из текущего контекста.
  • android.content.Context.getDir (String name, Context.MODE_PRIVATE) : возвращает объект java.io.File, представляющий имя каталога во внутреннем хранилище, создавая каталог, если он не существует. Второй параметр также можно использовать для установки каталога на MODE_WORLD_READABLE или MODE_WORLD_WRITABLE, чтобы он был виден всем другим приложениям, но это рискованно с точки зрения безопасности и не рекомендуется на уровне API 17 (Android 4.2).
  • android.content.Context.getCacheDir (): возвращает объект java.io.File, представляющий каталог внутреннего кэша для приложения. Это означает, что для небольших файлов (в документации предлагается не более 1 МБ), которые можно удалить в любое время, когда системе требуется больше места для хранения. Нет гарантии, что кэш будет очищен, поэтому вы также должны очищать эти файлы вручную, когда они больше не нужны.

Как видите, файлы представлены объектом File из пространства имен java.io: нет файлового объекта, специфичного для Android SDK, и используются стандартные API Java для чтения и записи файлов. Кроме того, в манифесте Android нет специального разрешения на использование внутреннего хранилища, поскольку оно уже является частным для приложения.

Внешнее хранилище

Помимо внутреннего хранилища, существует внешнее хранилище, совместно используемое всеми приложениями, которое сохраняется при удалении вашего приложения. Это хранилище, которое отображается при использовании приложения проводника и когда устройство подключено к вашему компьютеру. Он может быть реализован как SD-карта, которую можно извлечь, или как раздел встроенного хранилища в устройстве, поэтому ваше приложение должно работать, даже если карта извлечена или заменена. Чтобы проверить текущее состояние внешнего хранилища, вы можете вызвать метод getExternalStorageState () .

На устройстве с большим количеством пользователей (начиная с Android 4.4) внешнее хранилище зависит от текущего пользователя, и файлы для других пользователей недоступны. Кроме того, может быть более одного внешнего хранилища, если устройство имеет встроенное внешнее хранилище, которое является разделом на внутренней памяти и SD-карте: в этом случае встроенное хранилище является основным внешним хранилищем. Для чтения файлов из внешнего хранилища требуется разрешение READ_EXTERNAL_STORAGE, а для записи или чтения файлов требуется разрешение WRITE_EXTERNAL_STORAGE.

Вот методы, которые вы должны использовать для вызова каталогов основного внешнего хранилища:

  • android.os.Environment.getExternalStorageDirectory (): возвращает объект java.io.File, представляющий корневой каталог основного внешнего хранилища устройства, которое используется всеми приложениями.
  • android.os.Environment.getExternalStoragePublicDirectory (): возвращает объект java.io.File, представляющий общедоступный каталог для файлов определенного типа на первичном внешнем хранилище устройства. Например, вы можете получить путь к общедоступному музыкальному каталогу, вызвав Environment.getExternalStoragePublicDirectory ( Environment .DIRECTORY_MUSIC) или общедоступный каталог изображений, вызвав Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_PICTURES) .
  • android.content.Context.getExternalFilesDir (): возвращает файл java.io.File, представляющий корневой каталог основного внешнего хранилища, определенного для вашего приложения, который находится в каталоге, возвращаемом getExternalStorageDirectory () . В отличие от других каталогов внешнего хранилища, файлы, которые вы храните в этой папке, будут удалены при удалении приложения. Таким образом, если вам нужно хранить файлы, которые нужны только вашему приложению, вы должны использовать эту папку. Кроме того, для приложения не требуется специальных разрешений для чтения или записи в собственное внешнее хранилище, начиная с Android 4.4, но в более старых версиях вашему приложению требуется разрешение READ_EXTERNAL_STORAGE или WRITE_EXTERNAL_STORAGE.
  • android.content.Context.getExternalFilesDirs (): возвращает массив java.io.File, представляющий корневые каталоги всех каталогов внешнего хранилища, которые могут использоваться вашим приложением с первичным внешним хранилищем в качестве первого каталога в массиве. Все эти каталоги работают так же, как и основное хранилище, возвращаемое методом getExternalFilesDir () . Если устройство имеет встроенное хранилище в качестве основного внешнего хранилища и SD-карту в качестве вторичного внешнего хранилища, это единственный способ получить путь к SD-карте. Этот метод был введен в Android 4.4, до этого было невозможно получить путь к вторичному хранилищу.
  • android.content.Context.getExternalCacheDir (): возвращает объект java.io.File, представляющий кэш приложения в основном внешнем хранилище. Этот кэш не виден пользователю и удаляется при удалении приложения. В Android SDK отсутствует механизм удаления файлов в каталоге кеша, поэтому вам нужно управлять кешем, чтобы поддерживать его разумный максимальный размер. Начиная с Android 4.4, приложению не требуются разрешения для доступа к собственному кешу, но в более старых версиях вашему приложению требуются разрешения READ_EXTERNAL_STORAGE или WRITE_EXTERNAL_STORAGE.

Пример кода для сохранения в файл

Чтобы сохранить файл, вам нужно получить путь к хранилищу, которое вы хотите использовать, которое используется одинаково, независимо от типа используемого хранилища, поскольку все методы возвращают объект java.io.File, представляющий используемый каталог. Вот пример использования внешнего хранилища для сохранения текстового файла из Activity :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
try
   {
                            // Creates a trace file in the primary external storage space of the
                            // current application.
                            // If the file does not exists, it is created.
   File traceFile = new File(((Context)this).getExternalFilesDir(null), "TraceFile.txt");
   if (!traceFile.exists())
      traceFile.createNewFile();
                            // Adds a line to the trace file
   BufferedWriter writer = new BufferedWriter(new FileWriter(traceFile, true /*append*/));
   writer.write("This is a test trace file.");
   writer.close();
                           // Refresh the data so it can seen when the device is plugged in a
                           // computer. You may have to unplug and replug the device to see the
                           // latest changes. This is not necessary if the user should not modify
                           // the files.
    MediaScannerConnection.scanFile((Context)(this),
                                     new String[] { traceFile.toString() },
                                     null,
                                     null);
    
    }
catch (IOException e)
    {
    Log.e("com.cindypotvin.FileTest", "Unable to write to the TraceFile.txt file.");
    }
}